{"id":22514386,"url":"https://github.com/xujif/async-hooks-map","last_synced_at":"2026-04-19T04:32:51.315Z","repository":{"id":57158725,"uuid":"130349743","full_name":"xujif/async-hooks-map","owner":"xujif","description":"A Thread-local storage (TLS) like Map implementation, base on node async hooks, support nodejs \u0026 typescript","archived":false,"fork":false,"pushed_at":"2018-06-11T11:09:25.000Z","size":30,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-06T06:15:19.015Z","etag":null,"topics":["async-hooks","nodejs","threadlocal","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xujif.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-20T10:51:23.000Z","updated_at":"2024-02-01T01:35:44.000Z","dependencies_parsed_at":"2022-09-06T04:02:10.470Z","dependency_job_id":null,"html_url":"https://github.com/xujif/async-hooks-map","commit_stats":null,"previous_names":["xujif/async-hooks-storage"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/xujif/async-hooks-map","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xujif%2Fasync-hooks-map","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xujif%2Fasync-hooks-map/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xujif%2Fasync-hooks-map/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xujif%2Fasync-hooks-map/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xujif","download_url":"https://codeload.github.com/xujif/async-hooks-map/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xujif%2Fasync-hooks-map/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31994985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async-hooks","nodejs","threadlocal","typescript"],"created_at":"2024-12-07T03:17:33.272Z","updated_at":"2026-04-19T04:32:51.298Z","avatar_url":"https://github.com/xujif.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![NPM version][npm-image]][npm-url]\r\n[![node version][node-image]][node-url]\r\n[![npm download][download-image]][download-url]\r\n[![npm license][license-image]][download-url]\r\n### A Thread-local storage (TLS) like Map implementation, base on node async hooks, support nodejs \u0026 typescript\r\n\r\n- #### thread local support for nodejs \u0026 typescript\r\n- #### named scope \u0026 chain support , easily to get closest forefather scope\r\n- #### browser or lower version of node support if provided an async-hooks implementation with constructor\r\n\r\n## install\r\n```\r\nnpm install async-hooks-map\r\n```\r\n\r\n## import\r\n```javascript\r\nconst { AsyncHookMap } = require('async-hooks-map')\r\n```\r\n## Usage\r\n\r\ntypescript: \r\n```typescript\r\n    import { AsyncHookMap } from 'async-hooks-map'\r\n    // import asyncHookMap from 'async-hooks-map'\r\n    // import global instance which is lazy initialize\r\n    // Object.defineProperty(exports, 'default', {\r\n    //     get () {}\r\n    // })\r\n\r\n    const scope = new AsyncHookMap()\r\n\r\n    Promise.resolve().then(() =\u003e {\r\n        scope.set('aa', 'first')\r\n        scope.alias('ccc')\r\n        assert.equal(scope.get('aa'), 'first')\r\n        return Promise.resolve().then(() =\u003e {\r\n            assert(scope.has('aa'), 'should has the key')\r\n            assert(!scope.has('not'), 'should not has the key')\r\n            assert(!scope.has('aa', false), 'should not has the key in this scope')\r\n            assert.equal(scope.get('aa'), 'first')\r\n            scope.set('aa', 'second')\r\n            assert.equal(scope.get('aa'), 'second')\r\n        }).then(() =\u003e {\r\n            assert.equal(scope.get('aa'), 'second')\r\n            assert.equal(scope.closest('ccc').get('aa'), 'first')\r\n            // 'root' as alias of 'ccc'\r\n            assert.equal(scope.closest('root').get('aa'), 'first')\r\n            scope.closest().delete('aa')\r\n            // parent scope 'aa' has been delete, 'aa' will be first\r\n            assert.equal(scope.get('aa'), 'first')\r\n            scope.closest('ccc').set('bb', 'bb')\r\n            assert.equal(scope.get('bb'), 'bb')\r\n            scope.delete('bb')\r\n            // can not be deleted ,because bb is set to \"ccc\" scope\r\n            assert.equal(scope.get('bb'), 'bb')\r\n        })\r\n    })\r\n})\r\n\r\n```\r\nApi:\r\n```typescript\r\nexport interface AsyncMapNode\u003cK, V\u003e {\r\n    hasName (name: string): boolean\r\n    alias (name: string): this\r\n    parent (name?: string): AsyncMapNode\u003cK, V\u003e | undefined\r\n    closest (name: string): AsyncMapNode\u003cK, V\u003e\r\n    has (key: K, recurse?: boolean): boolean\r\n    get (key: K): V | undefined\r\n    set (key: K, value: V): this\r\n    clear (): void\r\n    delete (key: K): boolean\r\n}\r\n```\r\n### tips\r\n- closest(name:string) contains this and parent(name?:string) not\r\n  closest will throw when cant find the scope and parent() will return undefined\r\n- A async scope can have multiple names\r\n- Top async scope is named 'root' by default\r\n\r\n\r\n[npm-image]: https://img.shields.io/npm/v/async-hooks-map.svg?style=flat-square\r\n[npm-url]: https://npmjs.org/package/async-hooks-map\r\n[travis-image]: https://img.shields.io/travis/https://github.com/xujif/async-hooks-map.svg?style=flat-square\r\n[travis-url]: https://travis-ci.org/https://github.com/xujif/async-hooks-map\r\n[coveralls-image]: https://img.shields.io/coveralls/https://github.com/xujif/async-hooks-map.svg?style=flat-square\r\n[coveralls-url]: https://coveralls.io/r/https://github.com/xujif/async-hooks-map?branch=master\r\n[david-image]: https://img.shields.io/david/https://github.com/xujif/async-hooks-map.svg?style=flat-square\r\n[david-url]: https://david-dm.org/https://github.com/xujif/async-hooks-map\r\n[node-image]: https://img.shields.io/badge/node.js-%3E=_8.6.0-green.svg?style=flat-square\r\n[node-url]: http://nodejs.org/download/\r\n[download-image]: https://img.shields.io/npm/dm/async-hooks-map.svg?style=flat-square\r\n[download-url]: https://npmjs.org/package/async-hooks-map\r\n[license-image]: https://img.shields.io/npm/l/async-hooks-map.svg","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxujif%2Fasync-hooks-map","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxujif%2Fasync-hooks-map","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxujif%2Fasync-hooks-map/lists"}