@declaro/core 2.0.0-y.0 → 2.1.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/{LICENSE → LICENSE.md} +1 -1
- package/README.md +203 -0
- package/dist/browser/index.js +28 -0
- package/dist/browser/index.js.map +133 -0
- package/dist/browser/scope/index.js +3 -0
- package/dist/browser/scope/index.js.map +9 -0
- package/dist/bun/index.js +19011 -0
- package/dist/bun/index.js.map +132 -0
- package/dist/bun/scope/index.js +4 -0
- package/dist/bun/scope/index.js.map +9 -0
- package/dist/node/index.cjs +19039 -0
- package/dist/node/index.cjs.map +132 -0
- package/dist/node/index.js +19010 -0
- package/dist/node/index.js.map +132 -0
- package/dist/node/scope/index.cjs +69 -0
- package/dist/node/scope/index.cjs.map +9 -0
- package/dist/node/scope/index.js +3 -0
- package/dist/node/scope/index.js.map +9 -0
- package/dist/ts/app/app-context.d.ts +9 -0
- package/dist/ts/app/app-context.d.ts.map +1 -0
- package/dist/ts/app/app-lifecycle.d.ts +6 -0
- package/dist/ts/app/app-lifecycle.d.ts.map +1 -0
- package/dist/ts/app/app.d.ts +24 -0
- package/dist/ts/app/app.d.ts.map +1 -0
- package/dist/{app → ts/app}/index.d.ts +1 -0
- package/dist/ts/app/index.d.ts.map +1 -0
- package/dist/ts/application/create-request-context.d.ts +4 -0
- package/dist/ts/application/create-request-context.d.ts.map +1 -0
- package/dist/ts/application/create-request-context.test.d.ts +2 -0
- package/dist/ts/application/create-request-context.test.d.ts.map +1 -0
- package/dist/ts/application/use-declaro.d.ts +3 -0
- package/dist/ts/application/use-declaro.d.ts.map +1 -0
- package/dist/{auth → ts/auth}/permission-validator.d.ts +1 -0
- package/dist/ts/auth/permission-validator.d.ts.map +1 -0
- package/dist/ts/auth/permission-validator.test.d.ts +2 -0
- package/dist/ts/auth/permission-validator.test.d.ts.map +1 -0
- package/dist/ts/context/async-context.d.ts +54 -0
- package/dist/ts/context/async-context.d.ts.map +1 -0
- package/dist/ts/context/async-context.test.d.ts +2 -0
- package/dist/ts/context/async-context.test.d.ts.map +1 -0
- package/dist/{context → ts/context}/context-consumer.d.ts +4 -0
- package/dist/ts/context/context-consumer.d.ts.map +1 -0
- package/dist/ts/context/context.circular-deps.test.d.ts +2 -0
- package/dist/ts/context/context.circular-deps.test.d.ts.map +1 -0
- package/dist/ts/context/context.d.ts +452 -0
- package/dist/ts/context/context.d.ts.map +1 -0
- package/dist/ts/context/context.test.d.ts +2 -0
- package/dist/ts/context/context.test.d.ts.map +1 -0
- package/dist/ts/context/legacy-context.test.d.ts +2 -0
- package/dist/ts/context/legacy-context.test.d.ts.map +1 -0
- package/dist/{context → ts/context}/validators.d.ts +2 -1
- package/dist/ts/context/validators.d.ts.map +1 -0
- package/dist/ts/dataflow/index.d.ts +2 -0
- package/dist/ts/dataflow/index.d.ts.map +1 -0
- package/dist/ts/dataflow/objects.d.ts +7 -0
- package/dist/ts/dataflow/objects.d.ts.map +1 -0
- package/dist/ts/dataflow/objects.test.d.ts +2 -0
- package/dist/ts/dataflow/objects.test.d.ts.map +1 -0
- package/dist/{errors → ts/errors}/errors.d.ts +16 -3
- package/dist/ts/errors/errors.d.ts.map +1 -0
- package/dist/ts/events/event-manager.d.ts +19 -0
- package/dist/ts/events/event-manager.d.ts.map +1 -0
- package/dist/ts/events/event-manager.spec.d.ts +2 -0
- package/dist/ts/events/event-manager.spec.d.ts.map +1 -0
- package/dist/ts/events/index.d.ts +2 -0
- package/dist/ts/events/index.d.ts.map +1 -0
- package/dist/ts/http/headers.d.ts +21 -0
- package/dist/ts/http/headers.d.ts.map +1 -0
- package/dist/ts/http/headers.spec.d.ts +2 -0
- package/dist/ts/http/headers.spec.d.ts.map +1 -0
- package/dist/ts/http/request-context.d.ts +17 -0
- package/dist/ts/http/request-context.d.ts.map +1 -0
- package/dist/ts/http/request-context.spec.d.ts +2 -0
- package/dist/ts/http/request-context.spec.d.ts.map +1 -0
- package/dist/ts/http/request.d.ts +31 -0
- package/dist/ts/http/request.d.ts.map +1 -0
- package/dist/ts/http/request.spec.d.ts +2 -0
- package/dist/ts/http/request.spec.d.ts.map +1 -0
- package/dist/{http → ts/http}/url.d.ts +5 -4
- package/dist/ts/http/url.d.ts.map +1 -0
- package/dist/ts/http/url.spec.d.ts +2 -0
- package/dist/ts/http/url.spec.d.ts.map +1 -0
- package/dist/ts/index.d.ts +47 -0
- package/dist/ts/index.d.ts.map +1 -0
- package/dist/{pipelines → ts/pipelines}/index.d.ts +1 -0
- package/dist/ts/pipelines/index.d.ts.map +1 -0
- package/dist/{pipelines → ts/pipelines}/pipeline-action.d.ts +1 -0
- package/dist/ts/pipelines/pipeline-action.d.ts.map +1 -0
- package/dist/ts/pipelines/pipeline-action.test.d.ts +2 -0
- package/dist/ts/pipelines/pipeline-action.test.d.ts.map +1 -0
- package/dist/{pipelines → ts/pipelines}/pipeline.d.ts +3 -2
- package/dist/ts/pipelines/pipeline.d.ts.map +1 -0
- package/dist/ts/pipelines/pipeline.test.d.ts +2 -0
- package/dist/ts/pipelines/pipeline.test.d.ts.map +1 -0
- package/dist/ts/schema/json-schema.d.ts +12 -0
- package/dist/ts/schema/json-schema.d.ts.map +1 -0
- package/dist/ts/schema/labels.d.ts +14 -0
- package/dist/ts/schema/labels.d.ts.map +1 -0
- package/dist/ts/schema/model-schema.d.ts +75 -0
- package/dist/ts/schema/model-schema.d.ts.map +1 -0
- package/dist/ts/schema/model-schema.test.d.ts +2 -0
- package/dist/ts/schema/model-schema.test.d.ts.map +1 -0
- package/dist/ts/schema/model.d.ts +35 -0
- package/dist/ts/schema/model.d.ts.map +1 -0
- package/dist/ts/schema/schema-mixin.d.ts +24 -0
- package/dist/ts/schema/schema-mixin.d.ts.map +1 -0
- package/dist/ts/schema/test/mock-model.d.ts +8 -0
- package/dist/ts/schema/test/mock-model.d.ts.map +1 -0
- package/dist/ts/scope/index.d.ts +34 -0
- package/dist/ts/scope/index.d.ts.map +1 -0
- package/dist/ts/shared/utils/action-descriptor.d.ts +28 -0
- package/dist/ts/shared/utils/action-descriptor.d.ts.map +1 -0
- package/dist/ts/shared/utils/action-descriptor.test.d.ts +2 -0
- package/dist/ts/shared/utils/action-descriptor.test.d.ts.map +1 -0
- package/dist/ts/shared/utils/schema-utils.d.ts +3 -0
- package/dist/ts/shared/utils/schema-utils.d.ts.map +1 -0
- package/dist/ts/shared/utils/schema-utils.test.d.ts +2 -0
- package/dist/ts/shared/utils/schema-utils.test.d.ts.map +1 -0
- package/dist/ts/shims/async-local-storage.d.ts +36 -0
- package/dist/ts/shims/async-local-storage.d.ts.map +1 -0
- package/dist/ts/shims/async-local-storage.test.d.ts +2 -0
- package/dist/ts/shims/async-local-storage.test.d.ts.map +1 -0
- package/dist/{timing.d.ts → ts/timing.d.ts} +1 -0
- package/dist/ts/timing.d.ts.map +1 -0
- package/dist/{typescript → ts/typescript}/arrays.d.ts +1 -0
- package/dist/ts/typescript/arrays.d.ts.map +1 -0
- package/dist/{typescript → ts/typescript}/baseModel.d.ts +1 -0
- package/dist/ts/typescript/baseModel.d.ts.map +1 -0
- package/dist/{typescript → ts/typescript}/classes.d.ts +1 -0
- package/dist/ts/typescript/classes.d.ts.map +1 -0
- package/dist/{typescript → ts/typescript}/constant-manipulation/snake-case.d.ts +1 -0
- package/dist/ts/typescript/constant-manipulation/snake-case.d.ts.map +1 -0
- package/dist/{typescript → ts/typescript}/errors.d.ts +1 -0
- package/dist/ts/typescript/errors.d.ts.map +1 -0
- package/dist/ts/typescript/fetch.d.ts +3 -0
- package/dist/ts/typescript/fetch.d.ts.map +1 -0
- package/dist/{typescript → ts/typescript}/generics.d.ts +1 -0
- package/dist/ts/typescript/generics.d.ts.map +1 -0
- package/dist/{typescript → ts/typescript}/index.d.ts +1 -0
- package/dist/ts/typescript/index.d.ts.map +1 -0
- package/dist/ts/typescript/objects.d.ts +26 -0
- package/dist/ts/typescript/objects.d.ts.map +1 -0
- package/dist/{typescript → ts/typescript}/promises.d.ts +1 -0
- package/dist/ts/typescript/promises.d.ts.map +1 -0
- package/dist/{validation → ts/validation}/index.d.ts +1 -0
- package/dist/ts/validation/index.d.ts.map +1 -0
- package/dist/{validation → ts/validation}/validation.d.ts +1 -0
- package/dist/ts/validation/validation.d.ts.map +1 -0
- package/dist/{validation → ts/validation}/validator.d.ts +1 -0
- package/dist/ts/validation/validator.d.ts.map +1 -0
- package/dist/ts/validation/validator.test.d.ts +2 -0
- package/dist/ts/validation/validator.test.d.ts.map +1 -0
- package/package.json +46 -13
- package/src/app/app-context.ts +4 -5
- package/src/app/app-lifecycle.ts +4 -3
- package/src/app/app.ts +7 -5
- package/src/application/create-request-context.test.ts +345 -0
- package/src/application/create-request-context.ts +19 -0
- package/src/application/use-declaro.ts +27 -0
- package/src/auth/permission-validator.test.ts +238 -2
- package/src/auth/permission-validator.ts +3 -3
- package/src/context/async-context.test.ts +348 -0
- package/src/context/async-context.ts +129 -0
- package/src/context/context-consumer.ts +4 -4
- package/src/context/context.circular-deps.test.ts +1047 -0
- package/src/context/context.test.ts +420 -3
- package/src/context/context.ts +590 -87
- package/src/context/legacy-context.test.ts +9 -9
- package/src/dataflow/objects.test.ts +7 -7
- package/src/dataflow/objects.ts +10 -9
- package/src/errors/errors.ts +19 -3
- package/src/events/event-manager.spec.ts +129 -0
- package/src/events/event-manager.ts +25 -14
- package/src/http/headers.ts +17 -2
- package/src/http/request-context.ts +24 -15
- package/src/http/request.ts +27 -6
- package/src/http/url.ts +3 -3
- package/src/index.ts +34 -3
- package/src/pipelines/pipeline.test.ts +11 -9
- package/src/schema/json-schema.ts +16 -0
- package/src/schema/labels.ts +23 -23
- package/src/schema/model-schema.test.ts +282 -0
- package/src/schema/model-schema.ts +197 -0
- package/src/schema/model.ts +143 -0
- package/src/schema/schema-mixin.ts +51 -0
- package/src/schema/test/mock-model.ts +19 -0
- package/src/scope/index.ts +33 -0
- package/src/shared/utils/action-descriptor.test.ts +182 -0
- package/src/shared/utils/action-descriptor.ts +102 -0
- package/src/shared/utils/schema-utils.test.ts +33 -0
- package/src/shared/utils/schema-utils.ts +17 -0
- package/src/shims/async-local-storage.test.ts +258 -0
- package/src/shims/async-local-storage.ts +82 -0
- package/src/typescript/objects.ts +32 -1
- package/src/validation/validator.test.ts +12 -20
- package/dist/app/app-context.d.ts +0 -8
- package/dist/app/app-lifecycle.d.ts +0 -4
- package/dist/app/app.d.ts +0 -22
- package/dist/auth/permission-validator.test.d.ts +0 -1
- package/dist/context/context.d.ts +0 -161
- package/dist/context/context.test.d.ts +0 -1
- package/dist/context/legacy-context.test.d.ts +0 -1
- package/dist/dataflow/index.d.ts +0 -1
- package/dist/dataflow/objects.d.ts +0 -5
- package/dist/dataflow/objects.test.d.ts +0 -1
- package/dist/events/event-manager.d.ts +0 -16
- package/dist/events/event-manager.spec.d.ts +0 -1
- package/dist/events/index.d.ts +0 -1
- package/dist/helpers/index.d.ts +0 -1
- package/dist/helpers/ucfirst.d.ts +0 -1
- package/dist/http/headers.d.ts +0 -4
- package/dist/http/headers.spec.d.ts +0 -1
- package/dist/http/request-context.d.ts +0 -12
- package/dist/http/request-context.spec.d.ts +0 -1
- package/dist/http/request.d.ts +0 -8
- package/dist/http/request.spec.d.ts +0 -1
- package/dist/http/url.spec.d.ts +0 -1
- package/dist/index.d.ts +0 -19
- package/dist/pipelines/pipeline-action.test.d.ts +0 -1
- package/dist/pipelines/pipeline.test.d.ts +0 -1
- package/dist/pkg.cjs +0 -30
- package/dist/pkg.mjs +0 -56612
- package/dist/schema/application.d.ts +0 -83
- package/dist/schema/application.test.d.ts +0 -1
- package/dist/schema/define-model.d.ts +0 -10
- package/dist/schema/define-model.test.d.ts +0 -1
- package/dist/schema/formats.d.ts +0 -10
- package/dist/schema/index.d.ts +0 -10
- package/dist/schema/labels.d.ts +0 -13
- package/dist/schema/labels.test.d.ts +0 -1
- package/dist/schema/module.d.ts +0 -7
- package/dist/schema/module.test.d.ts +0 -1
- package/dist/schema/properties.d.ts +0 -19
- package/dist/schema/response.d.ts +0 -31
- package/dist/schema/response.test.d.ts +0 -1
- package/dist/schema/supported-types.d.ts +0 -12
- package/dist/schema/supported-types.test.d.ts +0 -1
- package/dist/schema/transform-model.d.ts +0 -4
- package/dist/schema/transform-model.test.d.ts +0 -1
- package/dist/schema/types.d.ts +0 -95
- package/dist/schema/types.test.d.ts +0 -1
- package/dist/typescript/fetch.d.ts +0 -2
- package/dist/typescript/objects.d.ts +0 -12
- package/dist/validation/validator.test.d.ts +0 -1
- package/src/helpers/index.ts +0 -1
- package/src/helpers/ucfirst.ts +0 -3
- package/src/schema/application.test.ts +0 -286
- package/src/schema/application.ts +0 -150
- package/src/schema/define-model.test.ts +0 -81
- package/src/schema/define-model.ts +0 -50
- package/src/schema/formats.ts +0 -23
- package/src/schema/index.ts +0 -10
- package/src/schema/labels.test.ts +0 -60
- package/src/schema/module.test.ts +0 -39
- package/src/schema/module.ts +0 -6
- package/src/schema/properties.ts +0 -40
- package/src/schema/response.test.ts +0 -101
- package/src/schema/response.ts +0 -93
- package/src/schema/supported-types.test.ts +0 -20
- package/src/schema/supported-types.ts +0 -15
- package/src/schema/transform-model.test.ts +0 -31
- package/src/schema/transform-model.ts +0 -24
- package/src/schema/types.test.ts +0 -28
- package/src/schema/types.ts +0 -163
- package/tsconfig.json +0 -11
- package/vite.config.ts +0 -24
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { AsyncLocalStorage } from './async-local-storage'
|
|
3
|
+
|
|
4
|
+
describe('AsyncLocalStorage shim', () => {
|
|
5
|
+
describe('run()', () => {
|
|
6
|
+
it('returns the fn result synchronously', () => {
|
|
7
|
+
const als = new AsyncLocalStorage<number>()
|
|
8
|
+
const result = als.run(1, () => 42)
|
|
9
|
+
expect(result).toBe(42)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('returns a Promise when fn is async', async () => {
|
|
13
|
+
const als = new AsyncLocalStorage<string>()
|
|
14
|
+
const result = await als.run('ctx', async () => 'hello')
|
|
15
|
+
expect(result).toBe('hello')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('forwards extra args to fn', () => {
|
|
19
|
+
const als = new AsyncLocalStorage<string>()
|
|
20
|
+
const result = als.run('ctx', (a: number, b: number) => a + b, 3, 4)
|
|
21
|
+
expect(result).toBe(7)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('getStore() returns the active store inside run()', () => {
|
|
25
|
+
const als = new AsyncLocalStorage<string>()
|
|
26
|
+
als.run('hello', () => {
|
|
27
|
+
expect(als.getStore()).toBe('hello')
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('getStore() returns undefined outside of run()', () => {
|
|
32
|
+
const als = new AsyncLocalStorage<string>()
|
|
33
|
+
expect(als.getStore()).toBeUndefined()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('store is not visible after run() completes', () => {
|
|
37
|
+
const als = new AsyncLocalStorage<string>()
|
|
38
|
+
als.run('hello', () => {})
|
|
39
|
+
expect(als.getStore()).toBeUndefined()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('nested run() calls use the innermost store', () => {
|
|
43
|
+
const als = new AsyncLocalStorage<string>()
|
|
44
|
+
|
|
45
|
+
als.run('outer', () => {
|
|
46
|
+
expect(als.getStore()).toBe('outer')
|
|
47
|
+
|
|
48
|
+
als.run('inner', () => {
|
|
49
|
+
expect(als.getStore()).toBe('inner')
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
expect(als.getStore()).toBe('outer')
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('restores prior store after nested run() completes', () => {
|
|
57
|
+
const als = new AsyncLocalStorage<string>()
|
|
58
|
+
als.run('outer', () => {
|
|
59
|
+
als.run('inner', () => {})
|
|
60
|
+
expect(als.getStore()).toBe('outer')
|
|
61
|
+
})
|
|
62
|
+
expect(als.getStore()).toBeUndefined()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('full lifecycle: undefined → outer → inner → outer → undefined', () => {
|
|
66
|
+
const als = new AsyncLocalStorage<string>()
|
|
67
|
+
const snapshots: (string | undefined)[] = []
|
|
68
|
+
|
|
69
|
+
snapshots.push(als.getStore())
|
|
70
|
+
als.run('outer', () => {
|
|
71
|
+
snapshots.push(als.getStore())
|
|
72
|
+
als.run('inner', () => {
|
|
73
|
+
snapshots.push(als.getStore())
|
|
74
|
+
})
|
|
75
|
+
snapshots.push(als.getStore())
|
|
76
|
+
})
|
|
77
|
+
snapshots.push(als.getStore())
|
|
78
|
+
|
|
79
|
+
expect(snapshots).toEqual([undefined, 'outer', 'inner', 'outer', undefined])
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('restores store even when fn throws', () => {
|
|
83
|
+
const als = new AsyncLocalStorage<string>()
|
|
84
|
+
expect(() =>
|
|
85
|
+
als.run('ctx', () => {
|
|
86
|
+
throw new Error('boom')
|
|
87
|
+
}),
|
|
88
|
+
).toThrow('boom')
|
|
89
|
+
expect(als.getStore()).toBeUndefined()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('multiple ALS instances are isolated from each other', () => {
|
|
93
|
+
const als1 = new AsyncLocalStorage<string>()
|
|
94
|
+
const als2 = new AsyncLocalStorage<number>()
|
|
95
|
+
|
|
96
|
+
als1.run('hello', () => {
|
|
97
|
+
als2.run(42, () => {
|
|
98
|
+
expect(als1.getStore()).toBe('hello')
|
|
99
|
+
expect(als2.getStore()).toBe(42)
|
|
100
|
+
})
|
|
101
|
+
expect(als1.getStore()).toBe('hello')
|
|
102
|
+
expect(als2.getStore()).toBeUndefined()
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
describe('async usage', () => {
|
|
108
|
+
it('store is accessible at the start of an async fn (before any await)', async () => {
|
|
109
|
+
const als = new AsyncLocalStorage<string>()
|
|
110
|
+
let captured: string | undefined
|
|
111
|
+
|
|
112
|
+
await als.run('ctx', async () => {
|
|
113
|
+
// No await yet — still in the synchronous call stack of run()
|
|
114
|
+
captured = als.getStore()
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
expect(captured).toBe('ctx')
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('resolves the returned Promise correctly', async () => {
|
|
121
|
+
const als = new AsyncLocalStorage<string>()
|
|
122
|
+
const result = await als.run('ctx', async () => 'resolved')
|
|
123
|
+
expect(result).toBe('resolved')
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('propagates rejections correctly', async () => {
|
|
127
|
+
const als = new AsyncLocalStorage<string>()
|
|
128
|
+
await expect(
|
|
129
|
+
als.run('ctx', async () => {
|
|
130
|
+
throw new Error('async boom')
|
|
131
|
+
}),
|
|
132
|
+
).rejects.toThrow('async boom')
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('restores store after an async fn resolves', async () => {
|
|
136
|
+
const als = new AsyncLocalStorage<string>()
|
|
137
|
+
await als.run('ctx', async () => {})
|
|
138
|
+
expect(als.getStore()).toBeUndefined()
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// The shim uses synchronous save/restore. The finally block in run()
|
|
142
|
+
// fires as soon as the async fn returns its Promise — before any
|
|
143
|
+
// awaited microtasks resume. Context is therefore not visible after an
|
|
144
|
+
// await boundary. Native AsyncLocalStorage (Node/Bun) does not have
|
|
145
|
+
// this limitation.
|
|
146
|
+
it('does NOT propagate store across await boundaries (synchronous shim limitation)', async () => {
|
|
147
|
+
const als = new AsyncLocalStorage<string>()
|
|
148
|
+
let captured: string | undefined = 'sentinel'
|
|
149
|
+
|
|
150
|
+
await als.run('ctx', async () => {
|
|
151
|
+
await Promise.resolve()
|
|
152
|
+
captured = als.getStore()
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
expect(captured).toBeUndefined()
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('does NOT isolate concurrent async tasks (synchronous shim limitation)', async () => {
|
|
159
|
+
const als = new AsyncLocalStorage<string>()
|
|
160
|
+
const results: (string | undefined)[] = []
|
|
161
|
+
|
|
162
|
+
await Promise.all([
|
|
163
|
+
als.run('task-a', async () => {
|
|
164
|
+
await new Promise<void>((r) => setTimeout(r, 10))
|
|
165
|
+
results.push(als.getStore())
|
|
166
|
+
}),
|
|
167
|
+
als.run('task-b', async () => {
|
|
168
|
+
await new Promise<void>((r) => setTimeout(r, 5))
|
|
169
|
+
results.push(als.getStore())
|
|
170
|
+
}),
|
|
171
|
+
])
|
|
172
|
+
|
|
173
|
+
expect(results).toEqual([undefined, undefined])
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
describe('exit()', () => {
|
|
178
|
+
it('clears the store for the duration of fn', () => {
|
|
179
|
+
const als = new AsyncLocalStorage<string>()
|
|
180
|
+
als.run('ctx', () => {
|
|
181
|
+
als.exit(() => {
|
|
182
|
+
expect(als.getStore()).toBeUndefined()
|
|
183
|
+
})
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
it('restores the store after exit() completes', () => {
|
|
188
|
+
const als = new AsyncLocalStorage<string>()
|
|
189
|
+
als.run('ctx', () => {
|
|
190
|
+
als.exit(() => {})
|
|
191
|
+
expect(als.getStore()).toBe('ctx')
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
it('restores store even when fn throws', () => {
|
|
196
|
+
const als = new AsyncLocalStorage<string>()
|
|
197
|
+
als.run('ctx', () => {
|
|
198
|
+
expect(() =>
|
|
199
|
+
als.exit(() => {
|
|
200
|
+
throw new Error('boom')
|
|
201
|
+
}),
|
|
202
|
+
).toThrow('boom')
|
|
203
|
+
expect(als.getStore()).toBe('ctx')
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
describe('enterWith()', () => {
|
|
209
|
+
it('sets the store imperatively', () => {
|
|
210
|
+
const als = new AsyncLocalStorage<string>()
|
|
211
|
+
als.enterWith('hello')
|
|
212
|
+
expect(als.getStore()).toBe('hello')
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('can be overwritten by another enterWith()', () => {
|
|
216
|
+
const als = new AsyncLocalStorage<string>()
|
|
217
|
+
als.enterWith('first')
|
|
218
|
+
als.enterWith('second')
|
|
219
|
+
expect(als.getStore()).toBe('second')
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
describe('disable()', () => {
|
|
224
|
+
it('clears the store', () => {
|
|
225
|
+
const als = new AsyncLocalStorage<string>()
|
|
226
|
+
als.enterWith('hello')
|
|
227
|
+
als.disable()
|
|
228
|
+
expect(als.getStore()).toBeUndefined()
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
it('has no effect when store is already empty', () => {
|
|
232
|
+
const als = new AsyncLocalStorage<string>()
|
|
233
|
+
als.disable()
|
|
234
|
+
expect(als.getStore()).toBeUndefined()
|
|
235
|
+
})
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
describe('AsyncLocalStorage.bind()', () => {
|
|
239
|
+
it('returns the function unchanged', () => {
|
|
240
|
+
const fn = () => 42
|
|
241
|
+
expect(AsyncLocalStorage.bind(fn)).toBe(fn)
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
describe('AsyncLocalStorage.snapshot()', () => {
|
|
246
|
+
it('returns a function that calls fn with provided args', () => {
|
|
247
|
+
const run = AsyncLocalStorage.snapshot()
|
|
248
|
+
const result = run((a: number, b: number) => a + b, 3, 4)
|
|
249
|
+
expect(result).toBe(7)
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('each call to snapshot() returns an independent executor', () => {
|
|
253
|
+
const run1 = AsyncLocalStorage.snapshot()
|
|
254
|
+
const run2 = AsyncLocalStorage.snapshot()
|
|
255
|
+
expect(run1).not.toBe(run2)
|
|
256
|
+
})
|
|
257
|
+
})
|
|
258
|
+
})
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser polyfill for Node's AsyncLocalStorage.
|
|
3
|
+
*
|
|
4
|
+
* ## How it works
|
|
5
|
+
*
|
|
6
|
+
* Each AsyncLocalStorage instance has a unique Symbol as its "column" ID.
|
|
7
|
+
* The currently active state is a single `Map<symbol, unknown>` called a
|
|
8
|
+
* _frame_, where each column holds the value for one ALS instance.
|
|
9
|
+
*
|
|
10
|
+
* `run()` creates a new frame (a shallow copy of the parent frame with this
|
|
11
|
+
* instance's value set), makes it active for the duration of `fn`, then
|
|
12
|
+
* restores the previous frame in a `finally` block.
|
|
13
|
+
*
|
|
14
|
+
* Multiple ALS instances are fully isolated from each other within the same
|
|
15
|
+
* frame: `als1.run()` only writes to its own column and does not affect any
|
|
16
|
+
* other instance's column.
|
|
17
|
+
*
|
|
18
|
+
* ## Browser limitation
|
|
19
|
+
*
|
|
20
|
+
* Because browsers have no native async-context hook, the frame is propagated
|
|
21
|
+
* only within the synchronous call stack of `fn`. Any code that runs after an
|
|
22
|
+
* `await` boundary cannot see the frame that was active when the `await` was
|
|
23
|
+
* encountered. For true async propagation in the browser, use Zone.js or the
|
|
24
|
+
* forthcoming `AsyncContext` TC39 API.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
// A frame maps ALS instance IDs → their stored values.
|
|
28
|
+
// All concurrently active ALS instances share one frame object.
|
|
29
|
+
type Frame = Map<symbol, unknown>
|
|
30
|
+
|
|
31
|
+
let _activeFrame: Frame | undefined = undefined
|
|
32
|
+
|
|
33
|
+
export class AsyncLocalStorage<T = any> {
|
|
34
|
+
// Unique identity for this ALS instance within a frame.
|
|
35
|
+
readonly #id: symbol = Symbol('AsyncLocalStorage')
|
|
36
|
+
|
|
37
|
+
getStore(): T | undefined {
|
|
38
|
+
return _activeFrame?.get(this.#id) as T | undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
run<R>(store: T, fn: (...args: any[]) => R, ...args: any[]): R {
|
|
42
|
+
const prev = _activeFrame
|
|
43
|
+
_activeFrame = new Map(prev)
|
|
44
|
+
_activeFrame.set(this.#id, store)
|
|
45
|
+
try {
|
|
46
|
+
return fn(...args)
|
|
47
|
+
} finally {
|
|
48
|
+
_activeFrame = prev
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
exit<R>(fn: (...args: any[]) => R, ...args: any[]): R {
|
|
53
|
+
const prev = _activeFrame
|
|
54
|
+
_activeFrame = new Map(prev)
|
|
55
|
+
_activeFrame.delete(this.#id)
|
|
56
|
+
try {
|
|
57
|
+
return fn(...args)
|
|
58
|
+
} finally {
|
|
59
|
+
_activeFrame = prev
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
enterWith(store: T): void {
|
|
64
|
+
const frame = new Map(_activeFrame)
|
|
65
|
+
frame.set(this.#id, store)
|
|
66
|
+
_activeFrame = frame
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
disable(): void {
|
|
70
|
+
const frame = new Map(_activeFrame)
|
|
71
|
+
frame.delete(this.#id)
|
|
72
|
+
_activeFrame = frame
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static bind<F extends (...args: any[]) => any>(fn: F): F {
|
|
76
|
+
return fn
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static snapshot(): <R>(fn: (...args: any[]) => R, ...args: any[]) => R {
|
|
80
|
+
return (fn, ...args) => fn(...args)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -11,5 +11,36 @@ export type DeepPartial<T> = T extends object
|
|
|
11
11
|
* Merge two object types without using an intersection type. Intersection types preserve the original types of the objects causing confusion, while this type will merge the types of the objects.
|
|
12
12
|
*/
|
|
13
13
|
export type Merge<A, B> = {
|
|
14
|
-
[
|
|
14
|
+
[K in keyof A | keyof B]: K extends keyof B
|
|
15
|
+
? B[K] extends object[] // Support for arrays
|
|
16
|
+
? K extends keyof A
|
|
17
|
+
? A[K] extends object[]
|
|
18
|
+
? Merge<A[K], B[K]> // If both are arrays, merge them
|
|
19
|
+
: B[K] // If only B is an array, use B
|
|
20
|
+
: B[K]
|
|
21
|
+
: B[K] extends object
|
|
22
|
+
? K extends keyof A
|
|
23
|
+
? A[K] extends object
|
|
24
|
+
? Merge<A[K], B[K]>
|
|
25
|
+
: B[K]
|
|
26
|
+
: B[K]
|
|
27
|
+
: B[K]
|
|
28
|
+
: K extends keyof A
|
|
29
|
+
? A[K]
|
|
30
|
+
: never
|
|
15
31
|
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Shallow merge two object types, replacing types of properties instead of merging them.
|
|
35
|
+
* Properties in B will completely replace properties in A.
|
|
36
|
+
*/
|
|
37
|
+
export type ShallowMerge<A extends object, B extends object> = {
|
|
38
|
+
[K in UniqueKeys<keyof A, keyof B>]: A[K]
|
|
39
|
+
} & {
|
|
40
|
+
[K in keyof B]: B[K]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Extract keys from A that are not present in B
|
|
45
|
+
*/
|
|
46
|
+
export type UniqueKeys<A, B> = A extends B ? never : A
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { validate, validateAny } from './validator'
|
|
2
|
-
import { describe, it, vi } from 'vitest'
|
|
2
|
+
import { describe, it, vi, expect } from 'vitest'
|
|
3
3
|
|
|
4
4
|
async function sleep(duration: number) {
|
|
5
5
|
return new Promise((resolve, reject) => {
|
|
@@ -10,31 +10,25 @@ async function sleep(duration: number) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
describe('Validator', () => {
|
|
13
|
-
it('Should validate with valid property', async (
|
|
13
|
+
it('Should validate with valid property', async () => {
|
|
14
14
|
const value = {
|
|
15
15
|
message: 'Hello World',
|
|
16
16
|
}
|
|
17
|
-
const valid = await validate(
|
|
18
|
-
value,
|
|
19
|
-
(val) => val.message === 'Hello World',
|
|
20
|
-
).valid
|
|
17
|
+
const valid = await validate(value, (val) => val.message === 'Hello World').valid
|
|
21
18
|
|
|
22
19
|
expect(valid).toBeTruthy()
|
|
23
20
|
})
|
|
24
21
|
|
|
25
|
-
it('Should validate with invalid property', async (
|
|
22
|
+
it('Should validate with invalid property', async () => {
|
|
26
23
|
const value = {
|
|
27
24
|
message: 'Hello Mr. Anderson',
|
|
28
25
|
}
|
|
29
|
-
const valid = await validate(
|
|
30
|
-
value,
|
|
31
|
-
(val) => val.message === 'Hello World',
|
|
32
|
-
).valid
|
|
26
|
+
const valid = await validate(value, (val) => val.message === 'Hello World').valid
|
|
33
27
|
|
|
34
28
|
expect(valid).toBeFalsy()
|
|
35
29
|
})
|
|
36
30
|
|
|
37
|
-
it('Should validate with onValid callback', async (
|
|
31
|
+
it('Should validate with onValid callback', async () => {
|
|
38
32
|
const valid = vi.fn((val) => {
|
|
39
33
|
expect(val).toBe(42)
|
|
40
34
|
})
|
|
@@ -54,7 +48,7 @@ describe('Validator', () => {
|
|
|
54
48
|
expect(invalid.mock.calls.length).toBe(0)
|
|
55
49
|
})
|
|
56
50
|
|
|
57
|
-
it('Should validate with onInvalid callback', async (
|
|
51
|
+
it('Should validate with onInvalid callback', async () => {
|
|
58
52
|
const valid = vi.fn((val) => {
|
|
59
53
|
expect(val).toBe(42)
|
|
60
54
|
})
|
|
@@ -73,7 +67,7 @@ describe('Validator', () => {
|
|
|
73
67
|
expect(invalid.mock.calls.length).toBe(1)
|
|
74
68
|
})
|
|
75
69
|
|
|
76
|
-
it('Should validate multiple validators', async (
|
|
70
|
+
it('Should validate multiple validators', async () => {
|
|
77
71
|
const value = {
|
|
78
72
|
message: 'Hello Mr. Anderson',
|
|
79
73
|
}
|
|
@@ -87,9 +81,7 @@ describe('Validator', () => {
|
|
|
87
81
|
expect(valid).toBeTruthy()
|
|
88
82
|
})
|
|
89
83
|
|
|
90
|
-
it('Should invalidate if one of multiple validators fails', async ({
|
|
91
|
-
expect,
|
|
92
|
-
}) => {
|
|
84
|
+
it('Should invalidate if one of multiple validators fails', async () => {
|
|
93
85
|
const value = {
|
|
94
86
|
message: 'Hello Mr. Anderson',
|
|
95
87
|
}
|
|
@@ -103,7 +95,7 @@ describe('Validator', () => {
|
|
|
103
95
|
expect(valid).toBeFalsy()
|
|
104
96
|
})
|
|
105
97
|
|
|
106
|
-
it('Should be able to validate an any strategy', async (
|
|
98
|
+
it('Should be able to validate an any strategy', async () => {
|
|
107
99
|
const value = {
|
|
108
100
|
message: 'Hello Mr. Anderson',
|
|
109
101
|
}
|
|
@@ -117,7 +109,7 @@ describe('Validator', () => {
|
|
|
117
109
|
expect(valid).toBeTruthy()
|
|
118
110
|
})
|
|
119
111
|
|
|
120
|
-
it('Should be able to invalidate an any strategy', async (
|
|
112
|
+
it('Should be able to invalidate an any strategy', async () => {
|
|
121
113
|
const value = {
|
|
122
114
|
message: 'Hello Mr. Anderson',
|
|
123
115
|
}
|
|
@@ -131,7 +123,7 @@ describe('Validator', () => {
|
|
|
131
123
|
expect(valid).toBeFalsy()
|
|
132
124
|
})
|
|
133
125
|
|
|
134
|
-
it('Should validate an async validator', async (
|
|
126
|
+
it('Should validate an async validator', async () => {
|
|
135
127
|
const value = {
|
|
136
128
|
message: 'Hello World',
|
|
137
129
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Context } from '../context/context';
|
|
2
|
-
/**
|
|
3
|
-
* Get the name of the app making the current request via header x-app. (returns "default" when no app was provided).
|
|
4
|
-
*
|
|
5
|
-
* @param context
|
|
6
|
-
* @returns the name of the app in a string.
|
|
7
|
-
*/
|
|
8
|
-
export declare function useApp(context: Context): string;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { Context, ContextListener } from '../context/context';
|
|
2
|
-
export declare function onInit(context: Context, listener: ContextListener): void;
|
|
3
|
-
export declare function onStart(context: Context, listener: ContextListener): void;
|
|
4
|
-
export declare function onDestroy(context: Context, listener: ContextListener): void;
|
package/dist/app/app.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Context, ContextMiddleware, ContextListener } from '../context/context';
|
|
2
|
-
export type AppConfig = {
|
|
3
|
-
context?: Context;
|
|
4
|
-
init?: ContextMiddleware;
|
|
5
|
-
start?: ContextMiddleware;
|
|
6
|
-
destroy?: ContextMiddleware;
|
|
7
|
-
};
|
|
8
|
-
export declare class App {
|
|
9
|
-
readonly context: Context;
|
|
10
|
-
constructor(context: Context);
|
|
11
|
-
static Events: {
|
|
12
|
-
Init: string;
|
|
13
|
-
Start: string;
|
|
14
|
-
Destroy: string;
|
|
15
|
-
};
|
|
16
|
-
init(): Promise<void>;
|
|
17
|
-
onInit(listener: ContextListener): this;
|
|
18
|
-
start(): Promise<void>;
|
|
19
|
-
onStart(listener: ContextListener): void;
|
|
20
|
-
destroy(): Promise<void>;
|
|
21
|
-
onDestroy(listener: ContextListener): void;
|
|
22
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { Class, PromiseOrValue, UnwrapPromise } from '../typescript';
|
|
2
|
-
import { Validator } from '../validation';
|
|
3
|
-
import { ContextConsumer } from './context-consumer';
|
|
4
|
-
export type AppScope = {};
|
|
5
|
-
export type RequestScope = {};
|
|
6
|
-
export type AppContext = Context<AppScope>;
|
|
7
|
-
export type RequestContext = Context<RequestScope>;
|
|
8
|
-
export type ContextMiddleware = (context: Context) => any | Promise<any>;
|
|
9
|
-
export type ContextState<TContext extends Context> = Record<PropertyKey, ContextAttribute<TContext, StateValue<any>>>;
|
|
10
|
-
export type ContextResolver<T> = (context: Context) => StateValue<T>;
|
|
11
|
-
export type StateValue<T> = T;
|
|
12
|
-
export declare enum DependencyType {
|
|
13
|
-
VALUE = "VALUE",
|
|
14
|
-
FACTORY = "FACTORY",
|
|
15
|
-
CLASS = "CLASS"
|
|
16
|
-
}
|
|
17
|
-
export type FactoryFn<T, A extends any[]> = (...args: A) => T;
|
|
18
|
-
export type ValueLoader<C extends Context, T> = (context: C) => T;
|
|
19
|
-
export type FilterKeysByType<TScope, TValue> = {
|
|
20
|
-
[Key in keyof TScope]: TScope[Key] extends TValue ? Key : never;
|
|
21
|
-
}[keyof TScope];
|
|
22
|
-
export type FilterKeysByAsyncType<TScope, TValue> = {
|
|
23
|
-
[Key in keyof TScope]: TScope[Key] extends PromiseOrValue<TValue> ? Key : never;
|
|
24
|
-
}[keyof TScope];
|
|
25
|
-
export type FilterArgsByType<TScope, TArgs extends any[]> = {
|
|
26
|
-
[Key in keyof TArgs]: FilterKeysByType<TScope, TArgs[Key]>;
|
|
27
|
-
};
|
|
28
|
-
export type FilterAsyncArgsByType<TScope, TArgs extends any[]> = {
|
|
29
|
-
[Key in keyof TArgs]: FilterKeysByAsyncType<TScope, TArgs[Key]>;
|
|
30
|
-
};
|
|
31
|
-
export type ContextAttribute<TContext extends Context<any>, TValue> = {
|
|
32
|
-
key: PropertyKey;
|
|
33
|
-
value?: ValueLoader<TContext, TValue>;
|
|
34
|
-
type: DependencyType;
|
|
35
|
-
resolveOptions: ResolveOptions;
|
|
36
|
-
cachedValue?: TValue;
|
|
37
|
-
inject: PropertyKey[];
|
|
38
|
-
};
|
|
39
|
-
export type ScopeKey<S extends object> = keyof S;
|
|
40
|
-
export type ContextListener = (context: Context) => any;
|
|
41
|
-
export type ResolveOptions = {
|
|
42
|
-
strict?: boolean;
|
|
43
|
-
eager?: boolean;
|
|
44
|
-
singleton?: boolean;
|
|
45
|
-
};
|
|
46
|
-
export declare function defaultResolveOptions(): ResolveOptions;
|
|
47
|
-
export type ContextOptions = {
|
|
48
|
-
defaultResolveOptions?: ResolveOptions;
|
|
49
|
-
};
|
|
50
|
-
export declare class Context<Scope extends object = any> {
|
|
51
|
-
private readonly state;
|
|
52
|
-
private readonly emitter;
|
|
53
|
-
readonly scope: Scope;
|
|
54
|
-
protected readonly defaultResolveOptions: ResolveOptions;
|
|
55
|
-
constructor(options?: ContextOptions);
|
|
56
|
-
/**
|
|
57
|
-
* Set a value in context, to be injected later.
|
|
58
|
-
*
|
|
59
|
-
* @param key
|
|
60
|
-
* @param payload
|
|
61
|
-
* @deprecated Use `provideValue` instead, or you can register the same dependency as a factory with `provideFactory` or class with `provideClass`.
|
|
62
|
-
*/
|
|
63
|
-
provide<K extends ScopeKey<Scope>>(key: K, payload: Scope[K]): void;
|
|
64
|
-
/**
|
|
65
|
-
* Manually register a dependency. This should normally be used by utils or integrations that need to register dependencies in creative ways. For normal use cases, using `provideValue`, `provideFactory`, or `provideClass` is sufficient.
|
|
66
|
-
*
|
|
67
|
-
* @param key The key to register the dependency under
|
|
68
|
-
* @param dep The dependency record
|
|
69
|
-
*/
|
|
70
|
-
register<K extends ScopeKey<Scope>>(key: K, dep: ContextAttribute<this, Scope[K]>): void;
|
|
71
|
-
/**
|
|
72
|
-
* Register a value in context scope.
|
|
73
|
-
*
|
|
74
|
-
* @param key The key to register the dependency under
|
|
75
|
-
* @param value The value to register
|
|
76
|
-
*/
|
|
77
|
-
registerValue<K extends ScopeKey<Scope>>(key: K, value: Scope[K], defaultResolveOptions?: ResolveOptions): this;
|
|
78
|
-
/**
|
|
79
|
-
* Register a dependency as a factory in context scope.
|
|
80
|
-
*
|
|
81
|
-
* @param key The key to register the dependency under
|
|
82
|
-
* @param factory A factory function that will be called to generate the value when it is requested.
|
|
83
|
-
* @param inject An array of keys to use when injecting factory args.
|
|
84
|
-
* @returns A chainable instance of context
|
|
85
|
-
*/
|
|
86
|
-
registerFactory<K extends ScopeKey<Scope>, A extends any[]>(key: K, factory: FactoryFn<Scope[K], A>, inject?: FilterArgsByType<Scope, A>, defaultResolveOptions?: ResolveOptions): this;
|
|
87
|
-
registerAsyncFactory<K extends FilterKeysByType<Scope, Promise<any>>, A extends any[]>(key: K, factory: FactoryFn<Scope[K], A>, inject?: FilterAsyncArgsByType<Scope, A>, defaultResolveOptions?: ResolveOptions): this;
|
|
88
|
-
registerClass<K extends FilterKeysByType<Scope, InstanceType<T>>, T extends Class<Scope[K]>>(key: K, Class: T, inject?: FilterArgsByType<Scope, ConstructorParameters<T>>, defaultResolveOptions?: ResolveOptions): this;
|
|
89
|
-
registerAsyncClass<K extends FilterKeysByType<Scope, InstanceType<any>>, T extends Class<UnwrapPromise<Scope[K]>>>(key: K, Class: T, inject?: FilterAsyncArgsByType<Scope, ConstructorParameters<T>>, defaultResolveOptions?: ResolveOptions): this;
|
|
90
|
-
getAllDependencies<K extends ScopeKey<Scope>>(key: K): ContextAttribute<this, any>[];
|
|
91
|
-
getAllDependents<K extends ScopeKey<Scope>>(key: K): ContextAttribute<this, any>[];
|
|
92
|
-
introspect<K extends ScopeKey<Scope>>(key: K): ContextState<this>[K];
|
|
93
|
-
protected _cacheIsValid<K extends ScopeKey<Scope>>(key: K): boolean;
|
|
94
|
-
protected _resolveValue<K extends ScopeKey<Scope>>(key: K, resolveOptions?: ResolveOptions): Scope[K];
|
|
95
|
-
/**
|
|
96
|
-
* Extract a value from context.
|
|
97
|
-
*
|
|
98
|
-
* @param key
|
|
99
|
-
* @returns
|
|
100
|
-
* @deprecated Use `resolve` instead
|
|
101
|
-
*/
|
|
102
|
-
inject<T = any>(key: ScopeKey<Scope>): T | undefined;
|
|
103
|
-
resolve<K extends ScopeKey<Scope>>(key: K, resolveOptions?: ResolveOptions): Scope[K];
|
|
104
|
-
/**
|
|
105
|
-
* Ensure that only one copy of this instance exists in this context. Provides the instance if it doesn't exist yet, otherwise inject the cached instance.
|
|
106
|
-
*
|
|
107
|
-
* @param key
|
|
108
|
-
* @param instance
|
|
109
|
-
*/
|
|
110
|
-
singleton<T = any>(key: ScopeKey<Scope>, instance: T): T;
|
|
111
|
-
/**
|
|
112
|
-
* Instantiate a ContextConsumer class
|
|
113
|
-
*
|
|
114
|
-
* @param Consumer
|
|
115
|
-
* @returns
|
|
116
|
-
*/
|
|
117
|
-
hydrate<T extends ContextConsumer<this, any[]>, A extends any[]>(Consumer: new (context: this, ...args: A) => T, ...args: A): T;
|
|
118
|
-
/**
|
|
119
|
-
* Create a new context from other instance(s) of Context
|
|
120
|
-
*
|
|
121
|
-
* @param contexts
|
|
122
|
-
* @returns
|
|
123
|
-
*/
|
|
124
|
-
extend(...contexts: Context[]): this;
|
|
125
|
-
/**
|
|
126
|
-
* Modify context with middleware
|
|
127
|
-
*
|
|
128
|
-
* @param middleware
|
|
129
|
-
* @returns
|
|
130
|
-
*/
|
|
131
|
-
use(...middleware: ContextMiddleware[]): Promise<any>;
|
|
132
|
-
/**
|
|
133
|
-
* Validate context ensuring all validators are valid.
|
|
134
|
-
*
|
|
135
|
-
* @param validators
|
|
136
|
-
* @returns
|
|
137
|
-
*/
|
|
138
|
-
validate(...validators: Validator<Context>[]): import('..').Validation<Context<any>>;
|
|
139
|
-
/**
|
|
140
|
-
* Validate context ensuring at least one validator is valid
|
|
141
|
-
* @param validators
|
|
142
|
-
* @returns
|
|
143
|
-
*/
|
|
144
|
-
validateAny(...validators: Validator<Context>[]): import('..').Validation<any>;
|
|
145
|
-
/**
|
|
146
|
-
* Add a callback to listen for an event in this context.
|
|
147
|
-
*
|
|
148
|
-
* @param event
|
|
149
|
-
* @param listener
|
|
150
|
-
* @returns
|
|
151
|
-
*/
|
|
152
|
-
on(event: string, listener: ContextListener): () => void;
|
|
153
|
-
/**
|
|
154
|
-
* Emit an event in this context
|
|
155
|
-
*
|
|
156
|
-
* @param event
|
|
157
|
-
* @param args
|
|
158
|
-
* @returns
|
|
159
|
-
*/
|
|
160
|
-
emit(event: string): Promise<void>;
|
|
161
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|