@xrkseek/harness 0.4.8 → 0.4.9
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/node_modules/@xrkseek/cordis/LICENSE +21 -0
- package/node_modules/@xrkseek/cordis/README.md +14 -0
- package/node_modules/@xrkseek/cordis/bin.js +16 -0
- package/node_modules/@xrkseek/cordis/lib/index.js +1828 -0
- package/node_modules/@xrkseek/cordis/lib/types/context.d.ts +101 -0
- package/node_modules/@xrkseek/cordis/lib/types/context.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/lib/types/events.d.ts +240 -0
- package/node_modules/@xrkseek/cordis/lib/types/events.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/lib/types/fiber.d.ts +202 -0
- package/node_modules/@xrkseek/cordis/lib/types/fiber.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/lib/types/index.d.ts +15 -0
- package/node_modules/@xrkseek/cordis/lib/types/index.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/lib/types/logger.d.ts +105 -0
- package/node_modules/@xrkseek/cordis/lib/types/logger.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/lib/types/reflect.d.ts +186 -0
- package/node_modules/@xrkseek/cordis/lib/types/reflect.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/lib/types/registry.d.ts +201 -0
- package/node_modules/@xrkseek/cordis/lib/types/registry.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/lib/types/service.d.ts +55 -0
- package/node_modules/@xrkseek/cordis/lib/types/service.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/lib/types/utils.d.ts +62 -0
- package/node_modules/@xrkseek/cordis/lib/types/utils.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/package.json +49 -0
- package/node_modules/@xrkseek/cordis/src/context.d.ts +101 -0
- package/node_modules/@xrkseek/cordis/src/context.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/context.js +99 -0
- package/node_modules/@xrkseek/cordis/src/context.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/context.ts +146 -0
- package/node_modules/@xrkseek/cordis/src/events.d.ts +240 -0
- package/node_modules/@xrkseek/cordis/src/events.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/events.js +199 -0
- package/node_modules/@xrkseek/cordis/src/events.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/events.ts +352 -0
- package/node_modules/@xrkseek/cordis/src/fiber.d.ts +202 -0
- package/node_modules/@xrkseek/cordis/src/fiber.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/fiber.js +677 -0
- package/node_modules/@xrkseek/cordis/src/fiber.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/fiber.ts +754 -0
- package/node_modules/@xrkseek/cordis/src/index.d.ts +15 -0
- package/node_modules/@xrkseek/cordis/src/index.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/index.js +15 -0
- package/node_modules/@xrkseek/cordis/src/index.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/index.ts +14 -0
- package/node_modules/@xrkseek/cordis/src/logger.d.ts +105 -0
- package/node_modules/@xrkseek/cordis/src/logger.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/logger.js +193 -0
- package/node_modules/@xrkseek/cordis/src/logger.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/logger.ts +270 -0
- package/node_modules/@xrkseek/cordis/src/reflect.d.ts +186 -0
- package/node_modules/@xrkseek/cordis/src/reflect.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/reflect.js +311 -0
- package/node_modules/@xrkseek/cordis/src/reflect.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/reflect.ts +418 -0
- package/node_modules/@xrkseek/cordis/src/registry.d.ts +201 -0
- package/node_modules/@xrkseek/cordis/src/registry.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/registry.js +218 -0
- package/node_modules/@xrkseek/cordis/src/registry.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/registry.ts +337 -0
- package/node_modules/@xrkseek/cordis/src/service.d.ts +55 -0
- package/node_modules/@xrkseek/cordis/src/service.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/service.js +113 -0
- package/node_modules/@xrkseek/cordis/src/service.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/service.ts +115 -0
- package/node_modules/@xrkseek/cordis/src/utils.d.ts +62 -0
- package/node_modules/@xrkseek/cordis/src/utils.d.ts.map +1 -0
- package/node_modules/@xrkseek/cordis/src/utils.js +271 -0
- package/node_modules/@xrkseek/cordis/src/utils.js.map +1 -0
- package/node_modules/@xrkseek/cordis/src/utils.ts +287 -0
- package/node_modules/@xrkseek/core-agent-loop/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/core-agent-loop/dist/index.js +39 -68
- package/node_modules/@xrkseek/core-agent-loop/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/core-session/dist/compaction.d.ts +4 -3
- package/node_modules/@xrkseek/core-session/dist/compaction.d.ts.map +1 -1
- package/node_modules/@xrkseek/core-session/dist/compaction.js.map +1 -1
- package/node_modules/@xrkseek/core-tools/dist/subagent-prompt.d.ts.map +1 -1
- package/node_modules/@xrkseek/core-tools/dist/subagent-prompt.js +2 -1
- package/node_modules/@xrkseek/core-tools/dist/subagent-prompt.js.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/README.md +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/catalog.d.ts +16 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/catalog.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/catalog.js +152 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/catalog.js.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/deepinfra-http.d.ts +9 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/deepinfra-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/deepinfra-http.js +21 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/deepinfra-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/fal-http.d.ts +16 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/fal-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/fal-http.js +189 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/fal-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/index.d.ts +10 -5
- package/node_modules/@xrkseek/exec-image-gen/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/index.js +174 -18
- package/node_modules/@xrkseek/exec-image-gen/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/krea-http.d.ts +16 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/krea-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/krea-http.js +144 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/krea-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/meta-ai-http.d.ts +9 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/meta-ai-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/meta-ai-http.js +21 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/meta-ai-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/openai-http.d.ts +4 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/openai-http.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/openai-http.js +7 -5
- package/node_modules/@xrkseek/exec-image-gen/dist/openai-http.js.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/openrouter-http.d.ts +14 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/openrouter-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/openrouter-http.js +117 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/openrouter-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/tools.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/tools.js +43 -6
- package/node_modules/@xrkseek/exec-image-gen/dist/tools.js.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/types.d.ts +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/types.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/types.js.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/dist/xai-http.d.ts +16 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/xai-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/xai-http.js +137 -0
- package/node_modules/@xrkseek/exec-image-gen/dist/xai-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-memory/dist/consolidate-pipeline.d.ts +52 -0
- package/node_modules/@xrkseek/exec-memory/dist/consolidate-pipeline.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-memory/dist/consolidate-pipeline.js +216 -0
- package/node_modules/@xrkseek/exec-memory/dist/consolidate-pipeline.js.map +1 -0
- package/node_modules/@xrkseek/exec-memory/dist/index.d.ts +1 -0
- package/node_modules/@xrkseek/exec-memory/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-memory/dist/index.js +1 -0
- package/node_modules/@xrkseek/exec-memory/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/exec-memory/dist/tools.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-memory/dist/tools.js +20 -7
- package/node_modules/@xrkseek/exec-memory/dist/tools.js.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/README.md +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/catalog.d.ts +14 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/catalog.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/catalog.js +99 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/catalog.js.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/deepinfra-http.d.ts +9 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/deepinfra-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/deepinfra-http.js +17 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/deepinfra-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/fal-http.d.ts +14 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/fal-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/fal-http.js +342 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/fal-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/index.d.ts +8 -6
- package/node_modules/@xrkseek/exec-video-gen/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/index.js +122 -19
- package/node_modules/@xrkseek/exec-video-gen/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/openai-http.d.ts +4 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/openai-http.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/openai-http.js +21 -15
- package/node_modules/@xrkseek/exec-video-gen/dist/openai-http.js.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/openrouter-http.d.ts +9 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/openrouter-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/openrouter-http.js +18 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/openrouter-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/tools.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/tools.js +26 -6
- package/node_modules/@xrkseek/exec-video-gen/dist/tools.js.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/types.d.ts +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/types.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/types.js.map +1 -1
- package/node_modules/@xrkseek/exec-video-gen/dist/xai-http.d.ts +18 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/xai-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/xai-http.js +263 -0
- package/node_modules/@xrkseek/exec-video-gen/dist/xai-http.js.map +1 -0
- package/node_modules/@xrkseek/preset-harness/dist/preset.d.ts.map +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/preset.js +12 -3
- package/node_modules/@xrkseek/preset-harness/dist/preset.js.map +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/preset-minimal/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/preset-server/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/server-face/dist/agent-team-graph.d.ts +31 -0
- package/node_modules/@xrkseek/server-face/dist/agent-team-graph.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/agent-team-graph.js +125 -1
- package/node_modules/@xrkseek/server-face/dist/agent-team-graph.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/context.d.ts +19 -1
- package/node_modules/@xrkseek/server-face/dist/context.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/index.d.ts +3 -3
- package/node_modules/@xrkseek/server-face/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/index.js +1 -1
- package/node_modules/@xrkseek/server-face/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/mcp-oauth.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/mcp-oauth.js +25 -3
- package/node_modules/@xrkseek/server-face/dist/mcp-oauth.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/ralph-tool.d.ts +2 -0
- package/node_modules/@xrkseek/server-face/dist/ralph-tool.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/ralph-tool.js +11 -5
- package/node_modules/@xrkseek/server-face/dist/ralph-tool.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/runtime.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/runtime.js +1 -0
- package/node_modules/@xrkseek/server-face/dist/runtime.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/session-status.d.ts +16 -0
- package/node_modules/@xrkseek/server-face/dist/session-status.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/session-status.js +44 -5
- package/node_modules/@xrkseek/server-face/dist/session-status.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.d.ts +9 -0
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.js +50 -0
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-document.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-document.js +40 -0
- package/node_modules/@xrkseek/server-face/dist/settings-document.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.js +20 -4
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/subagent-tools.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/subagent-tools.js +191 -0
- package/node_modules/@xrkseek/server-face/dist/subagent-tools.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/wire/rpc-error.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/wire/rpc-error.js +8 -0
- package/node_modules/@xrkseek/server-face/dist/wire/rpc-error.js.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/index.js +135 -24
- package/node_modules/@xrkseek/server-host/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/sidebar-face-bridge.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/sidebar-face-bridge.js +6 -0
- package/node_modules/@xrkseek/server-host/dist/sidebar-face-bridge.js.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/workflow-engine-mount.d.ts +32 -0
- package/node_modules/@xrkseek/server-host/dist/workflow-engine-mount.d.ts.map +1 -0
- package/node_modules/@xrkseek/server-host/dist/workflow-engine-mount.js +134 -0
- package/node_modules/@xrkseek/server-host/dist/workflow-engine-mount.js.map +1 -0
- package/node_modules/@xrkseek/server-host/package.json +2 -0
- package/node_modules/@xrkseek/server-http/dist/sidebar/sidebar-adapter.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/sidebar/sidebar-adapter.js +20 -0
- package/node_modules/@xrkseek/server-http/dist/sidebar/sidebar-adapter.js.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/sidebar/sidebar-face-bridge.d.ts +10 -2
- package/node_modules/@xrkseek/server-http/dist/sidebar/sidebar-face-bridge.d.ts.map +1 -1
- package/node_modules/@xrkseek/xrk-workflow/README.i18n.yaml +6 -0
- package/node_modules/@xrkseek/xrk-workflow/README.md +73 -0
- package/node_modules/@xrkseek/xrk-workflow/README.zh.md +72 -0
- package/node_modules/@xrkseek/xrk-workflow/lib/types/index.d.ts +177 -0
- package/node_modules/@xrkseek/xrk-workflow/lib/types/index.js +730 -0
- package/node_modules/@xrkseek/xrk-workflow/lib/types/invariant.d.ts +13 -0
- package/node_modules/@xrkseek/xrk-workflow/lib/types/invariant.js +118 -0
- package/node_modules/@xrkseek/xrk-workflow/lib/types/runtime-types.d.ts +45 -0
- package/node_modules/@xrkseek/xrk-workflow/lib/types/runtime-types.js +9 -0
- package/node_modules/@xrkseek/xrk-workflow/lib/types/types.d.ts +118 -0
- package/node_modules/@xrkseek/xrk-workflow/lib/types/types.js +16 -0
- package/node_modules/@xrkseek/xrk-workflow/package.json +53 -0
- package/node_modules/@xrkseek/xrk-workflow/src/index.ts +947 -0
- package/package.json +5 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { defineProperty } from '@xrkseek/cosmokit';
|
|
2
|
+
import { Fiber } from "./fiber.js";
|
|
3
|
+
import { buildOuterStack, DisposableList, symbols, withProps } from "./utils.js";
|
|
4
|
+
function isApplicable(object) {
|
|
5
|
+
return object && typeof object === 'object' && typeof object.apply === 'function';
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Decorator for declaring service dependencies on classes or class methods.
|
|
9
|
+
*
|
|
10
|
+
* On classes it contributes to the plugin's static `inject` map. On methods it
|
|
11
|
+
* delays the method call until the declared services are available.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @param name — the required service name.
|
|
15
|
+
* @param config — optional intercept config applied for that service.
|
|
16
|
+
* @returns the class or method decorator.
|
|
17
|
+
*/
|
|
18
|
+
export function Inject(name, config) {
|
|
19
|
+
return function (value, decorator) {
|
|
20
|
+
if (decorator.kind === 'class') {
|
|
21
|
+
if (!Object.hasOwn(value, 'inject')) {
|
|
22
|
+
defineProperty(value, 'inject', Object.create(Object.getPrototypeOf(value).inject ?? null));
|
|
23
|
+
defineProperty(value.inject, symbols.checkProto, true);
|
|
24
|
+
}
|
|
25
|
+
value.inject[name] = config;
|
|
26
|
+
}
|
|
27
|
+
else if (decorator.kind === 'method') {
|
|
28
|
+
const inject = (value[symbols.metadata] ??= {}).inject ??= Object.create(null);
|
|
29
|
+
inject[name] = config;
|
|
30
|
+
decorator.addInitializer(function () {
|
|
31
|
+
const property = this[symbols.tracker]?.property;
|
|
32
|
+
(this[symbols.initHooks] ??= []).push(() => {
|
|
33
|
+
this.ctx.inject(inject, (ctx) => {
|
|
34
|
+
return value.call(property ? withProps(this, { [property]: ctx }) : this);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new Error('@Inject() can only be used on class or class methods');
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Utilities for normalizing plugin dependency declarations. */
|
|
45
|
+
(function (Inject) {
|
|
46
|
+
/**
|
|
47
|
+
* Convert array/object/class-inherited inject metadata into a plain map.
|
|
48
|
+
*
|
|
49
|
+
* @param inject — the declaration to normalize; `null`/`undefined` add nothing.
|
|
50
|
+
* @param result — the map to fill (service name → intercept config or `null`).
|
|
51
|
+
* @returns `result`.
|
|
52
|
+
*/
|
|
53
|
+
function resolve(inject, result = Object.create(null)) {
|
|
54
|
+
if (!inject)
|
|
55
|
+
return result;
|
|
56
|
+
if (Array.isArray(inject)) {
|
|
57
|
+
for (const name of inject) {
|
|
58
|
+
result[name] = null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (Reflect.has(inject, symbols.checkProto)) {
|
|
62
|
+
Object.assign(result, resolve(Object.getPrototypeOf(inject)));
|
|
63
|
+
for (const name of Object.keys(inject)) {
|
|
64
|
+
result[name] = inject[name] ?? null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
for (const name of Object.keys(inject)) {
|
|
69
|
+
result[name] = inject[name] ?? null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
Inject.resolve = resolve;
|
|
75
|
+
})(Inject || (Inject = {}));
|
|
76
|
+
/**
|
|
77
|
+
* Plugin registry installed as `ctx.registry` and mixed into every context.
|
|
78
|
+
*
|
|
79
|
+
* It normalizes plugin shapes, tracks plugin runtimes, starts fibers, and
|
|
80
|
+
* exposes map-like inspection over active plugin callbacks.
|
|
81
|
+
*/
|
|
82
|
+
export class RegistryService {
|
|
83
|
+
ctx;
|
|
84
|
+
_counter = 0;
|
|
85
|
+
_internal = new Map();
|
|
86
|
+
constructor(ctx) {
|
|
87
|
+
this.ctx = ctx;
|
|
88
|
+
defineProperty(this, symbols.tracker, {
|
|
89
|
+
property: 'ctx',
|
|
90
|
+
noShadow: true,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/** Allocate the next fiber uid (increments on every read). */
|
|
94
|
+
get counter() {
|
|
95
|
+
return ++this._counter;
|
|
96
|
+
}
|
|
97
|
+
/** Number of registered plugin runtimes. */
|
|
98
|
+
get size() {
|
|
99
|
+
return this._internal.size;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Resolve a supported plugin shape to its executable callback.
|
|
103
|
+
*
|
|
104
|
+
* @param plugin — a function, class, or `{ apply }` object plugin.
|
|
105
|
+
* @returns the callback identifying the plugin, or `undefined` if invalid.
|
|
106
|
+
*/
|
|
107
|
+
resolve(plugin) {
|
|
108
|
+
// plugin.apply may throw
|
|
109
|
+
try {
|
|
110
|
+
if (typeof plugin === 'function')
|
|
111
|
+
return plugin;
|
|
112
|
+
if (isApplicable(plugin))
|
|
113
|
+
return plugin.apply;
|
|
114
|
+
}
|
|
115
|
+
catch { }
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Look up the runtime record for a plugin.
|
|
119
|
+
*
|
|
120
|
+
* @param plugin — any supported plugin shape.
|
|
121
|
+
* @returns the runtime, or `undefined` when the plugin is not registered.
|
|
122
|
+
*/
|
|
123
|
+
get(plugin) {
|
|
124
|
+
const key = this.resolve(plugin);
|
|
125
|
+
return key && this._internal.get(key);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Check whether a plugin has a registered runtime.
|
|
129
|
+
*
|
|
130
|
+
* @param plugin — any supported plugin shape.
|
|
131
|
+
* @returns `true` when at least one fiber of the plugin exists.
|
|
132
|
+
*/
|
|
133
|
+
has(plugin) {
|
|
134
|
+
const key = this.resolve(plugin);
|
|
135
|
+
return !!key && this._internal.has(key);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Dispose every running fiber for a plugin and remove its runtime record.
|
|
139
|
+
*
|
|
140
|
+
* @param plugin — any supported plugin shape.
|
|
141
|
+
* @returns the removed runtime, or `undefined` when none was registered.
|
|
142
|
+
*/
|
|
143
|
+
delete(plugin) {
|
|
144
|
+
const key = this.resolve(plugin);
|
|
145
|
+
const runtime = key && this._internal.get(key);
|
|
146
|
+
if (!runtime)
|
|
147
|
+
return;
|
|
148
|
+
this._internal.delete(key);
|
|
149
|
+
for (const fiber of runtime.fibers) {
|
|
150
|
+
fiber.dispose();
|
|
151
|
+
}
|
|
152
|
+
return runtime;
|
|
153
|
+
}
|
|
154
|
+
/** Iterate the registered plugin callbacks. */
|
|
155
|
+
keys() {
|
|
156
|
+
return this._internal.keys();
|
|
157
|
+
}
|
|
158
|
+
/** Iterate the registered plugin runtimes. */
|
|
159
|
+
values() {
|
|
160
|
+
return this._internal.values();
|
|
161
|
+
}
|
|
162
|
+
/** Iterate `[callback, runtime]` pairs. */
|
|
163
|
+
entries() {
|
|
164
|
+
return this._internal.entries();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Visit every registered runtime.
|
|
168
|
+
*
|
|
169
|
+
* @param callback — receives each runtime and its identifying callback.
|
|
170
|
+
*/
|
|
171
|
+
forEach(callback) {
|
|
172
|
+
return this._internal.forEach(callback);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Start a callback once the requested dependencies are available.
|
|
176
|
+
*
|
|
177
|
+
* @param inject — required services, as an array or a name → config map.
|
|
178
|
+
* @param callback — plugin body called with `(ctx, config)`.
|
|
179
|
+
* @returns the fiber; awaiting it settles once loading finished.
|
|
180
|
+
*/
|
|
181
|
+
inject(inject, callback) {
|
|
182
|
+
return this.plugin({ inject, apply: callback, name: callback.name });
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Start a plugin in the current context and return its fiber.
|
|
186
|
+
*
|
|
187
|
+
* Creates (or reuses) the plugin's runtime record, then starts a new fiber
|
|
188
|
+
* under the current context. Throws if `plugin` is not a supported shape or
|
|
189
|
+
* if the current fiber is already disposed.
|
|
190
|
+
*
|
|
191
|
+
* @param plugin — a function, class, or `{ apply }` object plugin.
|
|
192
|
+
* @param config — the plugin config, validated against its `Config` schema.
|
|
193
|
+
* @param getOuterStack — captures the caller stack for effect diagnostics.
|
|
194
|
+
* @returns the fiber; awaiting it settles once loading finished.
|
|
195
|
+
*/
|
|
196
|
+
plugin(plugin, config, getOuterStack = buildOuterStack()) {
|
|
197
|
+
// check if it's a valid plugin
|
|
198
|
+
const callback = this.resolve(plugin);
|
|
199
|
+
if (!callback)
|
|
200
|
+
throw new Error('invalid plugin, expect function or object with an "apply" method, received ' + typeof plugin);
|
|
201
|
+
this.ctx.fiber.assertActive();
|
|
202
|
+
let runtime = this._internal.get(callback);
|
|
203
|
+
if (!runtime) {
|
|
204
|
+
let name = plugin.name;
|
|
205
|
+
if (name === 'apply')
|
|
206
|
+
name = undefined;
|
|
207
|
+
runtime = { name, callback, fibers: new DisposableList(), Config: plugin.Config };
|
|
208
|
+
this._internal.set(callback, runtime);
|
|
209
|
+
}
|
|
210
|
+
const fiber = new Fiber(this.ctx, config, Inject.resolve(plugin.inject), runtime, getOuterStack);
|
|
211
|
+
const wrapped = Object.create(fiber);
|
|
212
|
+
wrapped.then = (onFulfilled, onRejected) => {
|
|
213
|
+
return fiber.await().then(onFulfilled, onRejected);
|
|
214
|
+
};
|
|
215
|
+
return wrapped;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { defineProperty } from '@xrkseek/cosmokit'
|
|
2
|
+
import type { Dict } from '@xrkseek/cosmokit'
|
|
3
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
|
4
|
+
import { Context } from './context.ts'
|
|
5
|
+
import { Fiber } from './fiber.ts'
|
|
6
|
+
import { buildOuterStack, DisposableList, symbols, withProps } from './utils.ts'
|
|
7
|
+
|
|
8
|
+
function isApplicable(object: Plugin) {
|
|
9
|
+
return object && typeof object === 'object' && typeof object.apply === 'function'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Service dependency declaration accepted by plugins and the `@Inject`
|
|
14
|
+
* decorator.
|
|
15
|
+
*
|
|
16
|
+
* Array form requests services without intercept config. Object form maps each
|
|
17
|
+
* service name to optional intercept config for the plugin context.
|
|
18
|
+
*/
|
|
19
|
+
export type Inject<M = Dict> = (keyof M)[] | { [K in keyof M]?: M[K] }
|
|
20
|
+
|
|
21
|
+
/** Context keys that correspond to services with typed intercept config. */
|
|
22
|
+
export type InjectKey = keyof {
|
|
23
|
+
[K in keyof Context & string as Context[K] extends { [symbols.config]: any } ? K : never]: any
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Decorator for declaring service dependencies on classes or class methods.
|
|
28
|
+
*
|
|
29
|
+
* On classes it contributes to the plugin's static `inject` map. On methods it
|
|
30
|
+
* delays the method call until the declared services are available.
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* @param name — the required service name.
|
|
34
|
+
* @param config — optional intercept config applied for that service.
|
|
35
|
+
* @returns the class or method decorator.
|
|
36
|
+
*/
|
|
37
|
+
export function Inject<K extends InjectKey>(name: K, config?: Context[K] extends { [symbols.config]: infer T } ? T : never) {
|
|
38
|
+
return function (value: any, decorator: ClassDecoratorContext<any> | ClassMethodDecoratorContext<any>) {
|
|
39
|
+
if (decorator.kind === 'class') {
|
|
40
|
+
if (!Object.hasOwn(value, 'inject')) {
|
|
41
|
+
defineProperty(value, 'inject', Object.create(Object.getPrototypeOf(value).inject ?? null))
|
|
42
|
+
defineProperty(value.inject, symbols.checkProto, true)
|
|
43
|
+
}
|
|
44
|
+
value.inject[name] = config
|
|
45
|
+
} else if (decorator.kind === 'method') {
|
|
46
|
+
const inject = (value[symbols.metadata] ??= {}).inject ??= Object.create(null)
|
|
47
|
+
inject[name] = config
|
|
48
|
+
decorator.addInitializer(function () {
|
|
49
|
+
const property = this[symbols.tracker]?.property
|
|
50
|
+
;(this[symbols.initHooks] ??= []).push(() => {
|
|
51
|
+
(this.ctx as Context).inject(inject, (ctx) => {
|
|
52
|
+
return value.call(property ? withProps(this, { [property]: ctx }) : this)
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error('@Inject() can only be used on class or class methods')
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Utilities for normalizing plugin dependency declarations. */
|
|
63
|
+
export namespace Inject {
|
|
64
|
+
/**
|
|
65
|
+
* Convert array/object/class-inherited inject metadata into a plain map.
|
|
66
|
+
*
|
|
67
|
+
* @param inject — the declaration to normalize; `null`/`undefined` add nothing.
|
|
68
|
+
* @param result — the map to fill (service name → intercept config or `null`).
|
|
69
|
+
* @returns `result`.
|
|
70
|
+
*/
|
|
71
|
+
export function resolve(inject: Inject | null | undefined, result: Dict = Object.create(null)) {
|
|
72
|
+
if (!inject) return result
|
|
73
|
+
if (Array.isArray(inject)) {
|
|
74
|
+
for (const name of inject) {
|
|
75
|
+
result[name] = null
|
|
76
|
+
}
|
|
77
|
+
} else if (Reflect.has(inject, symbols.checkProto)) {
|
|
78
|
+
Object.assign(result, resolve(Object.getPrototypeOf(inject)))
|
|
79
|
+
for (const name of Object.keys(inject)) {
|
|
80
|
+
result[name] = inject[name] ?? null
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
for (const name of Object.keys(inject)) {
|
|
84
|
+
result[name] = inject[name] ?? null
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return result
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Supported plugin entrypoint shapes. */
|
|
92
|
+
export type Plugin<T = any> =
|
|
93
|
+
| Plugin.Function<T>
|
|
94
|
+
| Plugin.Constructor<T>
|
|
95
|
+
| Plugin.Object<T>
|
|
96
|
+
|
|
97
|
+
/** Types associated with plugin entrypoints and runtime records. */
|
|
98
|
+
export namespace Plugin {
|
|
99
|
+
/** Shared metadata understood by the plugin registry and related tooling. */
|
|
100
|
+
export interface Base<T = any> {
|
|
101
|
+
/** Display name used for fiber diagnostics and logger names. */
|
|
102
|
+
name?: string
|
|
103
|
+
/** Standard-schema validator applied to config before the plugin starts. */
|
|
104
|
+
Config?: StandardSchemaV1<any, T>
|
|
105
|
+
/** Services the plugin requires; it only loads while all are available. */
|
|
106
|
+
inject?: Inject
|
|
107
|
+
/** Service name(s) the plugin provides (read by `Service` and by loaders). */
|
|
108
|
+
provide?: string | string[]
|
|
109
|
+
/** Service names whose intercept config the plugin declares it consumes. */
|
|
110
|
+
intercept?: Dict<boolean>
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface Transform<S, T> {
|
|
114
|
+
/** Marks the transform object as a schema/config transform. */
|
|
115
|
+
schema?: true
|
|
116
|
+
/** Convert user-facing config to runtime config. */
|
|
117
|
+
Config: (config: S) => T
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Function plugin called with `(ctx, config)`. */
|
|
121
|
+
export interface Function<T = any> extends Base<T> {
|
|
122
|
+
(ctx: Context, config: T): any
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Class plugin constructed with `(ctx, config)`. */
|
|
126
|
+
export interface Constructor<T = any> extends Base<T> {
|
|
127
|
+
new (ctx: Context, config: T): any
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Object plugin with an `apply(ctx, config)` method. */
|
|
131
|
+
export interface Object<T = any> extends Base<T> {
|
|
132
|
+
apply(ctx: Context, config: T): any
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Mutable registry record shared by all fibers of one plugin callback. */
|
|
136
|
+
export interface Runtime {
|
|
137
|
+
/** Display name copied from the first registered plugin shape. */
|
|
138
|
+
name?: string
|
|
139
|
+
/** Every live fiber of this plugin (one per `ctx.plugin()` call). */
|
|
140
|
+
fibers: DisposableList<Fiber>
|
|
141
|
+
/** The executable entrypoint all fibers share (registry identity key). */
|
|
142
|
+
callback: globalThis.Function
|
|
143
|
+
/** Standard-schema validator applied to each fiber's config. */
|
|
144
|
+
Config?: StandardSchemaV1
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
type Spread<T> = undefined extends T ? [config?: T] : [config: T]
|
|
149
|
+
|
|
150
|
+
type GetPluginParameters<P> =
|
|
151
|
+
| P extends (ctx: Context, ...args: infer R) => any
|
|
152
|
+
? R
|
|
153
|
+
: P extends new (ctx: Context, ...args: infer R) => any
|
|
154
|
+
? R
|
|
155
|
+
: P extends { apply(ctx: Context, ...args: infer R): any }
|
|
156
|
+
? R
|
|
157
|
+
: never
|
|
158
|
+
|
|
159
|
+
type GetPluginConfig<P> =
|
|
160
|
+
| P extends Plugin.Transform<infer S, any>
|
|
161
|
+
? S
|
|
162
|
+
: GetPluginParameters<P>[0]
|
|
163
|
+
|
|
164
|
+
declare module './context.ts' {
|
|
165
|
+
export interface Context {
|
|
166
|
+
/**
|
|
167
|
+
* Run a callback once the requested services are available.
|
|
168
|
+
*
|
|
169
|
+
* Shorthand for `ctx.plugin({ inject, apply: callback })`: the callback
|
|
170
|
+
* is unloaded and re-run whenever a required service changes.
|
|
171
|
+
*
|
|
172
|
+
* @param deps — required services, as an array or a name → config map.
|
|
173
|
+
* @param callback — plugin body called with `(ctx, config)`.
|
|
174
|
+
* @returns the fiber; awaiting it settles once loading finished.
|
|
175
|
+
*/
|
|
176
|
+
inject(deps: Inject, callback: Plugin.Function<void>): Fiber & PromiseLike<Fiber>
|
|
177
|
+
/**
|
|
178
|
+
* Load a plugin in the current context.
|
|
179
|
+
*
|
|
180
|
+
* @param plugin — a function, class, or `{ apply }` object plugin.
|
|
181
|
+
* @param args — the plugin config, validated against its `Config` schema.
|
|
182
|
+
* @returns the fiber; awaiting it settles once loading finished
|
|
183
|
+
* (rejecting on config or startup errors).
|
|
184
|
+
*/
|
|
185
|
+
plugin<P extends Plugin>(plugin: P, ...args: Spread<GetPluginConfig<P>>): Fiber & PromiseLike<Fiber>
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Plugin registry installed as `ctx.registry` and mixed into every context.
|
|
191
|
+
*
|
|
192
|
+
* It normalizes plugin shapes, tracks plugin runtimes, starts fibers, and
|
|
193
|
+
* exposes map-like inspection over active plugin callbacks.
|
|
194
|
+
*/
|
|
195
|
+
export class RegistryService {
|
|
196
|
+
private _counter = 0
|
|
197
|
+
private _internal = new Map<Function, Plugin.Runtime>()
|
|
198
|
+
|
|
199
|
+
constructor(public ctx: Context) {
|
|
200
|
+
defineProperty(this, symbols.tracker, {
|
|
201
|
+
property: 'ctx',
|
|
202
|
+
noShadow: true,
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Allocate the next fiber uid (increments on every read). */
|
|
207
|
+
get counter() {
|
|
208
|
+
return ++this._counter
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Number of registered plugin runtimes. */
|
|
212
|
+
get size() {
|
|
213
|
+
return this._internal.size
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Resolve a supported plugin shape to its executable callback.
|
|
218
|
+
*
|
|
219
|
+
* @param plugin — a function, class, or `{ apply }` object plugin.
|
|
220
|
+
* @returns the callback identifying the plugin, or `undefined` if invalid.
|
|
221
|
+
*/
|
|
222
|
+
resolve(plugin: Plugin): Function | undefined {
|
|
223
|
+
// plugin.apply may throw
|
|
224
|
+
try {
|
|
225
|
+
if (typeof plugin === 'function') return plugin
|
|
226
|
+
if (isApplicable(plugin)) return plugin.apply
|
|
227
|
+
} catch {}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Look up the runtime record for a plugin.
|
|
232
|
+
*
|
|
233
|
+
* @param plugin — any supported plugin shape.
|
|
234
|
+
* @returns the runtime, or `undefined` when the plugin is not registered.
|
|
235
|
+
*/
|
|
236
|
+
get(plugin: Plugin) {
|
|
237
|
+
const key = this.resolve(plugin)
|
|
238
|
+
return key && this._internal.get(key)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Check whether a plugin has a registered runtime.
|
|
243
|
+
*
|
|
244
|
+
* @param plugin — any supported plugin shape.
|
|
245
|
+
* @returns `true` when at least one fiber of the plugin exists.
|
|
246
|
+
*/
|
|
247
|
+
has(plugin: Plugin) {
|
|
248
|
+
const key = this.resolve(plugin)
|
|
249
|
+
return !!key && this._internal.has(key)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Dispose every running fiber for a plugin and remove its runtime record.
|
|
254
|
+
*
|
|
255
|
+
* @param plugin — any supported plugin shape.
|
|
256
|
+
* @returns the removed runtime, or `undefined` when none was registered.
|
|
257
|
+
*/
|
|
258
|
+
delete(plugin: Plugin) {
|
|
259
|
+
const key = this.resolve(plugin)
|
|
260
|
+
const runtime = key && this._internal.get(key)
|
|
261
|
+
if (!runtime) return
|
|
262
|
+
this._internal.delete(key)
|
|
263
|
+
for (const fiber of runtime.fibers) {
|
|
264
|
+
fiber.dispose()
|
|
265
|
+
}
|
|
266
|
+
return runtime
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** Iterate the registered plugin callbacks. */
|
|
270
|
+
keys() {
|
|
271
|
+
return this._internal.keys()
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Iterate the registered plugin runtimes. */
|
|
275
|
+
values() {
|
|
276
|
+
return this._internal.values()
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** Iterate `[callback, runtime]` pairs. */
|
|
280
|
+
entries() {
|
|
281
|
+
return this._internal.entries()
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Visit every registered runtime.
|
|
286
|
+
*
|
|
287
|
+
* @param callback — receives each runtime and its identifying callback.
|
|
288
|
+
*/
|
|
289
|
+
forEach(callback: (value: Plugin.Runtime, key: Function) => void) {
|
|
290
|
+
return this._internal.forEach(callback)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Start a callback once the requested dependencies are available.
|
|
295
|
+
*
|
|
296
|
+
* @param inject — required services, as an array or a name → config map.
|
|
297
|
+
* @param callback — plugin body called with `(ctx, config)`.
|
|
298
|
+
* @returns the fiber; awaiting it settles once loading finished.
|
|
299
|
+
*/
|
|
300
|
+
inject(inject: Inject, callback: Plugin.Function<void>) {
|
|
301
|
+
return this.plugin({ inject, apply: callback, name: callback.name })
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Start a plugin in the current context and return its fiber.
|
|
306
|
+
*
|
|
307
|
+
* Creates (or reuses) the plugin's runtime record, then starts a new fiber
|
|
308
|
+
* under the current context. Throws if `plugin` is not a supported shape or
|
|
309
|
+
* if the current fiber is already disposed.
|
|
310
|
+
*
|
|
311
|
+
* @param plugin — a function, class, or `{ apply }` object plugin.
|
|
312
|
+
* @param config — the plugin config, validated against its `Config` schema.
|
|
313
|
+
* @param getOuterStack — captures the caller stack for effect diagnostics.
|
|
314
|
+
* @returns the fiber; awaiting it settles once loading finished.
|
|
315
|
+
*/
|
|
316
|
+
plugin(plugin: Plugin, config?: any, getOuterStack = buildOuterStack()) {
|
|
317
|
+
// check if it's a valid plugin
|
|
318
|
+
const callback = this.resolve(plugin)
|
|
319
|
+
if (!callback) throw new Error('invalid plugin, expect function or object with an "apply" method, received ' + typeof plugin)
|
|
320
|
+
this.ctx.fiber.assertActive()
|
|
321
|
+
|
|
322
|
+
let runtime = this._internal.get(callback)
|
|
323
|
+
if (!runtime) {
|
|
324
|
+
let name = plugin.name
|
|
325
|
+
if (name === 'apply') name = undefined
|
|
326
|
+
runtime = { name, callback, fibers: new DisposableList(), Config: plugin.Config }
|
|
327
|
+
this._internal.set(callback, runtime)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const fiber = new Fiber(this.ctx, config, Inject.resolve(plugin.inject), runtime, getOuterStack)
|
|
331
|
+
const wrapped = Object.create(fiber) as Fiber & PromiseLike<Fiber>
|
|
332
|
+
wrapped.then = (onFulfilled, onRejected) => {
|
|
333
|
+
return fiber.await().then(onFulfilled, onRejected)
|
|
334
|
+
}
|
|
335
|
+
return wrapped
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Context } from './context.ts';
|
|
2
|
+
import { symbols } from './utils.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Base class for services that expose a named API on `ctx`.
|
|
5
|
+
*
|
|
6
|
+
* Subclasses call `super(ctx, name)` from their constructor. The service is
|
|
7
|
+
* registered immediately and is automatically removed with the owning fiber.
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class Service<out T = never> {
|
|
10
|
+
protected ctx: Context;
|
|
11
|
+
/** Symbol key of an instance method run after construction (class plugins). */
|
|
12
|
+
static readonly init: unique symbol;
|
|
13
|
+
/** Symbol key of the availability predicate passed to `ctx.provide()`. */
|
|
14
|
+
static readonly check: unique symbol;
|
|
15
|
+
/** Symbol key of the phantom intercept-config type parameter. */
|
|
16
|
+
static readonly config: unique symbol;
|
|
17
|
+
/** Symbol key of the call body making a service callable (e.g. `ctx.logger()`). */
|
|
18
|
+
static readonly invoke: unique symbol;
|
|
19
|
+
/** Symbol key of the helper deriving an extended service instance. */
|
|
20
|
+
static readonly extend: unique symbol;
|
|
21
|
+
/** Symbol key of the tracker metadata used for context tracing. */
|
|
22
|
+
static readonly tracker: unique symbol;
|
|
23
|
+
/** Symbol key of the intercept-config resolution helper below. */
|
|
24
|
+
static readonly resolveConfig: unique symbol;
|
|
25
|
+
[symbols.config]: T;
|
|
26
|
+
/** The service name this instance is registered under. */
|
|
27
|
+
name: string;
|
|
28
|
+
/**
|
|
29
|
+
* Register this instance as `name` in the current context.
|
|
30
|
+
*
|
|
31
|
+
* Calls `ctx.reflect.provide(name, this, this[Service.check])`, so the
|
|
32
|
+
* service is unregistered automatically when the owning fiber unloads.
|
|
33
|
+
* Services with a `[Service.invoke]` body return a callable instance.
|
|
34
|
+
*
|
|
35
|
+
* @param ctx — the context to register in (stored as `this.ctx`).
|
|
36
|
+
* @param name — the service name; defaults to the static `provide` field.
|
|
37
|
+
*/
|
|
38
|
+
constructor(ctx: Context, name: string);
|
|
39
|
+
protected [symbols.filter](ctx: Context): boolean;
|
|
40
|
+
protected [symbols.extend](props?: any): any;
|
|
41
|
+
/**
|
|
42
|
+
* Merge intercept config from ancestors with optional base and head values.
|
|
43
|
+
*
|
|
44
|
+
* Entries added closer to the root apply first; `base` is prepended and
|
|
45
|
+
* `head` appended. Uses `Config.merge` when the service declares one,
|
|
46
|
+
* otherwise a shallow `Object.assign`.
|
|
47
|
+
*
|
|
48
|
+
* @param base — lowest-precedence config merged before all intercepts.
|
|
49
|
+
* @param head — highest-precedence config merged after all intercepts.
|
|
50
|
+
* @returns the merged config.
|
|
51
|
+
*/
|
|
52
|
+
[symbols.resolveConfig](base?: T, head?: T): T;
|
|
53
|
+
static [Symbol.hasInstance](instance: any): boolean;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAiC,OAAO,EAAgB,MAAM,YAAY,CAAA;AAEjF;;;;;GAKG;AACH,8BAAsB,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK;IA+B7B,SAAS,CAAC,GAAG,EAAE,OAAO;IA9BlC,+EAA+E;IAC/E,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,MAAM,CAAe;IAClD,0EAA0E;IAC1E,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,MAAM,CAAgB;IACpD,iEAAiE;IACjE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,MAAM,CAAiB;IACtD,mFAAmF;IACnF,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,MAAM,CAAiB;IACtD,sEAAsE;IACtE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,MAAM,CAAiB;IACtD,mEAAmE;IACnE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,MAAM,CAAkB;IACxD,kEAAkE;IAClE,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,MAAM,CAAwB;IAE5D,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAE3B,0DAA0D;IACnD,IAAI,EAAG,MAAM,CAAA;IAEpB;;;;;;;;;OASG;gBACmB,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM;IAmBhD,SAAS,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO;IAIvC,SAAS,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG;IAUtC;;;;;;;;;;OAUG;IACH,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;IAkB9C,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,GAAG;CAW1C"}
|