@arki/dot 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 +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 +11 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +66 -11
- 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-openapi.d.ts +38 -0
- package/dist/cli/render-openapi.d.ts.map +1 -0
- package/dist/cli/render-openapi.js +131 -0
- package/dist/cli/render-openapi.js.map +1 -0
- 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 -29
- 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 +40 -10
- package/dist/pip-contract.d.ts.map +1 -1
- package/dist/pip-contract.js +1 -25
- 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 +93 -15
- 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 +38 -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 -31
- package/src/{pip-contract.ts → plugin-contract.ts} +83 -44
- package/src/{pip.ts → plugin.ts} +38 -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
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Public
|
|
2
|
+
* Public plugin contract for the DOT kernel (v2).
|
|
3
3
|
*
|
|
4
|
-
* A
|
|
4
|
+
* A plugin declares what it **needs** as a shape of type witnesses and
|
|
5
5
|
* publishes what it **provides** from its `boot` hook. The kernel wires
|
|
6
|
-
* services by key, injects them into hook contexts under the
|
|
6
|
+
* services by key, injects them into hook contexts under the plugin's local
|
|
7
7
|
* aliases, and fails loudly (coded errors) on unsatisfied needs or key
|
|
8
8
|
* collisions.
|
|
9
9
|
*
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
* makes out-of-order composition a compile error; the kernel re-validates
|
|
16
16
|
* at runtime for erased/dynamic composition.
|
|
17
17
|
* - `stop` and `dispose` run in reverse declaration order and continue
|
|
18
|
-
* through individual
|
|
18
|
+
* through individual plugin failures, reporting an aggregate error.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import type {
|
|
21
|
+
import type { ActionManifest, ProjectionManifest, JsonObject, ServiceKind } from './manifest.js';
|
|
22
22
|
|
|
23
23
|
declare const TypeOf: unique symbol;
|
|
24
24
|
|
|
@@ -72,7 +72,7 @@ export function isLazyWitness(witness: object): boolean {
|
|
|
72
72
|
* export const Db = token<NodePgDatabase<Schema>>()('arki.db');
|
|
73
73
|
*
|
|
74
74
|
* // any consumer, any local alias:
|
|
75
|
-
* const reports =
|
|
75
|
+
* const reports = plugin({
|
|
76
76
|
* name: 'reports',
|
|
77
77
|
* needs: { db: Db },
|
|
78
78
|
* async boot({ db }) { ... },
|
|
@@ -126,7 +126,7 @@ export const LazyTag: unique symbol = Symbol('dot.lazy');
|
|
|
126
126
|
* Laziness is visible in the type — consumers declare
|
|
127
127
|
* `needs: { db: service<Lazy<Db>>() }` and call `await db.get()`. The
|
|
128
128
|
* kernel auto-disposes initialized handles in reverse declaration order
|
|
129
|
-
* during `dispose` (and boot rollback), even when the publishing
|
|
129
|
+
* during `dispose` (and boot rollback), even when the publishing plugin has
|
|
130
130
|
* no `dispose` hook. A handle that was never `get()`ed never initializes
|
|
131
131
|
* and never runs cleanup.
|
|
132
132
|
*/
|
|
@@ -226,7 +226,7 @@ export function isLazy(value: unknown): value is Lazy<unknown> {
|
|
|
226
226
|
/**
|
|
227
227
|
* Wrap an already-available value in a pre-initialized `Lazy<T>` handle.
|
|
228
228
|
* Used by the kernel to lift eager provides for `service.lazy` consumers;
|
|
229
|
-
* also handy for handing fakes to lazy-consuming
|
|
229
|
+
* also handy for handing fakes to lazy-consuming plugins in tests. The handle
|
|
230
230
|
* has no cleanup of its own — the underlying value's lifecycle belongs to
|
|
231
231
|
* whoever created it.
|
|
232
232
|
*/
|
|
@@ -282,13 +282,13 @@ export type WireNeeds<S extends NeedsShape> = {
|
|
|
282
282
|
* witness or service value satisfies, so the violation errors at the
|
|
283
283
|
* exact offending property. The kernel re-validates at runtime with
|
|
284
284
|
* `DOT_LIFECYCLE_E014` for paths the constraint cannot see (renames,
|
|
285
|
-
* erased
|
|
285
|
+
* erased plugins).
|
|
286
286
|
*/
|
|
287
287
|
export type NoReservedKeys = Readonly<Record<`$${string}`, never>>;
|
|
288
288
|
|
|
289
289
|
/**
|
|
290
290
|
* Kernel-supplied context keys, present in every service-carrying hook
|
|
291
|
-
* context. The `$` prefix is a reserved namespace: `
|
|
291
|
+
* context. The `$` prefix is a reserved namespace: `plugin()` rejects
|
|
292
292
|
* `$`-prefixed needs aliases and publish keys at compile time (via
|
|
293
293
|
* {@link NoReservedKeys}) and the kernel enforces it at runtime
|
|
294
294
|
* (`DOT_LIFECYCLE_E014`), so these keys can never be shadowed.
|
|
@@ -296,26 +296,51 @@ export type NoReservedKeys = Readonly<Record<`$${string}`, never>>;
|
|
|
296
296
|
export type KernelCtx = {
|
|
297
297
|
/** App name (passed to `defineApp`). */
|
|
298
298
|
readonly $app: string;
|
|
299
|
-
/** This
|
|
300
|
-
readonly $
|
|
299
|
+
/** This plugin's name. */
|
|
300
|
+
readonly $plugin: string;
|
|
301
301
|
/** Read-only runtime config bag from `defineApp(name, { config })`. */
|
|
302
302
|
readonly $config: Readonly<Record<string, unknown>>;
|
|
303
303
|
};
|
|
304
304
|
|
|
305
305
|
/** Context provided to a `configure` hook (sync registration only). */
|
|
306
|
+
export type ActionDeclaration = Omit<ActionManifest, 'plugin'>;
|
|
307
|
+
|
|
308
|
+
/** Structural protocol for adapter-owned declarations. */
|
|
309
|
+
export type ActionSource = ActionDeclaration | { toDotAction(): ActionDeclaration };
|
|
310
|
+
|
|
311
|
+
export type ProjectionDeclaration = Omit<ProjectionManifest, 'plugin'>;
|
|
312
|
+
|
|
313
|
+
type LegacyRouteDeclaration = {
|
|
314
|
+
id: string;
|
|
315
|
+
method?: string;
|
|
316
|
+
path?: string;
|
|
317
|
+
transport: string;
|
|
318
|
+
description?: string;
|
|
319
|
+
input?: {
|
|
320
|
+
readonly query?: Readonly<JsonObject>;
|
|
321
|
+
readonly body?: Readonly<JsonObject>;
|
|
322
|
+
};
|
|
323
|
+
output?: Readonly<JsonObject>;
|
|
324
|
+
streaming?: boolean;
|
|
325
|
+
};
|
|
326
|
+
|
|
306
327
|
export type DotConfigureContext = {
|
|
307
|
-
|
|
328
|
+
pluginName: string;
|
|
308
329
|
/** App name. */
|
|
309
330
|
appName: string;
|
|
310
331
|
/**
|
|
311
|
-
* Register a service this
|
|
332
|
+
* Register a service this plugin publishes, for manifest/diagnostics
|
|
312
333
|
* purposes. Registration is metadata-only — the actual service instance
|
|
313
334
|
* is returned from the `boot` hook.
|
|
314
335
|
*/
|
|
315
336
|
registerService(name: string, kind: ServiceKind): void;
|
|
316
|
-
/** Register
|
|
317
|
-
|
|
318
|
-
/**
|
|
337
|
+
/** Register an action this plugin contributes at an app boundary. */
|
|
338
|
+
registerAction(action: ActionDeclaration): void;
|
|
339
|
+
/** Register a projection renderer this plugin contributes. */
|
|
340
|
+
registerProjection(projection: ProjectionDeclaration): void;
|
|
341
|
+
/** @deprecated Use `registerAction`; removed in DOT 0.5.0. */
|
|
342
|
+
registerRoute(route: LegacyRouteDeclaration): void;
|
|
343
|
+
/** Mark the plugin as participating in a lifecycle hook. */
|
|
319
344
|
registerLifecycleHook(hook: 'configure' | 'boot' | 'start' | 'stop' | 'dispose'): void;
|
|
320
345
|
/** Append `provides` capability strings (informational, manifest-only). */
|
|
321
346
|
declareProvides(...capabilities: string[]): void;
|
|
@@ -327,26 +352,27 @@ declare const NeedsSym: unique symbol;
|
|
|
327
352
|
declare const ProvidesSym: unique symbol;
|
|
328
353
|
|
|
329
354
|
/**
|
|
330
|
-
* The DOT
|
|
355
|
+
* The DOT plugin (v2). Author through {@link plugin} — never construct directly.
|
|
331
356
|
*
|
|
332
357
|
* Hook signatures are type-erased here (`ctx: never`): the typed view
|
|
333
|
-
* lives on `
|
|
358
|
+
* lives on `plugin()`'s parameter, and `(ctx: Typed) => R` is assignable to
|
|
334
359
|
* `(ctx: never) => R` without casts (parameter contravariance from the
|
|
335
360
|
* bottom type). The kernel crosses the erasure boundary at the call site.
|
|
336
361
|
*
|
|
337
362
|
* The phantom symbol properties carry `TNeeds` / `TProvides` for the app
|
|
338
363
|
* builder's compile-time wiring check; they never exist at runtime.
|
|
339
364
|
*/
|
|
340
|
-
export type
|
|
365
|
+
export type Plugin<
|
|
341
366
|
TNeeds extends ServiceRecord = ServiceRecord,
|
|
342
367
|
TProvides extends ServiceRecord = ServiceRecord,
|
|
343
368
|
> = {
|
|
344
|
-
/** Unique identifier for this
|
|
369
|
+
/** Unique identifier for this plugin within the app. */
|
|
345
370
|
readonly name: string;
|
|
346
371
|
/** Optional semantic version string. */
|
|
347
372
|
readonly version?: string;
|
|
348
373
|
/** Runtime needs shape (local alias → witness). */
|
|
349
374
|
readonly needs: NeedsShape;
|
|
375
|
+
readonly actions: readonly ActionSource[];
|
|
350
376
|
/** Mount-time renames: publish key → new wire key (see {@link rename}). */
|
|
351
377
|
readonly renames: Readonly<Record<string, string>>;
|
|
352
378
|
readonly hooks: {
|
|
@@ -360,28 +386,28 @@ export type Pip<
|
|
|
360
386
|
readonly [ProvidesSym]?: TProvides;
|
|
361
387
|
};
|
|
362
388
|
|
|
363
|
-
/** Extract a
|
|
364
|
-
export type
|
|
365
|
-
/** Extract a
|
|
366
|
-
export type
|
|
389
|
+
/** Extract a plugin's (wire-keyed) needs record. */
|
|
390
|
+
export type PluginNeeds<P> = P extends Plugin<infer N, ServiceRecord> ? N : never;
|
|
391
|
+
/** Extract a plugin's (wire-keyed) provides record. */
|
|
392
|
+
export type PluginProvides<P> = P extends Plugin<ServiceRecord, infer Pr> ? Pr : never;
|
|
367
393
|
|
|
368
|
-
/** Internal type alias used by the kernel to erase
|
|
369
|
-
export type
|
|
394
|
+
/** Internal type alias used by the kernel to erase plugin service generics. */
|
|
395
|
+
export type AnyPlugin = Plugin<ServiceRecord, ServiceRecord>;
|
|
370
396
|
|
|
371
397
|
/**
|
|
372
|
-
* Author a DOT
|
|
398
|
+
* Author a DOT plugin.
|
|
373
399
|
*
|
|
374
400
|
* - `TShape` is inferred from the `needs` object literal.
|
|
375
401
|
* - `TProvides` is inferred from `boot`'s return type — no generic argument.
|
|
376
402
|
* - `boot({ db, log, $app })` destructures typed services under the local
|
|
377
403
|
* aliases declared in `needs`, plus the `$`-prefixed kernel keys.
|
|
378
|
-
* - `start` / `stop` / `dispose` additionally receive the
|
|
404
|
+
* - `start` / `stop` / `dispose` additionally receive the plugin's own
|
|
379
405
|
* provides. Reverse-order teardown guarantees needs are still alive in
|
|
380
406
|
* `dispose`.
|
|
381
407
|
*
|
|
382
408
|
* @example
|
|
383
409
|
* ```ts
|
|
384
|
-
* export const billing =
|
|
410
|
+
* export const billing = plugin({
|
|
385
411
|
* name: 'billing',
|
|
386
412
|
* needs: { db: service<Db>(), log: service<Logger>() },
|
|
387
413
|
* async boot({ db, log }) {
|
|
@@ -393,23 +419,36 @@ export type AnyPip = Pip<ServiceRecord, ServiceRecord>;
|
|
|
393
419
|
* });
|
|
394
420
|
* ```
|
|
395
421
|
*/
|
|
396
|
-
|
|
422
|
+
/**
|
|
423
|
+
* A `boot` that returns `void` gives `TProvides` no inference candidate,
|
|
424
|
+
* and TypeScript then substitutes the CONSTRAINT (`ServiceRecord & …`,
|
|
425
|
+
* whose `keyof` is `string`) rather than the declared default. That wide
|
|
426
|
+
* record would poison the app builder's collision check for every later
|
|
427
|
+
* `.use()` — `keyof TAvail & string` is never empty. Detect the fallback
|
|
428
|
+
* by its tell (a full string index signature — no `plugin()`-authored
|
|
429
|
+
* provides record has one) and collapse it to "provides nothing".
|
|
430
|
+
*/
|
|
431
|
+
export type InferredProvides<TP extends ServiceRecord> = string extends keyof TP ? EmptyShape : TP;
|
|
432
|
+
|
|
433
|
+
export function plugin<
|
|
397
434
|
TShape extends NeedsShape & NoReservedKeys = EmptyShape,
|
|
398
435
|
TProvides extends ServiceRecord & NoReservedKeys = EmptyShape,
|
|
399
436
|
>(def: {
|
|
400
437
|
readonly name: string;
|
|
401
438
|
readonly version?: string;
|
|
402
439
|
readonly needs?: TShape;
|
|
440
|
+
readonly actions?: readonly ActionSource[];
|
|
403
441
|
readonly configure?: (ctx: DotConfigureContext) => void;
|
|
404
442
|
readonly boot?: (ctx: CtxOf<TShape> & KernelCtx) => MaybePromise<TProvides | void>;
|
|
405
443
|
readonly start?: (ctx: CtxOf<TShape> & TProvides & KernelCtx) => MaybePromise<void>;
|
|
406
444
|
readonly stop?: (ctx: CtxOf<TShape> & TProvides & KernelCtx) => MaybePromise<void>;
|
|
407
445
|
readonly dispose?: (ctx: CtxOf<TShape> & TProvides & KernelCtx) => MaybePromise<void>;
|
|
408
|
-
}):
|
|
446
|
+
}): Plugin<WireNeeds<TShape>, InferredProvides<TProvides>> {
|
|
409
447
|
return {
|
|
410
448
|
name: def.name,
|
|
411
449
|
...(def.version === undefined ? {} : { version: def.version }),
|
|
412
450
|
needs: def.needs ?? {},
|
|
451
|
+
actions: def.actions ?? [],
|
|
413
452
|
renames: {},
|
|
414
453
|
hooks: {
|
|
415
454
|
...(def.configure === undefined ? {} : { configure: def.configure }),
|
|
@@ -421,13 +460,13 @@ export function pip<
|
|
|
421
460
|
};
|
|
422
461
|
}
|
|
423
462
|
|
|
424
|
-
/** Rename a
|
|
463
|
+
/** Rename a plugin's published wire keys — the multi-instance primitive. */
|
|
425
464
|
export type RenamedProvides<TP, M> = {
|
|
426
465
|
[K in keyof TP as K extends keyof M ? (M[K] extends string ? M[K] : K) : K]: TP[K];
|
|
427
466
|
};
|
|
428
467
|
|
|
429
468
|
/**
|
|
430
|
-
* Mount-time rename. `rename(
|
|
469
|
+
* Mount-time rename. `rename(dbPlugin, { db: 'reportsDb' }, 'reports-db')`
|
|
431
470
|
* publishes the same service under a different wire key, retyped
|
|
432
471
|
* accordingly — the way to mount a second instance of an adapter without
|
|
433
472
|
* a key collision. Renames compose: renaming an already-renamed key
|
|
@@ -437,7 +476,7 @@ export function rename<
|
|
|
437
476
|
TN extends ServiceRecord,
|
|
438
477
|
TP extends ServiceRecord,
|
|
439
478
|
const M extends { readonly [K in keyof TP]?: string },
|
|
440
|
-
>(p:
|
|
479
|
+
>(p: Plugin<TN, TP>, map: M, newName?: string): Plugin<TN, RenamedProvides<TP, M>> {
|
|
441
480
|
const renames: Record<string, string> = { ...p.renames };
|
|
442
481
|
for (const [wireKey, next] of Object.entries(map)) {
|
|
443
482
|
if (typeof next !== 'string') continue;
|
|
@@ -448,27 +487,27 @@ export function rename<
|
|
|
448
487
|
}
|
|
449
488
|
// Phantom-only cast: runtime fields are unchanged except `renames`/`name`;
|
|
450
489
|
// only the [ProvidesSym] carrier retypes.
|
|
451
|
-
return { ...p, name: newName ?? p.name, renames } as
|
|
490
|
+
return { ...p, name: newName ?? p.name, renames } as Plugin<TN, RenamedProvides<TP, M>>;
|
|
452
491
|
}
|
|
453
492
|
|
|
454
493
|
/**
|
|
455
|
-
* Stable error thrown by DOT
|
|
494
|
+
* Stable error thrown by DOT plugin adapters.
|
|
456
495
|
*
|
|
457
|
-
* Adapters MUST throw `
|
|
496
|
+
* Adapters MUST throw `DotPluginError` (not raw `Error`) when surfacing a
|
|
458
497
|
* misconfiguration, missing-input, or other fail-fast condition. Consumers
|
|
459
498
|
* and coding agents can then match on a stable `code`, follow `docsUrl`,
|
|
460
499
|
* and apply `remediation` without parsing the message.
|
|
461
500
|
*
|
|
462
|
-
* Codes are per-adapter. Recommended prefix is `<PKG>
|
|
463
|
-
* `
|
|
501
|
+
* Codes are per-adapter. Recommended prefix is `<PKG>_PLUGIN_E<NNN>` (e.g.
|
|
502
|
+
* `KV_PLUGIN_E001`, `DB_PLUGIN_E001`). The kernel does not own the code
|
|
464
503
|
* namespace — each adapter defines its own constants and links them in
|
|
465
504
|
* its README.
|
|
466
505
|
*
|
|
467
506
|
* @see packages/dot/docs/principles.md — principle 1.3 ("errors are part
|
|
468
507
|
* of the API") and principle 4 ("agent-discoverable everywhere").
|
|
469
508
|
*/
|
|
470
|
-
export class
|
|
471
|
-
/** Stable error code, e.g. `
|
|
509
|
+
export class DotPluginError extends Error {
|
|
510
|
+
/** Stable error code, e.g. `KV_PLUGIN_E001`. */
|
|
472
511
|
readonly code: string;
|
|
473
512
|
/** One-sentence guidance on how to fix the underlying problem. */
|
|
474
513
|
readonly remediation: string;
|
|
@@ -482,7 +521,7 @@ export class DotPipError extends Error {
|
|
|
482
521
|
readonly docsUrl: string;
|
|
483
522
|
}) {
|
|
484
523
|
super(args.message);
|
|
485
|
-
this.name = '
|
|
524
|
+
this.name = 'DotPluginError';
|
|
486
525
|
this.code = args.code;
|
|
487
526
|
this.remediation = args.remediation;
|
|
488
527
|
this.docsUrl = args.docsUrl;
|
|
@@ -491,4 +530,4 @@ export class DotPipError extends Error {
|
|
|
491
530
|
|
|
492
531
|
/** Re-exported for downstream typing. */
|
|
493
532
|
|
|
494
|
-
export { type DotAppManifest, type
|
|
533
|
+
export { type ActionManifest, type DotAppManifest, type PluginManifest, type ProjectionManifest } from './manifest.js';
|
package/src/{pip.ts → plugin.ts}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Narrow public surface for
|
|
2
|
+
* Narrow public surface for plugin authors.
|
|
3
3
|
*
|
|
4
|
-
* Exposes the
|
|
5
|
-
* author + test
|
|
4
|
+
* Exposes the plugin contract and the entry points a plugin author needs to
|
|
5
|
+
* author + test plugins — `plugin`, `service`, `token`, `provide`, `rename`,
|
|
6
6
|
* `defineApp`, `testApp` / `bootTestApp`, plus lifecycle / manifest /
|
|
7
7
|
* diagnostics types.
|
|
8
8
|
*
|
|
@@ -11,32 +11,48 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```ts
|
|
14
|
-
* import {
|
|
14
|
+
* import { plugin, service, type Plugin } from '@arki/dot/plugin';
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
export { isLazy, lazy, lazyOf,
|
|
18
|
+
export { isLazy, lazy, lazyOf, plugin, provide, rename, service, token, DotPluginError } from './plugin-contract.js';
|
|
19
19
|
export type {
|
|
20
|
-
|
|
20
|
+
AnyPlugin,
|
|
21
|
+
ActionDeclaration,
|
|
22
|
+
ActionSource,
|
|
21
23
|
CtxOf,
|
|
22
24
|
DotConfigureContext,
|
|
23
25
|
EmptyShape,
|
|
26
|
+
InferredProvides,
|
|
24
27
|
KernelCtx,
|
|
25
28
|
Lazy,
|
|
26
29
|
LazyService,
|
|
27
30
|
NeedsShape,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
NoReservedKeys,
|
|
32
|
+
Plugin,
|
|
33
|
+
PluginNeeds,
|
|
34
|
+
PluginProvides,
|
|
35
|
+
ProjectionDeclaration,
|
|
31
36
|
RenamedProvides,
|
|
32
37
|
Service,
|
|
33
38
|
ServiceRecord,
|
|
34
39
|
Token,
|
|
35
40
|
WireNeeds,
|
|
36
|
-
} from './
|
|
41
|
+
} from './plugin-contract.js';
|
|
37
42
|
|
|
38
43
|
export { defineApp } from './define-app.js';
|
|
39
|
-
export type {
|
|
44
|
+
export type {
|
|
45
|
+
DotApp,
|
|
46
|
+
DotAppBuilder,
|
|
47
|
+
DotAppConfigured,
|
|
48
|
+
NormalizeProvides,
|
|
49
|
+
UseAllAvail,
|
|
50
|
+
UseAllGuard,
|
|
51
|
+
UseGuard,
|
|
52
|
+
} from './define-app.js';
|
|
53
|
+
|
|
54
|
+
export { initPlugins } from './init-plugins.js';
|
|
55
|
+
export type { InitPluginsFactory } from './init-plugins.js';
|
|
40
56
|
|
|
41
57
|
export { testApp, bootTestApp } from './test-harness.js';
|
|
42
58
|
export type { TestAppOptions } from './test-harness.js';
|
|
@@ -44,27 +60,31 @@ export type { TestAppOptions } from './test-harness.js';
|
|
|
44
60
|
export type {
|
|
45
61
|
DotLifecycleHook,
|
|
46
62
|
DotLifecycleState,
|
|
47
|
-
|
|
63
|
+
DotLifecyclePluginFailure,
|
|
48
64
|
DotLifecycleErrorCodeValue,
|
|
49
65
|
} from './lifecycle.js';
|
|
50
66
|
export { DotLifecycleError, DotLifecycleErrorCode, DOT_LIFECYCLE_HOOKS } from './lifecycle.js';
|
|
51
67
|
|
|
52
68
|
export type {
|
|
53
69
|
DotAppManifest,
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
ActionDirection,
|
|
71
|
+
ActionManifest,
|
|
72
|
+
JsonObject,
|
|
73
|
+
JsonValue,
|
|
74
|
+
PluginManifest,
|
|
75
|
+
ProjectionManifest,
|
|
56
76
|
ServiceManifest,
|
|
57
77
|
LifecycleManifest,
|
|
58
78
|
DependencyEdge,
|
|
59
79
|
DependencyEdgeKind,
|
|
60
80
|
ServiceKind,
|
|
61
|
-
RouteTransport,
|
|
62
81
|
} from './manifest.js';
|
|
82
|
+
export { toJsonObject } from './manifest.js';
|
|
63
83
|
|
|
64
84
|
export type {
|
|
65
85
|
DotDiagnosticsSnapshot,
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
PluginDiagnostic,
|
|
87
|
+
ActionDiagnostic,
|
|
68
88
|
ServiceDiagnostic,
|
|
69
89
|
LifecycleDiagnostic,
|
|
70
90
|
DiagnosticIssue,
|
|
@@ -77,7 +97,7 @@ export type {
|
|
|
77
97
|
DotLifecycleEventStatus,
|
|
78
98
|
DotLifecycleObserver,
|
|
79
99
|
DotPhaseLifecycleEvent,
|
|
80
|
-
|
|
100
|
+
DotPluginHookLifecycleEvent,
|
|
81
101
|
} from './lifecycle-observer.js';
|
|
82
102
|
|
|
83
103
|
export { renderTimeline } from './timeline.js';
|