Skip to content

Instantly share code, notes, and snippets.

@chaosmonster
Created January 23, 2021 13:10
Show Gist options
  • Save chaosmonster/e3ef129fc38ae6ff2ef91bf2658e4968 to your computer and use it in GitHub Desktop.
Save chaosmonster/e3ef129fc38ae6ff2ef91bf2658e4968 to your computer and use it in GitHub Desktop.
/// <reference lib="webworker" />
interface IMessageEvent<T> {
name: string;
payload: T;
}
function PostMessage(eventName: string) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function () {
const context = this;
const result = originalMethod.apply(context, arguments);
postMessage({name: eventName, payload: result});
return result;
}
return descriptor;
}
}
function OnMessage(eventName: string) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const internalMethodName = `__OnMessage${eventName}`;
target[internalMethodName] = descriptor.value;
return descriptor;
}
}
function Messageable<T extends { new(...args: any[]): {} }>(constructor: T) {
return class extends constructor {
constructor(...args: any[]) {
super(...args);
addEventListener('message', this.__messageDistributor.bind(this));
}
// @ts-ignore
__messageDistributor({ data }) {
if (data.name) {
const theoreticalMethodName = `__OnMessage${data.name}`;
// @ts-ignore
if (typeof this[theoreticalMethodName] === 'function') {
// @ts-ignore
this[theoreticalMethodName].apply(this, [data.payload]);
}
}
}
}
}
@Messageable
class MyWorker {
foo = 'bar';
o: string;
constructor(v: string, private p: string) {
this.o = v;
}
@PostMessage('bar')
test(value: string) {
console.log('test value', value);
console.log('test this.foo', this.foo);
console.log('test this.o', this.o);
console.log('test this.p', this.p);
return `${this.foo} - 0${value}`;
}
@OnMessage('hello')
listener(data: any) {
console.log('listener', this);
console.log('listener data', data);
console.log('listener this.foo', this.foo);
console.log('listener this.o', this.o);
console.log('listener this.p', this.p);
setTimeout(() => {
this.test(`1${this.foo} - 2${this.o} - 3${this.p} - 4${data.fuur}`);
}, 1000);
}
}
const w = new MyWorker('aaaa', 'bbbbb');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment