1.2.0 • Published 6 years ago

async-hooks-map v1.2.0

Weekly downloads
47
License
MIT
Repository
-
Last release
6 years ago

NPM version node version npm download npm license

A Thread-local storage (TLS) like Map implementation, base on node async hooks, support nodejs & typescript

  • thread local support for nodejs & typescript

  • named scope & chain support , easily to get closest forefather scope

  • browser or lower version of node support if provided an async-hooks implementation with constructor

install

npm install async-hooks-map

import

// typescript
import { AsyncHookMap } from 'async-hooks-map';
// javascript
const { AsyncHookMap } = require('async-hooks-map')

Usage

typescript:

    import { AsyncHookMap } from 'async-hooks-map'
    // import asyncHookMap from 'async-hooks-map'
    // import global instance which is lazy initialize
    // Object.defineProperty(exports, 'default', {
    //     get () {}
    // })

    const scope = new AsyncHookMap()

    Promise.resolve().then(() => {
        scope.set('aa', 'first')
        scope.alias('ccc')
        assert.equal(scope.get('aa'), 'first')
        return Promise.resolve().then(() => {
            assert(scope.has('aa'), 'should has the key')
            assert(!scope.has('not'), 'should not has the key')
            assert(!scope.has('aa', false), 'should not has the key in this scope')
            assert.equal(scope.get('aa'), 'first')
            scope.set('aa', 'second')
            assert.equal(scope.get('aa'), 'second')
        }).then(() => {
            assert.equal(scope.get('aa'), 'second')
            assert.equal(scope.closest('ccc').get('aa'), 'first')
            // 'root' as alias of 'ccc'
            assert.equal(scope.closest('root').get('aa'), 'first')
            scope.closest().delete('aa')
            // parent scope 'aa' has been delete, 'aa' will be first
            assert.equal(scope.get('aa'), 'first')
            scope.closest('ccc').set('bb', 'bb')
            assert.equal(scope.get('bb'), 'bb')
            scope.delete('bb')
            // can not be deleted ,because bb is set to "ccc" scope
            assert.equal(scope.get('bb'), 'bb')
        })
    })
})

Api:

export class AsyncHookMap<K=any, V=any>{

    /**
     * alias to asynchooks.executionAsyncId()
     *
     * @returns {number}
     * @memberof AsyncHookMap
     */
    executionAsyncId (): number {
        return this._asyncHooks.executionAsyncId()
    }

    /**
     * get the current AsyncMapNode
     *
     * @returns {AsyncMapNode<K, V>}
     * @memberof AsyncHookMap
     */
    current (): AsyncMapNode<K, V> 

    /**
     * add alias of AsyncNode, a AsyncNode can own multi names
     * 
     * @param {string} name 
     * @returns {this} 
     */
    alias (name: string): this

    /**
     * check the alias name
     * 
     * @param {string} name 
     * @returns {boolean} 
     */
    hasName (name: string): boolean 

    /** 
     * get parent AsyncMapNode
     * if name provided , return the named closest AsyncMapNode
     * this method will throw an error if there is no parent
     * 
     * @param {string} [name] 
     * @returns {AsyncMapNode<K, V>} 
     * @memberof AsyncStorageInterface
     */
    parent (name?: string): AsyncMapNode<K, V> | undefined

    /**
     * alias of parent
     * 
     * @param {string} name 
     * @returns {AsyncMapNode<K, V>} 
     * @memberof AsyncStorage
     */
    closest (name: string): AsyncMapNode<K, V>

    /**
     * get from AsyncStorage
     * 
     * @param {K} key 
     * @returns {(V | undefined)} 
     * @memberof AsyncStorage
     */
    get (key: K): V | undefined 

    /**
     * check key
     * @param key 
     * @param recursion check forefathers?
     */
    has (key: K, recursion = true): boolean

    /**
     * set value to current async AsyncNode
     * effect current AsyncNode and children
     * 
     * @param {K} key 
     * @param {V} value 
     * @returns {this} 
     * @memberof AsyncStorage
     */
    set (key: K, value: V): this

    /**
     * delete the value of current AsyncNode
     * 
     * @param {K} key 
     * @returns {boolean} 
     * @memberof AsyncStorage
     */
    delete (key: K): boolean

    /**
     * clear the current AsyncNode
     * 
     * @memberof AsyncStorage
     */
    clear (): void

    /**
     * print the async path
     *
     * @memberof AsyncHookMap
     */
    printPath (): void

    /**
     * get the distance of scope which has the key
     *
     * @param {K} key
     * @returns {number}
     * @memberof AsyncHookMap
     */
    distance (key: K): number
}
export interface AsyncMapNode<K, V> {
    hasName (name: string): boolean
    alias (name: string): this
    parent (name?: string): AsyncMapNode<K, V> | undefined
    closest (name: string): AsyncMapNode<K, V>
    has (key: K, recurse?: boolean): boolean
    get (key: K): V | undefined
    set (key: K, value: V): this
    clear (): void
    delete (key: K): boolean
}

tips

  • closest(name:string) contains this and parent(name?:string) not closest will throw when cant find the scope and parent() will return undefined
  • A async scope can have multiple names
  • Top async scope is named 'root' by default