download
raw
4.15 kB
/**
* Main content for the worker that handles the loading and execution of
* modules within it.
*/
export function workerBootstrap() {
const modules = Object.create(null)
// Handle messages for registering a module
function registerModule({id, name, dependencies=[], init=function(){}, getTransferables=null}, callback) {
// Only register once
if (modules[id]) return
try {
// If any dependencies are modules, ensure they're registered and grab their value
dependencies = dependencies.map(dep => {
if (dep && dep.isWorkerModule) {
registerModule(dep, depResult => {
if (depResult instanceof Error) throw depResult
})
dep = modules[dep.id].value
}
return dep
})
// Rehydrate functions
init = rehydrate(`<${name}>.init`, init)
if (getTransferables) {
getTransferables = rehydrate(`<${name}>.getTransferables`, getTransferables)
}
// Initialize the module and store its value
let value = null
if (typeof init === 'function') {
value = init(...dependencies)
} else {
console.error('worker module init function failed to rehydrate')
}
modules[id] = {
id,
value,
getTransferables
}
callback(value)
} catch(err) {
if (!(err && err.noLog)) {
console.error(err)
}
callback(err)
}
}
// Handle messages for calling a registered module's result function
function callModule({id, args}, callback) {
if (!modules[id] || typeof modules[id].value !== 'function') {
callback(new Error(`Worker module ${id}: not found or its 'init' did not return a function`))
}
try {
const result = modules[id].value(...args)
if (result && typeof result.then === 'function') {
result.then(handleResult, rej => callback(rej instanceof Error ? rej : new Error('' + rej)))
} else {
handleResult(result)
}
} catch(err) {
callback(err)
}
function handleResult(result) {
try {
let tx = modules[id].getTransferables && modules[id].getTransferables(result)
if (!tx || !Array.isArray(tx) || !tx.length) {
tx = undefined //postMessage is very picky about not passing null or empty transferables
}
callback(result, tx)
} catch(err) {
console.error(err)
callback(err)
}
}
}
function rehydrate(name, str) {
let result = void 0
self.troikaDefine = r => result = r
let url = URL.createObjectURL(
new Blob(
[`/** ${name.replace(/\*/g, '')} **/\n\ntroikaDefine(\n${str}\n)`],
{type: 'application/javascript'}
)
)
try {
importScripts(url)
} catch(err) {
console.error(err)
}
URL.revokeObjectURL(url)
delete self.troikaDefine
return result
}
// Handler for all messages within the worker
self.addEventListener('message', e => {
const {messageId, action, data} = e.data
try {
// Module registration
if (action === 'registerModule') {
registerModule(data, result => {
if (result instanceof Error) {
postMessage({
messageId,
success: false,
error: result.message
})
} else {
postMessage({
messageId,
success: true,
result: {isCallable: typeof result === 'function'}
})
}
})
}
// Invocation
if (action === 'callModule') {
callModule(data, (result, transferables) => {
if (result instanceof Error) {
postMessage({
messageId,
success: false,
error: result.message
})
} else {
postMessage({
messageId,
success: true,
result
}, transferables || undefined)
}
})
}
} catch(err) {
postMessage({
messageId,
success: false,
error: err.stack
})
}
})
}

Xet Storage Details

Size:
4.15 kB
·
Xet hash:
73f19e565c102944d778b68a5f08329d6f899ebe31678a80918bad6da484ce62

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.