@unional/async-context 1.0.1 → 2.0.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.
Files changed (50) hide show
  1. package/README.md +1 -0
  2. package/cjs/AsyncContext.d.ts +15 -0
  3. package/cjs/AsyncContext.d.ts.map +1 -0
  4. package/{lib → cjs}/AsyncContext.js +80 -33
  5. package/cjs/AsyncContext.js.map +1 -0
  6. package/cjs/errors.d.ts +5 -0
  7. package/cjs/errors.d.ts.map +1 -0
  8. package/{lib → cjs}/errors.js +6 -3
  9. package/cjs/errors.js.map +1 -0
  10. package/{lib → cjs}/index.d.ts +0 -0
  11. package/cjs/index.d.ts.map +1 -0
  12. package/cjs/index.js +19 -0
  13. package/cjs/index.js.map +1 -0
  14. package/esm/AsyncContext.d.ts +15 -0
  15. package/esm/AsyncContext.d.ts.map +1 -0
  16. package/esm/AsyncContext.js +57 -0
  17. package/esm/AsyncContext.js.map +1 -0
  18. package/esm/errors.d.ts +5 -0
  19. package/esm/errors.d.ts.map +1 -0
  20. package/{libm → esm}/errors.js +2 -2
  21. package/esm/errors.js.map +1 -0
  22. package/{libm → esm}/index.d.ts +0 -0
  23. package/esm/index.d.ts.map +1 -0
  24. package/{libm → esm}/index.js +0 -0
  25. package/esm/index.js.map +1 -0
  26. package/package.json +52 -19
  27. package/ts/AsyncContext.ts +53 -0
  28. package/{src → ts}/errors.ts +3 -3
  29. package/{src → ts}/index.ts +0 -0
  30. package/CHANGELOG.md +0 -8
  31. package/lib/AsyncContext.d.ts +0 -11
  32. package/lib/AsyncContext.d.ts.map +0 -1
  33. package/lib/AsyncContext.js.map +0 -1
  34. package/lib/errors.d.ts +0 -5
  35. package/lib/errors.d.ts.map +0 -1
  36. package/lib/errors.js.map +0 -1
  37. package/lib/index.d.ts.map +0 -1
  38. package/lib/index.js +0 -8
  39. package/lib/index.js.map +0 -1
  40. package/libm/AsyncContext.d.ts +0 -11
  41. package/libm/AsyncContext.d.ts.map +0 -1
  42. package/libm/AsyncContext.js +0 -25
  43. package/libm/AsyncContext.js.map +0 -1
  44. package/libm/errors.d.ts +0 -5
  45. package/libm/errors.d.ts.map +0 -1
  46. package/libm/errors.js.map +0 -1
  47. package/libm/index.d.ts.map +0 -1
  48. package/libm/index.js.map +0 -1
  49. package/src/AsyncContext.spec.ts +0 -187
  50. package/src/AsyncContext.ts +0 -27
package/README.md CHANGED
@@ -17,6 +17,7 @@ it is common to pass in a context object containing dependencies used by the fun
17
17
 
18
18
  This is useful in many cases. For example,
19
19
 
20
+ <!-- no toc -->
20
21
  - [Just-in-time Dependency Loading](#just-in-time-dependency-loading)
21
22
  - [Chained Dependency Loading](#chained-dependency-loading)
22
23
  - [Configuration Injection](#configuration-injection)
@@ -0,0 +1,15 @@
1
+ import { LeftJoin } from 'type-plus';
2
+ export declare class AsyncContext<T extends Record<string | symbol, any>> {
3
+ private context?;
4
+ private resolve;
5
+ private resolving;
6
+ constructor(context?: T | Promise<T> | AsyncContext.Initializer<T> | undefined);
7
+ get(): Promise<T>;
8
+ initialize(context: T | Promise<T> | AsyncContext.Initializer<T>): void;
9
+ extend<R extends Record<string | symbol, any>>(context: R | Promise<R> | AsyncContext.Transformer<T, R>): AsyncContext<LeftJoin<T, R>>;
10
+ }
11
+ export declare namespace AsyncContext {
12
+ type Initializer<T> = () => T | Promise<T>;
13
+ type Transformer<T, R> = (context: AsyncContext<T>) => R | Promise<R>;
14
+ }
15
+ //# sourceMappingURL=AsyncContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncContext.d.ts","sourceRoot":"","sources":["../ts/AsyncContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAGpC,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC;IAGlD,OAAO,CAAC,OAAO,CAAC;IAF5B,OAAO,CAAC,OAAO,CAAmD;IAClE,OAAO,CAAC,SAAS,CAAwB;gBACrB,OAAO,CAAC,0DAA8C;IACpE,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAMvB,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC;IAKhE,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAQvI;AAED,yBAAiB,YAAY,CAAC;IAC5B,KAAY,WAAW,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACjD,KAAY,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAC7E"}
@@ -47,46 +47,93 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
47
47
  }
48
48
  };
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.AsyncContext = void 0;
50
51
  var errors_1 = require("./errors");
51
52
  var AsyncContext = /** @class */ (function () {
52
53
  function AsyncContext(context) {
53
- this.context = context;
54
+ Object.defineProperty(this, "context", {
55
+ enumerable: true,
56
+ configurable: true,
57
+ writable: true,
58
+ value: context
59
+ });
60
+ Object.defineProperty(this, "resolve", {
61
+ enumerable: true,
62
+ configurable: true,
63
+ writable: true,
64
+ value: void 0
65
+ });
66
+ Object.defineProperty(this, "resolving", {
67
+ enumerable: true,
68
+ configurable: true,
69
+ writable: true,
70
+ value: void 0
71
+ });
54
72
  }
55
- AsyncContext.prototype.get = function () {
56
- return __awaiter(this, void 0, void 0, function () {
57
- var _this = this;
58
- return __generator(this, function (_a) {
59
- if (this.resolving)
60
- return [2 /*return*/, this.resolving];
61
- return [2 /*return*/, this.resolving = this.context ? resolveContext(this.context) : new Promise(function (a) { return _this.resolve = a; })];
73
+ Object.defineProperty(AsyncContext.prototype, "get", {
74
+ enumerable: false,
75
+ configurable: true,
76
+ writable: true,
77
+ value: function () {
78
+ return __awaiter(this, void 0, void 0, function () {
79
+ var _this = this;
80
+ return __generator(this, function (_a) {
81
+ if (this.resolving)
82
+ return [2 /*return*/, this.resolving];
83
+ return [2 /*return*/, this.resolving = this.context
84
+ ? Promise.resolve(initContext(this.context))
85
+ : new Promise(function (a) { return _this.resolve = a; })];
86
+ });
62
87
  });
63
- });
64
- };
65
- AsyncContext.prototype.initialize = function (context) {
66
- if (this.context)
67
- throw new errors_1.ContextAlreadyInitialized();
68
- this.context = context;
69
- if (this.resolve)
70
- this.resolve(resolveContext(context));
71
- };
72
- AsyncContext.prototype.extend = function (context) {
73
- var _this = this;
74
- return new AsyncContext(function () { return __awaiter(_this, void 0, void 0, function () { var _a, _b; return __generator(this, function (_c) {
75
- switch (_c.label) {
76
- case 0:
77
- _a = [{}];
78
- return [4 /*yield*/, this.get()];
79
- case 1:
80
- _b = [__assign.apply(void 0, _a.concat([_c.sent()]))];
81
- return [4 /*yield*/, resolveContext(context, this)];
82
- case 2: return [2 /*return*/, (__assign.apply(void 0, _b.concat([_c.sent()])))];
83
- }
84
- }); }); });
85
- };
88
+ }
89
+ });
90
+ Object.defineProperty(AsyncContext.prototype, "initialize", {
91
+ enumerable: false,
92
+ configurable: true,
93
+ writable: true,
94
+ value: function (context) {
95
+ if (this.context)
96
+ throw new errors_1.ContextAlreadyInitialized();
97
+ this.context = context;
98
+ if (this.resolve)
99
+ this.resolve(initContext(context));
100
+ }
101
+ });
102
+ Object.defineProperty(AsyncContext.prototype, "extend", {
103
+ enumerable: false,
104
+ configurable: true,
105
+ writable: true,
106
+ value: function (context) {
107
+ var _this = this;
108
+ return new AsyncContext(function () { return __awaiter(_this, void 0, void 0, function () {
109
+ var current, next;
110
+ return __generator(this, function (_a) {
111
+ switch (_a.label) {
112
+ case 0: return [4 /*yield*/, this.get()];
113
+ case 1:
114
+ current = _a.sent();
115
+ return [4 /*yield*/, transformContext(context, this)];
116
+ case 2:
117
+ next = _a.sent();
118
+ return [2 /*return*/, __assign(__assign({}, current), next)];
119
+ }
120
+ });
121
+ }); });
122
+ }
123
+ });
86
124
  return AsyncContext;
87
125
  }());
88
126
  exports.AsyncContext = AsyncContext;
89
- function resolveContext(context, currentContext) {
90
- return typeof context === 'function' ? context(currentContext) : context;
127
+ function initContext(context) {
128
+ return isInitializer(context) ? context() : context;
129
+ }
130
+ function transformContext(context, currentContext) {
131
+ return isTransformer(context) ? context(currentContext) : context;
132
+ }
133
+ function isTransformer(context) {
134
+ return typeof context === 'function';
135
+ }
136
+ function isInitializer(context) {
137
+ return typeof context === 'function';
91
138
  }
92
139
  //# sourceMappingURL=AsyncContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncContext.js","sourceRoot":"","sources":["../ts/AsyncContext.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,mCAAoD;AAEpD;IAGE,sBAAoB,OAAsD;;;;;mBAAtD;;QAFpB;;;;;WAAkE;QAClE;;;;;WAAyC;IACqC,CAAC;;;;;eAC/E;;;;oBACE,IAAI,IAAI,CAAC,SAAS;wBAAE,sBAAO,IAAI,CAAC,SAAS,EAAA;oBACzC,sBAAO,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO;4BAClC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BAC5C,CAAC,CAAC,IAAI,OAAO,CAAI,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,OAAO,GAAG,CAAC,EAAhB,CAAgB,CAAC,EAAA;;;SAC1C;;;;;;eACD,UAAW,OAAqD;YAC9D,IAAI,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,kCAAyB,EAAE,CAAA;YACvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;YACtB,IAAI,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;QACtD,CAAC;;;;;;eACD,UAA+C,OAAwD;YAAvG,iBAOC;YANC,OAAO,IAAI,YAAY,CAAC;;;;gCACN,qBAAM,IAAI,CAAC,GAAG,EAAE,EAAA;;4BAA1B,OAAO,GAAG,SAAgB;4BACnB,qBAAM,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,EAAA;;4BAA5C,IAAI,GAAG,SAAqC;4BAElD,sBAAO,sBAAK,OAAO,GAAK,IAAI,CAAoB,EAAA;;;iBACjD,CAAC,CAAA;QACJ,CAAC;;IACH,mBAAC;AAAD,CAAC,AAvBD,IAuBC;AAvBY,oCAAY;AA8BzB,SAAS,WAAW,CAEhB,OAAqD;IACvD,OAAO,aAAa,CAAI,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;AACxD,CAAC;AAED,SAAS,gBAAgB,CAGvB,OAAwD,EAAE,cAA+B;IACzF,OAAO,aAAa,CAAO,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AACzE,CAAC;AAED,SAAS,aAAa,CAAO,OAAY;IACvC,OAAO,OAAO,OAAO,KAAK,UAAU,CAAA;AACtC,CAAC;AAED,SAAS,aAAa,CAAI,OAAY;IACpC,OAAO,OAAO,OAAO,KAAK,UAAU,CAAA;AACtC,CAAC","sourcesContent":["import { LeftJoin } from 'type-plus'\nimport { ContextAlreadyInitialized } from './errors'\n\nexport class AsyncContext<T extends Record<string | symbol, any>> {\n private resolve: ((value: T | PromiseLike<T>) => void) | undefined\n private resolving: Promise<T> | undefined\n constructor(private context?: T | Promise<T> | AsyncContext.Initializer<T>) { }\n async get(): Promise<T> {\n if (this.resolving) return this.resolving\n return this.resolving = this.context\n ? Promise.resolve(initContext(this.context))\n : new Promise<T>(a => this.resolve = a)\n }\n initialize(context: T | Promise<T> | AsyncContext.Initializer<T>) {\n if (this.context) throw new ContextAlreadyInitialized()\n this.context = context\n if (this.resolve) this.resolve(initContext(context))\n }\n extend<R extends Record<string | symbol, any>>(context: R | Promise<R> | AsyncContext.Transformer<T, R>): AsyncContext<LeftJoin<T, R>> {\n return new AsyncContext(async () => {\n const current = await this.get()\n const next = await transformContext(context, this)\n\n return { ...current, ...next } as LeftJoin<T, R>\n })\n }\n}\n\nexport namespace AsyncContext {\n export type Initializer<T> = () => T | Promise<T>\n export type Transformer<T, R> = (context: AsyncContext<T>) => R | Promise<R>\n}\n\nfunction initContext<\n T extends Record<string | symbol, any>,\n >(context: T | Promise<T> | AsyncContext.Initializer<T>): T | Promise<T> {\n return isInitializer<T>(context) ? context() : context\n}\n\nfunction transformContext<\n T extends Record<string | symbol, any>,\n R extends Record<string | symbol, any>\n>(context: R | Promise<R> | AsyncContext.Transformer<T, R>, currentContext: AsyncContext<T>): R | Promise<R> {\n return isTransformer<T, R>(context) ? context(currentContext) : context\n}\n\nfunction isTransformer<T, R>(context: any): context is AsyncContext.Transformer<T, R> {\n return typeof context === 'function'\n}\n\nfunction isInitializer<T>(context: any): context is AsyncContext.Initializer<T> {\n return typeof context === 'function'\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { IsoError, ModuleError } from 'iso-error';
2
+ export declare class ContextAlreadyInitialized extends ModuleError {
3
+ constructor(options?: IsoError.Options);
4
+ }
5
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../ts/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEjD,qBAAa,yBAA0B,SAAQ,WAAW;gBAC5C,OAAO,CAAC,EAAE,QAAQ,CAAC,OAAO;CAGvC"}
@@ -3,21 +3,24 @@ var __extends = (this && this.__extends) || (function () {
3
3
  var extendStatics = function (d, b) {
4
4
  extendStatics = Object.setPrototypeOf ||
5
5
  ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
7
  return extendStatics(d, b);
8
8
  };
9
9
  return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
10
12
  extendStatics(d, b);
11
13
  function __() { this.constructor = d; }
12
14
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13
15
  };
14
16
  })();
15
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.ContextAlreadyInitialized = void 0;
16
19
  var iso_error_1 = require("iso-error");
17
20
  var ContextAlreadyInitialized = /** @class */ (function (_super) {
18
21
  __extends(ContextAlreadyInitialized, _super);
19
- function ContextAlreadyInitialized() {
20
- return _super.call(this, '@unional/async-context', 'context can only be initialized once.') || this;
22
+ function ContextAlreadyInitialized(options) {
23
+ return _super.call(this, '@unional/async-context', 'context can only be initialized once.', options) || this;
21
24
  }
22
25
  return ContextAlreadyInitialized;
23
26
  }(iso_error_1.ModuleError));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../ts/errors.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,uCAAiD;AAEjD;IAA+C,6CAAW;IACxD,mCAAY,OAA0B;eACpC,kBAAM,wBAAwB,EAAE,uCAAuC,EAAE,OAAO,CAAC;IACnF,CAAC;IACH,gCAAC;AAAD,CAAC,AAJD,CAA+C,uBAAW,GAIzD;AAJY,8DAAyB","sourcesContent":["import { IsoError, ModuleError } from 'iso-error'\n\nexport class ContextAlreadyInitialized extends ModuleError {\n constructor(options?: IsoError.Options) {\n super('@unional/async-context', 'context can only be initialized once.', options)\n }\n}\n"]}
File without changes
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA"}
package/cjs/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./AsyncContext"), exports);
18
+ __exportStar(require("./errors"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA8B;AAC9B,2CAAwB","sourcesContent":["export * from './AsyncContext'\nexport * from './errors'\n"]}
@@ -0,0 +1,15 @@
1
+ import { LeftJoin } from 'type-plus';
2
+ export declare class AsyncContext<T extends Record<string | symbol, any>> {
3
+ private context?;
4
+ private resolve;
5
+ private resolving;
6
+ constructor(context?: T | Promise<T> | AsyncContext.Initializer<T> | undefined);
7
+ get(): Promise<T>;
8
+ initialize(context: T | Promise<T> | AsyncContext.Initializer<T>): void;
9
+ extend<R extends Record<string | symbol, any>>(context: R | Promise<R> | AsyncContext.Transformer<T, R>): AsyncContext<LeftJoin<T, R>>;
10
+ }
11
+ export declare namespace AsyncContext {
12
+ type Initializer<T> = () => T | Promise<T>;
13
+ type Transformer<T, R> = (context: AsyncContext<T>) => R | Promise<R>;
14
+ }
15
+ //# sourceMappingURL=AsyncContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncContext.d.ts","sourceRoot":"","sources":["../ts/AsyncContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAGpC,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC;IAGlD,OAAO,CAAC,OAAO,CAAC;IAF5B,OAAO,CAAC,OAAO,CAAmD;IAClE,OAAO,CAAC,SAAS,CAAwB;gBACrB,OAAO,CAAC,0DAA8C;IACpE,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAMvB,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC;IAKhE,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAQvI;AAED,yBAAiB,YAAY,CAAC;IAC5B,KAAY,WAAW,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACjD,KAAY,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAC7E"}
@@ -0,0 +1,57 @@
1
+ import { ContextAlreadyInitialized } from './errors';
2
+ export class AsyncContext {
3
+ constructor(context) {
4
+ Object.defineProperty(this, "context", {
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true,
8
+ value: context
9
+ });
10
+ Object.defineProperty(this, "resolve", {
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true,
14
+ value: void 0
15
+ });
16
+ Object.defineProperty(this, "resolving", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: void 0
21
+ });
22
+ }
23
+ async get() {
24
+ if (this.resolving)
25
+ return this.resolving;
26
+ return this.resolving = this.context
27
+ ? Promise.resolve(initContext(this.context))
28
+ : new Promise(a => this.resolve = a);
29
+ }
30
+ initialize(context) {
31
+ if (this.context)
32
+ throw new ContextAlreadyInitialized();
33
+ this.context = context;
34
+ if (this.resolve)
35
+ this.resolve(initContext(context));
36
+ }
37
+ extend(context) {
38
+ return new AsyncContext(async () => {
39
+ const current = await this.get();
40
+ const next = await transformContext(context, this);
41
+ return { ...current, ...next };
42
+ });
43
+ }
44
+ }
45
+ function initContext(context) {
46
+ return isInitializer(context) ? context() : context;
47
+ }
48
+ function transformContext(context, currentContext) {
49
+ return isTransformer(context) ? context(currentContext) : context;
50
+ }
51
+ function isTransformer(context) {
52
+ return typeof context === 'function';
53
+ }
54
+ function isInitializer(context) {
55
+ return typeof context === 'function';
56
+ }
57
+ //# sourceMappingURL=AsyncContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncContext.js","sourceRoot":"","sources":["../ts/AsyncContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAA;AAEpD,MAAM,OAAO,YAAY;IAGvB,YAAoB,OAAsD;;;;;mBAAtD;;QAFpB;;;;;WAAkE;QAClE;;;;;WAAyC;IACqC,CAAC;IAC/E,KAAK,CAAC,GAAG;QACP,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAA;QACzC,OAAO,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO;YAClC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5C,CAAC,CAAC,IAAI,OAAO,CAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;IAC3C,CAAC;IACD,UAAU,CAAC,OAAqD;QAC9D,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,yBAAyB,EAAE,CAAA;QACvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;IACtD,CAAC;IACD,MAAM,CAAyC,OAAwD;QACrG,OAAO,IAAI,YAAY,CAAC,KAAK,IAAI,EAAE;YACjC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;YAChC,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YAElD,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,EAAoB,CAAA;QAClD,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAOD,SAAS,WAAW,CAEhB,OAAqD;IACvD,OAAO,aAAa,CAAI,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;AACxD,CAAC;AAED,SAAS,gBAAgB,CAGvB,OAAwD,EAAE,cAA+B;IACzF,OAAO,aAAa,CAAO,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AACzE,CAAC;AAED,SAAS,aAAa,CAAO,OAAY;IACvC,OAAO,OAAO,OAAO,KAAK,UAAU,CAAA;AACtC,CAAC;AAED,SAAS,aAAa,CAAI,OAAY;IACpC,OAAO,OAAO,OAAO,KAAK,UAAU,CAAA;AACtC,CAAC","sourcesContent":["import { LeftJoin } from 'type-plus'\nimport { ContextAlreadyInitialized } from './errors'\n\nexport class AsyncContext<T extends Record<string | symbol, any>> {\n private resolve: ((value: T | PromiseLike<T>) => void) | undefined\n private resolving: Promise<T> | undefined\n constructor(private context?: T | Promise<T> | AsyncContext.Initializer<T>) { }\n async get(): Promise<T> {\n if (this.resolving) return this.resolving\n return this.resolving = this.context\n ? Promise.resolve(initContext(this.context))\n : new Promise<T>(a => this.resolve = a)\n }\n initialize(context: T | Promise<T> | AsyncContext.Initializer<T>) {\n if (this.context) throw new ContextAlreadyInitialized()\n this.context = context\n if (this.resolve) this.resolve(initContext(context))\n }\n extend<R extends Record<string | symbol, any>>(context: R | Promise<R> | AsyncContext.Transformer<T, R>): AsyncContext<LeftJoin<T, R>> {\n return new AsyncContext(async () => {\n const current = await this.get()\n const next = await transformContext(context, this)\n\n return { ...current, ...next } as LeftJoin<T, R>\n })\n }\n}\n\nexport namespace AsyncContext {\n export type Initializer<T> = () => T | Promise<T>\n export type Transformer<T, R> = (context: AsyncContext<T>) => R | Promise<R>\n}\n\nfunction initContext<\n T extends Record<string | symbol, any>,\n >(context: T | Promise<T> | AsyncContext.Initializer<T>): T | Promise<T> {\n return isInitializer<T>(context) ? context() : context\n}\n\nfunction transformContext<\n T extends Record<string | symbol, any>,\n R extends Record<string | symbol, any>\n>(context: R | Promise<R> | AsyncContext.Transformer<T, R>, currentContext: AsyncContext<T>): R | Promise<R> {\n return isTransformer<T, R>(context) ? context(currentContext) : context\n}\n\nfunction isTransformer<T, R>(context: any): context is AsyncContext.Transformer<T, R> {\n return typeof context === 'function'\n}\n\nfunction isInitializer<T>(context: any): context is AsyncContext.Initializer<T> {\n return typeof context === 'function'\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { IsoError, ModuleError } from 'iso-error';
2
+ export declare class ContextAlreadyInitialized extends ModuleError {
3
+ constructor(options?: IsoError.Options);
4
+ }
5
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../ts/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEjD,qBAAa,yBAA0B,SAAQ,WAAW;gBAC5C,OAAO,CAAC,EAAE,QAAQ,CAAC,OAAO;CAGvC"}
@@ -1,7 +1,7 @@
1
1
  import { ModuleError } from 'iso-error';
2
2
  export class ContextAlreadyInitialized extends ModuleError {
3
- constructor() {
4
- super('@unional/async-context', 'context can only be initialized once.');
3
+ constructor(options) {
4
+ super('@unional/async-context', 'context can only be initialized once.', options);
5
5
  }
6
6
  }
7
7
  //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../ts/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,WAAW,EAAE,MAAM,WAAW,CAAA;AAEjD,MAAM,OAAO,yBAA0B,SAAQ,WAAW;IACxD,YAAY,OAA0B;QACpC,KAAK,CAAC,wBAAwB,EAAE,uCAAuC,EAAE,OAAO,CAAC,CAAA;IACnF,CAAC;CACF","sourcesContent":["import { IsoError, ModuleError } from 'iso-error'\n\nexport class ContextAlreadyInitialized extends ModuleError {\n constructor(options?: IsoError.Options) {\n super('@unional/async-context', 'context can only be initialized once.', options)\n }\n}\n"]}
File without changes
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA"}
File without changes
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA","sourcesContent":["export * from './AsyncContext'\nexport * from './errors'\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unional/async-context",
3
- "version": "1.0.1",
3
+ "version": "2.0.0",
4
4
  "description": "Asynchronous context for functional style programming",
5
5
  "keywords": [
6
6
  "async",
@@ -23,30 +23,63 @@
23
23
  "email": "homawong@gmail.com"
24
24
  },
25
25
  "sideEffects": false,
26
- "main": "lib/index.js",
27
- "module": "libm/index.js",
28
- "jsnext:main": "libm/index.js",
29
- "typings": "libm/index.d.ts",
26
+ "main": "cjs/index.js",
27
+ "module": "esm/index.js",
28
+ "jsnext:main": "esm/index.js",
29
+ "typings": "esm/index.d.ts",
30
30
  "files": [
31
- "lib",
32
- "libm",
33
- "src"
31
+ "cjs",
32
+ "esm",
33
+ "ts",
34
+ "!**/*.spec.*"
34
35
  ],
35
- "scripts": {
36
- "build": "tsc -p tsconfig.lib.json && tsc -p tsconfig.libm.json",
37
- "clean": "rimraf lib libm .tsbuildinfo",
38
- "depcheck": "dependency-check . --unused --no-dev -i type-plus && dependency-check . --missing --no-dev",
39
- "prepublishOnly": "yarn build"
40
- },
41
36
  "dependencies": {
42
- "iso-error": "^3.2.1",
43
- "type-plus": "^1.35.1"
37
+ "iso-error": "^4.3.6",
38
+ "type-plus": "^4.11.1"
39
+ },
40
+ "devDependencies": {
41
+ "@size-limit/preset-small-lib": "^8.0.1",
42
+ "@types/node": "^14.18.23",
43
+ "@typescript-eslint/eslint-plugin": "^5.33.0",
44
+ "@typescript-eslint/parser": "^5.33.0",
45
+ "assertron": "^10.0.0",
46
+ "cross-env": "^7.0.3",
47
+ "depcheck": "^1.4.3",
48
+ "eslint": "^8.22.0",
49
+ "eslint-config-prettier": "^8.5.0",
50
+ "eslint-plugin-harmony": "^7.1.0",
51
+ "jest": "^28.1.3",
52
+ "npm-run-all": "^4.1.5",
53
+ "rimraf": "^3.0.2",
54
+ "size-limit": "^8.0.1",
55
+ "ts-jest": "^28.0.7",
56
+ "typescript": "^4.7.4"
44
57
  },
45
58
  "engines": {
46
- "node": ">= 10"
59
+ "node": ">= 14.16"
47
60
  },
48
61
  "publishConfig": {
49
62
  "access": "public"
50
63
  },
51
- "gitHead": "ad9a0ddeda5adaaeca0a0dfb9a06d25f2f992f7c"
52
- }
64
+ "size-limit": [
65
+ {
66
+ "path": "./cjs/index.js"
67
+ },
68
+ {
69
+ "path": "./esm/index.js"
70
+ }
71
+ ],
72
+ "scripts": {
73
+ "build": "run-p build:cjs build:esm",
74
+ "build:cjs": "tsc -p tsconfig.cjs.json",
75
+ "build:esm": "tsc",
76
+ "clean": "rimraf cjs esm .tsbuildinfo",
77
+ "coverage": "jest --coverage",
78
+ "depcheck": "depcheck",
79
+ "lint": "cross-env TIMING=1 eslint --ext=ts,js,cjs,mjs .",
80
+ "nuke": "pnpm clean && rimraf node_modules",
81
+ "size": "size-limit",
82
+ "test": "jest",
83
+ "verify": "npm-run-all -p lint build coverage -p depcheck size"
84
+ }
85
+ }
@@ -0,0 +1,53 @@
1
+ import { LeftJoin } from 'type-plus'
2
+ import { ContextAlreadyInitialized } from './errors'
3
+
4
+ export class AsyncContext<T extends Record<string | symbol, any>> {
5
+ private resolve: ((value: T | PromiseLike<T>) => void) | undefined
6
+ private resolving: Promise<T> | undefined
7
+ constructor(private context?: T | Promise<T> | AsyncContext.Initializer<T>) { }
8
+ async get(): Promise<T> {
9
+ if (this.resolving) return this.resolving
10
+ return this.resolving = this.context
11
+ ? Promise.resolve(initContext(this.context))
12
+ : new Promise<T>(a => this.resolve = a)
13
+ }
14
+ initialize(context: T | Promise<T> | AsyncContext.Initializer<T>) {
15
+ if (this.context) throw new ContextAlreadyInitialized()
16
+ this.context = context
17
+ if (this.resolve) this.resolve(initContext(context))
18
+ }
19
+ extend<R extends Record<string | symbol, any>>(context: R | Promise<R> | AsyncContext.Transformer<T, R>): AsyncContext<LeftJoin<T, R>> {
20
+ return new AsyncContext(async () => {
21
+ const current = await this.get()
22
+ const next = await transformContext(context, this)
23
+
24
+ return { ...current, ...next } as LeftJoin<T, R>
25
+ })
26
+ }
27
+ }
28
+
29
+ export namespace AsyncContext {
30
+ export type Initializer<T> = () => T | Promise<T>
31
+ export type Transformer<T, R> = (context: AsyncContext<T>) => R | Promise<R>
32
+ }
33
+
34
+ function initContext<
35
+ T extends Record<string | symbol, any>,
36
+ >(context: T | Promise<T> | AsyncContext.Initializer<T>): T | Promise<T> {
37
+ return isInitializer<T>(context) ? context() : context
38
+ }
39
+
40
+ function transformContext<
41
+ T extends Record<string | symbol, any>,
42
+ R extends Record<string | symbol, any>
43
+ >(context: R | Promise<R> | AsyncContext.Transformer<T, R>, currentContext: AsyncContext<T>): R | Promise<R> {
44
+ return isTransformer<T, R>(context) ? context(currentContext) : context
45
+ }
46
+
47
+ function isTransformer<T, R>(context: any): context is AsyncContext.Transformer<T, R> {
48
+ return typeof context === 'function'
49
+ }
50
+
51
+ function isInitializer<T>(context: any): context is AsyncContext.Initializer<T> {
52
+ return typeof context === 'function'
53
+ }
@@ -1,7 +1,7 @@
1
- import { ModuleError } from 'iso-error'
1
+ import { IsoError, ModuleError } from 'iso-error'
2
2
 
3
3
  export class ContextAlreadyInitialized extends ModuleError {
4
- constructor() {
5
- super('@unional/async-context', 'context can only be initialized once.')
4
+ constructor(options?: IsoError.Options) {
5
+ super('@unional/async-context', 'context can only be initialized once.', options)
6
6
  }
7
7
  }
File without changes
package/CHANGELOG.md DELETED
@@ -1,8 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- ## 1.0.1 (2020-03-15)
7
-
8
- **Note:** Version bump only for package @unional/async-context
@@ -1,11 +0,0 @@
1
- import { LeftJoin } from 'type-plus';
2
- export declare class AsyncContext<T extends Record<string | symbol, any>> {
3
- private context?;
4
- private resolve;
5
- private resolving;
6
- constructor(context?: T | Promise<T> | (() => T | Promise<T>) | undefined);
7
- get(): Promise<T>;
8
- initialize(context: T | Promise<T> | (() => T | Promise<T>)): void;
9
- extend<R extends Record<string | symbol, any>>(context: R | Promise<R> | ((context: AsyncContext<T>) => R | Promise<R>)): AsyncContext<LeftJoin<T, R>>;
10
- }
11
- //# sourceMappingURL=AsyncContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AsyncContext.d.ts","sourceRoot":"","sources":["../src/AsyncContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAGpC,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC;IAGlD,OAAO,CAAC,OAAO,CAAC;IAF5B,OAAO,CAAC,OAAO,CAAmD;IAClE,OAAO,CAAC,SAAS,CAAwB;gBACrB,OAAO,CAAC,qDAAyC;IAC/D,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAIvB,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAK3D,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAGvJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AsyncContext.js","sourceRoot":"","sources":["../src/AsyncContext.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,mCAAoD;AAEpD;IAGE,sBAAoB,OAAiD;QAAjD,YAAO,GAAP,OAAO,CAA0C;IAAI,CAAC;IACpE,0BAAG,GAAT;;;;gBACE,IAAI,IAAI,CAAC,SAAS;oBAAE,sBAAO,IAAI,CAAC,SAAS,EAAA;gBACzC,sBAAO,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAI,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,OAAO,GAAG,CAAC,EAAhB,CAAgB,CAAC,EAAA;;;KAC5G;IACD,iCAAU,GAAV,UAAW,OAAgD;QACzD,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,kCAAyB,EAAE,CAAA;QACvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACzD,CAAC;IACD,6BAAM,GAAN,UAA+C,OAAwE;QAAvH,iBAEC;QADC,OAAO,IAAI,YAAY,CAAC;;;;oBAAkB,qBAAM,IAAI,CAAC,GAAG,EAAE,EAAA;;4DAAhB,SAAgB;oBAAK,qBAAM,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAA;wBAA9D,sBAAA,mCAA2B,SAAmC,IAAG,EAAA;;iBAAA,CAAC,CAAA;IACxG,CAAC;IACH,mBAAC;AAAD,CAAC,AAhBD,IAgBC;AAhBY,oCAAY;AAkBzB,SAAS,cAAc,CAGrB,OAAwE,EAAE,cAAgC;IAC1G,OAAO,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAE,OAAe,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AACnF,CAAC"}
package/lib/errors.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import { ModuleError } from 'iso-error';
2
- export declare class ContextAlreadyInitialized extends ModuleError {
3
- constructor();
4
- }
5
- //# sourceMappingURL=errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,qBAAa,yBAA0B,SAAQ,WAAW;;CAIzD"}
package/lib/errors.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uCAAuC;AAEvC;IAA+C,6CAAW;IACxD;eACE,kBAAM,wBAAwB,EAAE,uCAAuC,CAAC;IAC1E,CAAC;IACH,gCAAC;AAAD,CAAC,AAJD,CAA+C,uBAAW,GAIzD;AAJY,8DAAyB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA"}
package/lib/index.js DELETED
@@ -1,8 +0,0 @@
1
- "use strict";
2
- function __export(m) {
3
- for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
4
- }
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- __export(require("./AsyncContext"));
7
- __export(require("./errors"));
8
- //# sourceMappingURL=index.js.map
package/lib/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,oCAA8B;AAC9B,8BAAwB"}
@@ -1,11 +0,0 @@
1
- import { LeftJoin } from 'type-plus';
2
- export declare class AsyncContext<T extends Record<string | symbol, any>> {
3
- private context?;
4
- private resolve;
5
- private resolving;
6
- constructor(context?: T | Promise<T> | (() => T | Promise<T>) | undefined);
7
- get(): Promise<T>;
8
- initialize(context: T | Promise<T> | (() => T | Promise<T>)): void;
9
- extend<R extends Record<string | symbol, any>>(context: R | Promise<R> | ((context: AsyncContext<T>) => R | Promise<R>)): AsyncContext<LeftJoin<T, R>>;
10
- }
11
- //# sourceMappingURL=AsyncContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AsyncContext.d.ts","sourceRoot":"","sources":["../src/AsyncContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAGpC,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC;IAGlD,OAAO,CAAC,OAAO,CAAC;IAF5B,OAAO,CAAC,OAAO,CAAmD;IAClE,OAAO,CAAC,SAAS,CAAwB;gBACrB,OAAO,CAAC,qDAAyC;IAC/D,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAIvB,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAK3D,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAGvJ"}
@@ -1,25 +0,0 @@
1
- import { ContextAlreadyInitialized } from './errors';
2
- export class AsyncContext {
3
- constructor(context) {
4
- this.context = context;
5
- }
6
- async get() {
7
- if (this.resolving)
8
- return this.resolving;
9
- return this.resolving = this.context ? resolveContext(this.context) : new Promise(a => this.resolve = a);
10
- }
11
- initialize(context) {
12
- if (this.context)
13
- throw new ContextAlreadyInitialized();
14
- this.context = context;
15
- if (this.resolve)
16
- this.resolve(resolveContext(context));
17
- }
18
- extend(context) {
19
- return new AsyncContext(async () => (Object.assign(Object.assign({}, await this.get()), await resolveContext(context, this))));
20
- }
21
- }
22
- function resolveContext(context, currentContext) {
23
- return typeof context === 'function' ? context(currentContext) : context;
24
- }
25
- //# sourceMappingURL=AsyncContext.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AsyncContext.js","sourceRoot":"","sources":["../src/AsyncContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAA;AAEpD,MAAM,OAAO,YAAY;IAGvB,YAAoB,OAAiD;QAAjD,YAAO,GAAP,OAAO,CAA0C;IAAI,CAAC;IAC1E,KAAK,CAAC,GAAG;QACP,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAA;QACzC,OAAO,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;IAC7G,CAAC;IACD,UAAU,CAAC,OAAgD;QACzD,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,yBAAyB,EAAE,CAAA;QACvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACzD,CAAC;IACD,MAAM,CAAyC,OAAwE;QACrH,OAAO,IAAI,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC,iCAAM,MAAM,IAAI,CAAC,GAAG,EAAE,GAAK,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAG,CAAC,CAAA;IACxG,CAAC;CACF;AAED,SAAS,cAAc,CAGrB,OAAwE,EAAE,cAAgC;IAC1G,OAAO,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAE,OAAe,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AACnF,CAAC"}
package/libm/errors.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import { ModuleError } from 'iso-error';
2
- export declare class ContextAlreadyInitialized extends ModuleError {
3
- constructor();
4
- }
5
- //# sourceMappingURL=errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,qBAAa,yBAA0B,SAAQ,WAAW;;CAIzD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,MAAM,OAAO,yBAA0B,SAAQ,WAAW;IACxD;QACE,KAAK,CAAC,wBAAwB,EAAE,uCAAuC,CAAC,CAAA;IAC1E,CAAC;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA"}
package/libm/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA"}
@@ -1,187 +0,0 @@
1
- import a, { AssertOrder } from 'assertron'
2
- import { assertType, assignability } from 'type-plus'
3
- import { AsyncContext, ContextAlreadyInitialized } from '.'
4
-
5
- describe('constructor', () => {
6
- test('with object', async () => {
7
- const ctx = new AsyncContext({ a: 1 })
8
-
9
- const { a } = await ctx.get()
10
-
11
- expect(a).toBe(1)
12
- })
13
-
14
- test('with Promise', async () => {
15
- const ctx = new AsyncContext(Promise.resolve({ a: 1 }))
16
-
17
- const { a } = await ctx.get()
18
-
19
- expect(a).toBe(1)
20
- })
21
-
22
- test('with initialize function', async () => {
23
- const ctx = new AsyncContext(() => ({ a: 1 }))
24
- const { a } = await ctx.get()
25
-
26
- expect(a).toBe(1)
27
- })
28
-
29
- test('with async initialize function', async () => {
30
- const ctx = new AsyncContext(async () => ({ a: 1 }))
31
- const { a } = await ctx.get()
32
-
33
- expect(a).toBe(1)
34
- })
35
-
36
- test('constructor initialize function is only called once', async () => {
37
- const o = new AssertOrder(1)
38
- const ctx = new AsyncContext(() => {
39
- o.once(1)
40
- return { a: 1 }
41
- })
42
- await ctx.get()
43
- const { a } = await ctx.get()
44
-
45
- expect(a).toBe(1)
46
- o.end()
47
- })
48
-
49
- test('intialize function is not called until first get()', async () => {
50
- new AsyncContext(() => { throw new Error('should not reach') })
51
- })
52
- })
53
-
54
- describe('initialize()', () => {
55
- test('specify type through generics', async () => {
56
- const ctx = new AsyncContext<{ a: string }>()
57
- ctx.initialize({ a: 'a' })
58
- const { a } = await ctx.get()
59
-
60
- assertType.isTrue(assignability<string>()(a))
61
- expect(a).toBe('a')
62
- })
63
-
64
- test('with object', async () => {
65
- const ctx = new AsyncContext()
66
-
67
- ctx.initialize({ a: 1 })
68
- const { a } = await ctx.get()
69
-
70
- expect(a).toBe(1)
71
- })
72
-
73
- test('with promise', async () => {
74
- const ctx = new AsyncContext()
75
-
76
- ctx.initialize(Promise.resolve({ a: 1 }))
77
- const { a } = await ctx.get()
78
-
79
- expect(a).toBe(1)
80
- })
81
-
82
- test('initialize function', async () => {
83
- const ctx = new AsyncContext()
84
-
85
- ctx.initialize(() => ({ a: 1 }))
86
- const { a } = await ctx.get()
87
-
88
- expect(a).toBe(1)
89
- })
90
-
91
- test('with async initialize function', async () => {
92
- const ctx = new AsyncContext()
93
-
94
- ctx.initialize(async () => ({ a: 1 }))
95
- const { a } = await ctx.get()
96
-
97
- expect(a).toBe(1)
98
- })
99
-
100
- test('initialize function is only called once', async () => {
101
- const o = new AssertOrder(1)
102
- const ctx = new AsyncContext()
103
- ctx.initialize(() => {
104
- o.once(1)
105
- return { a: 1 }
106
- })
107
- await ctx.get()
108
- const { a } = await ctx.get()
109
-
110
- expect(a).toBe(1)
111
- o.end()
112
- })
113
-
114
- test('call initialize function with constructor initialized context throws ContextAlreadyInitialized', () => {
115
- const ctx = new AsyncContext({ a: 1 })
116
-
117
- a.throws(() => ctx.initialize({ a: 2 }), ContextAlreadyInitialized)
118
- })
119
-
120
- test('intialize function is not called until first get()', async () => {
121
- const ctx = new AsyncContext()
122
- ctx.initialize(() => { throw new Error('should not reach') })
123
- })
124
- })
125
-
126
- describe('extend()', () => {
127
- test('with object', async () => {
128
- const ctx = new AsyncContext({ a: 1 })
129
- const actual = ctx.extend({ b: 'b' })
130
-
131
- expect(await actual.get()).toEqual({ a: 1, b: 'b' })
132
- })
133
-
134
- test('with promise', async () => {
135
- const ctx = new AsyncContext({ a: 1 })
136
- const actual = ctx.extend(Promise.resolve({ b: 'b' }))
137
-
138
- expect(await actual.get()).toEqual({ a: 1, b: 'b' })
139
- })
140
-
141
- test('with function', async () => {
142
- const ctx = new AsyncContext({ a: 1 })
143
- const actual = ctx.extend(() => ({ b: 'b' }))
144
-
145
- expect(await actual.get()).toEqual({ a: 1, b: 'b' })
146
- })
147
-
148
- test('with async function', async () => {
149
- const ctx = new AsyncContext({ a: 1 })
150
- const actual = ctx.extend(async () => ({ b: 'b' }))
151
-
152
- expect(await actual.get()).toEqual({ a: 1, b: 'b' })
153
- })
154
-
155
- test('overrides existing value', async () => {
156
- const ctx = new AsyncContext({ a: 1 }).extend(() => ({ a: 2 }))
157
- expect(await ctx.get()).toEqual({ a: 2 })
158
- })
159
-
160
- test('change types of existing property', async () => {
161
- type Orig = { type: 'a' | 'b', value: string }
162
- const ctx = new AsyncContext<Orig>({ type: 'a', value: '1' })
163
- .extend(() => ({ value: 1 }))
164
-
165
- const result = await ctx.get()
166
-
167
- assertType<'a' | 'b'>(result.type)
168
- assertType.isNumber(result.value)
169
- })
170
-
171
- test('handler receives current context for more better merge function reuse', async () => {
172
- type Orig = { type: 'a' | 'b', value: number }
173
-
174
- const orig = new AsyncContext<Orig>({ type: 'a', value: 1 })
175
- const transform = async (context: AsyncContext<Orig>) => ({ value: String(await (await context.get()).value) })
176
-
177
- const merged = orig.extend(transform)
178
- expect(await merged.get()).toEqual({ type: 'a', value: '1' })
179
- })
180
- })
181
-
182
- test('get() waits for initialize() with no initial context', async () => {
183
- const ctx = new AsyncContext()
184
- setImmediate(() => ctx.initialize({ a: 2 }))
185
- const { a } = await ctx.get()
186
- expect(a).toBe(2)
187
- })
@@ -1,27 +0,0 @@
1
- import { LeftJoin } from 'type-plus'
2
- import { ContextAlreadyInitialized } from './errors'
3
-
4
- export class AsyncContext<T extends Record<string | symbol, any>> {
5
- private resolve: ((value: T | PromiseLike<T>) => void) | undefined
6
- private resolving: Promise<T> | undefined
7
- constructor(private context?: T | Promise<T> | (() => T | Promise<T>)) { }
8
- async get(): Promise<T> {
9
- if (this.resolving) return this.resolving
10
- return this.resolving = this.context ? resolveContext(this.context) : new Promise<T>(a => this.resolve = a)
11
- }
12
- initialize(context: T | Promise<T> | (() => T | Promise<T>)) {
13
- if (this.context) throw new ContextAlreadyInitialized()
14
- this.context = context
15
- if (this.resolve) this.resolve(resolveContext(context))
16
- }
17
- extend<R extends Record<string | symbol, any>>(context: R | Promise<R> | ((context: AsyncContext<T>) => R | Promise<R>)): AsyncContext<LeftJoin<T, R>> {
18
- return new AsyncContext(async () => ({ ...await this.get(), ...await resolveContext(context, this) }))
19
- }
20
- }
21
-
22
- function resolveContext<
23
- T extends Record<string | symbol, any>,
24
- R extends Record<string | symbol, any>
25
- >(context: R | Promise<R> | ((context: AsyncContext<T>) => R | Promise<R>), currentContext?: AsyncContext<T>) {
26
- return typeof context === 'function' ? (context as any)(currentContext) : context
27
- }