UNPKG

narrative-studio-sdk

Version:

Narrative SDK for building apps on the Narrative Studio

133 lines (132 loc) 5.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Narrative = void 0; const FunctionRegistry_1 = require("./scheme/FunctionRegistry"); class WorkerMessageHandler { postMessage(message) { self.postMessage(message); } addMessageListener(listener) { self.addEventListener('message', listener); } } class Narrative { /** @internal */ static _setMessageHandler(handler) { this.messageHandler = handler; } /** * Creates a new scheme. * @param scheme - The scheme to create. * @returns Promise<void | Error> - Resolves on successful scheme creation, returns the error on failure. */ static createScheme(scheme) { // Clone scheme to avoid mutating consumer input const clonedScheme = JSON.parse(JSON.stringify(scheme)); const serializedScheme = this.serializeSchemeFunctions(clonedScheme); return new Promise((resolve, reject) => { this.messageHandler.postMessage({ type: 'create-scheme', scheme: serializedScheme }); this.messageHandler.addMessageListener((event) => { if (event.data.type === 'command-response') { event.data.error ? reject(new Error(event.data.error)) : resolve(); } }); }); } /** * Serializes all function references in a scheme (e.g., file transform rules) * so they can be postMessage-safe and later looked up by ID. */ static serializeSchemeFunctions(scheme) { return { ...scheme, categories: scheme.categories.map((category) => ({ ...category, constructs: category.constructs.map((construct) => ({ ...construct, filesTransformRules: this.serializeFileTransformRules(construct.filesTransformRules), })), assets: category.assets.map((asset) => ({ ...asset, filesTransformRules: this.serializeFileTransformRules(asset.filesTransformRules), })), })), }; } /** * Replaces function fields with ID references and registers them. */ static serializeFileTransformRules(rules = []) { return rules.map((rule) => { const transformedRule = { ...rule }; if (typeof rule.transformToTarget === 'function') { const id = `transformToTarget:${rule.sourceName}->${rule.targetName}`; (0, FunctionRegistry_1.registerFunction)(id, rule.transformToTarget); transformedRule.transformToTarget = id; } if (typeof rule.transformToSource === 'function') { const id = `transformToSource:${rule.sourceName}->${rule.targetName}`; (0, FunctionRegistry_1.registerFunction)(id, rule.transformToSource); transformedRule.transformToSource = id; } if (typeof rule.merge === 'function') { const id = `merge:${rule.sourceName}->${rule.targetName}`; (0, FunctionRegistry_1.registerFunction)(id, rule.merge); transformedRule.merge = id; } return transformedRule; }); } //** Get<>(id: string): Promise<any> { /** * Sends a command to be processed, specifying the command class and its parameters. * Resolves or rejects based on the command’s result. * @param CommandClass - The constructor of the command to be sent. * @param params - Parameters required by the command. * @returns Promise<void | Error> - Resolves on successful command execution, returns the error on failure. */ static sendCommand(CommandClass, params) { return new Promise((resolve, reject) => { const payload = { type: 'command', commandClass: new CommandClass(params).name, params, }; this.messageHandler.postMessage(payload); this.messageHandler.addMessageListener((event) => { if (event.data.type === 'command-response') { event.data.error ? reject(new Error(event.data.error)) : resolve(); } }); }); } /** * Subscribes to specified events and executes a handler function when the event is received. * @param eventClasses - An array of event constructors to subscribe to. * @param handler - A function to handle the incoming events. */ static subscribeToEvents(eventClasses, handler) { eventClasses.forEach((EventClass) => { const payload = { type: 'subscribe', event: EventClass.type }; this.messageHandler.postMessage(payload); this.messageHandler.addMessageListener((event) => { if (event.data.type === 'event' && eventClasses.some((ec) => ec.type === event.data.event)) { const eventClass = eventClasses.find((ec) => ec.type === event.data.event); if (eventClass) { handler(event.data.payload); } } }); }); } /** * Updates the ReadModel with the provided data. * @param data - The data to update the ReadModel with. */ static updateReadModel(data) { const payload = { type: 'update-store', data }; this.messageHandler.postMessage(payload); } } exports.Narrative = Narrative; Narrative.messageHandler = new WorkerMessageHandler();