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

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules/
lib/

2
.npmingore Normal file
View File

@ -0,0 +1,2 @@
src/
node_modules/

14
package-lock.json generated Normal file
View File

@ -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
}
}
}

21
package.json Normal file
View File

@ -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 <dev@fabianstamm.de>",
"license": "MIT",
"repository": {
"url": "https://git.stamm.me/OpenServer/Utils.git",
"type": "git"
},
"devDependencies": {
"typescript": "^3.3.3333"
}
}

57
readme.md Normal file
View File

@ -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");
```

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);
}
}
}
}

13
tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "lib",
"sourceRoot": "src",
"preserveWatchOutput": true,
"declaration": true,
"sourceMap": true,
"strict": true
}
}