Last active
December 15, 2022 11:27
-
-
Save ahankinson/c655dd35ed455c2b0139f3bd9f60e36c to your computer and use it in GitHub Desktop.
Verovio Worker and WorkerProxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let worker = new Worker("verovio-worker.js"); | |
let verovio = new WorkerProxy(worker); | |
let setOptions = await verovio.setOptions({}); | |
let loadSuccess = await verovio.loadData(somestring); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The Worker for Verovio | |
*/ | |
class Deferred | |
{ | |
public promise: Promise<unknown>; | |
public reject: ((reason?: any) => void) | undefined; | |
public resolve: ((value: (PromiseLike<unknown> | unknown)) => void) | undefined; | |
constructor() | |
{ | |
// @ts-ignore | |
this.promise = new Promise((resolve, reject) => | |
{ | |
this.reject = reject; | |
this.resolve = resolve; | |
}); | |
} | |
} | |
importScripts("https://www.verovio.org/javascript/develop/verovio-toolkit-wasm.js"); | |
// importScripts("/dist/static/verovio-toolkit-wasm.js"); | |
// Initializing an empty object to prevent if in onMessage listener the toolkit | |
// is being accessed before Module.onRuntimeInitialized | |
let verovioToolkit = {}; | |
// Global deferred Promise that can be resolved when Module is initialized | |
const moduleIsReady = new Deferred(); | |
// Create a new toolkit instance when Module is ready | |
// @ts-ignore | |
verovio.module.onRuntimeInitialized = function () | |
{ | |
// Set the global | |
// @ts-ignore | |
verovio.enableLog(verovio.LOG_ERROR); | |
// @ts-ignore | |
verovioToolkit = new verovio.toolkit(); | |
postMessage({ | |
method: "verovio-ready", | |
result: null, | |
}); | |
}; | |
// Listen to messages send to this worker | |
addEventListener("message", (event) => | |
{ | |
// Destruct properties passed to this message event | |
const {taskId, method, args} = event.data; | |
// Check if verovio toolkit has passed method | |
// @ts-ignore | |
const fn = verovioToolkit[method || null]; | |
let result; | |
if (!fn) | |
{ | |
postMessage({ | |
taskId, | |
method, | |
result: null | |
}); | |
} | |
else | |
{ | |
// console.log("Verovio call", method, args); | |
// Always respond to worker calls with postMessage | |
// Call verovio toolkit method and pass arguments | |
result = fn.apply(verovioToolkit, args || []); | |
postMessage({ | |
taskId, | |
method, | |
result, | |
}); | |
} | |
}, false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Deferred } from "./deferred.js"; | |
let id: number = 1; | |
let callList: Map<number, Deferred> = new Map<number, Deferred>; | |
export class WorkerProxy | |
{ | |
private worker: Worker; | |
constructor(worker: Worker) | |
{ | |
this.worker = worker; | |
// Listen to response of the service worker | |
this.worker.addEventListener("message", (event) => | |
{ | |
const {taskId, result} = event.data; | |
// Check if there is a Deferred instance in workerTasks | |
const task: Deferred | undefined = callList.get(taskId); | |
if (task) | |
{ | |
// If so resolve deferred promise and pass the returned value | |
// @ts-ignore | |
task.resolve(result); | |
// delete it from the list | |
callList.delete(taskId); | |
} | |
}, false); | |
// Return a Proxy so it is possible to catch all property and method or function calls of the worker | |
return new Proxy(this, { | |
get: (target, method) => | |
{ | |
return function () | |
{ | |
const taskId = id++; | |
const args = Array.prototype.slice.call(arguments); | |
// Post a message to service worker with UUID, method or function name of the worker and passed arguments | |
target.worker.postMessage({ | |
taskId, | |
method, | |
args | |
}); | |
// Create a new Deferred instance and store it in workerTasks HashMap | |
const deferred = new Deferred(); | |
callList.set(taskId, deferred); | |
// Return the (currently still unresolved) Promise of the Deferred instance | |
return deferred.promise; | |
}; | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment