diff --git a/README.md b/README.md index 6a7c2eb..13f1164 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ $ npm install sdk-base Constructor argument: - {Object} options - {String} [initMethod] - the async init method name, the method should be a function return promise. If set, will execute the function in the constructor. + - {AsyncLocalStorage} [localStorage] - async localStorage instance. ```js const Base = require('sdk-base'); @@ -35,6 +36,7 @@ Constructor argument: constructor() { super({ initMethod: 'init', + localStorage: app.ctxStorage, }); } diff --git a/index.d.ts b/index.d.ts index dcb698a..53ac6af 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,33 +1,29 @@ -// Type definitions for sdk-base 3.4 -// Project: https://github.com/node-modules/sdk-base -// Definitions by: Sang Lv -// TypeScript Version: 2.9.2 - /* =================== USAGE =================== - import Base from "sdk-base"; - class newSDK extends Base {} - =============================================== */ - -/// + import Base from "sdk-base"; + class newSDK extends Base {} + class newSDK extends Base {} +=============================================== */ import { EventEmitter } from 'events'; +import { AsyncLocalStorage } from 'async_hooks'; -interface BaseOptions { - initMethod?: string; - [key: string]: any; +export interface BaseOptions { + initMethod?: string; + localStorage?: any; + [key: string]: any; } -export default class Base extends EventEmitter { - constructor(option?: BaseOptions); +export default class Base extends EventEmitter { + constructor(option?: BaseOptions); - isReady: boolean; - options: BaseOptions; - await(...args: any[]): Promise; - awaitFirst(...args: any[]): Promise; - - ready(): Promise; - ready(err: Error): void; - ready(ready: boolean): void; - ready(readyCallback: Function): void; - readyOrTimeout(milliseconds: number): Promise; + isReady: boolean; + options: BaseOptions; + localStorage?: AsyncLocalStorage; + await(...args: any[]): Promise; + awaitFirst(...args: any[]): Promise; + ready(): Promise; + ready(err: Error): void; + ready(ready: boolean): void; + ready(readyCallback: Function): void; + readyOrTimeout(milliseconds: number): Promise; } diff --git a/index.js b/index.js index 1ec7549..3d11e4c 100644 --- a/index.js +++ b/index.js @@ -109,6 +109,14 @@ class Base extends EventEmitter { return this._ready; } + /** + * get AsyncLocalStorage from options + * @return {AsyncLocalStorage} asyncLocalStorage instance or undefined + */ + get localStorage() { + return this.options.localStorage; + } + /** * set ready state or onready callback * diff --git a/index.test-d.ts b/index.test-d.ts index fff9c70..3ef459a 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,11 +1,31 @@ import { expectType } from 'tsd'; +import { AsyncLocalStorage } from 'async_hooks'; import Base from '.'; -class Client extends Base { - +class MockContenxt {} + +class Client extends Base { + constructor() { + super({ + initMethod: 'init', + localStorage: new AsyncLocalStorage, + }); + } } const client = new Client(); expectType>(client.readyOrTimeout(1000)); expectType>(client.ready()); +expectType(client.localStorage?.getStore()); + +class ClientDefaultContext extends Base { + constructor() { + super({ + initMethod: 'init', + }); + } +} + +const client2 = new ClientDefaultContext(); +expectType(client2.localStorage?.getStore()); diff --git a/package.json b/package.json index 2a11a68..def6372 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "lint": "eslint --ext .js .", "tsd": "tsd", - "test": "npm run lint && npm run test-local", + "test": "npm run lint && npm run tsd && npm run test-local", "test-local": "egg-bin test -r co-mocha", "cov": "egg-bin cov -r co-mocha", "ci": "npm run lint && npm run tsd && npm run cov", diff --git a/test/fixtures/ts/index.ts b/test/fixtures/ts/index.ts index 3f696ec..b3aa96f 100644 --- a/test/fixtures/ts/index.ts +++ b/test/fixtures/ts/index.ts @@ -1,12 +1,19 @@ import Base, { BaseOptions } from '../../..'; -class Client extends Base { +class FooContext { + traceId?: string; +} + +class ClientSimple extends Base {} + +class Client extends Base { errorHandlerLength: number = 0; - constructor(options?: BaseOptions) { - super(Object.assign({ + constructor(options: BaseOptions & { foo: string }) { + super({ initMethod: 'init', - }, options)); + ...options, + }); } init() { @@ -32,12 +39,12 @@ class Client extends Base { } export async function test() { - - let client; + let client: Client; - client = new Client(); + client = new Client({ foo: 'bar' }); client.ready(() => { console.log('ready'); + console.log('localStorage should be undefined: %o', client.localStorage?.getStore()); }); await client.await('someEvent'); await client.awaitFirst([ 'one', 'two' ]); diff --git a/test/index.test.js b/test/index.test.js index aa32d69..a8a56c8 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -3,6 +3,7 @@ const pedding = require('pedding'); const Base = require('..'); const path = require('path'); const runscript = require('runscript'); +const { AsyncLocalStorage } = require('async_hooks'); const baseDir = path.join(__dirname, './fixtures/ts'); function sleep(ms) { @@ -121,6 +122,7 @@ describe('test/index.test.js', () => { yield client.ready(); yield client.ready(); assert(client.foo === 'bar'); + assert(client.localStorage === undefined); }); it('should trigger ready callback without err', done => { @@ -190,13 +192,17 @@ describe('test/index.test.js', () => { } it('should auto init with options.initMethod', async () => { - const client = new Client({ a: 'a' }); - assert.deepEqual(client.options, { - a: 'a', - initMethod: 'init', - }); + const localStorage = new AsyncLocalStorage(); + const client = new Client({ a: 'a', localStorage }); + assert(client.options.initMethod === 'init'); + assert(client.isReady === false); await client.ready(); + assert(client.localStorage.getStore() === undefined); + await client.localStorage.run({ foo: 'bar' }, async () => { + assert(client.localStorage.getStore().foo === 'bar'); + }); await client.ready(); + assert(client.isReady === true); assert(client.foo === 'bar'); });