First Commit

This commit is contained in:
Fabian Stamm
2019-03-07 19:39:43 -05:00
commit 7fed9fc8de
9 changed files with 234 additions and 0 deletions

9
src/index.ts Normal file
View File

@ -0,0 +1,9 @@
import Lock, { Release } from "./lock";
import Observable, { ObserverCallback } from "./observable";
export {
Lock,
Release,
Observable,
ObserverCallback
}

53
src/lock.ts Executable file
View File

@ -0,0 +1,53 @@
export type Release = { release: () => void };
/**
* Basic Locking mechanism for JavaScript
*
*/
export default class Lock {
private _locked: boolean = false;
/**
* Returns the state of the Locken
*
* @returns {boolean}
*/
get locked(): boolean {
return this._locked;
}
private toCome: (() => void)[] = [];
constructor() {
this.release = this.release.bind(this);
}
/**
* Waits till lock is free and returns a release function
*
* @return {function}
*/
async getLock(): Promise<Release> {
if (!this._locked) return { release: this.lock() };
else {
return new Promise<Release>((resolve) => {
this.toCome.push(() => {
resolve({ release: this.lock() });
})
})
}
}
private lock() {
this._locked = true;
return this.release;
}
private async release() {
let next = this.toCome.shift();
if (next) {
next();
} else {
this._locked = false;
}
}
}

63
src/observable.ts Executable file
View File

@ -0,0 +1,63 @@
export type ObserverCallback<T> = (data: T[]) => void;
export default class Observable<T = any> {
private subscriber: { callback: ObserverCallback<T>, one: boolean }[] = [];
private events: T[] = [];
private timeout: number | undefined = undefined;
constructor(private collect: boolean = true, private collect_intervall: number = 100) { }
/**
* Creates Public API with subscribe and unsubscribe
*
* @returns {object}
*/
getPublicApi() {
return {
/**
* Subscribe to Observable
* @param {function} callback
*/
subscribe: (callback: ObserverCallback<T>, one: boolean = false) => {
let oldcb = this.subscriber.find(e => e.callback === callback);
if (oldcb)
oldcb.one = one
else
this.subscriber.push({ callback, one })
},
/**
* Subscribe fron Observable
* @param {function} callback
*/
unsubscribe: (callback: ObserverCallback<T>) => {
let idx = this.subscriber.findIndex(e => e.callback === callback);
if (idx >= 0) {
this.subscriber.splice(idx, 1);
}
}
}
}
/**
* Sends data to all subscribers
* @param data data to be sent
*/
send(data: T) {
if (!this.collect)
this.subscriber.forEach(e => e.callback([data]));
else {
this.events.push(data);
if (!this.timeout) {
this.timeout = setTimeout(() => {
this.subscriber.forEach(cb => {
if (cb.one)
this.events.forEach(e => cb.callback([e]));
else
cb.callback(this.events)
});
this.timeout = undefined;
}, this.collect_intervall);
}
}
}
}