@zlepper/rpc
Version:
Allows RPC from the main thread to a background worker thread (Of any kind), using ES6 classes.
120 lines • 3.98 kB
JavaScript
class EventPipe {
listeners = new Map();
addListener(refId, listener) {
this.listeners.set(refId, listener);
return () => {
this.listeners.delete(refId);
};
}
emit(result) {
if (result.kind === 'message') {
const listener = this.listeners.get(result.refId);
if (listener) {
listener(result);
}
}
else {
const eventListeners = this._eventListeners.get(result.type);
if (eventListeners) {
for (let listener of eventListeners) {
listener(result.data);
}
}
}
}
_eventListeners = new Map();
addEventListener(type, listener, _options) {
const listeners = this._eventListeners.get(type);
if (!listeners) {
const newListeners = new Set();
newListeners.add(listener);
this._eventListeners.set(type, newListeners);
}
else {
listeners.add(listener);
}
}
removeEventListener(type, listener) {
const listeners = this._eventListeners.get(type);
if (!listeners) {
return;
}
if (listener) {
listeners.delete(listener);
}
else {
this._eventListeners.delete(type);
}
}
}
class BackgroundWrapper {
workerConnection;
refId = 1;
pipe = new EventPipe();
constructor(workerConnection) {
this.workerConnection = workerConnection;
workerConnection.addListener(data => {
this.pipe.emit(data);
});
}
get(_target, propertyName) {
if (propertyName === 'addEventListener') {
return (type, listener, options) => {
this.pipe.addEventListener(type, listener, options);
};
}
else if (propertyName === 'removeEventListener') {
return (type, listener) => {
this.pipe.removeEventListener(type, listener);
};
}
return (...args) => {
return new Promise((resolve, reject) => {
const message = {
propertyName,
args,
refId: this.refId++,
};
const cleanup = this.pipe.addListener(message.refId, result => {
if (result.kind === 'message') {
if (result.success) {
resolve(result.result);
}
else {
reject(result.error);
}
cleanup();
}
else {
throw new Error('Got event result for a non-event invocation');
}
});
this.workerConnection.send(message);
});
};
}
set(_target, _propertyName, _vValue) {
throw new Error('`set` is not supported on wrapped objects');
}
deleteProperty(_target, _propertyName) {
throw new Error('deleteProperty is not supported on wrapped objects');
}
ownKeys(_target) {
throw new Error('ownKeys is not supported on wrapped objects');
}
has(_target, _propertyName) {
throw new Error('has is not supported on wrapped objects');
}
defineProperty(_target, _propertyName, _oDesc) {
throw new Error('defineProperty is not supposed on wrapped objects');
}
getOwnPropertyDescriptor(_target, _propertyName) {
throw new Error('getOwnPropertyDescriptor is not supported on background wrapped objects');
}
}
export function wrapBackgroundService(workerConnection) {
const wrapper = new BackgroundWrapper(workerConnection);
const proxiedWrapper = new Proxy({}, wrapper);
return proxiedWrapper;
}
//# sourceMappingURL=worker-consumer.js.map