apprun
Version:
JavaScript library that has Elm inspired architecture, event pub-sub and components
82 lines (66 loc) • 2.14 kB
text/typescript
import { EventOptions} from './types'
export class App {
private _events: Object;
public start;
public h;
public createElement;
public render;
public Fragment;
public webComponent;
constructor() {
this._events = {};
}
on(name: string, fn: (...args) => void, options: EventOptions = {}): void {
this._events[name] = this._events[name] || [];
this._events[name].push({ fn, options });
}
off(name: string, fn: (...args) => void): void {
const subscribers = this._events[name] || [];
this._events[name] = subscribers.filter((sub) => sub.fn !== fn);
}
find(name: string): any {
return this._events[name];
}
run(name: string, ...args): number {
const subscribers = this._events[name] || [];
console.assert(subscribers && subscribers.length > 0, 'No subscriber for event: ' + name);
// Update the list of subscribers by pulling out those which will run once.
// We must do this update prior to running any of the events in case they
// cause additional events to be turned off or on.
this._events[name] = subscribers.filter((sub) => {
return !sub.options.once;
});
subscribers.forEach((sub) => {
const { fn, options } = sub;
if (options.delay) {
this.delay(name, fn, args, options);
} else {
fn.apply(this, args);
}
return !sub.options.once;
});
return subscribers.length;
}
once(name: string, fn, options: EventOptions = {}): void {
this.on(name, fn, { ...options, once: true });
}
private delay(name, fn, args, options): void {
if (options._t) clearTimeout(options._t);
options._t = setTimeout(() => {
clearTimeout(options._t);
fn.apply(this, args);
}, options.delay);
}
}
const AppRunVersions = 'AppRun-2';
let app: App;
const root = (typeof self === 'object' && self.self === self && self) ||
(typeof global === 'object' && global.global === global && global)
if (root['app'] && root['_AppRunVersions']) {
app = root['app'];
} else {
app = new App();
root['app'] = app;
root['_AppRunVersions'] = AppRunVersions;
}
export default app;