conode 0.1.23 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,13 +1,11 @@
1
1
  # CoNode
2
2
 
3
- 0-Deps, simple and fast context library for NodeJS
3
+ 0-deps async context management for Node.js
4
4
 
5
5
  [![Build Status][github-image]][github-url]
6
6
  [![NPM version][npm-image]][npm-url]
7
7
  [![Downloads][downloads-image]][npm-url]
8
8
  [![Coverage Status][codecov-image]][codecov-url]
9
- [![Maintainability][codeclimate-image]][codeclimate-url]
10
- [![Snyk][snyk-image]][snyk-url]
11
9
 
12
10
  ## Table of Contents
13
11
 
@@ -18,9 +16,10 @@
18
16
 
19
17
  ## Features
20
18
 
21
- - Provides useful wrappers of [AsyncLocalStorage](https://nodejs.org/api/async_context.html)
22
- - Supports TypeScript typings
23
- - Supports CommonJS and ES Module systems
19
+ - Zero dependencies
20
+ - Lightweight wrappers around [AsyncLocalStorage](https://nodejs.org/api/async_hooks.html)
21
+ - Full TypeScript support
22
+ - Works in CommonJS and ES Module environments
24
23
 
25
24
  ## Installing
26
25
 
@@ -38,6 +37,22 @@ yarn add conode
38
37
 
39
38
  ## Examples
40
39
 
40
+ Quick start
41
+ ```typescript
42
+ import { createContext } from 'conode';
43
+
44
+ interface RequestContext { userId: string }
45
+
46
+ const reqCtx = createContext<RequestContext>();
47
+
48
+ async function handleRequest() {
49
+ console.log(reqCtx.getContext()?.userId);
50
+ }
51
+
52
+ await reqCtx.contextualize({ userId: 'abc123' }, handleRequest);
53
+ // Logs: 'abc123'
54
+ ```
55
+
41
56
  Functional approach
42
57
  ```typescript
43
58
  import { createContext } from '../index';
@@ -51,16 +66,16 @@ const action = () => {
51
66
  auth.contextualize(jwt, action);
52
67
  ```
53
68
 
54
- Class approach
69
+ Class approach with decorator
55
70
  ```typescript
56
- import { contextualize, Context } from '../index';
71
+ import { contextualize, Contextable } from '../index';
57
72
 
58
73
  const action = () => {
59
74
  const service = Service.getContext();
60
75
  console.log(service.getSomething());
61
76
  };
62
77
 
63
- class Service extends Context() {
78
+ class Service extends Contextable() {
64
79
  @contextualize
65
80
  async run() {
66
81
  await action();
@@ -83,12 +98,8 @@ Copyright (c) 2022-present Ivan Zakharchanka
83
98
  [npm-url]: https://www.npmjs.com/package/conode
84
99
  [downloads-image]: https://img.shields.io/npm/dw/conode.svg?maxAge=43200
85
100
  [npm-image]: https://img.shields.io/npm/v/conode.svg?maxAge=43200
86
- [github-url]: https://github.com/3axap4eHko/conode/actions/workflows/cicd.yml
87
- [github-image]: https://github.com/3axap4eHko/conode/actions/workflows/cicd.yml/badge.svg
101
+ [github-url]: https://github.com/3axap4eHko/conode/actions/workflows/build.yml
102
+ [github-image]: https://github.com/3axap4eHko/conode/actions/workflows/build.yml/badge.svg
88
103
  [codecov-url]: https://codecov.io/gh/3axap4eHko/conode
89
104
  [codecov-image]: https://codecov.io/gh/3axap4eHko/conode/branch/master/graph/badge.svg?token=JZ8QCGH6PI
90
- [codeclimate-url]: https://codeclimate.com/github/3axap4eHko/conode/maintainability
91
- [codeclimate-image]: https://api.codeclimate.com/v1/badges/0ba20f27f6db2b0fec8c/maintainability
92
- [snyk-url]: https://snyk.io/test/npm/conode/latest
93
- [snyk-image]: https://img.shields.io/snyk/vulnerabilities/github/3axap4eHko/conode.svg?maxAge=43200
94
105
 
package/build/index.cjs CHANGED
@@ -1,70 +1,65 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
9
  });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.contextualize = exports.Context = exports.createContext = void 0;
13
- const async_hooks_1 = require("async_hooks");
14
- const createContext = () => {
15
- const storage = new async_hooks_1.AsyncLocalStorage();
10
+ }
11
+ _export(exports, {
12
+ Contextable: function() {
13
+ return Contextable;
14
+ },
15
+ contextualize: function() {
16
+ return contextualize;
17
+ },
18
+ createContext: function() {
19
+ return createContext;
20
+ }
21
+ });
22
+ const _nodeasync_hooks = require("node:async_hooks");
23
+ const createContext = ()=>{
24
+ const storage = new _nodeasync_hooks.AsyncLocalStorage();
16
25
  return {
17
- contextualize(value, callback) {
18
- return new Promise((resolve, reject) => {
19
- storage.run(value, () => __awaiter(this, void 0, void 0, function* () {
20
- try {
21
- yield callback();
22
- resolve();
23
- }
24
- catch (e) {
25
- reject(e);
26
- }
27
- }));
28
- });
26
+ contextualize (context, callback) {
27
+ return storage.run({
28
+ context
29
+ }, callback);
29
30
  },
30
- getContext() {
31
- return storage.getStore();
31
+ getContext () {
32
+ const store = storage.getStore();
33
+ if (!store) {
34
+ throw new Error('Context not initialized');
35
+ }
36
+ return store.context;
32
37
  }
33
38
  };
34
39
  };
35
- exports.createContext = createContext;
36
- function Context(Base) {
37
- const context = (0, exports.createContext)();
38
- return Base
39
- ? class Contextual extends Base {
40
- static get context() {
41
- return context.getContext();
42
- }
43
- contextualize(callback) {
44
- return __awaiter(this, void 0, void 0, function* () {
45
- return context.contextualize(this, callback);
46
- });
47
- }
40
+ function Contextable(BaseClass = class {
41
+ }) {
42
+ const context = createContext();
43
+ return class Contextual extends BaseClass {
44
+ static getContext() {
45
+ return context.getContext();
48
46
  }
49
- : class Contextual {
50
- static get context() {
51
- return context.getContext();
52
- }
53
- contextualize(callback) {
54
- return __awaiter(this, void 0, void 0, function* () {
55
- return context.contextualize(this, callback);
56
- });
57
- }
58
- };
47
+ constructor(...args){
48
+ super(...args);
49
+ }
50
+ contextualize(callback) {
51
+ return context.contextualize(this, callback);
52
+ }
53
+ };
59
54
  }
60
- exports.Context = Context;
61
- function contextualize(target, _, descriptor) {
62
- const method = descriptor.value;
63
- function contextualized() {
64
- return target.contextualize(() => method.apply(this, arguments));
55
+ function contextualize(...args) {
56
+ const [, , descriptor] = args;
57
+ const property = descriptor?.value;
58
+ if (typeof property === 'function') {
59
+ descriptor.value = function(...args) {
60
+ return this.contextualize(()=>property.apply(this, args));
61
+ };
65
62
  }
66
- ;
67
- descriptor.value = contextualized;
68
63
  }
69
- exports.contextualize = contextualize;
70
- //# sourceMappingURL=index.cjs.map
64
+
65
+ //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAAgD;AAIzC,MAAM,aAAa,GAAG,GAAM,EAAE;IACnC,MAAM,OAAO,GAAG,IAAI,+BAAiB,EAAK,CAAC;IAE3C,OAAO;QACL,aAAa,CAAC,KAAQ,EAAE,QAAkB;YACxC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAS,EAAE;oBAC5B,IAAI;wBACF,MAAM,QAAQ,EAAE,CAAC;wBACjB,OAAO,EAAE,CAAC;qBACX;oBAAC,OAAO,CAAC,EAAE;wBACV,MAAM,CAAC,CAAC,CAAC,CAAC;qBACX;gBACH,CAAC,CAAA,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QACD,UAAU;YACR,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AApBW,QAAA,aAAa,iBAoBxB;AAIF,SAAgB,OAAO,CAAC,IAAkB;IACxC,MAAM,OAAO,GAAG,IAAA,qBAAa,GAAE,CAAC;IAEhC,OAAO,IAAI;QACT,CAAC,CAAC,MAAM,UAAW,SAAQ,IAAI;YAC7B,MAAM,KAAK,OAAO;gBAChB,OAAO,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9B,CAAC;YAEK,aAAa,CAAC,QAAkB;;oBACpC,OAAO,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAC/C,CAAC;aAAA;SACF;QACD,CAAC,CAAC,MAAM,UAAU;YAChB,MAAM,KAAK,OAAO;gBAChB,OAAO,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9B,CAAC;YAEK,aAAa,CAAC,QAAkB;;oBACpC,OAAO,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAC/C,CAAC;aAAA;SACF,CAAC;AACN,CAAC;AAtBD,0BAsBC;AAMD,SAAgB,aAAa,CAA2B,MAAS,EAAE,CAAS,EAAE,UAA6C;IACzH,MAAM,MAAM,GAAG,UAAU,CAAC,KAAM,CAAC;IACjC,SAAS,cAAc;QACrB,OAAO,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IACnE,CAAC;IAAA,CAAC;IACF,UAAU,CAAC,KAAK,GAAG,cAAqB,CAAC;AAC3C,CAAC;AAND,sCAMC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\n\nexport type Fn<T extends unknown[], R> = (...args: T) => R;\n\nexport const createContext = <T>() => {\n const storage = new AsyncLocalStorage<{ context: T }>();\n return {\n contextualize<R>(context: T, callback: Fn<[], R>): R {\n return storage.run({ context }, callback);\n },\n getContext() {\n const store = storage.getStore();\n if (!store) {\n throw new Error('Context not initialized');\n }\n return store.context;\n }\n };\n};\n\ntype Constructor = new (...args: any) => any;\n\nexport interface Contextualized {\n contextualize<R>(callback: Fn<[], R>): Promise<R>;\n}\n\nexport function Contextable(BaseClass: Constructor = class { }) {\n const context = createContext();\n return class Contextual extends BaseClass {\n static getContext<C extends Constructor>(this: C) {\n return context.getContext() as InstanceType<C>;\n }\n constructor(...args: unknown[]) {\n super(...args);\n }\n\n contextualize<R>(callback: Fn<[], R>): R {\n return context.contextualize(this, callback);\n }\n };\n}\n\nexport function contextualize<T extends Contextualized, K extends keyof T>(...args: unknown[]) {\n const [, , descriptor] = args as [T, K, TypedPropertyDescriptor<T[K]>];\n const property = descriptor?.value;\n if (typeof property === 'function') {\n descriptor.value = function(this: Contextualized, ...args: unknown[]) {\n return this.contextualize(() => property.apply(this, args));\n } as T[K];\n }\n}\n\n"],"names":["Contextable","contextualize","createContext","storage","AsyncLocalStorage","context","callback","run","getContext","store","getStore","Error","BaseClass","Contextual","constructor","args","descriptor","property","value","apply"],"mappings":";;;;;;;;;;;IA0BgBA,WAAW;eAAXA;;IAgBAC,aAAa;eAAbA;;IAtCHC,aAAa;eAAbA;;;iCAJqB;AAI3B,MAAMA,gBAAgB;IAC3B,MAAMC,UAAU,IAAIC,kCAAiB;IACrC,OAAO;QACLH,eAAiBI,OAAU,EAAEC,QAAmB;YAC9C,OAAOH,QAAQI,GAAG,CAAC;gBAAEF;YAAQ,GAAGC;QAClC;QACAE;YACE,MAAMC,QAAQN,QAAQO,QAAQ;YAC9B,IAAI,CAACD,OAAO;gBACV,MAAM,IAAIE,MAAM;YAClB;YACA,OAAOF,MAAMJ,OAAO;QACtB;IACF;AACF;AAQO,SAASL,YAAYY,YAAyB;AAAQ,CAAC;IAC5D,MAAMP,UAAUH;IAChB,OAAO,MAAMW,mBAAmBD;QAC9B,OAAOJ,aAA2C;YAChD,OAAOH,QAAQG,UAAU;QAC3B;QACAM,YAAY,GAAGC,IAAe,CAAE;YAC9B,KAAK,IAAIA;QACX;QAEAd,cAAiBK,QAAmB,EAAK;YACvC,OAAOD,QAAQJ,aAAa,CAAC,IAAI,EAAEK;QACrC;IACF;AACF;AAEO,SAASL,cAA2D,GAAGc,IAAe;IAC3F,MAAM,KAAKC,WAAW,GAAGD;IACzB,MAAME,WAAWD,YAAYE;IAC7B,IAAI,OAAOD,aAAa,YAAY;QAClCD,WAAWE,KAAK,GAAG,SAA+B,GAAGH,IAAe;YAClE,OAAO,IAAI,CAACd,aAAa,CAAC,IAAMgB,SAASE,KAAK,CAAC,IAAI,EAAEJ;QACvD;IACF;AACF"}
package/build/index.d.ts CHANGED
@@ -1,17 +1,18 @@
1
- export type Callback = () => any;
1
+ export type Fn<T extends unknown[], R> = (...args: T) => R;
2
2
  export declare const createContext: <T>() => {
3
- contextualize(value: T, callback: Callback): Promise<void>;
4
- getContext(): T | undefined;
5
- };
6
- type Constructor = new (...args: any[]) => {};
7
- export declare function Context(Base?: Constructor): {
8
- new (...args: any[]): {
9
- contextualize(callback: Callback): Promise<void>;
10
- };
11
- readonly context: unknown;
3
+ contextualize<R>(context: T, callback: Fn<[], R>): R;
4
+ getContext(): T;
12
5
  };
6
+ type Constructor = new (...args: any) => any;
13
7
  export interface Contextualized {
14
- contextualize(callback: Callback): Promise<any>;
8
+ contextualize<R>(callback: Fn<[], R>): Promise<R>;
15
9
  }
16
- export declare function contextualize<T extends Contextualized>(target: T, _: string, descriptor: TypedPropertyDescriptor<Callback>): void;
10
+ export declare function Contextable(BaseClass?: Constructor): {
11
+ new (...args: unknown[]): {
12
+ [x: string]: any;
13
+ contextualize<R>(callback: Fn<[], R>): R;
14
+ };
15
+ getContext<C extends Constructor>(this: C): InstanceType<C>;
16
+ };
17
+ export declare function contextualize<T extends Contextualized, K extends keyof T>(...args: unknown[]): void;
17
18
  export {};
package/build/index.js CHANGED
@@ -1,51 +1,44 @@
1
- import { AsyncLocalStorage } from 'async_hooks';
2
- export const createContext = () => {
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ export const createContext = ()=>{
3
3
  const storage = new AsyncLocalStorage();
4
4
  return {
5
- contextualize(value, callback) {
6
- return new Promise((resolve, reject) => {
7
- storage.run(value, async () => {
8
- try {
9
- await callback();
10
- resolve();
11
- }
12
- catch (e) {
13
- reject(e);
14
- }
15
- });
16
- });
5
+ contextualize (context, callback) {
6
+ return storage.run({
7
+ context
8
+ }, callback);
17
9
  },
18
- getContext() {
19
- return storage.getStore();
10
+ getContext () {
11
+ const store = storage.getStore();
12
+ if (!store) {
13
+ throw new Error('Context not initialized');
14
+ }
15
+ return store.context;
20
16
  }
21
17
  };
22
18
  };
23
- export function Context(Base) {
19
+ export function Contextable(BaseClass = class {
20
+ }) {
24
21
  const context = createContext();
25
- return Base
26
- ? class Contextual extends Base {
27
- static get context() {
28
- return context.getContext();
29
- }
30
- async contextualize(callback) {
31
- return context.contextualize(this, callback);
32
- }
22
+ return class Contextual extends BaseClass {
23
+ static getContext() {
24
+ return context.getContext();
33
25
  }
34
- : class Contextual {
35
- static get context() {
36
- return context.getContext();
37
- }
38
- async contextualize(callback) {
39
- return context.contextualize(this, callback);
40
- }
41
- };
26
+ constructor(...args){
27
+ super(...args);
28
+ }
29
+ contextualize(callback) {
30
+ return context.contextualize(this, callback);
31
+ }
32
+ };
42
33
  }
43
- export function contextualize(target, _, descriptor) {
44
- const method = descriptor.value;
45
- function contextualized() {
46
- return target.contextualize(() => method.apply(this, arguments));
34
+ export function contextualize(...args) {
35
+ const [, , descriptor] = args;
36
+ const property = descriptor?.value;
37
+ if (typeof property === 'function') {
38
+ descriptor.value = function(...args) {
39
+ return this.contextualize(()=>property.apply(this, args));
40
+ };
47
41
  }
48
- ;
49
- descriptor.value = contextualized;
50
42
  }
51
- //# sourceMappingURL=index.js.map
43
+
44
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIhD,MAAM,CAAC,MAAM,aAAa,GAAG,GAAM,EAAE;IACnC,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAK,CAAC;IAE3C,OAAO;QACL,aAAa,CAAC,KAAQ,EAAE,QAAkB;YACxC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;oBAC5B,IAAI;wBACF,MAAM,QAAQ,EAAE,CAAC;wBACjB,OAAO,EAAE,CAAC;qBACX;oBAAC,OAAO,CAAC,EAAE;wBACV,MAAM,CAAC,CAAC,CAAC,CAAC;qBACX;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QACD,UAAU;YACR,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAIF,MAAM,UAAU,OAAO,CAAC,IAAkB;IACxC,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAEhC,OAAO,IAAI;QACT,CAAC,CAAC,MAAM,UAAW,SAAQ,IAAI;YAC7B,MAAM,KAAK,OAAO;gBAChB,OAAO,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9B,CAAC;YAED,KAAK,CAAC,aAAa,CAAC,QAAkB;gBACpC,OAAO,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;SACF;QACD,CAAC,CAAC,MAAM,UAAU;YAChB,MAAM,KAAK,OAAO;gBAChB,OAAO,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9B,CAAC;YAED,KAAK,CAAC,aAAa,CAAC,QAAkB;gBACpC,OAAO,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;SACF,CAAC;AACN,CAAC;AAMD,MAAM,UAAU,aAAa,CAA2B,MAAS,EAAE,CAAS,EAAE,UAA6C;IACzH,MAAM,MAAM,GAAG,UAAU,CAAC,KAAM,CAAC;IACjC,SAAS,cAAc;QACrB,OAAO,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IACnE,CAAC;IAAA,CAAC;IACF,UAAU,CAAC,KAAK,GAAG,cAAqB,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\n\nexport type Fn<T extends unknown[], R> = (...args: T) => R;\n\nexport const createContext = <T>() => {\n const storage = new AsyncLocalStorage<{ context: T }>();\n return {\n contextualize<R>(context: T, callback: Fn<[], R>): R {\n return storage.run({ context }, callback);\n },\n getContext() {\n const store = storage.getStore();\n if (!store) {\n throw new Error('Context not initialized');\n }\n return store.context;\n }\n };\n};\n\ntype Constructor = new (...args: any) => any;\n\nexport interface Contextualized {\n contextualize<R>(callback: Fn<[], R>): Promise<R>;\n}\n\nexport function Contextable(BaseClass: Constructor = class { }) {\n const context = createContext();\n return class Contextual extends BaseClass {\n static getContext<C extends Constructor>(this: C) {\n return context.getContext() as InstanceType<C>;\n }\n constructor(...args: unknown[]) {\n super(...args);\n }\n\n contextualize<R>(callback: Fn<[], R>): R {\n return context.contextualize(this, callback);\n }\n };\n}\n\nexport function contextualize<T extends Contextualized, K extends keyof T>(...args: unknown[]) {\n const [, , descriptor] = args as [T, K, TypedPropertyDescriptor<T[K]>];\n const property = descriptor?.value;\n if (typeof property === 'function') {\n descriptor.value = function(this: Contextualized, ...args: unknown[]) {\n return this.contextualize(() => property.apply(this, args));\n } as T[K];\n }\n}\n\n"],"names":["AsyncLocalStorage","createContext","storage","contextualize","context","callback","run","getContext","store","getStore","Error","Contextable","BaseClass","Contextual","constructor","args","descriptor","property","value","apply"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,mBAAmB;AAIrD,OAAO,MAAMC,gBAAgB;IAC3B,MAAMC,UAAU,IAAIF;IACpB,OAAO;QACLG,eAAiBC,OAAU,EAAEC,QAAmB;YAC9C,OAAOH,QAAQI,GAAG,CAAC;gBAAEF;YAAQ,GAAGC;QAClC;QACAE;YACE,MAAMC,QAAQN,QAAQO,QAAQ;YAC9B,IAAI,CAACD,OAAO;gBACV,MAAM,IAAIE,MAAM;YAClB;YACA,OAAOF,MAAMJ,OAAO;QACtB;IACF;AACF,EAAE;AAQF,OAAO,SAASO,YAAYC,YAAyB;AAAQ,CAAC;IAC5D,MAAMR,UAAUH;IAChB,OAAO,MAAMY,mBAAmBD;QAC9B,OAAOL,aAA2C;YAChD,OAAOH,QAAQG,UAAU;QAC3B;QACAO,YAAY,GAAGC,IAAe,CAAE;YAC9B,KAAK,IAAIA;QACX;QAEAZ,cAAiBE,QAAmB,EAAK;YACvC,OAAOD,QAAQD,aAAa,CAAC,IAAI,EAAEE;QACrC;IACF;AACF;AAEA,OAAO,SAASF,cAA2D,GAAGY,IAAe;IAC3F,MAAM,KAAKC,WAAW,GAAGD;IACzB,MAAME,WAAWD,YAAYE;IAC7B,IAAI,OAAOD,aAAa,YAAY;QAClCD,WAAWE,KAAK,GAAG,SAA+B,GAAGH,IAAe;YAClE,OAAO,IAAI,CAACZ,aAAa,CAAC,IAAMc,SAASE,KAAK,CAAC,IAAI,EAAEJ;QACvD;IACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conode",
3
- "version": "0.1.23",
3
+ "version": "0.2.0",
4
4
  "description": "0-Deps, simple and fast context library for NodeJS",
5
5
  "type": "module",
6
6
  "main": "build/index.cjs",
@@ -11,13 +11,6 @@
11
11
  ],
12
12
  "module": "build/index.js",
13
13
  "sideEffects": false,
14
- "scripts": {
15
- "convert-cjs": "node scripts/convert-cjs.js",
16
- "build": "rm -rf build && yarn build:cjs && yarn build:mjs",
17
- "build:cjs": "tsc -p tsconfig.cjs.json && yarn convert-cjs",
18
- "build:mjs": "tsc -p tsconfig.mjs.json --declaration",
19
- "test": "jest"
20
- },
21
14
  "repository": {
22
15
  "type": "git",
23
16
  "url": "git+https://github.com/3axap4eHko/conode.git"
@@ -39,10 +32,16 @@
39
32
  },
40
33
  "homepage": "https://github.com/3axap4eHko/conode#readme",
41
34
  "devDependencies": {
42
- "@types/jest": "^27.5.1",
43
- "@types/node": "^17.0.35",
44
- "jest": "^28.1.0",
45
- "ts-jest": "^28.0.3",
46
- "typescript": "^4.7.2"
35
+ "@swc/jest": "^0.2.38",
36
+ "@types/jest": "^29.5.14",
37
+ "@types/node": "^22.15.18",
38
+ "inop": "^0.7.8",
39
+ "jest": "^29.7.0",
40
+ "typescript": "^5.8.3"
41
+ },
42
+ "scripts": {
43
+ "build": "rm -rf build && inop src build -i __tests__ -i *.tmp.ts && tsc --declaration --emitDeclarationOnly",
44
+ "test": "jest",
45
+ "test:build": "node src/__tests__/index.cjs && node src/__tests__/index.mjs"
47
46
  }
48
- }
47
+ }
package/src/index.ts CHANGED
@@ -1,63 +1,52 @@
1
- import { AsyncLocalStorage } from 'async_hooks';
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
 
3
- export type Callback = () => any;
3
+ export type Fn<T extends unknown[], R> = (...args: T) => R;
4
4
 
5
5
  export const createContext = <T>() => {
6
- const storage = new AsyncLocalStorage<T>();
7
-
6
+ const storage = new AsyncLocalStorage<{ context: T }>();
8
7
  return {
9
- contextualize(value: T, callback: Callback) {
10
- return new Promise<void>((resolve, reject) => {
11
- storage.run(value, async () => {
12
- try {
13
- await callback();
14
- resolve();
15
- } catch (e) {
16
- reject(e);
17
- }
18
- });
19
- });
8
+ contextualize<R>(context: T, callback: Fn<[], R>): R {
9
+ return storage.run({ context }, callback);
20
10
  },
21
11
  getContext() {
22
- return storage.getStore();
12
+ const store = storage.getStore();
13
+ if (!store) {
14
+ throw new Error('Context not initialized');
15
+ }
16
+ return store.context;
23
17
  }
24
18
  };
25
19
  };
26
20
 
27
- type Constructor = new (...args: any[]) => {};
21
+ type Constructor = new (...args: any) => any;
28
22
 
29
- export function Context(Base?: Constructor) {
30
- const context = createContext();
31
-
32
- return Base
33
- ? class Contextual extends Base {
34
- static get context() {
35
- return context.getContext();
36
- }
23
+ export interface Contextualized {
24
+ contextualize<R>(callback: Fn<[], R>): Promise<R>;
25
+ }
37
26
 
38
- async contextualize(callback: Callback) {
39
- return context.contextualize(this, callback);
40
- }
27
+ export function Contextable(BaseClass: Constructor = class { }) {
28
+ const context = createContext();
29
+ return class Contextual extends BaseClass {
30
+ static getContext<C extends Constructor>(this: C) {
31
+ return context.getContext() as InstanceType<C>;
32
+ }
33
+ constructor(...args: unknown[]) {
34
+ super(...args);
41
35
  }
42
- : class Contextual {
43
- static get context() {
44
- return context.getContext();
45
- }
46
36
 
47
- async contextualize(callback: Callback) {
48
- return context.contextualize(this, callback);
49
- }
50
- };
37
+ contextualize<R>(callback: Fn<[], R>): R {
38
+ return context.contextualize(this, callback);
39
+ }
40
+ };
51
41
  }
52
42
 
53
- export interface Contextualized {
54
- contextualize(callback: Callback): Promise<any>;
43
+ export function contextualize<T extends Contextualized, K extends keyof T>(...args: unknown[]) {
44
+ const [, , descriptor] = args as [T, K, TypedPropertyDescriptor<T[K]>];
45
+ const property = descriptor?.value;
46
+ if (typeof property === 'function') {
47
+ descriptor.value = function(this: Contextualized, ...args: unknown[]) {
48
+ return this.contextualize(() => property.apply(this, args));
49
+ } as T[K];
50
+ }
55
51
  }
56
52
 
57
- export function contextualize<T extends Contextualized>(target: T, _: string, descriptor: TypedPropertyDescriptor<Callback>) {
58
- const method = descriptor.value!;
59
- function contextualized() {
60
- return target.contextualize(() => method.apply(this, arguments));
61
- };
62
- descriptor.value = contextualized as any;
63
- }