commit 7fed9fc8de2038f908444b50cf15081c7a6f145f Author: Fabian Stamm Date: Thu Mar 7 19:39:43 2019 -0500 First Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..88edb62 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +lib/ diff --git a/.npmingore b/.npmingore new file mode 100644 index 0000000..a3f930d --- /dev/null +++ b/.npmingore @@ -0,0 +1,2 @@ +src/ +node_modules/ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..04958c7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,14 @@ +{ + "name": "@hibas123/utils", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "typescript": { + "version": "3.3.3333", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3333.tgz", + "integrity": "sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9c12fca --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "@hibas123/utils", + "version": "1.0.0", + "description": "Different Utilities, that are not worth own packages", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "scripts": { + "prepublishOnly": "tsc", + "build": "tsc", + "watch-ts": "tsc -w" + }, + "author": "Fabian Stamm ", + "license": "MIT", + "repository": { + "url": "https://git.stamm.me/OpenServer/Utils.git", + "type": "git" + }, + "devDependencies": { + "typescript": "^3.3.3333" + } +} \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..0628ea0 --- /dev/null +++ b/readme.md @@ -0,0 +1,57 @@ +# Utils + +The utils only use standard JavaScript, so they can be used in Browser and NodeJS. + +Also they are very small. Uncompressed and unminified only 3kb. + +The utils have TypeScript definitions and are compatible with ES2015. + +## Lock + +Lock is a very simple promise based Locking mechanism for JavaScript. + +Usage: +``` typescript + import { Lock } from "@hibas123/utils"; + + const lock = new Lock(); + + async doThingThatNeedsLocking() { + let release = await lock.getLock(); // This will wait till lock from others is released + + // Do stuff that requires lock + + release(); // Release lock + } +``` + +## Observable + +Very simple and light weight Observable. + +Usage: +``` typescript + import { Observable } from "@hibas123/util"; + + const server = new Observable(); // Get new Observable Server + + // Server can only send, not subscribe to messages + // Receiving is only possible via the public API + const public = server.getPublicApi(); + + const func = (data)=>{ + console.log(data); + } + + // func will be callen when a message is available + public.subscribe(func); + + server.send("Hello World"); + + // This will unsubscribe the function. Please note, that it can + // only unsubscribe the exact function, that is used in subscribe + public.unsubscribe(func); + + // This now won't call func anymore + server.send("Hello World2"); +``` \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..ec3ae34 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,9 @@ +import Lock, { Release } from "./lock"; +import Observable, { ObserverCallback } from "./observable"; + +export { + Lock, + Release, + Observable, + ObserverCallback +} \ No newline at end of file diff --git a/src/lock.ts b/src/lock.ts new file mode 100755 index 0000000..cd7e7b0 --- /dev/null +++ b/src/lock.ts @@ -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 { + if (!this._locked) return { release: this.lock() }; + else { + return new Promise((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; + } + } +} diff --git a/src/observable.ts b/src/observable.ts new file mode 100755 index 0000000..f9395b1 --- /dev/null +++ b/src/observable.ts @@ -0,0 +1,63 @@ +export type ObserverCallback = (data: T[]) => void; + +export default class Observable { + private subscriber: { callback: ObserverCallback, 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, 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) => { + 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); + } + } + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c6f203c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2015", + "module": "commonjs", + "moduleResolution": "node", + "outDir": "lib", + "sourceRoot": "src", + "preserveWatchOutput": true, + "declaration": true, + "sourceMap": true, + "strict": true + } +} \ No newline at end of file