injeca 0.2.0 → 0.4.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 +596 -32
- package/dist/decision-BXZu3N1O.mjs +1356 -0
- package/dist/decision-BXZu3N1O.mjs.map +1 -0
- package/dist/global-B5N-d-TO.mjs +3600 -0
- package/dist/global-B5N-d-TO.mjs.map +1 -0
- package/dist/global-DPfe26g5.d.mts +217 -0
- package/dist/global.d.mts +2 -2
- package/dist/global.mjs +1 -3
- package/dist/index-DTYp044J.d.mts +763 -0
- package/dist/index.d.mts +199 -2
- package/dist/index.mjs +242 -2
- package/dist/index.mjs.map +1 -0
- package/dist/testing.d.mts +61 -0
- package/dist/testing.mjs +103 -0
- package/dist/testing.mjs.map +1 -0
- package/package.json +15 -28
- package/dist/builtin-BPDNf8Z-.mjs +0 -25
- package/dist/builtin-BPDNf8Z-.mjs.map +0 -1
- package/dist/global-BLY6_SI_.d.mts +0 -130
- package/dist/src-UXkTj4Np.mjs +0 -294
- package/dist/src-UXkTj4Np.mjs.map +0 -1
package/dist/testing.mjs
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { G as nodeOf, St as InvalidArgumentError, r as validateDecision, t as createDecide } from "./decision-BXZu3N1O.mjs";
|
|
2
|
+
// src/testing/drained.ts
|
|
3
|
+
/**
|
|
4
|
+
* Resolves when the work queue of `container` has drained and stays drained.
|
|
5
|
+
*
|
|
6
|
+
* A build or a hook that settles on a microtask can queue more work after a drain.
|
|
7
|
+
* So it waits one macrotask after each drain, and starts again when another drain happens.
|
|
8
|
+
* The macrotask is a real `setTimeout(0)`, so it does not resolve while the fake timers of a test runner hold `setTimeout`.
|
|
9
|
+
* A `manualClock` does not change `setTimeout`, so the two work together.
|
|
10
|
+
*
|
|
11
|
+
* It does not wait for work that a timer starts later, for example a requeue delay or a policy timeout. Move the clock first, then await `drained` again.
|
|
12
|
+
*/
|
|
13
|
+
function drained(container) {
|
|
14
|
+
const { reconciler } = nodeOf(container).runtime;
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
let timer;
|
|
17
|
+
const stopListening = reconciler.onDrained(() => {
|
|
18
|
+
clearTimeout(timer);
|
|
19
|
+
timer = setTimeout(() => {
|
|
20
|
+
stopListening();
|
|
21
|
+
resolve();
|
|
22
|
+
}, 0);
|
|
23
|
+
});
|
|
24
|
+
reconciler.requestDrain();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// src/testing/manual-clock.ts
|
|
28
|
+
/**
|
|
29
|
+
* Creates a manual clock for tests. It drives `timeout()`, `withTimeout()`, requeue delays, and the `start` and `stop` policy timeouts without real time.
|
|
30
|
+
*
|
|
31
|
+
* `advance` runs the timer callbacks synchronously. Await `drained(container)` after it, so that the work that the callbacks start settles.
|
|
32
|
+
*/
|
|
33
|
+
function manualClock() {
|
|
34
|
+
let now = 0;
|
|
35
|
+
let seq = 0;
|
|
36
|
+
const timers = /* @__PURE__ */ new Map();
|
|
37
|
+
return {
|
|
38
|
+
clock: {
|
|
39
|
+
now: () => now,
|
|
40
|
+
setTimeout: (callback, ms) => {
|
|
41
|
+
const id = ++seq;
|
|
42
|
+
timers.set(id, {
|
|
43
|
+
at: now + ms,
|
|
44
|
+
callback
|
|
45
|
+
});
|
|
46
|
+
return () => timers.delete(id);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
advance: (ms) => {
|
|
50
|
+
now += ms;
|
|
51
|
+
const due = [...timers].filter(([, timer]) => timer.at <= now).sort(([, a], [, b]) => a.at - b.at);
|
|
52
|
+
for (const [id, timer] of due) {
|
|
53
|
+
timers.delete(id);
|
|
54
|
+
timer.callback();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
pending: () => timers.size
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// src/testing/testing.ts
|
|
61
|
+
const runs = /* @__PURE__ */ new WeakMap();
|
|
62
|
+
/**
|
|
63
|
+
* Creates a hook context for a unit test of a hook handler, or of a helper that gets `decide`.
|
|
64
|
+
*
|
|
65
|
+
* Its decisions are bound to this context, as in a real run. Use `checkDecision` to check a result as injeca does.
|
|
66
|
+
*/
|
|
67
|
+
function createHookContext(hook, options = {}) {
|
|
68
|
+
const attempt = options.attempt ?? 1;
|
|
69
|
+
if (!Number.isInteger(attempt) || attempt < 1) throw new InvalidArgumentError(`The attempt of a hook context must be an integer of 1 or more. Got ${String(attempt)}.`);
|
|
70
|
+
const run = {
|
|
71
|
+
service: options.service ?? "test",
|
|
72
|
+
instanceId: options.instanceId ?? "test-instance",
|
|
73
|
+
hook,
|
|
74
|
+
attempt,
|
|
75
|
+
now: options.now ?? (() => Date.now())
|
|
76
|
+
};
|
|
77
|
+
const dependencyHook = hook === "dependency-change" || hook === "dependency-status-change";
|
|
78
|
+
const context = Object.freeze({
|
|
79
|
+
decide: createDecide(run),
|
|
80
|
+
attempt,
|
|
81
|
+
previous: options.previous,
|
|
82
|
+
signal: options.signal ?? new AbortController().signal,
|
|
83
|
+
...dependencyHook ? {
|
|
84
|
+
dependsOn: Object.freeze({ ...options.dependsOn }),
|
|
85
|
+
changes: Object.freeze([...options.changes ?? []])
|
|
86
|
+
} : {}
|
|
87
|
+
});
|
|
88
|
+
runs.set(context, run);
|
|
89
|
+
return context;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Checks the value that a handler returned for `context`, as injeca does. `undefined` gives `undefined`: the default of the hook.
|
|
93
|
+
*
|
|
94
|
+
* @throws {InvalidDecisionError} for a decision from another context, or a kind that the hook does not accept. A value that is not a decision gives `undefined`.
|
|
95
|
+
*/
|
|
96
|
+
function checkDecision(context, value) {
|
|
97
|
+
const run = runs.get(context);
|
|
98
|
+
if (!run) throw new InvalidArgumentError("The context does not come from createHookContext.");
|
|
99
|
+
return validateDecision(run, value);
|
|
100
|
+
}
|
|
101
|
+
export { checkDecision, createHookContext, drained, manualClock };
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=testing.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.mjs","names":[],"sources":["../src/testing/drained.ts","../src/testing/manual-clock.ts","../src/testing/testing.ts"],"sourcesContent":["import type { Container } from '../types'\n\nimport { nodeOf } from '../graph/nodes'\n\n/**\n * Resolves when the work queue of `container` has drained and stays drained.\n *\n * A build or a hook that settles on a microtask can queue more work after a drain.\n * So it waits one macrotask after each drain, and starts again when another drain happens.\n * The macrotask is a real `setTimeout(0)`, so it does not resolve while the fake timers of a test runner hold `setTimeout`.\n * A `manualClock` does not change `setTimeout`, so the two work together.\n *\n * It does not wait for work that a timer starts later, for example a requeue delay or a policy timeout. Move the clock first, then await `drained` again.\n */\nexport function drained(container: Container): Promise<void> {\n const { reconciler } = nodeOf(container).runtime\n\n return new Promise((resolve) => {\n let timer: ReturnType<typeof setTimeout> | undefined\n const stopListening = reconciler.onDrained(() => {\n clearTimeout(timer)\n timer = setTimeout(() => {\n stopListening()\n resolve()\n }, 0)\n })\n reconciler.requestDrain()\n })\n}\n","import type { Clock } from '../helpers/clock'\n\n/** A clock that moves only when a test calls `advance`. Pass `clock` to `createContainer`. */\nexport interface ManualClock {\n /** The clock for `createContainer({ clock })`. Its time starts at 0. */\n readonly clock: Clock\n /**\n * Moves the time forward by `ms`, and runs each timer that is due, in the order of its time.\n * A timer that a callback sets during the call runs at a later call, also when it is due now.\n */\n readonly advance: (ms: number) => void\n /** The number of timers that wait. A timer that was cancelled or that ran does not count. */\n readonly pending: () => number\n}\n\n/**\n * Creates a manual clock for tests. It drives `timeout()`, `withTimeout()`, requeue delays, and the `start` and `stop` policy timeouts without real time.\n *\n * `advance` runs the timer callbacks synchronously. Await `drained(container)` after it, so that the work that the callbacks start settles.\n */\nexport function manualClock(): ManualClock {\n let now = 0\n let seq = 0\n const timers = new Map<number, { readonly at: number, readonly callback: () => void }>()\n\n return {\n clock: {\n now: () => now,\n setTimeout: (callback, ms) => {\n const id = ++seq\n timers.set(id, { at: now + ms, callback })\n return () => timers.delete(id)\n },\n },\n advance: (ms) => {\n now += ms\n const due = [...timers].filter(([, timer]) => timer.at <= now).sort(([, a], [, b]) => a.at - b.at)\n for (const [id, timer] of due) {\n timers.delete(id)\n timer.callback()\n }\n },\n pending: () => timers.size,\n }\n}\n","import type { Decision, HookRun, ServiceHook } from '../primitives/decision'\nimport type { DependencyChange, HookContextFor, HookDependencies } from '../types'\n\nimport { InvalidArgumentError } from '../diagnostics/errors'\nimport { createDecide, validateDecision } from '../primitives/decision'\n\nexport { drained } from './drained'\nexport { manualClock } from './manual-clock'\nexport type { ManualClock } from './manual-clock'\n\nexport interface HookContextOptions<D = undefined> {\n /** The service name that the decisions carry. It defaults to `'test'`. */\n service?: string\n /** The instance id that the decisions carry. It defaults to `'test-instance'`. */\n instanceId?: string\n /** It defaults to `1`. */\n attempt?: number\n previous?: Decision\n /** It defaults to a signal that does not abort. */\n signal?: AbortSignal\n /** The snapshot of a dependency hook. It defaults to an empty record. */\n dependsOn?: HookDependencies<D>\n /** The changes of a dependency hook. It defaults to an empty list. */\n changes?: readonly DependencyChange[]\n /** The clock for `issuedAt`. It defaults to `Date.now`. */\n now?: () => number\n}\n\nconst runs = new WeakMap<object, HookRun>()\n\n/**\n * Creates a hook context for a unit test of a hook handler, or of a helper that gets `decide`.\n *\n * Its decisions are bound to this context, as in a real run. Use `checkDecision` to check a result as injeca does.\n */\nexport function createHookContext<H extends ServiceHook, D = undefined>(hook: H, options: HookContextOptions<D> = {}): HookContextFor<H, D> {\n const attempt = options.attempt ?? 1\n if (!Number.isInteger(attempt) || attempt < 1)\n throw new InvalidArgumentError(`The attempt of a hook context must be an integer of 1 or more. Got ${String(attempt)}.`)\n\n const run: HookRun = {\n service: options.service ?? 'test',\n instanceId: options.instanceId ?? 'test-instance',\n hook,\n attempt,\n now: options.now ?? (() => Date.now()),\n }\n const dependencyHook = hook === 'dependency-change' || hook === 'dependency-status-change'\n const context = Object.freeze({\n decide: createDecide(run),\n attempt,\n previous: options.previous,\n signal: options.signal ?? new AbortController().signal,\n ...(dependencyHook ? { dependsOn: Object.freeze({ ...options.dependsOn }), changes: Object.freeze([...(options.changes ?? [])]) } : {}),\n })\n runs.set(context, run)\n\n return context as unknown as HookContextFor<H, D>\n}\n\n/**\n * Checks the value that a handler returned for `context`, as injeca does. `undefined` gives `undefined`: the default of the hook.\n *\n * @throws {InvalidDecisionError} for a decision from another context, or a kind that the hook does not accept. A value that is not a decision gives `undefined`.\n */\nexport function checkDecision(context: object, value: unknown): Decision | undefined {\n const run = runs.get(context)\n if (!run)\n throw new InvalidArgumentError('The context does not come from createHookContext.')\n\n return validateDecision(run, value)\n}\n"],"mappings":";;;;;;;;;;;;AAcA,SAAgB,QAAQ,WAAqC;CAC3D,MAAM,EAAE,eAAe,OAAO,SAAS,CAAC,CAAC;CAEzC,OAAO,IAAI,SAAS,YAAY;EAC9B,IAAI;EACJ,MAAM,gBAAgB,WAAW,gBAAgB;GAC/C,aAAa,KAAK;GAClB,QAAQ,iBAAiB;IACvB,cAAc;IACd,QAAQ;GACV,GAAG,CAAC;EACN,CAAC;EACD,WAAW,aAAa;CAC1B,CAAC;AACH;;;;;;;ACRA,SAAgB,cAA2B;CACzC,IAAI,MAAM;CACV,IAAI,MAAM;CACV,MAAM,yBAAS,IAAI,IAAoE;CAEvF,OAAO;EACL,OAAO;GACL,WAAW;GACX,aAAa,UAAU,OAAO;IAC5B,MAAM,KAAK,EAAE;IACb,OAAO,IAAI,IAAI;KAAE,IAAI,MAAM;KAAI;IAAS,CAAC;IACzC,aAAa,OAAO,OAAO,EAAE;GAC/B;EACF;EACA,UAAU,OAAO;GACf,OAAO;GACP,MAAM,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,QAAQ,GAAG,WAAW,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE;GACjG,KAAK,MAAM,CAAC,IAAI,UAAU,KAAK;IAC7B,OAAO,OAAO,EAAE;IAChB,MAAM,SAAS;GACjB;EACF;EACA,eAAe,OAAO;CACxB;AACF;;AChBA,MAAM,uBAAO,IAAI,QAAyB;;;;;;AAO1C,SAAgB,kBAAwD,MAAS,UAAiC,CAAC,GAAyB;CAC1I,MAAM,UAAU,QAAQ,WAAW;CACnC,IAAI,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,GAC1C,MAAM,IAAI,qBAAqB,sEAAsE,OAAO,OAAO,EAAE,EAAE;CAEzH,MAAM,MAAe;EACnB,SAAS,QAAQ,WAAW;EAC5B,YAAY,QAAQ,cAAc;EAClC;EACA;EACA,KAAK,QAAQ,cAAc,KAAK,IAAI;CACtC;CACA,MAAM,iBAAiB,SAAS,uBAAuB,SAAS;CAChE,MAAM,UAAU,OAAO,OAAO;EAC5B,QAAQ,aAAa,GAAG;EACxB;EACA,UAAU,QAAQ;EAClB,QAAQ,QAAQ,UAAU,IAAI,gBAAgB,CAAC,CAAC;EAChD,GAAI,iBAAiB;GAAE,WAAW,OAAO,OAAO,EAAE,GAAG,QAAQ,UAAU,CAAC;GAAG,SAAS,OAAO,OAAO,CAAC,GAAI,QAAQ,WAAW,CAAC,CAAE,CAAC;EAAE,IAAI,CAAC;CACvI,CAAC;CACD,KAAK,IAAI,SAAS,GAAG;CAErB,OAAO;AACT;;;;;;AAOA,SAAgB,cAAc,SAAiB,OAAsC;CACnF,MAAM,MAAM,KAAK,IAAI,OAAO;CAC5B,IAAI,CAAC,KACH,MAAM,IAAI,qBAAqB,mDAAmD;CAEpF,OAAO,iBAAiB,KAAK,KAAK;AACpC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "injeca",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"description": "Pure functional programming based dependency injection library inspired by go.uber.org/fig and go.uber.org/dig.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Moeru AI Project AIRI Team",
|
|
@@ -12,22 +12,28 @@
|
|
|
12
12
|
"homepage": "https://github.com/moeru-ai/injeca",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/moeru-ai/injeca.git"
|
|
15
|
+
"url": "https://github.com/moeru-ai/injeca.git",
|
|
16
|
+
"directory": "packages/injeca"
|
|
16
17
|
},
|
|
17
18
|
"exports": {
|
|
18
19
|
".": {
|
|
19
|
-
"
|
|
20
|
+
"types": "./dist/index.d.mts",
|
|
20
21
|
"default": "./dist/index.mjs"
|
|
21
22
|
},
|
|
22
23
|
"./global": {
|
|
23
|
-
"
|
|
24
|
+
"types": "./dist/global.d.mts",
|
|
24
25
|
"default": "./dist/global.mjs"
|
|
26
|
+
},
|
|
27
|
+
"./testing": {
|
|
28
|
+
"types": "./dist/testing.d.mts",
|
|
29
|
+
"default": "./dist/testing.mjs"
|
|
25
30
|
}
|
|
26
31
|
},
|
|
27
32
|
"main": "./dist/index.mjs",
|
|
28
33
|
"module": "./dist/index.mjs",
|
|
29
|
-
"types": "./dist/index.mts",
|
|
34
|
+
"types": "./dist/index.d.mts",
|
|
30
35
|
"files": [
|
|
36
|
+
"LICENSE",
|
|
31
37
|
"README.md",
|
|
32
38
|
"dist",
|
|
33
39
|
"package.json"
|
|
@@ -42,31 +48,12 @@
|
|
|
42
48
|
"optional": true
|
|
43
49
|
}
|
|
44
50
|
},
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"@moeru/std": "^0.1.0-beta.18",
|
|
49
|
-
"@moeru/tsconfig": "^0.1.0-beta.18",
|
|
50
|
-
"@types/node": "^25.6.0",
|
|
51
|
-
"bumpp": "^11.0.1",
|
|
52
|
-
"eslint": "^10.2.0",
|
|
53
|
-
"eslint-plugin-oxlint": "^1.60.0",
|
|
54
|
-
"oxlint": "^1.60.0",
|
|
55
|
-
"publint": "^0.3.18",
|
|
56
|
-
"taze": "^19.11.0",
|
|
57
|
-
"tsdown": "^0.17.4",
|
|
58
|
-
"typescript": "^6.0.2",
|
|
59
|
-
"unplugin-unused": "^0.5.7",
|
|
60
|
-
"vite": "^8.0.8",
|
|
61
|
-
"vitest": "^4.1.4"
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"alien-signals": "^3.2.1",
|
|
53
|
+
"es-toolkit": "^1.53.1"
|
|
62
54
|
},
|
|
63
55
|
"scripts": {
|
|
64
56
|
"build": "tsdown",
|
|
65
|
-
"
|
|
66
|
-
"test:run": "vitest run",
|
|
67
|
-
"lint": "eslint --cache .",
|
|
68
|
-
"lint:fix": "eslint --cache --fix .",
|
|
69
|
-
"typecheck": "tsc --noEmit",
|
|
70
|
-
"up": "taze -w -r -I -f && pnpm prune && pnpm dedupe"
|
|
57
|
+
"typecheck": "tsc --noEmit -p ../../tsconfig.json"
|
|
71
58
|
}
|
|
72
59
|
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
//#region src/builtin.ts
|
|
2
|
-
function buildLifecycle() {
|
|
3
|
-
const onStartHooks = [];
|
|
4
|
-
const onStopHooks = [];
|
|
5
|
-
return {
|
|
6
|
-
appHooks: {
|
|
7
|
-
onStart(hook) {
|
|
8
|
-
if (hook) onStartHooks.push(hook);
|
|
9
|
-
},
|
|
10
|
-
onStop(hook) {
|
|
11
|
-
if (hook) onStopHooks.push(hook);
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
emitOnStart: async () => {
|
|
15
|
-
for (const hook of onStartHooks) await hook();
|
|
16
|
-
},
|
|
17
|
-
emitOnStop: async () => {
|
|
18
|
-
for (const hook of onStopHooks) await hook();
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
export { buildLifecycle };
|
|
25
|
-
//# sourceMappingURL=builtin-BPDNf8Z-.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-BPDNf8Z-.mjs","names":["onStartHooks: (() => void | Promise<void>)[]","onStopHooks: (() => void | Promise<void>)[]"],"sources":["../src/builtin.ts"],"sourcesContent":["export interface LifecycleAppHooks {\n onStart: (hook: () => void | Promise<void>) => void\n onStop: (hook: () => void | Promise<void>) => void\n}\n\nexport interface Lifecycle {\n appHooks: LifecycleAppHooks\n}\n\nexport interface LifecycleTriggerable extends Lifecycle {\n emitOnStart: () => Promise<void>\n emitOnStop: () => Promise<void>\n}\n\nexport function buildLifecycle(): Lifecycle {\n const onStartHooks: (() => void | Promise<void>)[] = []\n const onStopHooks: (() => void | Promise<void>)[] = []\n\n const lifecycle: LifecycleTriggerable = {\n appHooks: {\n onStart(hook: () => void | Promise<void>) {\n if (hook) {\n onStartHooks.push(hook)\n }\n },\n onStop(hook: () => void | Promise<void>) {\n if (hook) {\n onStopHooks.push(hook)\n }\n },\n },\n emitOnStart: async () => {\n for (const hook of onStartHooks) {\n await hook()\n }\n },\n emitOnStop: async () => {\n for (const hook of onStopHooks) {\n await hook()\n }\n },\n }\n\n return lifecycle\n}\n"],"mappings":";AAcA,SAAgB,iBAA4B;CAC1C,MAAMA,eAA+C,EAAE;CACvD,MAAMC,cAA8C,EAAE;AA2BtD,QAzBwC;EACtC,UAAU;GACR,QAAQ,MAAkC;AACxC,QAAI,KACF,cAAa,KAAK,KAAK;;GAG3B,OAAO,MAAkC;AACvC,QAAI,KACF,aAAY,KAAK,KAAK;;GAG3B;EACD,aAAa,YAAY;AACvB,QAAK,MAAM,QAAQ,aACjB,OAAM,MAAM;;EAGhB,YAAY,YAAY;AACtB,QAAK,MAAM,QAAQ,YACjB,OAAM,MAAM;;EAGjB"}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { Logg } from "@guiiai/logg";
|
|
2
|
-
|
|
3
|
-
//#region src/builtin.d.ts
|
|
4
|
-
interface LifecycleAppHooks {
|
|
5
|
-
onStart: (hook: () => void | Promise<void>) => void;
|
|
6
|
-
onStop: (hook: () => void | Promise<void>) => void;
|
|
7
|
-
}
|
|
8
|
-
interface Lifecycle {
|
|
9
|
-
appHooks: LifecycleAppHooks;
|
|
10
|
-
}
|
|
11
|
-
interface LifecycleTriggerable extends Lifecycle {
|
|
12
|
-
emitOnStart: () => Promise<void>;
|
|
13
|
-
emitOnStop: () => Promise<void>;
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
//#region src/logger.d.ts
|
|
17
|
-
interface Logger {
|
|
18
|
-
provide: (name: string, dependencies: string[]) => void;
|
|
19
|
-
invoke: (dependencies: string[]) => void;
|
|
20
|
-
beforeRun: (name: string) => void;
|
|
21
|
-
run: (name: string, duration: number) => void;
|
|
22
|
-
hookOnStart: (name: string) => void;
|
|
23
|
-
hookOnStartComplete: (name: string, duration: number) => void;
|
|
24
|
-
hookOnStop: (name: string) => void;
|
|
25
|
-
hookOnStopComplete: (name: string, duration: number) => void;
|
|
26
|
-
running: () => void;
|
|
27
|
-
}
|
|
28
|
-
interface LoggerOptions {
|
|
29
|
-
enabled?: boolean;
|
|
30
|
-
logger?: Logger;
|
|
31
|
-
}
|
|
32
|
-
declare function createDefaultLogger(): Logger;
|
|
33
|
-
declare function createLoggLogger(logg: Logg): Logger;
|
|
34
|
-
declare function createNoopLogger(): Logger;
|
|
35
|
-
//#endregion
|
|
36
|
-
//#region src/scoped.d.ts
|
|
37
|
-
type DependencyMap = Record<string, any>;
|
|
38
|
-
interface Container {
|
|
39
|
-
providers: Map<string, ProvideOptionObject<any, any>>;
|
|
40
|
-
instances: Map<string, any>;
|
|
41
|
-
lifecycleHooks: Map<string, LifecycleTriggerable>;
|
|
42
|
-
dependencyGraph: Map<string, string[]>;
|
|
43
|
-
invocations: InvokeOptionObject<any>[];
|
|
44
|
-
logger: Logger;
|
|
45
|
-
}
|
|
46
|
-
type BuildContext<D extends DependencyMap | undefined = undefined> = {
|
|
47
|
-
container: Container;
|
|
48
|
-
name: string;
|
|
49
|
-
} & (D extends undefined ? {
|
|
50
|
-
dependsOn?: unknown;
|
|
51
|
-
} : {
|
|
52
|
-
dependsOn: D;
|
|
53
|
-
});
|
|
54
|
-
type ResolveDependencyDeclaration<Deps extends Record<string, string | ProvidedKey<any, any, any>>> = { [K in keyof Deps]: Deps[K] extends ProvidedKey<any, infer T, any> ? T : Deps[K] extends ProvidedBy<infer T> ? T : any };
|
|
55
|
-
type ProvideOptionObject<T, D extends DependencyMap | undefined = undefined> = {
|
|
56
|
-
build: (context: BuildContext<D>) => T | Promise<T>;
|
|
57
|
-
} & (D extends undefined ? {
|
|
58
|
-
dependsOn?: Record<string, never>;
|
|
59
|
-
} : {
|
|
60
|
-
dependsOn: { [K in keyof D]: string };
|
|
61
|
-
});
|
|
62
|
-
type ProvideOptionFunc<T, D extends DependencyMap | undefined = undefined> = (context: BuildContext<D>) => T | Promise<T>;
|
|
63
|
-
type ProvideOption<T, D extends DependencyMap | undefined = undefined> = ProvideOptionObject<T, D> | ProvideOptionFunc<T, D>;
|
|
64
|
-
interface ProvideOptionObjectWithKeys<T, Deps extends Record<string, string | ProvidedKey<any, any, any>>> {
|
|
65
|
-
build: (context: BuildContext<ResolveDependencyDeclaration<Deps>>) => T | Promise<T>;
|
|
66
|
-
dependsOn: Deps;
|
|
67
|
-
}
|
|
68
|
-
type ProvideOptionWithKeys<T, Deps extends Record<string, string | ProvidedKey<any, any, any>>> = ProvideOptionObjectWithKeys<T, Deps>;
|
|
69
|
-
type InvokeOptionObject<D extends DependencyMap | undefined = undefined> = {
|
|
70
|
-
callback: (dependencies: D) => void | Promise<void>;
|
|
71
|
-
} & (D extends undefined ? {
|
|
72
|
-
dependsOn?: Record<string, never>;
|
|
73
|
-
} : {
|
|
74
|
-
dependsOn: { [K in keyof D]: string };
|
|
75
|
-
});
|
|
76
|
-
type InvokeOptionFunc<D extends DependencyMap | undefined = undefined> = (dependencies: D) => void | Promise<void>;
|
|
77
|
-
type InvokeOption<D extends DependencyMap | undefined = undefined> = InvokeOptionObject<D> | InvokeOptionFunc<D>;
|
|
78
|
-
interface InvokeOptionObjectWithKeys<Deps extends Record<string, string | ProvidedKey<any, any, any>>> {
|
|
79
|
-
callback: (dependencies: ResolveDependencyDeclaration<Deps>) => void | Promise<void>;
|
|
80
|
-
dependsOn: Deps;
|
|
81
|
-
}
|
|
82
|
-
type InvokeOptionWithKeys<Deps extends Record<string, string | ProvidedKey<any, any, any>>> = InvokeOptionObjectWithKeys<Deps>;
|
|
83
|
-
declare const lifecycle: ProvidedKey<'lifecycle', Lifecycle, undefined>;
|
|
84
|
-
declare function createContainer(options?: LoggerOptions): Container;
|
|
85
|
-
interface ProvidedKey<Key, _T, _D extends DependencyMap | undefined> {
|
|
86
|
-
key: Key;
|
|
87
|
-
}
|
|
88
|
-
type ProvidedBy<T> = string & {
|
|
89
|
-
__providedType?: T;
|
|
90
|
-
};
|
|
91
|
-
type InferProvided<T> = T extends ProvidedKey<any, infer P, any> ? P : T extends ProvidedBy<infer P> ? P : never;
|
|
92
|
-
declare function provide$1<T, Key extends string, Deps extends Record<string, string | ProvidedKey<any, any, any>>>(container: Container, name: Key, option: ProvideOptionWithKeys<T, Deps>): ProvidedKey<Key, T, ResolveDependencyDeclaration<Deps>>;
|
|
93
|
-
declare function provide$1<T, Key extends string, Deps extends Record<string, string | ProvidedKey<any, any, any>>>(container: Container, option: ProvideOptionWithKeys<T, Deps> & {
|
|
94
|
-
autoNameStackIndex?: number;
|
|
95
|
-
}): ProvidedKey<Key, T, ResolveDependencyDeclaration<Deps>>;
|
|
96
|
-
declare function provide$1<D extends DependencyMap | undefined, T = any, Key extends string = string>(container: Container, name: Key, option: ProvideOption<T, D>): ProvidedKey<Key, T, D>;
|
|
97
|
-
declare function provide$1<D extends DependencyMap | undefined, T = any, Key extends string = string>(container: Container, option: ProvideOption<T, D> & {
|
|
98
|
-
autoNameStackIndex?: number;
|
|
99
|
-
}): ProvidedKey<Key, T, D>;
|
|
100
|
-
declare function invoke$1<Deps extends Record<string, string | ProvidedKey<any, any, any>>>(container: Container, option: InvokeOptionWithKeys<Deps>): void;
|
|
101
|
-
declare function invoke$1<D extends DependencyMap>(container: Container, option: InvokeOption<D>): void;
|
|
102
|
-
declare function resolve$1<Deps extends Record<string, string | ProvidedKey<any, any, any>>>(container: Container, dependsOn: Deps): Promise<ResolveDependencyDeclaration<Deps>>;
|
|
103
|
-
declare function start$1(container: Container): Promise<void>;
|
|
104
|
-
declare function stop$1(container: Container): Promise<void>;
|
|
105
|
-
//#endregion
|
|
106
|
-
//#region src/index.d.ts
|
|
107
|
-
declare const injeca: {
|
|
108
|
-
provide: typeof provide;
|
|
109
|
-
invoke: typeof invoke;
|
|
110
|
-
resolve: typeof resolve;
|
|
111
|
-
start: typeof start;
|
|
112
|
-
stop: typeof stop;
|
|
113
|
-
setLogger: typeof setLogger;
|
|
114
|
-
};
|
|
115
|
-
//#endregion
|
|
116
|
-
//#region src/global.d.ts
|
|
117
|
-
declare function setLogger(logger: Logger): void;
|
|
118
|
-
declare function resetContainer(): void;
|
|
119
|
-
declare function provide<T, Key extends string, Deps extends Record<string, string | ProvidedKey<any, any, any>>>(name: Key, option: ProvideOptionWithKeys<T, Deps>): ProvidedKey<Key, T, ResolveDependencyDeclaration<Deps>>;
|
|
120
|
-
declare function provide<D extends DependencyMap | undefined, T = any, Key extends string = string>(name: Key, option: ProvideOption<T, D>): ProvidedKey<Key, T, D>;
|
|
121
|
-
declare function provide<T, Key extends string, Deps extends Record<string, string | ProvidedKey<any, any, any>>>(option: ProvideOptionWithKeys<T, Deps>): ProvidedKey<Key, T, ResolveDependencyDeclaration<Deps>>;
|
|
122
|
-
declare function provide<D extends DependencyMap | undefined, T = any, Key extends string = string>(option: ProvideOption<T, D>): ProvidedKey<Key, T, D>;
|
|
123
|
-
declare function invoke<Deps extends Record<string, string | ProvidedKey<any, any, any>>>(option: InvokeOptionWithKeys<Deps>): void;
|
|
124
|
-
declare function invoke<D extends DependencyMap>(option: InvokeOption<D>): void;
|
|
125
|
-
declare function resolve<Deps extends Record<string, string | ProvidedKey<any, any, any>>>(dependsOn: Deps): Promise<ResolveDependencyDeclaration<Deps>>;
|
|
126
|
-
declare function start(): Promise<void>;
|
|
127
|
-
declare function stop(): Promise<void>;
|
|
128
|
-
//#endregion
|
|
129
|
-
export { resolve$1 as A, ProvidedBy as C, invoke$1 as D, createContainer as E, createDefaultLogger as F, createLoggLogger as I, createNoopLogger as L, stop$1 as M, Logger as N, lifecycle as O, LoggerOptions as P, Lifecycle as R, ProvideOptionWithKeys as S, ResolveDependencyDeclaration as T, InvokeOptionWithKeys as _, setLogger as a, ProvideOptionObject as b, injeca as c, DependencyMap as d, InferProvided as f, InvokeOptionObjectWithKeys as g, InvokeOptionObject as h, resolve as i, start$1 as j, provide$1 as k, BuildContext as l, InvokeOptionFunc as m, provide as n, start as o, InvokeOption as p, resetContainer as r, stop as s, invoke as t, Container as u, ProvideOption as v, ProvidedKey as w, ProvideOptionObjectWithKeys as x, ProvideOptionFunc as y };
|
|
130
|
-
//# sourceMappingURL=global-BLY6_SI_.d.mts.map
|
package/dist/src-UXkTj4Np.mjs
DELETED
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import ErrorStackParser from "error-stack-parser";
|
|
2
|
-
import { nanoid } from "nanoid";
|
|
3
|
-
|
|
4
|
-
//#region src/global.ts
|
|
5
|
-
let globalContainer = createContainer();
|
|
6
|
-
function setLogger(logger) {
|
|
7
|
-
globalContainer.logger = logger;
|
|
8
|
-
}
|
|
9
|
-
function resetContainer() {
|
|
10
|
-
globalContainer = createContainer();
|
|
11
|
-
}
|
|
12
|
-
function provide(nameOrOption, option) {
|
|
13
|
-
if (option != null && typeof option === "function") return provide$1(globalContainer, nameOrOption, {
|
|
14
|
-
build: option,
|
|
15
|
-
autoNameStackIndex: 2
|
|
16
|
-
});
|
|
17
|
-
return provide$1(globalContainer, nameOrOption, {
|
|
18
|
-
...option,
|
|
19
|
-
autoNameStackIndex: 2
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
function invoke(option) {
|
|
23
|
-
if (typeof option === "function") globalContainer.invocations.push({ callback: option });
|
|
24
|
-
else globalContainer.invocations.push(option);
|
|
25
|
-
}
|
|
26
|
-
function resolve(dependsOn) {
|
|
27
|
-
return resolve$1(globalContainer, dependsOn);
|
|
28
|
-
}
|
|
29
|
-
function start() {
|
|
30
|
-
return start$1(globalContainer);
|
|
31
|
-
}
|
|
32
|
-
function stop() {
|
|
33
|
-
return stop$1(globalContainer);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
//#endregion
|
|
37
|
-
//#region package.json
|
|
38
|
-
var name = "injeca";
|
|
39
|
-
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region src/logger.ts
|
|
42
|
-
function formatDuration(ms) {
|
|
43
|
-
if (ms < 1) return `${(ms * 1e3).toFixed(3)}µs`;
|
|
44
|
-
if (ms < 1e3) return `${ms.toFixed(3)}ms`;
|
|
45
|
-
return `${(ms / 1e3).toFixed(3)}s`;
|
|
46
|
-
}
|
|
47
|
-
function createDefaultLogger() {
|
|
48
|
-
return {
|
|
49
|
-
provide: (name$1, dependencies) => {
|
|
50
|
-
const depsStr = dependencies.length > 0 ? ` (depends on: ${dependencies.join(", ")})` : "";
|
|
51
|
-
console.log(`[${name$1}] PROVIDE ${name$1}${depsStr}`);
|
|
52
|
-
},
|
|
53
|
-
invoke: (dependencies) => {
|
|
54
|
-
const depsStr = dependencies.length > 0 ? ` (depends on: ${dependencies.join(", ")})` : "";
|
|
55
|
-
console.log(`[${name}] INVOKE${depsStr}`);
|
|
56
|
-
},
|
|
57
|
-
beforeRun: (name$1) => {
|
|
58
|
-
console.log(`[${name$1}] BEFORE RUN provide: ${name$1}()`);
|
|
59
|
-
},
|
|
60
|
-
run: (name$1, duration) => {
|
|
61
|
-
console.log(`[${name$1}] RUN provide: ${name$1}() in ${formatDuration(duration)}`);
|
|
62
|
-
},
|
|
63
|
-
hookOnStart: (name$1) => {
|
|
64
|
-
console.log(`[${name$1}] HOOK OnStart ${name$1}() executing`);
|
|
65
|
-
},
|
|
66
|
-
hookOnStartComplete: (name$1, duration) => {
|
|
67
|
-
console.log(`[${name$1}] HOOK OnStart ${name$1}() ran successfully in ${formatDuration(duration)}`);
|
|
68
|
-
},
|
|
69
|
-
hookOnStop: (name$1) => {
|
|
70
|
-
console.log(`[${name$1}] HOOK OnStop ${name$1}() executing`);
|
|
71
|
-
},
|
|
72
|
-
hookOnStopComplete: (name$1, duration) => {
|
|
73
|
-
console.log(`[${name$1}] HOOK OnStop ${name$1}() ran successfully in ${formatDuration(duration)}`);
|
|
74
|
-
},
|
|
75
|
-
running: () => {
|
|
76
|
-
console.log(`[${name}] RUNNING`);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
function createLoggLogger(logg) {
|
|
81
|
-
return {
|
|
82
|
-
provide: (name$1, dependencies) => {
|
|
83
|
-
const depsStr = dependencies.length > 0 ? ` (depends on: ${dependencies.join(", ")})` : "";
|
|
84
|
-
logg.log(`PROVIDE ${name$1}${depsStr}`);
|
|
85
|
-
},
|
|
86
|
-
invoke: (dependencies) => {
|
|
87
|
-
const depsStr = dependencies.length > 0 ? ` (depends on: ${dependencies.join(", ")})` : "";
|
|
88
|
-
logg.log(`INVOKE${depsStr}`);
|
|
89
|
-
},
|
|
90
|
-
beforeRun: (name$1) => {
|
|
91
|
-
logg.log(`BEFORE RUN provide: ${name$1}()`);
|
|
92
|
-
},
|
|
93
|
-
run: (name$1, duration) => {
|
|
94
|
-
logg.log(`RUN provide: ${name$1}() in ${formatDuration(duration)}`);
|
|
95
|
-
},
|
|
96
|
-
hookOnStart: (name$1) => {
|
|
97
|
-
logg.log(`HOOK OnStart ${name$1}() executing`);
|
|
98
|
-
},
|
|
99
|
-
hookOnStartComplete: (name$1, duration) => {
|
|
100
|
-
logg.log(`HOOK OnStart ${name$1}() ran successfully in ${formatDuration(duration)}`);
|
|
101
|
-
},
|
|
102
|
-
hookOnStop: (name$1) => {
|
|
103
|
-
logg.log(`HOOK OnStop ${name$1}() executing`);
|
|
104
|
-
},
|
|
105
|
-
hookOnStopComplete: (name$1, duration) => {
|
|
106
|
-
logg.log(`HOOK OnStop ${name$1}() ran successfully in ${formatDuration(duration)}`);
|
|
107
|
-
},
|
|
108
|
-
running: () => {
|
|
109
|
-
logg.log(`RUNNING`);
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function createNoopLogger() {
|
|
114
|
-
return {
|
|
115
|
-
provide: () => {},
|
|
116
|
-
invoke: () => {},
|
|
117
|
-
beforeRun: () => {},
|
|
118
|
-
run: () => {},
|
|
119
|
-
hookOnStart: () => {},
|
|
120
|
-
hookOnStartComplete: () => {},
|
|
121
|
-
hookOnStop: () => {},
|
|
122
|
-
hookOnStopComplete: () => {},
|
|
123
|
-
running: () => {}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
//#endregion
|
|
128
|
-
//#region src/scoped.ts
|
|
129
|
-
const lifecycle = { key: "lifecycle" };
|
|
130
|
-
function createContainer(options) {
|
|
131
|
-
const logger = options?.enabled === false ? createNoopLogger() : options?.logger ?? createDefaultLogger();
|
|
132
|
-
return {
|
|
133
|
-
providers: /* @__PURE__ */ new Map(),
|
|
134
|
-
instances: /* @__PURE__ */ new Map(),
|
|
135
|
-
lifecycleHooks: /* @__PURE__ */ new Map(),
|
|
136
|
-
dependencyGraph: /* @__PURE__ */ new Map(),
|
|
137
|
-
invocations: [],
|
|
138
|
-
logger
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
function normalizeName(nameOrProvidedKey) {
|
|
142
|
-
if (typeof nameOrProvidedKey === "object" && nameOrProvidedKey !== null && "key" in nameOrProvidedKey) return nameOrProvidedKey.key;
|
|
143
|
-
return nameOrProvidedKey;
|
|
144
|
-
}
|
|
145
|
-
function normalizeProvideOption(nameOrOption, option) {
|
|
146
|
-
if (typeof nameOrOption === "string") {
|
|
147
|
-
if (option == null || !("build" in option) && typeof option !== "function") throw new Error("When using provide(...) as named callback, the second argument must be either a valid ProvideOptionObject<T, D> or a ProvideOptionFunc<T, D>.");
|
|
148
|
-
if (typeof option === "function") return { build: option };
|
|
149
|
-
return option;
|
|
150
|
-
}
|
|
151
|
-
if (typeof nameOrOption === "object" && "key" in nameOrOption) {
|
|
152
|
-
if (option == null || !("build" in option) && typeof option !== "function") throw new Error("When using provide(...) as typed ProvideOptionWithKeys<T, D, Key> callback, the second argument must be either a valid ProvideOptionObject<T, D> or a ProvideOptionFunc<T, D>.");
|
|
153
|
-
if (typeof option === "function") return { build: option };
|
|
154
|
-
return option;
|
|
155
|
-
}
|
|
156
|
-
if (typeof nameOrOption === "function") return { build: nameOrOption };
|
|
157
|
-
return nameOrOption;
|
|
158
|
-
}
|
|
159
|
-
function provide$1(container, nameOrOption, option) {
|
|
160
|
-
const parentFile = ErrorStackParser.parse(/* @__PURE__ */ new Error("providing"))[option?.autoNameStackIndex ?? 1];
|
|
161
|
-
const name$1 = typeof nameOrOption === "string" ? nameOrOption : `${parentFile.fileName ?? `unknown-${nanoid()}`}:${parentFile.lineNumber ?? 0}:${parentFile.columnNumber ?? 0}`;
|
|
162
|
-
const providerObject = normalizeProvideOption(nameOrOption, option);
|
|
163
|
-
if (providerObject.dependsOn) {
|
|
164
|
-
const resolvedDependsOn = {};
|
|
165
|
-
for (const [key, value] of Object.entries(providerObject.dependsOn)) resolvedDependsOn[key] = normalizeName(value);
|
|
166
|
-
providerObject.dependsOn = resolvedDependsOn;
|
|
167
|
-
}
|
|
168
|
-
container.providers.set(name$1, providerObject);
|
|
169
|
-
const dependencies = providerObject.dependsOn ? Object.values(providerObject.dependsOn) : [];
|
|
170
|
-
container.logger.provide(name$1, dependencies);
|
|
171
|
-
container.dependencyGraph.set(name$1, dependencies);
|
|
172
|
-
return { key: name$1 };
|
|
173
|
-
}
|
|
174
|
-
function invoke$1(container, option) {
|
|
175
|
-
const invocationObject = typeof option === "function" ? { callback: option } : option;
|
|
176
|
-
if (invocationObject.dependsOn) {
|
|
177
|
-
const resolvedDependsOn = {};
|
|
178
|
-
for (const [key, value] of Object.entries(invocationObject.dependsOn)) resolvedDependsOn[key] = normalizeName(value);
|
|
179
|
-
invocationObject.dependsOn = resolvedDependsOn;
|
|
180
|
-
}
|
|
181
|
-
const dependencies = invocationObject.dependsOn ? Object.values(invocationObject.dependsOn) : [];
|
|
182
|
-
container.logger.invoke(dependencies);
|
|
183
|
-
container.invocations.push(invocationObject);
|
|
184
|
-
}
|
|
185
|
-
async function resolveInstance(container, name$1) {
|
|
186
|
-
if (container.instances.has(name$1)) {
|
|
187
|
-
const existing = container.instances.get(name$1);
|
|
188
|
-
return existing instanceof Promise ? await existing : existing;
|
|
189
|
-
}
|
|
190
|
-
const provider = container.providers.get(name$1);
|
|
191
|
-
if (!provider) throw new Error(`No provider found for '${name$1}'`);
|
|
192
|
-
const resolvedDependencies = {};
|
|
193
|
-
let serviceLifecycle = null;
|
|
194
|
-
if (provider.dependsOn) for (const [key, depName] of Object.entries(provider.dependsOn)) if (depName === "lifecycle") {
|
|
195
|
-
const { buildLifecycle } = await import("./builtin-BPDNf8Z-.mjs");
|
|
196
|
-
serviceLifecycle = buildLifecycle();
|
|
197
|
-
resolvedDependencies[key] = serviceLifecycle;
|
|
198
|
-
container.lifecycleHooks.set(name$1, serviceLifecycle);
|
|
199
|
-
} else resolvedDependencies[key] = await resolveInstance(container, depName);
|
|
200
|
-
const context = {
|
|
201
|
-
container,
|
|
202
|
-
dependsOn: resolvedDependencies,
|
|
203
|
-
name: name$1
|
|
204
|
-
};
|
|
205
|
-
async function buildAndStore() {
|
|
206
|
-
container.logger.beforeRun(name$1);
|
|
207
|
-
const startTime = performance.now();
|
|
208
|
-
const instance = await provider.build(context);
|
|
209
|
-
const duration = performance.now() - startTime;
|
|
210
|
-
container.logger.run(name$1, duration);
|
|
211
|
-
container.instances.set(name$1, instance);
|
|
212
|
-
return instance;
|
|
213
|
-
}
|
|
214
|
-
const buildPromise = buildAndStore();
|
|
215
|
-
container.instances.set(name$1, buildPromise);
|
|
216
|
-
return await buildPromise;
|
|
217
|
-
}
|
|
218
|
-
async function resolve$1(container, dependsOn) {
|
|
219
|
-
const resolved = {};
|
|
220
|
-
for (const [key, depName] of Object.entries(dependsOn)) resolved[key] = await resolveInstance(container, normalizeName(depName));
|
|
221
|
-
return resolved;
|
|
222
|
-
}
|
|
223
|
-
function topologicalSort(dependencyGraph) {
|
|
224
|
-
const visited = /* @__PURE__ */ new Set();
|
|
225
|
-
const visiting = /* @__PURE__ */ new Set();
|
|
226
|
-
const result = [];
|
|
227
|
-
function visit(node) {
|
|
228
|
-
if (visiting.has(node)) throw new Error(`Circular dependency detected involving '${node}'`);
|
|
229
|
-
if (visited.has(node)) return;
|
|
230
|
-
visiting.add(node);
|
|
231
|
-
const dependencies = dependencyGraph.get(node) || [];
|
|
232
|
-
for (const dep of dependencies) visit(dep);
|
|
233
|
-
visiting.delete(node);
|
|
234
|
-
visited.add(node);
|
|
235
|
-
result.push(node);
|
|
236
|
-
}
|
|
237
|
-
for (const node of dependencyGraph.keys()) if (!visited.has(node)) visit(node);
|
|
238
|
-
return result;
|
|
239
|
-
}
|
|
240
|
-
async function startLifecycleHooks(container) {
|
|
241
|
-
const sortedServices = topologicalSort(container.dependencyGraph);
|
|
242
|
-
for (const serviceName of sortedServices) {
|
|
243
|
-
const lifecycle$1 = container.lifecycleHooks.get(serviceName);
|
|
244
|
-
if (lifecycle$1?.emitOnStart) {
|
|
245
|
-
container.logger.hookOnStart(serviceName);
|
|
246
|
-
const startTime = performance.now();
|
|
247
|
-
await lifecycle$1.emitOnStart();
|
|
248
|
-
const duration = performance.now() - startTime;
|
|
249
|
-
container.logger.hookOnStartComplete(serviceName, duration);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
async function stopLifecycleHooks(container) {
|
|
254
|
-
const sortedServices = topologicalSort(container.dependencyGraph);
|
|
255
|
-
for (const serviceName of sortedServices.reverse()) {
|
|
256
|
-
const lifecycle$1 = container.lifecycleHooks.get(serviceName);
|
|
257
|
-
if (lifecycle$1?.emitOnStop) {
|
|
258
|
-
container.logger.hookOnStop(serviceName);
|
|
259
|
-
const startTime = performance.now();
|
|
260
|
-
await lifecycle$1.emitOnStop();
|
|
261
|
-
const duration = performance.now() - startTime;
|
|
262
|
-
container.logger.hookOnStopComplete(serviceName, duration);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
async function start$1(container) {
|
|
267
|
-
const resolvedInvocations = [];
|
|
268
|
-
for (const invocation of container.invocations) {
|
|
269
|
-
const resolvedDependencies = {};
|
|
270
|
-
if (invocation.dependsOn) for (const [key, depName] of Object.entries(invocation.dependsOn)) resolvedDependencies[key] = await resolveInstance(container, normalizeName(depName));
|
|
271
|
-
resolvedInvocations.push(resolvedDependencies);
|
|
272
|
-
}
|
|
273
|
-
await startLifecycleHooks(container);
|
|
274
|
-
for (const [index, invocation] of container.invocations.entries()) await invocation.callback(resolvedInvocations[index] ?? {});
|
|
275
|
-
container.logger.running();
|
|
276
|
-
}
|
|
277
|
-
async function stop$1(container) {
|
|
278
|
-
await stopLifecycleHooks(container);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
//#endregion
|
|
282
|
-
//#region src/index.ts
|
|
283
|
-
const injeca = {
|
|
284
|
-
provide,
|
|
285
|
-
invoke,
|
|
286
|
-
resolve,
|
|
287
|
-
start,
|
|
288
|
-
stop,
|
|
289
|
-
setLogger
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
//#endregion
|
|
293
|
-
export { start as _, provide$1 as a, stop$1 as c, createNoopLogger as d, invoke as f, setLogger as g, resolve as h, lifecycle as i, createDefaultLogger as l, resetContainer as m, createContainer as n, resolve$1 as o, provide as p, invoke$1 as r, start$1 as s, injeca as t, createLoggLogger as u, stop as v };
|
|
294
|
-
//# sourceMappingURL=src-UXkTj4Np.mjs.map
|