Files
fluxscape/packages/noodl-viewer-cloud/src/index.ts
Michael Cartner b9c60b07dc Initial commit
Co-Authored-By: Eric Tuvesson <eric.tuvesson@gmail.com>
Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com>
Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com>
Co-Authored-By: Anders Larsson <64838990+anders-topp@users.noreply.github.com>
Co-Authored-By: Johan  <4934465+joolsus@users.noreply.github.com>
Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com>
Co-Authored-By: victoratndl <99176179+victoratndl@users.noreply.github.com>
2024-01-26 11:52:55 +01:00

100 lines
3.4 KiB
TypeScript

// We need to import this so it's available in NoodlRuntime.Services
//import WebSocket from 'ws';
import { NoodlRequest, NoodlResponse } from './bridge';
import { registerNodes } from './nodes';
import NoodlRuntime from '@noodl/runtime';
import Model from '@noodl/runtime/src/model';
import NodeScope from '@noodl/runtime/src/nodescope';
import './noodl-js-api';
require('./services/userservice');
export class CloudRunner {
private runtime: NoodlRuntime;
constructor(options: {
webSocketClass?: any;
enableDebugInspectors?: boolean;
connectToEditor?: boolean;
editorAddress?: string;
}) {
this.runtime = new NoodlRuntime({
type: 'cloud',
platform: {
requestUpdate: (f: any) => setImmediate(f),
getCurrentTime: () => new Date().getTime(),
objectToString: (o: any) => JSON.stringify(o, null, 2),
webSocketClass: options.webSocketClass,
isRunningLocally: () => options.connectToEditor
},
componentFilter: (c) => c.name.startsWith('/#__cloud__/'),
dontCreateRootComponent: true
});
registerNodes(this.runtime);
this.runtime.setDebugInspectorsEnabled(options.enableDebugInspectors);
if (options.connectToEditor && options.editorAddress) {
this.runtime.connectToEditor(options.editorAddress);
}
}
public async load(exportData: any, projectSettings?: any) {
await this.runtime.setData(exportData);
if (projectSettings) this.runtime.setProjectSettings(projectSettings);
}
public async run(functionName: string, request: NoodlRequest): Promise<NoodlResponse> {
return new Promise<NoodlResponse>((resolve, reject) => {
const requestId = Math.random().toString(26).slice(2);
const requestScope = new NodeScope(this.runtime.context);
requestScope.modelScope = new Model.Scope();
this.runtime.context
.createComponentInstanceNode('/#__cloud__/' + functionName, requestId + '-' + functionName, requestScope)
.then((functionComponent) => {
// Look for the first request node (should only be one)
const requestNode = functionComponent.nodeScope.getNodesWithType('noodl.cloud.request')[0];
if (requestNode) {
// Look for all response nodes
let hasResponded = false;
const responseNodes = functionComponent.nodeScope.getNodesWithTypeRecursive('noodl.cloud.response');
responseNodes.forEach((resp) => {
resp._internal._sendResponseCallback = (resp) => {
if (hasResponded) return;
hasResponded = true;
//the functionComponent is "manually" created outside of a scope, so call the delete function directly
functionComponent._onNodeDeleted();
requestScope.reset(); //this deletes any remaining nodes, although there shouldn't be any at this point
//clean upp all models
requestScope.modelScope.reset();
resolve(resp);
};
});
setImmediate(() => {
try {
requestNode.sendRequest(request).catch(reject);
} catch (e) {
reject(e);
}
});
} else {
reject(Error('Could not find request node for function'));
}
})
.catch((e) => {
// Failed creating component
reject(e);
});
});
}
}