|
'use strict'; |
|
const JSON = require('@ungap/structured-clone/json'); |
|
const fetch = (m => m.__esModule ? m.default : m )(require('@webreflection/fetch')); |
|
const coincident = (m => m.__esModule ? m.default : m )(require('coincident/window')); |
|
const xworker = (require('./xworker.js')); |
|
const { getConfigURLAndType } = require('../loader.js'); |
|
const { assign, create, defineProperties, importCSS, importJS } = require('../utils.js'); |
|
const Hook = (require('./hook.js')); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = (...args) => |
|
|
|
|
|
|
|
|
|
|
|
|
|
function XWorker(url, options) { |
|
const worker = xworker(); |
|
const { postMessage } = worker; |
|
const isHook = this instanceof Hook; |
|
|
|
if (args.length) { |
|
const [type, version] = args; |
|
options = assign({}, options || { type, version }); |
|
if (!options.type) options.type = type; |
|
} |
|
|
|
|
|
|
|
|
|
const [ config ] = getConfigURLAndType(options.config, options.configURL); |
|
|
|
const bootstrap = fetch(url) |
|
.text() |
|
.then(code => { |
|
const hooks = isHook ? this.toJSON() : void 0; |
|
postMessage.call(worker, { options, config, code, hooks }); |
|
}); |
|
|
|
const sync = assign( |
|
coincident(worker, JSON).proxy, |
|
{ importJS, importCSS }, |
|
); |
|
|
|
const resolver = Promise.withResolvers(); |
|
|
|
defineProperties(worker, { |
|
sync: { value: sync }, |
|
ready: { value: resolver.promise }, |
|
postMessage: { |
|
value: (data, ...rest) => |
|
bootstrap.then(() => |
|
postMessage.call(worker, data, ...rest), |
|
), |
|
}, |
|
onerror: { |
|
writable: true, |
|
configurable: true, |
|
value: console.error |
|
} |
|
}); |
|
|
|
worker.addEventListener('message', event => { |
|
const { data } = event; |
|
const isError = data instanceof Error; |
|
if (isError || data === 'polyscript:done') { |
|
event.stopImmediatePropagation(); |
|
if (isError) { |
|
resolver.reject(data); |
|
worker.onerror(create(event, { |
|
type: { value: 'error' }, |
|
error: { value: data } |
|
})); |
|
} |
|
else resolver.resolve(worker); |
|
} |
|
}); |
|
|
|
if (isHook) this.onWorker?.(this.interpreter, worker); |
|
|
|
return worker; |
|
}; |
|
|