@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
|
@@ -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,43 +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
|
-
/**
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
id: string;
|
|
324
|
-
method?: string;
|
|
325
|
-
path?: string;
|
|
326
|
-
transport: RouteTransport;
|
|
327
|
-
description?: string;
|
|
328
|
-
input?: {
|
|
329
|
-
readonly query?: Readonly<Record<string, unknown>>;
|
|
330
|
-
readonly body?: Readonly<Record<string, unknown>>;
|
|
331
|
-
};
|
|
332
|
-
output?: Readonly<Record<string, unknown>>;
|
|
333
|
-
streaming?: boolean;
|
|
334
|
-
}): void;
|
|
335
|
-
/** Mark the pip as participating in a lifecycle hook. */
|
|
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. */
|
|
336
344
|
registerLifecycleHook(hook: 'configure' | 'boot' | 'start' | 'stop' | 'dispose'): void;
|
|
337
345
|
/** Append `provides` capability strings (informational, manifest-only). */
|
|
338
346
|
declareProvides(...capabilities: string[]): void;
|
|
@@ -344,26 +352,27 @@ declare const NeedsSym: unique symbol;
|
|
|
344
352
|
declare const ProvidesSym: unique symbol;
|
|
345
353
|
|
|
346
354
|
/**
|
|
347
|
-
* The DOT
|
|
355
|
+
* The DOT plugin (v2). Author through {@link plugin} — never construct directly.
|
|
348
356
|
*
|
|
349
357
|
* Hook signatures are type-erased here (`ctx: never`): the typed view
|
|
350
|
-
* lives on `
|
|
358
|
+
* lives on `plugin()`'s parameter, and `(ctx: Typed) => R` is assignable to
|
|
351
359
|
* `(ctx: never) => R` without casts (parameter contravariance from the
|
|
352
360
|
* bottom type). The kernel crosses the erasure boundary at the call site.
|
|
353
361
|
*
|
|
354
362
|
* The phantom symbol properties carry `TNeeds` / `TProvides` for the app
|
|
355
363
|
* builder's compile-time wiring check; they never exist at runtime.
|
|
356
364
|
*/
|
|
357
|
-
export type
|
|
365
|
+
export type Plugin<
|
|
358
366
|
TNeeds extends ServiceRecord = ServiceRecord,
|
|
359
367
|
TProvides extends ServiceRecord = ServiceRecord,
|
|
360
368
|
> = {
|
|
361
|
-
/** Unique identifier for this
|
|
369
|
+
/** Unique identifier for this plugin within the app. */
|
|
362
370
|
readonly name: string;
|
|
363
371
|
/** Optional semantic version string. */
|
|
364
372
|
readonly version?: string;
|
|
365
373
|
/** Runtime needs shape (local alias → witness). */
|
|
366
374
|
readonly needs: NeedsShape;
|
|
375
|
+
readonly actions: readonly ActionSource[];
|
|
367
376
|
/** Mount-time renames: publish key → new wire key (see {@link rename}). */
|
|
368
377
|
readonly renames: Readonly<Record<string, string>>;
|
|
369
378
|
readonly hooks: {
|
|
@@ -377,28 +386,28 @@ export type Pip<
|
|
|
377
386
|
readonly [ProvidesSym]?: TProvides;
|
|
378
387
|
};
|
|
379
388
|
|
|
380
|
-
/** Extract a
|
|
381
|
-
export type
|
|
382
|
-
/** Extract a
|
|
383
|
-
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;
|
|
384
393
|
|
|
385
|
-
/** Internal type alias used by the kernel to erase
|
|
386
|
-
export type
|
|
394
|
+
/** Internal type alias used by the kernel to erase plugin service generics. */
|
|
395
|
+
export type AnyPlugin = Plugin<ServiceRecord, ServiceRecord>;
|
|
387
396
|
|
|
388
397
|
/**
|
|
389
|
-
* Author a DOT
|
|
398
|
+
* Author a DOT plugin.
|
|
390
399
|
*
|
|
391
400
|
* - `TShape` is inferred from the `needs` object literal.
|
|
392
401
|
* - `TProvides` is inferred from `boot`'s return type — no generic argument.
|
|
393
402
|
* - `boot({ db, log, $app })` destructures typed services under the local
|
|
394
403
|
* aliases declared in `needs`, plus the `$`-prefixed kernel keys.
|
|
395
|
-
* - `start` / `stop` / `dispose` additionally receive the
|
|
404
|
+
* - `start` / `stop` / `dispose` additionally receive the plugin's own
|
|
396
405
|
* provides. Reverse-order teardown guarantees needs are still alive in
|
|
397
406
|
* `dispose`.
|
|
398
407
|
*
|
|
399
408
|
* @example
|
|
400
409
|
* ```ts
|
|
401
|
-
* export const billing =
|
|
410
|
+
* export const billing = plugin({
|
|
402
411
|
* name: 'billing',
|
|
403
412
|
* needs: { db: service<Db>(), log: service<Logger>() },
|
|
404
413
|
* async boot({ db, log }) {
|
|
@@ -416,28 +425,30 @@ export type AnyPip = Pip<ServiceRecord, ServiceRecord>;
|
|
|
416
425
|
* whose `keyof` is `string`) rather than the declared default. That wide
|
|
417
426
|
* record would poison the app builder's collision check for every later
|
|
418
427
|
* `.use()` — `keyof TAvail & string` is never empty. Detect the fallback
|
|
419
|
-
* by its tell (a full string index signature — no `
|
|
428
|
+
* by its tell (a full string index signature — no `plugin()`-authored
|
|
420
429
|
* provides record has one) and collapse it to "provides nothing".
|
|
421
430
|
*/
|
|
422
431
|
export type InferredProvides<TP extends ServiceRecord> = string extends keyof TP ? EmptyShape : TP;
|
|
423
432
|
|
|
424
|
-
export function
|
|
433
|
+
export function plugin<
|
|
425
434
|
TShape extends NeedsShape & NoReservedKeys = EmptyShape,
|
|
426
435
|
TProvides extends ServiceRecord & NoReservedKeys = EmptyShape,
|
|
427
436
|
>(def: {
|
|
428
437
|
readonly name: string;
|
|
429
438
|
readonly version?: string;
|
|
430
439
|
readonly needs?: TShape;
|
|
440
|
+
readonly actions?: readonly ActionSource[];
|
|
431
441
|
readonly configure?: (ctx: DotConfigureContext) => void;
|
|
432
442
|
readonly boot?: (ctx: CtxOf<TShape> & KernelCtx) => MaybePromise<TProvides | void>;
|
|
433
443
|
readonly start?: (ctx: CtxOf<TShape> & TProvides & KernelCtx) => MaybePromise<void>;
|
|
434
444
|
readonly stop?: (ctx: CtxOf<TShape> & TProvides & KernelCtx) => MaybePromise<void>;
|
|
435
445
|
readonly dispose?: (ctx: CtxOf<TShape> & TProvides & KernelCtx) => MaybePromise<void>;
|
|
436
|
-
}):
|
|
446
|
+
}): Plugin<WireNeeds<TShape>, InferredProvides<TProvides>> {
|
|
437
447
|
return {
|
|
438
448
|
name: def.name,
|
|
439
449
|
...(def.version === undefined ? {} : { version: def.version }),
|
|
440
450
|
needs: def.needs ?? {},
|
|
451
|
+
actions: def.actions ?? [],
|
|
441
452
|
renames: {},
|
|
442
453
|
hooks: {
|
|
443
454
|
...(def.configure === undefined ? {} : { configure: def.configure }),
|
|
@@ -449,13 +460,13 @@ export function pip<
|
|
|
449
460
|
};
|
|
450
461
|
}
|
|
451
462
|
|
|
452
|
-
/** Rename a
|
|
463
|
+
/** Rename a plugin's published wire keys — the multi-instance primitive. */
|
|
453
464
|
export type RenamedProvides<TP, M> = {
|
|
454
465
|
[K in keyof TP as K extends keyof M ? (M[K] extends string ? M[K] : K) : K]: TP[K];
|
|
455
466
|
};
|
|
456
467
|
|
|
457
468
|
/**
|
|
458
|
-
* Mount-time rename. `rename(
|
|
469
|
+
* Mount-time rename. `rename(dbPlugin, { db: 'reportsDb' }, 'reports-db')`
|
|
459
470
|
* publishes the same service under a different wire key, retyped
|
|
460
471
|
* accordingly — the way to mount a second instance of an adapter without
|
|
461
472
|
* a key collision. Renames compose: renaming an already-renamed key
|
|
@@ -465,7 +476,7 @@ export function rename<
|
|
|
465
476
|
TN extends ServiceRecord,
|
|
466
477
|
TP extends ServiceRecord,
|
|
467
478
|
const M extends { readonly [K in keyof TP]?: string },
|
|
468
|
-
>(p:
|
|
479
|
+
>(p: Plugin<TN, TP>, map: M, newName?: string): Plugin<TN, RenamedProvides<TP, M>> {
|
|
469
480
|
const renames: Record<string, string> = { ...p.renames };
|
|
470
481
|
for (const [wireKey, next] of Object.entries(map)) {
|
|
471
482
|
if (typeof next !== 'string') continue;
|
|
@@ -476,27 +487,27 @@ export function rename<
|
|
|
476
487
|
}
|
|
477
488
|
// Phantom-only cast: runtime fields are unchanged except `renames`/`name`;
|
|
478
489
|
// only the [ProvidesSym] carrier retypes.
|
|
479
|
-
return { ...p, name: newName ?? p.name, renames } as
|
|
490
|
+
return { ...p, name: newName ?? p.name, renames } as Plugin<TN, RenamedProvides<TP, M>>;
|
|
480
491
|
}
|
|
481
492
|
|
|
482
493
|
/**
|
|
483
|
-
* Stable error thrown by DOT
|
|
494
|
+
* Stable error thrown by DOT plugin adapters.
|
|
484
495
|
*
|
|
485
|
-
* Adapters MUST throw `
|
|
496
|
+
* Adapters MUST throw `DotPluginError` (not raw `Error`) when surfacing a
|
|
486
497
|
* misconfiguration, missing-input, or other fail-fast condition. Consumers
|
|
487
498
|
* and coding agents can then match on a stable `code`, follow `docsUrl`,
|
|
488
499
|
* and apply `remediation` without parsing the message.
|
|
489
500
|
*
|
|
490
|
-
* Codes are per-adapter. Recommended prefix is `<PKG>
|
|
491
|
-
* `
|
|
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
|
|
492
503
|
* namespace — each adapter defines its own constants and links them in
|
|
493
504
|
* its README.
|
|
494
505
|
*
|
|
495
506
|
* @see packages/dot/docs/principles.md — principle 1.3 ("errors are part
|
|
496
507
|
* of the API") and principle 4 ("agent-discoverable everywhere").
|
|
497
508
|
*/
|
|
498
|
-
export class
|
|
499
|
-
/** Stable error code, e.g. `
|
|
509
|
+
export class DotPluginError extends Error {
|
|
510
|
+
/** Stable error code, e.g. `KV_PLUGIN_E001`. */
|
|
500
511
|
readonly code: string;
|
|
501
512
|
/** One-sentence guidance on how to fix the underlying problem. */
|
|
502
513
|
readonly remediation: string;
|
|
@@ -510,7 +521,7 @@ export class DotPipError extends Error {
|
|
|
510
521
|
readonly docsUrl: string;
|
|
511
522
|
}) {
|
|
512
523
|
super(args.message);
|
|
513
|
-
this.name = '
|
|
524
|
+
this.name = 'DotPluginError';
|
|
514
525
|
this.code = args.code;
|
|
515
526
|
this.remediation = args.remediation;
|
|
516
527
|
this.docsUrl = args.docsUrl;
|
|
@@ -519,4 +530,4 @@ export class DotPipError extends Error {
|
|
|
519
530
|
|
|
520
531
|
/** Re-exported for downstream typing. */
|
|
521
532
|
|
|
522
|
-
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,13 +11,15 @@
|
|
|
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,18 +28,31 @@ export type {
|
|
|
26
28
|
Lazy,
|
|
27
29
|
LazyService,
|
|
28
30
|
NeedsShape,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
NoReservedKeys,
|
|
32
|
+
Plugin,
|
|
33
|
+
PluginNeeds,
|
|
34
|
+
PluginProvides,
|
|
35
|
+
ProjectionDeclaration,
|
|
32
36
|
RenamedProvides,
|
|
33
37
|
Service,
|
|
34
38
|
ServiceRecord,
|
|
35
39
|
Token,
|
|
36
40
|
WireNeeds,
|
|
37
|
-
} from './
|
|
41
|
+
} from './plugin-contract.js';
|
|
38
42
|
|
|
39
43
|
export { defineApp } from './define-app.js';
|
|
40
|
-
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';
|
|
41
56
|
|
|
42
57
|
export { testApp, bootTestApp } from './test-harness.js';
|
|
43
58
|
export type { TestAppOptions } from './test-harness.js';
|
|
@@ -45,27 +60,31 @@ export type { TestAppOptions } from './test-harness.js';
|
|
|
45
60
|
export type {
|
|
46
61
|
DotLifecycleHook,
|
|
47
62
|
DotLifecycleState,
|
|
48
|
-
|
|
63
|
+
DotLifecyclePluginFailure,
|
|
49
64
|
DotLifecycleErrorCodeValue,
|
|
50
65
|
} from './lifecycle.js';
|
|
51
66
|
export { DotLifecycleError, DotLifecycleErrorCode, DOT_LIFECYCLE_HOOKS } from './lifecycle.js';
|
|
52
67
|
|
|
53
68
|
export type {
|
|
54
69
|
DotAppManifest,
|
|
55
|
-
|
|
56
|
-
|
|
70
|
+
ActionDirection,
|
|
71
|
+
ActionManifest,
|
|
72
|
+
JsonObject,
|
|
73
|
+
JsonValue,
|
|
74
|
+
PluginManifest,
|
|
75
|
+
ProjectionManifest,
|
|
57
76
|
ServiceManifest,
|
|
58
77
|
LifecycleManifest,
|
|
59
78
|
DependencyEdge,
|
|
60
79
|
DependencyEdgeKind,
|
|
61
80
|
ServiceKind,
|
|
62
|
-
RouteTransport,
|
|
63
81
|
} from './manifest.js';
|
|
82
|
+
export { toJsonObject } from './manifest.js';
|
|
64
83
|
|
|
65
84
|
export type {
|
|
66
85
|
DotDiagnosticsSnapshot,
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
PluginDiagnostic,
|
|
87
|
+
ActionDiagnostic,
|
|
69
88
|
ServiceDiagnostic,
|
|
70
89
|
LifecycleDiagnostic,
|
|
71
90
|
DiagnosticIssue,
|
|
@@ -78,7 +97,7 @@ export type {
|
|
|
78
97
|
DotLifecycleEventStatus,
|
|
79
98
|
DotLifecycleObserver,
|
|
80
99
|
DotPhaseLifecycleEvent,
|
|
81
|
-
|
|
100
|
+
DotPluginHookLifecycleEvent,
|
|
82
101
|
} from './lifecycle-observer.js';
|
|
83
102
|
|
|
84
103
|
export { renderTimeline } from './timeline.js';
|