mirror of
https://github.com/fluxscape/fluxscape.git
synced 2026-01-12 23:32:55 +01:00
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>
This commit is contained in:
179
packages/noodl-viewer-cloud/src/sandbox.isolate.js
Normal file
179
packages/noodl-viewer-cloud/src/sandbox.isolate.js
Normal file
@@ -0,0 +1,179 @@
|
||||
import { CloudRunner } from '.';
|
||||
|
||||
let _runner
|
||||
|
||||
const _api_response_handlers = {}
|
||||
_noodl_api_response = (token,res) => {
|
||||
if(typeof _api_response_handlers[token] === 'function') {
|
||||
_api_response_handlers[token](res)
|
||||
delete _api_response_handlers[token]
|
||||
}
|
||||
}
|
||||
|
||||
const eventQueue = []
|
||||
_noodl_process_jobs = () => {
|
||||
while(eventQueue.length > 0) {
|
||||
const cb = eventQueue.shift()
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
const _defineAPI = () => {
|
||||
global.require = function(module) {
|
||||
console.log("Error, require not supported: " + module)
|
||||
}
|
||||
|
||||
global.console = {
|
||||
log:function() {
|
||||
let text = "";
|
||||
for(let i = 0; i < arguments.length; i++)
|
||||
text += arguments[i] + '\n'
|
||||
|
||||
_noodl_api_call('log',undefined,{level:'info',message:text})
|
||||
},
|
||||
info:function() {
|
||||
global.console.log.apply(undefined,arguments)
|
||||
},
|
||||
error:function() {
|
||||
let text = "";
|
||||
for(let i = 0; i < arguments.length; i++)
|
||||
text += arguments[i] + '\n'
|
||||
|
||||
_noodl_api_call('log',undefined,{level:'error',message:text})
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------- Fetch API --------------------------------
|
||||
class Headers {
|
||||
constructor(headers) {
|
||||
this._headers = headers;
|
||||
}
|
||||
|
||||
append(key,value) {
|
||||
const _key = key.toLowerCase();
|
||||
this._headers[_key] = this._headers[_key]?this._headers[_key].concat([value]):[value]
|
||||
}
|
||||
|
||||
set(key,value) {
|
||||
const _key = key.toLowerCase();
|
||||
this._headers[_key] = [value]
|
||||
}
|
||||
|
||||
get(key) {
|
||||
const _key = key.toLowerCase();
|
||||
if(this._headers[_key] === undefined) return null
|
||||
return this._headers[_key].join(', ');
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
const _key = key.toLowerCase();
|
||||
delete this._headers[_key]
|
||||
}
|
||||
|
||||
has(key) {
|
||||
const _key = key.toLowerCase();
|
||||
return this._headers[key] !== undefined
|
||||
}
|
||||
|
||||
keys() {
|
||||
return Object.keys(this._headers)
|
||||
}
|
||||
|
||||
forEach(callback, thisArg = undefined) {
|
||||
for (const name of this.keys()) {
|
||||
Reflect.apply(callback, thisArg, [this.get(name), name, this]);
|
||||
}
|
||||
}
|
||||
|
||||
* values() {
|
||||
for (const name of this.keys()) {
|
||||
yield this.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
* entries() {
|
||||
for (const name of this.keys()) {
|
||||
yield [name, this.get(name)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global.fetch = async function(url,args) {
|
||||
return new Promise((resolve,reject) => {
|
||||
const token = Math.random().toString(26).slice(2)
|
||||
_api_response_handlers[token] = (res) => {
|
||||
if(res.error === undefined) {
|
||||
res.json = () => {
|
||||
try {
|
||||
return Promise.resolve(JSON.parse(res.body))
|
||||
}
|
||||
catch(e) {
|
||||
return Promise.reject('Failed to parse JSON response')
|
||||
}
|
||||
}
|
||||
res.text = () => {
|
||||
return Promise.resolve(res.body)
|
||||
}
|
||||
res.headers = new Headers(res.headers)
|
||||
resolve(res)
|
||||
}
|
||||
else reject(res.error)
|
||||
}
|
||||
_noodl_api_call("fetch",token,{url,...args})
|
||||
})
|
||||
}
|
||||
|
||||
global.setTimeout = function(cb,millis) {
|
||||
const token = Math.random().toString(26).slice(2)
|
||||
_api_response_handlers[token] = () => {
|
||||
cb()
|
||||
}
|
||||
_noodl_api_call("setTimeout",token,millis)
|
||||
}
|
||||
|
||||
global.setImmediate = function(cb) {
|
||||
eventQueue.push(cb)
|
||||
_noodl_request_process_jobs()
|
||||
}
|
||||
}
|
||||
|
||||
const _prepareCloudRunner = async () => {
|
||||
if(!_runner) {
|
||||
_runner = new CloudRunner({});
|
||||
if(typeof _exportedComponents === 'undefined') {
|
||||
throw Error("No cloud components present.")
|
||||
}
|
||||
await _runner.load(_exportedComponents)
|
||||
}
|
||||
}
|
||||
|
||||
const handleRequest = (req) => {
|
||||
return new Promise((resolve,reject) => {
|
||||
_prepareCloudRunner().then(() => {
|
||||
_runner.run(req.function,{
|
||||
body:req.body,
|
||||
headers:req.headers,
|
||||
}).then(resolve).catch(reject)
|
||||
}).catch(reject)
|
||||
})
|
||||
}
|
||||
|
||||
_noodl_handleReq = (token,req) => {
|
||||
// req.function
|
||||
// req.headers
|
||||
// req.body
|
||||
|
||||
if(!global.log) {
|
||||
_defineAPI()
|
||||
}
|
||||
|
||||
console.info(`Cloud function ${req.function} called (requestId:${token})`)
|
||||
|
||||
handleRequest(req).then(r => {
|
||||
console.info(`Cloud function ${req.function} response [${r.statusCode}] (requestId:${token})`)
|
||||
_noodl_response(token,r)
|
||||
}).catch(e => {
|
||||
console.error(`Cloud function ${req.function} response [400] message: ${e.message} (requestId:${token})`)
|
||||
_noodl_response(token,{statusCode:400,body:JSON.stringify({error:e.message})})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user