@arki/dot 0.3.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 +86 -86
- package/dist/cli/discover.js +2 -2
- package/dist/cli/discover.js.map +1 -1
- package/dist/cli/error-codes.d.ts +8 -0
- package/dist/cli/error-codes.d.ts.map +1 -1
- package/dist/cli/error-codes.js +12 -0
- package/dist/cli/error-codes.js.map +1 -1
- package/dist/cli/index.d.ts +9 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +54 -23
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/new.d.ts +1 -1
- package/dist/cli/new.js +1 -1
- package/dist/cli/render-doctor.d.ts +1 -1
- package/dist/cli/render-doctor.js +23 -23
- package/dist/cli/render-doctor.js.map +1 -1
- package/dist/cli/render-explain.d.ts.map +1 -1
- package/dist/cli/render-explain.js +33 -19
- package/dist/cli/render-explain.js.map +1 -1
- package/dist/cli/render-graph.d.ts +3 -3
- package/dist/cli/render-graph.js +12 -12
- package/dist/cli/render-graph.js.map +1 -1
- package/dist/cli/render-projection.d.ts +29 -0
- package/dist/cli/render-projection.d.ts.map +1 -0
- package/dist/cli/render-projection.js +202 -0
- package/dist/cli/render-projection.js.map +1 -0
- package/dist/define-app.d.ts +49 -17
- package/dist/define-app.d.ts.map +1 -1
- package/dist/define-app.js +16 -9
- package/dist/define-app.js.map +1 -1
- package/dist/diagnostics.d.ts +19 -15
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +2 -2
- package/dist/index.d.ts +15 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/init-pips.d.ts +45 -0
- package/dist/init-pips.d.ts.map +1 -0
- package/dist/init-pips.js +49 -0
- package/dist/init-pips.js.map +1 -0
- package/dist/init-plugins.d.ts +45 -0
- package/dist/init-plugins.d.ts.map +1 -0
- package/dist/init-plugins.js +49 -0
- package/dist/init-plugins.js.map +1 -0
- package/dist/kernel/app-instance.d.ts +5 -5
- package/dist/kernel/app-instance.d.ts.map +1 -1
- package/dist/kernel/app-instance.js +375 -244
- package/dist/kernel/app-instance.js.map +1 -1
- package/dist/kernel/otel.d.ts +19 -19
- package/dist/kernel/otel.d.ts.map +1 -1
- package/dist/kernel/otel.js +22 -22
- package/dist/kernel/otel.js.map +1 -1
- package/dist/lifecycle-observer.d.ts +10 -10
- package/dist/lifecycle-observer.d.ts.map +1 -1
- package/dist/lifecycle-observer.js +1 -1
- package/dist/lifecycle.d.ts +18 -14
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +13 -9
- package/dist/lifecycle.js.map +1 -1
- package/dist/manifest.d.ts +70 -48
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +74 -5
- package/dist/manifest.js.map +1 -1
- package/dist/pip-contract.d.ts +29 -21
- package/dist/pip-contract.d.ts.map +1 -1
- package/dist/pip-contract.js +1 -0
- package/dist/pip-contract.js.map +1 -1
- package/dist/pip.d.ts +7 -4
- package/dist/pip.d.ts.map +1 -1
- package/dist/pip.js +2 -0
- package/dist/pip.js.map +1 -1
- package/dist/plugin-contract.d.ts +335 -143
- package/dist/plugin-contract.d.ts.map +1 -1
- package/dist/plugin-contract.js +201 -36
- package/dist/plugin-contract.js.map +1 -1
- package/dist/plugin.d.ts +18 -15
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +11 -11
- package/dist/plugin.js.map +1 -1
- package/dist/test-harness.d.ts +31 -31
- package/dist/test-harness.d.ts.map +1 -1
- package/dist/test-harness.js +29 -28
- package/dist/test-harness.js.map +1 -1
- package/dist/timeline.d.ts +2 -2
- package/dist/timeline.js +5 -5
- package/dist/timeline.js.map +1 -1
- package/package.json +9 -9
- package/src/cli/discover.ts +2 -2
- package/src/cli/error-codes.ts +12 -0
- package/src/cli/index.ts +76 -29
- package/src/cli/new.ts +1 -1
- package/src/cli/render-doctor.ts +21 -21
- package/src/cli/render-explain.ts +37 -19
- package/src/cli/render-graph.ts +12 -12
- package/src/cli/render-projection.ts +239 -0
- package/src/define-app.ts +85 -22
- package/src/diagnostics.ts +19 -15
- package/src/index.ts +37 -20
- package/src/init-plugins.ts +142 -0
- package/src/kernel/app-instance.ts +428 -282
- package/src/kernel/otel.ts +27 -27
- package/src/lifecycle-observer.ts +10 -10
- package/src/lifecycle.ts +19 -15
- package/src/manifest.ts +128 -50
- package/src/{pip-contract.ts → plugin-contract.ts} +73 -62
- package/src/{pip.ts → plugin.ts} +37 -18
- package/src/test-harness.ts +52 -51
- package/src/timeline.ts +6 -6
- package/templates/app-minimal/AGENTS.md.tmpl +9 -9
- package/templates/app-minimal/README.md.tmpl +1 -1
- package/templates/app-minimal/tests/boot.test.ts.tmpl +1 -1
- package/src/cli/render-openapi.ts +0 -147
package/dist/plugin-contract.js
CHANGED
|
@@ -1,44 +1,209 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Public plugin contract for the DOT kernel.
|
|
2
|
+
* Public plugin contract for the DOT kernel (v2).
|
|
3
3
|
*
|
|
4
|
-
* A
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* A plugin declares what it **needs** as a shape of type witnesses and
|
|
5
|
+
* publishes what it **provides** from its `boot` hook. The kernel wires
|
|
6
|
+
* services by key, injects them into hook contexts under the plugin's local
|
|
7
|
+
* aliases, and fails loudly (coded errors) on unsatisfied needs or key
|
|
8
|
+
* collisions.
|
|
7
9
|
*
|
|
8
10
|
* Design constraints:
|
|
9
11
|
*
|
|
10
|
-
* - `configure` is SYNC. Returning a Promise is an error — the kernel
|
|
11
|
-
*
|
|
12
|
-
* -
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
12
|
+
* - `configure` is SYNC. Returning a Promise is an error — the kernel
|
|
13
|
+
* throws {@link DotLifecycleError} with code `DOT_LIFECYCLE_E001`.
|
|
14
|
+
* - Declaration order IS boot order. The app builder's type-level guard
|
|
15
|
+
* makes out-of-order composition a compile error; the kernel re-validates
|
|
16
|
+
* at runtime for erased/dynamic composition.
|
|
17
|
+
* - `stop` and `dispose` run in reverse declaration order and continue
|
|
18
|
+
* through individual plugin failures, reporting an aggregate error.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Create an app-local (anonymous) service witness for a `needs` shape.
|
|
22
|
+
*
|
|
23
|
+
* `service.lazy<T>()` creates a lifting witness instead — the hook context
|
|
24
|
+
* delivers a `Lazy<T>` handle whether the provider is eager or lazy.
|
|
25
|
+
*/
|
|
26
|
+
export const service = Object.assign(() => ({}), { lazy: () => ({ lazy: true }) });
|
|
27
|
+
/** Internal (kernel) check: is this witness a lazy-lifting one? */
|
|
28
|
+
export function isLazyWitness(witness) {
|
|
29
|
+
return 'lazy' in witness && witness.lazy === true;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a token. Curried so `T` is explicit while `K` is inferred as a
|
|
33
|
+
* literal: `const Db = token<DbHandle>()('arki.db')`.
|
|
34
|
+
*/
|
|
35
|
+
export function token() {
|
|
36
|
+
return (key) => ({
|
|
37
|
+
key,
|
|
38
|
+
instance(name) {
|
|
39
|
+
// Safe by construction: the runtime string is exactly the template type.
|
|
40
|
+
return token()(`${key}#${name}`);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Publish a value under a token's wire key. Returns a record typed by the
|
|
46
|
+
* token's literal key, so `boot: () => provide(Db, handle)` infers
|
|
47
|
+
* `TProvides = { 'arki.db': DbHandle }`.
|
|
48
|
+
*/
|
|
49
|
+
export function provide(tok, value) {
|
|
50
|
+
// Safe by construction: the computed key is exactly `tok.key: K`.
|
|
51
|
+
return { [tok.key]: value };
|
|
52
|
+
}
|
|
53
|
+
/** Runtime brand for lazy service handles (kernel detects these for auto-dispose). */
|
|
54
|
+
export const LazyTag = Symbol('dot.lazy');
|
|
55
|
+
/**
|
|
56
|
+
* Create a lazy service handle. See {@link Lazy} for semantics.
|
|
57
|
+
*
|
|
58
|
+
* @param init - Opens the resource. Runs at most once concurrently; a
|
|
59
|
+
* rejected attempt is not cached, so a later `get()` retries.
|
|
60
|
+
* @param options.dispose - Cleanup for the initialized value. Skipped when
|
|
61
|
+
* the handle was never initialized.
|
|
62
|
+
*/
|
|
63
|
+
export function lazy(init, options = {}) {
|
|
64
|
+
let state = { status: 'idle' };
|
|
65
|
+
return {
|
|
66
|
+
[LazyTag]: true,
|
|
67
|
+
get() {
|
|
68
|
+
if (state.status === 'ready')
|
|
69
|
+
return Promise.resolve(state.value);
|
|
70
|
+
if (state.status === 'pending')
|
|
71
|
+
return state.promise;
|
|
72
|
+
if (state.status === 'disposed') {
|
|
73
|
+
return Promise.reject(new Error('Lazy service handle is disposed — the app has shut down.'));
|
|
74
|
+
}
|
|
75
|
+
const promise = Promise.resolve()
|
|
76
|
+
.then(init)
|
|
77
|
+
.then(value => {
|
|
78
|
+
state = { status: 'ready', value };
|
|
79
|
+
return value;
|
|
80
|
+
}, (error) => {
|
|
81
|
+
// Failed initialization is not cached — allow retry.
|
|
82
|
+
state = { status: 'idle' };
|
|
83
|
+
throw error;
|
|
84
|
+
});
|
|
85
|
+
state = { status: 'pending', promise };
|
|
86
|
+
return promise;
|
|
87
|
+
},
|
|
88
|
+
get initialized() {
|
|
89
|
+
return state.status === 'ready';
|
|
90
|
+
},
|
|
91
|
+
peek() {
|
|
92
|
+
return state.status === 'ready' ? state.value : undefined;
|
|
93
|
+
},
|
|
94
|
+
async dispose() {
|
|
95
|
+
if (state.status === 'pending') {
|
|
96
|
+
try {
|
|
97
|
+
await state.promise;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Failed init: nothing to clean up.
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (state.status === 'ready') {
|
|
104
|
+
const { value } = state;
|
|
105
|
+
state = { status: 'disposed' };
|
|
106
|
+
await options.dispose?.(value);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
state = { status: 'disposed' };
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** Type guard: is this published value a lazy service handle? */
|
|
114
|
+
export function isLazy(value) {
|
|
115
|
+
return typeof value === 'object' && value !== null && LazyTag in value;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Wrap an already-available value in a pre-initialized `Lazy<T>` handle.
|
|
119
|
+
* Used by the kernel to lift eager provides for `service.lazy` consumers;
|
|
120
|
+
* also handy for handing fakes to lazy-consuming plugins in tests. The handle
|
|
121
|
+
* has no cleanup of its own — the underlying value's lifecycle belongs to
|
|
122
|
+
* whoever created it.
|
|
123
|
+
*/
|
|
124
|
+
export function lazyOf(value) {
|
|
125
|
+
let disposed = false;
|
|
126
|
+
return {
|
|
127
|
+
[LazyTag]: true,
|
|
128
|
+
get: () => disposed
|
|
129
|
+
? Promise.reject(new Error('Lazy service handle is disposed — the app has shut down.'))
|
|
130
|
+
: Promise.resolve(value),
|
|
131
|
+
get initialized() {
|
|
132
|
+
return !disposed;
|
|
133
|
+
},
|
|
134
|
+
peek: () => (disposed ? undefined : value),
|
|
135
|
+
async dispose() {
|
|
136
|
+
disposed = true;
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
export function plugin(def) {
|
|
141
|
+
return {
|
|
142
|
+
name: def.name,
|
|
143
|
+
...(def.version === undefined ? {} : { version: def.version }),
|
|
144
|
+
needs: def.needs ?? {},
|
|
145
|
+
actions: def.actions ?? [],
|
|
146
|
+
renames: {},
|
|
147
|
+
hooks: {
|
|
148
|
+
...(def.configure === undefined ? {} : { configure: def.configure }),
|
|
149
|
+
...(def.boot === undefined ? {} : { boot: def.boot }),
|
|
150
|
+
...(def.start === undefined ? {} : { start: def.start }),
|
|
151
|
+
...(def.stop === undefined ? {} : { stop: def.stop }),
|
|
152
|
+
...(def.dispose === undefined ? {} : { dispose: def.dispose }),
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Mount-time rename. `rename(dbPlugin, { db: 'reportsDb' }, 'reports-db')`
|
|
158
|
+
* publishes the same service under a different wire key, retyped
|
|
159
|
+
* accordingly — the way to mount a second instance of an adapter without
|
|
160
|
+
* a key collision. Renames compose: renaming an already-renamed key
|
|
161
|
+
* rewrites the earlier entry.
|
|
162
|
+
*/
|
|
163
|
+
export function rename(p, map, newName) {
|
|
164
|
+
const renames = { ...p.renames };
|
|
165
|
+
for (const [wireKey, next] of Object.entries(map)) {
|
|
166
|
+
if (typeof next !== 'string')
|
|
167
|
+
continue;
|
|
168
|
+
// If `wireKey` is itself the *result* of an earlier rename, rewrite that
|
|
169
|
+
// entry (compose); otherwise it is a local publish key.
|
|
170
|
+
const localKey = Object.entries(renames).find(([, w]) => w === wireKey)?.[0] ?? wireKey;
|
|
171
|
+
renames[localKey] = next;
|
|
172
|
+
}
|
|
173
|
+
// Phantom-only cast: runtime fields are unchanged except `renames`/`name`;
|
|
174
|
+
// only the [ProvidesSym] carrier retypes.
|
|
175
|
+
return { ...p, name: newName ?? p.name, renames };
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Stable error thrown by DOT plugin adapters.
|
|
179
|
+
*
|
|
180
|
+
* Adapters MUST throw `DotPluginError` (not raw `Error`) when surfacing a
|
|
181
|
+
* misconfiguration, missing-input, or other fail-fast condition. Consumers
|
|
182
|
+
* and coding agents can then match on a stable `code`, follow `docsUrl`,
|
|
183
|
+
* and apply `remediation` without parsing the message.
|
|
184
|
+
*
|
|
185
|
+
* Codes are per-adapter. Recommended prefix is `<PKG>_PLUGIN_E<NNN>` (e.g.
|
|
186
|
+
* `KV_PLUGIN_E001`, `DB_PLUGIN_E001`). The kernel does not own the code
|
|
187
|
+
* namespace — each adapter defines its own constants and links them in
|
|
188
|
+
* its README.
|
|
189
|
+
*
|
|
190
|
+
* @see packages/dot/docs/principles.md — principle 1.3 ("errors are part
|
|
191
|
+
* of the API") and principle 4 ("agent-discoverable everywhere").
|
|
192
|
+
*/
|
|
193
|
+
export class DotPluginError extends Error {
|
|
194
|
+
/** Stable error code, e.g. `KV_PLUGIN_E001`. */
|
|
195
|
+
code;
|
|
196
|
+
/** One-sentence guidance on how to fix the underlying problem. */
|
|
197
|
+
remediation;
|
|
198
|
+
/** URL of the documentation page that explains this error. */
|
|
199
|
+
docsUrl;
|
|
200
|
+
constructor(args) {
|
|
201
|
+
super(args.message);
|
|
202
|
+
this.name = 'DotPluginError';
|
|
203
|
+
this.code = args.code;
|
|
204
|
+
this.remediation = args.remediation;
|
|
205
|
+
this.docsUrl = args.docsUrl;
|
|
206
|
+
}
|
|
42
207
|
}
|
|
43
208
|
/** Re-exported for downstream typing. */
|
|
44
209
|
export {} from './manifest.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-contract.js","sourceRoot":"","sources":["../src/plugin-contract.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin-contract.js","sourceRoot":"","sources":["../src/plugin-contract.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Narrow public surface for plugin authors.
|
|
3
3
|
*
|
|
4
|
-
* Exposes the
|
|
5
|
-
* author
|
|
6
|
-
* `testApp` / `bootTestApp`, plus lifecycle / manifest /
|
|
4
|
+
* Exposes the plugin contract and the entry points a plugin author needs to
|
|
5
|
+
* author + test plugins — `plugin`, `service`, `token`, `provide`, `rename`,
|
|
6
|
+
* `defineApp`, `testApp` / `bootTestApp`, plus lifecycle / manifest /
|
|
7
|
+
* diagnostics types.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `@arki/kv/dot`, `@arki/db/dot`) import from this subpath so their
|
|
11
|
-
* `*.d.ts` graphs do not pull in the legacy surface — keeping their
|
|
12
|
-
* compile times tight and decoupling adapters from the legacy retirement
|
|
13
|
-
* schedule (Task 12).
|
|
9
|
+
* Adapter packages (e.g. `@arki/env/dot`, `@arki/kv/dot`, `@arki/db/dot`)
|
|
10
|
+
* import from this subpath so their `*.d.ts` graphs stay tight.
|
|
14
11
|
*
|
|
15
12
|
* @example
|
|
16
13
|
* ```ts
|
|
17
|
-
* import {
|
|
14
|
+
* import { plugin, service, type Plugin } from '@arki/dot/plugin';
|
|
18
15
|
* ```
|
|
19
16
|
*/
|
|
20
|
-
export {
|
|
21
|
-
export type {
|
|
17
|
+
export { isLazy, lazy, lazyOf, plugin, provide, rename, service, token, DotPluginError } from './plugin-contract.js';
|
|
18
|
+
export type { AnyPlugin, ActionDeclaration, ActionSource, CtxOf, DotConfigureContext, EmptyShape, InferredProvides, KernelCtx, Lazy, LazyService, NeedsShape, NoReservedKeys, Plugin, PluginNeeds, PluginProvides, ProjectionDeclaration, RenamedProvides, Service, ServiceRecord, Token, WireNeeds, } from './plugin-contract.js';
|
|
22
19
|
export { defineApp } from './define-app.js';
|
|
23
|
-
export type { DotApp, DotAppBuilder, DotAppConfigured } from './define-app.js';
|
|
20
|
+
export type { DotApp, DotAppBuilder, DotAppConfigured, NormalizeProvides, UseAllAvail, UseAllGuard, UseGuard, } from './define-app.js';
|
|
21
|
+
export { initPlugins } from './init-plugins.js';
|
|
22
|
+
export type { InitPluginsFactory } from './init-plugins.js';
|
|
24
23
|
export { testApp, bootTestApp } from './test-harness.js';
|
|
25
24
|
export type { TestAppOptions } from './test-harness.js';
|
|
26
25
|
export type { DotLifecycleHook, DotLifecycleState, DotLifecyclePluginFailure, DotLifecycleErrorCodeValue, } from './lifecycle.js';
|
|
27
26
|
export { DotLifecycleError, DotLifecycleErrorCode, DOT_LIFECYCLE_HOOKS } from './lifecycle.js';
|
|
28
|
-
export type { DotAppManifest, PluginManifest,
|
|
29
|
-
export
|
|
27
|
+
export type { DotAppManifest, ActionDirection, ActionManifest, JsonObject, JsonValue, PluginManifest, ProjectionManifest, ServiceManifest, LifecycleManifest, DependencyEdge, DependencyEdgeKind, ServiceKind, } from './manifest.js';
|
|
28
|
+
export { toJsonObject } from './manifest.js';
|
|
29
|
+
export type { DotDiagnosticsSnapshot, PluginDiagnostic, ActionDiagnostic, ServiceDiagnostic, LifecycleDiagnostic, DiagnosticIssue, DiagnosticSeverity, DiagnosticStatus, } from './diagnostics.js';
|
|
30
|
+
export type { DotLifecycleEvent, DotLifecycleEventStatus, DotLifecycleObserver, DotPhaseLifecycleEvent, DotPluginHookLifecycleEvent, } from './lifecycle-observer.js';
|
|
31
|
+
export { renderTimeline } from './timeline.js';
|
|
32
|
+
export type { RenderTimelineOptions } from './timeline.js';
|
|
30
33
|
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACrH,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,KAAK,EACL,mBAAmB,EACnB,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,IAAI,EACJ,WAAW,EACX,UAAU,EACV,cAAc,EACd,MAAM,EACN,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,OAAO,EACP,aAAa,EACb,KAAK,EACL,SAAS,GACV,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EACV,MAAM,EACN,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE/F,YAAY,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,UAAU,EACV,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,YAAY,EACV,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Narrow public surface for plugin authors.
|
|
3
3
|
*
|
|
4
|
-
* Exposes the
|
|
5
|
-
* author
|
|
6
|
-
* `testApp` / `bootTestApp`, plus lifecycle / manifest /
|
|
4
|
+
* Exposes the plugin contract and the entry points a plugin author needs to
|
|
5
|
+
* author + test plugins — `plugin`, `service`, `token`, `provide`, `rename`,
|
|
6
|
+
* `defineApp`, `testApp` / `bootTestApp`, plus lifecycle / manifest /
|
|
7
|
+
* diagnostics types.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `@arki/kv/dot`, `@arki/db/dot`) import from this subpath so their
|
|
11
|
-
* `*.d.ts` graphs do not pull in the legacy surface — keeping their
|
|
12
|
-
* compile times tight and decoupling adapters from the legacy retirement
|
|
13
|
-
* schedule (Task 12).
|
|
9
|
+
* Adapter packages (e.g. `@arki/env/dot`, `@arki/kv/dot`, `@arki/db/dot`)
|
|
10
|
+
* import from this subpath so their `*.d.ts` graphs stay tight.
|
|
14
11
|
*
|
|
15
12
|
* @example
|
|
16
13
|
* ```ts
|
|
17
|
-
* import {
|
|
14
|
+
* import { plugin, service, type Plugin } from '@arki/dot/plugin';
|
|
18
15
|
* ```
|
|
19
16
|
*/
|
|
20
|
-
export {
|
|
17
|
+
export { isLazy, lazy, lazyOf, plugin, provide, rename, service, token, DotPluginError } from './plugin-contract.js';
|
|
21
18
|
export { defineApp } from './define-app.js';
|
|
19
|
+
export { initPlugins } from './init-plugins.js';
|
|
22
20
|
export { testApp, bootTestApp } from './test-harness.js';
|
|
23
21
|
export { DotLifecycleError, DotLifecycleErrorCode, DOT_LIFECYCLE_HOOKS } from './lifecycle.js';
|
|
22
|
+
export { toJsonObject } from './manifest.js';
|
|
23
|
+
export { renderTimeline } from './timeline.js';
|
|
24
24
|
//# sourceMappingURL=plugin.js.map
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAyBrH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAW5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASzD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAgB/F,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAqB7C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/test-harness.d.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Test harness for unit-testing DOT
|
|
2
|
+
* Test harness for unit-testing DOT plugins.
|
|
3
3
|
*
|
|
4
|
-
* Provides `testApp` — a convenience wrapper that lets
|
|
4
|
+
* Provides `testApp` — a convenience wrapper that lets plugin authors verify
|
|
5
5
|
* lifecycle behaviour, registration, and service publishing without dragging
|
|
6
6
|
* in concrete framework dependencies.
|
|
7
7
|
*
|
|
8
|
-
* NOTE: `testApp` takes an erased
|
|
8
|
+
* NOTE: `testApp` takes an erased plugin array, so the compile-time wiring
|
|
9
9
|
* guard does not apply here — the kernel's runtime validation (unsatisfied
|
|
10
10
|
* needs, collisions) still does. Use `defineApp(...).use(...)` chains in
|
|
11
11
|
* tests that should exercise the type-level guard.
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
|
-
* import { testApp,
|
|
14
|
+
* import { testApp, plugin } from '@arki/dot';
|
|
15
15
|
*
|
|
16
|
-
* const
|
|
16
|
+
* const myPlugin = plugin({
|
|
17
17
|
* name: 'counter',
|
|
18
18
|
* boot: () => ({ counter: { value: 0 } }),
|
|
19
19
|
* });
|
|
20
20
|
*
|
|
21
21
|
* it('publishes a counter service', async () => {
|
|
22
|
-
* const app = await bootTestApp<{ counter: { value: number } }>([
|
|
22
|
+
* const app = await bootTestApp<{ counter: { value: number } }>([myPlugin]);
|
|
23
23
|
* expect(app.services.counter.value).toBe(0);
|
|
24
24
|
* await app.dispose();
|
|
25
25
|
* });
|
|
26
26
|
*/
|
|
27
27
|
import type { DotApp, DotAppBuilder } from './define-app.js';
|
|
28
|
-
import type {
|
|
28
|
+
import type { AnyPlugin, EmptyShape, Plugin, ServiceRecord, Token } from './plugin-contract.js';
|
|
29
29
|
export type TestAppOptions = {
|
|
30
30
|
/** App name used in the manifest. Defaults to `'test-app'`. */
|
|
31
31
|
name?: string;
|
|
@@ -33,73 +33,73 @@ export type TestAppOptions = {
|
|
|
33
33
|
config?: Readonly<Record<string, unknown>>;
|
|
34
34
|
};
|
|
35
35
|
/**
|
|
36
|
-
* Build a DOT app builder pre-populated with the given
|
|
36
|
+
* Build a DOT app builder pre-populated with the given plugins, ready to
|
|
37
37
|
* `.configure()`, `.boot()` or `.start()` from a test.
|
|
38
38
|
*/
|
|
39
|
-
export declare function testApp<TServices extends ServiceRecord = EmptyShape>(
|
|
39
|
+
export declare function testApp<TServices extends ServiceRecord = EmptyShape>(plugins?: readonly AnyPlugin[], options?: TestAppOptions): DotAppBuilder<TServices>;
|
|
40
40
|
/**
|
|
41
41
|
* Convenience: build, boot, return the running app. Caller is responsible for
|
|
42
42
|
* calling `app.dispose()` when finished.
|
|
43
43
|
*/
|
|
44
|
-
export declare function bootTestApp<TServices extends ServiceRecord = EmptyShape>(
|
|
44
|
+
export declare function bootTestApp<TServices extends ServiceRecord = EmptyShape>(plugins?: readonly AnyPlugin[], options?: TestAppOptions): Promise<DotApp<TServices>>;
|
|
45
45
|
/**
|
|
46
|
-
* Rest-tuple guard for {@link
|
|
46
|
+
* Rest-tuple guard for {@link TestPluginBuilder.boot} — the same trick the app
|
|
47
47
|
* builder's `UseGuard` uses. While any need is still unprovided, `boot()`
|
|
48
48
|
* demands an impossible second argument, so the call site fails with
|
|
49
49
|
* "Expected 2 arguments, but got 1" and the error payload names the
|
|
50
50
|
* missing wire keys and their types.
|
|
51
51
|
*/
|
|
52
|
-
type
|
|
52
|
+
type TestPluginBootGuard<TRemaining extends ServiceRecord> = keyof TRemaining extends never ? readonly [] : readonly [
|
|
53
53
|
needs: {
|
|
54
|
-
readonly 'DOT-TEST:
|
|
54
|
+
readonly 'DOT-TEST: plugin needs still unprovided — call .provide() for each': {
|
|
55
55
|
readonly [K in keyof TRemaining]: TRemaining[K];
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
];
|
|
59
59
|
/**
|
|
60
|
-
* Typed unit-test builder for a single
|
|
60
|
+
* Typed unit-test builder for a single plugin — see {@link testPlugin}.
|
|
61
61
|
*
|
|
62
62
|
* `TRemaining` tracks the wire keys not yet covered by `.provide()`;
|
|
63
63
|
* `TServices` accumulates what the booted app will expose (the fakes plus
|
|
64
|
-
* the
|
|
64
|
+
* the plugin's own provides).
|
|
65
65
|
*/
|
|
66
|
-
export type
|
|
66
|
+
export type TestPluginBuilder<TRemaining extends ServiceRecord, TServices extends ServiceRecord> = {
|
|
67
67
|
/**
|
|
68
68
|
* Satisfy one need directly with a fake. Token form — the token names
|
|
69
69
|
* the wire key and carries the type:
|
|
70
70
|
*
|
|
71
71
|
* ```ts
|
|
72
|
-
*
|
|
72
|
+
* testPlugin(reports).provide(Db, fakeDb)
|
|
73
73
|
* ```
|
|
74
74
|
*/
|
|
75
|
-
provide<K extends keyof TRemaining & string, T extends TRemaining[K]>(token: Token<T, K>, value: T):
|
|
75
|
+
provide<K extends keyof TRemaining & string, T extends TRemaining[K]>(token: Token<T, K>, value: T): TestPluginBuilder<Omit<TRemaining, K>, TServices & Readonly<Record<K, T>>>;
|
|
76
76
|
/**
|
|
77
77
|
* Satisfy one need directly with a fake. Key form — for anonymous
|
|
78
78
|
* `service<T>()` needs, where the wire key is the property name:
|
|
79
79
|
*
|
|
80
80
|
* ```ts
|
|
81
|
-
*
|
|
81
|
+
* testPlugin(billing).provide('db', fakeDb)
|
|
82
82
|
* ```
|
|
83
83
|
*/
|
|
84
|
-
provide<K extends keyof TRemaining & string>(key: K, value: TRemaining[K]):
|
|
85
|
-
/** Boot the
|
|
86
|
-
boot(...guard:
|
|
87
|
-
/** Boot + start. Same guard as {@link
|
|
88
|
-
start(...guard:
|
|
84
|
+
provide<K extends keyof TRemaining & string>(key: K, value: TRemaining[K]): TestPluginBuilder<Omit<TRemaining, K>, TServices & Readonly<Record<K, TRemaining[K]>>>;
|
|
85
|
+
/** Boot the plugin against the provided fakes. Compile error until every need is provided. */
|
|
86
|
+
boot(...guard: TestPluginBootGuard<TRemaining>): Promise<DotApp<TServices>>;
|
|
87
|
+
/** Boot + start. Same guard as {@link TestPluginBuilder.boot}. */
|
|
88
|
+
start(...guard: TestPluginBootGuard<TRemaining>): Promise<DotApp<TServices>>;
|
|
89
89
|
};
|
|
90
90
|
/**
|
|
91
|
-
* Unit-test a single
|
|
91
|
+
* Unit-test a single plugin with **typed overrides** — the compile-checked
|
|
92
92
|
* counterpart to {@link testApp}'s erased arrays.
|
|
93
93
|
*
|
|
94
|
-
* Each `.provide()` satisfies one of the
|
|
95
|
-
* provider
|
|
94
|
+
* Each `.provide()` satisfies one of the plugin's needs directly (no real
|
|
95
|
+
* provider plugin, no dependency chain) and removes it from the builder's
|
|
96
96
|
* remaining-needs type. `boot()` only compiles once every need is covered,
|
|
97
97
|
* and a fake of the wrong shape fails at the `.provide()` call site:
|
|
98
98
|
*
|
|
99
99
|
* ```ts
|
|
100
|
-
* import {
|
|
100
|
+
* import { testPlugin } from '@arki/dot/test-harness';
|
|
101
101
|
*
|
|
102
|
-
* const app = await
|
|
102
|
+
* const app = await testPlugin(catalog)
|
|
103
103
|
* .provide(Db, fakeDb) // token need
|
|
104
104
|
* .provide('cache', fakeKv) // anonymous need — wire key is the alias
|
|
105
105
|
* .boot();
|
|
@@ -111,9 +111,9 @@ export type TestPipBuilder<TRemaining extends ServiceRecord, TServices extends S
|
|
|
111
111
|
* `service.lazy<T>()` needs accept either a plain `T` fake (the kernel
|
|
112
112
|
* lifts it) or a `Lazy<T>` handle (`lazyOf(value)` is handy here).
|
|
113
113
|
* Lifecycle semantics are the real kernel's — the fakes are published by a
|
|
114
|
-
* synthetic first
|
|
114
|
+
* synthetic first plugin, so reverse-order teardown and lazy auto-dispose
|
|
115
115
|
* behave exactly as in production.
|
|
116
116
|
*/
|
|
117
|
-
export declare function
|
|
117
|
+
export declare function testPlugin<TNeeds extends ServiceRecord, TProvides extends ServiceRecord>(plugin: Plugin<TNeeds, TProvides>, options?: TestAppOptions): TestPluginBuilder<TNeeds, TProvides>;
|
|
118
118
|
export {};
|
|
119
119
|
//# sourceMappingURL=test-harness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-harness.d.ts","sourceRoot":"","sources":["../src/test-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"test-harness.d.ts","sourceRoot":"","sources":["../src/test-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAGhG,MAAM,MAAM,cAAc,GAAG;IAC3B,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC5C,CAAC;AAWF;;;GAGG;AACH,wBAAgB,OAAO,CAAC,SAAS,SAAS,aAAa,GAAG,UAAU,EAClE,OAAO,GAAE,SAAS,SAAS,EAAO,EAClC,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAAC,SAAS,CAAC,CAM1B;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,SAAS,SAAS,aAAa,GAAG,UAAU,EAC5E,OAAO,GAAE,SAAS,SAAS,EAAO,EAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAE5B;AAED;;;;;;GAMG;AACH,KAAK,mBAAmB,CAAC,UAAU,SAAS,aAAa,IAAI,MAAM,UAAU,SAAS,KAAK,GACvF,SAAS,EAAE,GACX,SAAS;IACP,KAAK,EAAE;QACL,QAAQ,CAAC,oEAAoE,EAAE;YAC7E,QAAQ,EAAE,CAAC,IAAI,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC;SAChD,CAAC;KACH;CACF,CAAC;AAEN;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,CAAC,UAAU,SAAS,aAAa,EAAE,SAAS,SAAS,aAAa,IAAI;IACjG;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,SAAS,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EAClE,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAClB,KAAK,EAAE,CAAC,GACP,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,SAAS,MAAM,UAAU,GAAG,MAAM,EACzC,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GACnB,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1F,8FAA8F;IAC9F,IAAI,CAAC,GAAG,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5E,kEAAkE;IAClE,KAAK,CAAC,GAAG,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;CAC9E,CAAC;AASF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,UAAU,CAAC,MAAM,SAAS,aAAa,EAAE,SAAS,SAAS,aAAa,EACtF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACjC,OAAO,GAAE,cAAmB,GAC3B,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAItC"}
|