@ontrails/core 1.0.0-beta.12 → 1.0.0-beta.14

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.
Files changed (139) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/CHANGELOG.md +65 -35
  3. package/README.md +21 -20
  4. package/dist/context.d.ts +1 -1
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +5 -4
  7. package/dist/context.js.map +1 -1
  8. package/dist/derive.d.ts +14 -3
  9. package/dist/derive.d.ts.map +1 -1
  10. package/dist/derive.js +36 -12
  11. package/dist/derive.js.map +1 -1
  12. package/dist/draft.d.ts +28 -0
  13. package/dist/draft.d.ts.map +1 -0
  14. package/dist/draft.js +156 -0
  15. package/dist/draft.js.map +1 -0
  16. package/dist/event.d.ts +4 -41
  17. package/dist/event.d.ts.map +1 -1
  18. package/dist/event.js +4 -14
  19. package/dist/event.js.map +1 -1
  20. package/dist/execute.d.ts +10 -10
  21. package/dist/execute.d.ts.map +1 -1
  22. package/dist/execute.js +35 -28
  23. package/dist/execute.js.map +1 -1
  24. package/dist/gate.d.ts +17 -0
  25. package/dist/gate.d.ts.map +1 -0
  26. package/dist/gate.js +21 -0
  27. package/dist/gate.js.map +1 -0
  28. package/dist/index.d.ts +16 -9
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +14 -9
  31. package/dist/index.js.map +1 -1
  32. package/dist/internal/topo-saves.d.ts +47 -0
  33. package/dist/internal/topo-saves.d.ts.map +1 -0
  34. package/dist/internal/topo-saves.js +310 -0
  35. package/dist/internal/topo-saves.js.map +1 -0
  36. package/dist/internal/topo-store-read.d.ts +67 -0
  37. package/dist/internal/topo-store-read.d.ts.map +1 -0
  38. package/dist/internal/topo-store-read.js +222 -0
  39. package/dist/internal/topo-store-read.js.map +1 -0
  40. package/dist/internal/topo-store.d.ts +12 -0
  41. package/dist/internal/topo-store.d.ts.map +1 -0
  42. package/dist/internal/topo-store.js +571 -0
  43. package/dist/internal/topo-store.js.map +1 -0
  44. package/dist/internal/trails-db.d.ts +16 -0
  45. package/dist/internal/trails-db.d.ts.map +1 -0
  46. package/dist/internal/trails-db.js +118 -0
  47. package/dist/internal/trails-db.js.map +1 -0
  48. package/dist/layer.d.ts +5 -16
  49. package/dist/layer.d.ts.map +1 -1
  50. package/dist/layer.js +3 -20
  51. package/dist/layer.js.map +1 -1
  52. package/dist/provision-config.d.ts +22 -0
  53. package/dist/provision-config.d.ts.map +1 -0
  54. package/dist/provision-config.js +210 -0
  55. package/dist/provision-config.js.map +1 -0
  56. package/dist/provision.d.ts +71 -0
  57. package/dist/provision.d.ts.map +1 -0
  58. package/dist/provision.js +56 -0
  59. package/dist/provision.js.map +1 -0
  60. package/dist/run.d.ts +27 -0
  61. package/dist/run.d.ts.map +1 -0
  62. package/dist/run.js +34 -0
  63. package/dist/run.js.map +1 -0
  64. package/dist/service-config.d.ts +7 -7
  65. package/dist/service-config.d.ts.map +1 -1
  66. package/dist/service-config.js +75 -73
  67. package/dist/service-config.js.map +1 -1
  68. package/dist/service.d.ts +32 -36
  69. package/dist/service.d.ts.map +1 -1
  70. package/dist/service.js +21 -21
  71. package/dist/service.js.map +1 -1
  72. package/dist/signal.d.ts +33 -0
  73. package/dist/signal.d.ts.map +1 -0
  74. package/dist/signal.js +17 -0
  75. package/dist/signal.js.map +1 -0
  76. package/dist/topo-store.d.ts +48 -0
  77. package/dist/topo-store.d.ts.map +1 -0
  78. package/dist/topo-store.js +175 -0
  79. package/dist/topo-store.js.map +1 -0
  80. package/dist/topo.d.ts +10 -10
  81. package/dist/topo.d.ts.map +1 -1
  82. package/dist/topo.js +48 -35
  83. package/dist/topo.js.map +1 -1
  84. package/dist/trail.d.ts +16 -16
  85. package/dist/trail.d.ts.map +1 -1
  86. package/dist/trail.js +5 -4
  87. package/dist/trail.js.map +1 -1
  88. package/dist/types.d.ts +10 -10
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/types.js +2 -2
  91. package/dist/types.js.map +1 -1
  92. package/dist/validate-established-topo.d.ts +76 -0
  93. package/dist/validate-established-topo.d.ts.map +1 -0
  94. package/dist/validate-established-topo.js +43 -0
  95. package/dist/validate-established-topo.js.map +1 -0
  96. package/dist/validate-topo.d.ts +2 -2
  97. package/dist/validate-topo.d.ts.map +1 -1
  98. package/dist/validate-topo.js +34 -32
  99. package/dist/validate-topo.js.map +1 -1
  100. package/package.json +4 -1
  101. package/src/__tests__/context.test.ts +8 -8
  102. package/src/__tests__/derive.test.ts +58 -1
  103. package/src/__tests__/execute.test.ts +124 -122
  104. package/src/__tests__/{layer.test.ts → gate.test.ts} +26 -26
  105. package/src/__tests__/{dispatch.test.ts → run.test.ts} +39 -39
  106. package/src/__tests__/service-config.test.ts +41 -37
  107. package/src/__tests__/service.test.ts +71 -71
  108. package/src/__tests__/{event.test.ts → signal.test.ts} +15 -15
  109. package/src/__tests__/topo-store-read.test.ts +251 -0
  110. package/src/__tests__/topo-store.test.ts +469 -0
  111. package/src/__tests__/topo.test.ts +54 -54
  112. package/src/__tests__/trail-permit.test.ts +4 -4
  113. package/src/__tests__/trail.test.ts +58 -58
  114. package/src/__tests__/trails-db.test.ts +191 -0
  115. package/src/__tests__/type-utils.test.ts +3 -3
  116. package/src/__tests__/validate-topo.test.ts +205 -38
  117. package/src/context.ts +5 -4
  118. package/src/derive.ts +47 -16
  119. package/src/draft.ts +334 -0
  120. package/src/event.ts +11 -73
  121. package/src/execute.ts +56 -40
  122. package/src/{layer.ts → gate.ts} +13 -13
  123. package/src/index.ts +54 -23
  124. package/src/internal/topo-saves.ts +429 -0
  125. package/src/internal/topo-store-read.ts +473 -0
  126. package/src/internal/topo-store.ts +1087 -0
  127. package/src/internal/trails-db.ts +189 -0
  128. package/src/{service-config.ts → provision-config.ts} +124 -105
  129. package/src/provision.ts +148 -0
  130. package/src/{dispatch.ts → run.ts} +8 -8
  131. package/src/signal.ts +65 -0
  132. package/src/topo-store.ts +301 -0
  133. package/src/topo.ts +74 -52
  134. package/src/trail.ts +23 -22
  135. package/src/types.ts +11 -11
  136. package/src/validate-established-topo.ts +63 -0
  137. package/src/validate-topo.ts +38 -34
  138. package/tsconfig.tsbuildinfo +1 -1
  139. package/src/service.ts +0 -145
package/src/execute.ts CHANGED
@@ -1,22 +1,22 @@
1
1
  /**
2
2
  * Centralized trail execution pipeline.
3
3
  *
4
- * Validates input, builds context, composes layers, and runs the
4
+ * Validates input, builds context, composes gates, and runs the
5
5
  * implementation. Surfaces (CLI, MCP, HTTP) delegate here instead
6
6
  * of reimplementing the pipeline.
7
7
  */
8
8
 
9
9
  import type { AnyTrail } from './trail.js';
10
- import type { Layer } from './layer.js';
11
- import type { ServiceOverrideMap } from './service.js';
10
+ import type { Gate } from './gate.js';
11
+ import type { ProvisionOverrideMap } from './provision.js';
12
12
  import type { TrailContext, TrailContextInit } from './types.js';
13
13
 
14
- import { composeLayers } from './layer.js';
14
+ import { composeGates } from './gate.js';
15
15
  import { createTrailContext } from './context.js';
16
16
  import { InternalError } from './errors.js';
17
17
  import { Result } from './result.js';
18
- import { createServiceLookup } from './service.js';
19
- import { resolveServices } from './service-config.js';
18
+ import { createProvisionLookup } from './provision.js';
19
+ import { resolveProvisions } from './provision-config.js';
20
20
  import { validateInput } from './validation.js';
21
21
 
22
22
  type MutableTrailContext = {
@@ -32,16 +32,16 @@ export interface ExecuteTrailOptions {
32
32
  /** Partial context overrides merged on top of the base context. */
33
33
  readonly ctx?: Partial<TrailContextInit> | undefined;
34
34
  /** AbortSignal override (takes final precedence over ctx and factory). */
35
- readonly signal?: AbortSignal | undefined;
36
- /** Layers to compose around the implementation. */
37
- readonly layers?: readonly Layer[] | undefined;
35
+ readonly abortSignal?: AbortSignal | undefined;
36
+ /** Gates to compose around the implementation. */
37
+ readonly gates?: readonly Gate[] | undefined;
38
38
  /** Factory that produces a base TrailContext (takes precedence over defaults). */
39
39
  readonly createContext?:
40
40
  | (() => TrailContextInit | Promise<TrailContextInit>)
41
41
  | undefined;
42
- /** Explicit service instance overrides keyed by service ID. */
43
- readonly services?: ServiceOverrideMap | undefined;
44
- /** Config values for services that declare a `config` schema, keyed by service ID. */
42
+ /** Explicit provision instance overrides keyed by provision ID. */
43
+ readonly provisions?: ProvisionOverrideMap | undefined;
44
+ /** Config values for provisions that declare a `config` schema, keyed by provision ID. */
45
45
  readonly configValues?:
46
46
  | Readonly<Record<string, Record<string, unknown>>>
47
47
  | undefined;
@@ -51,21 +51,10 @@ export interface ExecuteTrailOptions {
51
51
  // Context resolution
52
52
  // ---------------------------------------------------------------------------
53
53
 
54
- /**
55
- * Build a TrailContext from options.
56
- *
57
- * Resolution order:
58
- * 1. Factory (`createContext`) or `createTrailContext()` defaults.
59
- * 2. Partial `ctx` overrides merged on top.
60
- * 3. `signal` override takes final precedence.
61
- */
62
- const resolveContext = async (
54
+ const applyContextOverrides = (
55
+ base: TrailContextInit,
63
56
  options?: ExecuteTrailOptions
64
- ): Promise<TrailContext> => {
65
- const seed = options?.createContext
66
- ? await options.createContext()
67
- : createTrailContext();
68
- const base = seed.service ? seed : createTrailContext(seed);
57
+ ): TrailContextInit => {
69
58
  const withOverrides = options?.ctx
70
59
  ? {
71
60
  ...base,
@@ -73,19 +62,46 @@ const resolveContext = async (
73
62
  extensions: { ...base.extensions, ...options.ctx.extensions },
74
63
  }
75
64
  : base;
76
- const resolved = options?.signal
77
- ? { ...withOverrides, signal: options.signal }
65
+
66
+ return options?.abortSignal
67
+ ? { ...withOverrides, abortSignal: options.abortSignal }
78
68
  : withOverrides;
69
+ };
70
+
71
+ const bindProvisionLookup = (
72
+ resolved: TrailContextInit,
73
+ options?: ExecuteTrailOptions
74
+ ): TrailContext => {
79
75
  if (
80
- options?.ctx?.extensions !== undefined ||
81
- resolved.service === undefined
76
+ options?.ctx?.extensions === undefined &&
77
+ resolved.provision !== undefined
82
78
  ) {
83
- const bound = { ...resolved } as MutableTrailContext;
84
- bound.service = createServiceLookup(() => bound);
85
- return bound;
79
+ return resolved as TrailContext;
86
80
  }
87
81
 
88
- return resolved as TrailContext;
82
+ const bound = { ...resolved } as MutableTrailContext;
83
+ const lookup = createProvisionLookup(() => bound);
84
+ bound.provision = lookup;
85
+ return bound;
86
+ };
87
+
88
+ /**
89
+ * Build a TrailContext from options.
90
+ *
91
+ * Resolution order:
92
+ * 1. Factory (`createContext`) or `createTrailContext()` defaults.
93
+ * 2. Partial `ctx` overrides merged on top.
94
+ * 3. `abortSignal` override takes final precedence.
95
+ */
96
+ const resolveContext = async (
97
+ options?: ExecuteTrailOptions
98
+ ): Promise<TrailContext> => {
99
+ const seed = options?.createContext
100
+ ? await options.createContext()
101
+ : createTrailContext();
102
+ const base = seed.provision ? seed : createTrailContext(seed);
103
+ const resolved = applyContextOverrides(base, options);
104
+ return bindProvisionLookup(resolved, options);
89
105
  };
90
106
 
91
107
  const prepareContext = async (
@@ -93,10 +109,10 @@ const prepareContext = async (
93
109
  options?: ExecuteTrailOptions
94
110
  ): Promise<Result<TrailContext, Error>> => {
95
111
  const baseCtx = await resolveContext(options);
96
- return await resolveServices(
112
+ return await resolveProvisions(
97
113
  trail,
98
114
  baseCtx,
99
- options?.services,
115
+ options?.provisions,
100
116
  options?.configValues
101
117
  );
102
118
  };
@@ -105,9 +121,9 @@ const runTrail = async (
105
121
  trail: AnyTrail,
106
122
  input: unknown,
107
123
  ctx: TrailContext,
108
- layers: readonly Layer[]
124
+ gates: readonly Gate[]
109
125
  ): Promise<Result<unknown, Error>> => {
110
- const impl = composeLayers([...layers], trail, trail.run);
126
+ const impl = composeGates([...gates], trail, trail.blaze);
111
127
  return await impl(input, ctx);
112
128
  };
113
129
 
@@ -116,7 +132,7 @@ const runTrail = async (
116
132
  // ---------------------------------------------------------------------------
117
133
 
118
134
  /**
119
- * Execute a trail through the standard validate-context-layers-run pipeline.
135
+ * Execute a trail through the standard validate-context-gates-run pipeline.
120
136
  *
121
137
  * The function never throws -- unexpected exceptions are caught and
122
138
  * returned as `Result.err(InternalError)`.
@@ -141,7 +157,7 @@ export const executeTrail = async (
141
157
  trail,
142
158
  validated.value,
143
159
  resolvedCtx.value,
144
- options?.layers ?? []
160
+ options?.gates ?? []
145
161
  );
146
162
  } catch (error: unknown) {
147
163
  const message = error instanceof Error ? error.message : String(error);
@@ -2,15 +2,15 @@ import type { Trail } from './trail.js';
2
2
  import type { Implementation } from './types.js';
3
3
 
4
4
  // ---------------------------------------------------------------------------
5
- // Layer interface
5
+ // Gate interface
6
6
  // ---------------------------------------------------------------------------
7
7
 
8
- /** A composable middleware that wraps trail implementations */
9
- export interface Layer {
8
+ /** A composable gate that wraps trail implementations. */
9
+ export interface Gate {
10
10
  readonly name: string;
11
11
  readonly description?: string | undefined;
12
12
 
13
- /** Wrap a trail's implementation, returning a new implementation */
13
+ /** Wrap a trail's implementation, returning a new implementation. */
14
14
  wrap<I, O>(
15
15
  trail: Trail<I, O>,
16
16
  implementation: Implementation<I, O>
@@ -22,22 +22,22 @@ export interface Layer {
22
22
  // ---------------------------------------------------------------------------
23
23
 
24
24
  /**
25
- * Apply layers outermost-first: layers[0] wraps layers[1] wraps ... wraps
25
+ * Apply gates outermost-first: gates[0] wraps gates[1] wraps ... wraps
26
26
  * the base implementation.
27
27
  *
28
- * An empty layers array returns the implementation unchanged.
28
+ * An empty gates array returns the implementation unchanged.
29
29
  */
30
- export const composeLayers = <I, O>(
31
- layers: readonly Layer[],
30
+ export const composeGates = <I, O>(
31
+ gates: readonly Gate[],
32
32
  trail: Trail<I, O>,
33
33
  implementation: Implementation<I, O>
34
34
  ): Implementation<I, O> => {
35
- // Fold right so layers[0] is the outermost wrapper
35
+ // Fold right so gates[0] is the outermost wrapper.
36
36
  let result = implementation;
37
- for (let i = layers.length - 1; i >= 0; i -= 1) {
38
- const layer = layers[i];
39
- if (layer) {
40
- result = layer.wrap(trail, result);
37
+ for (let i = gates.length - 1; i >= 0; i -= 1) {
38
+ const gate = gates[i];
39
+ if (gate) {
40
+ result = gate.wrap(trail, result);
41
41
  }
42
42
  }
43
43
  return result;
package/src/index.ts CHANGED
@@ -31,33 +31,33 @@ export type {
31
31
  Implementation,
32
32
  TrailContext,
33
33
  TrailContextInit,
34
- FollowFn,
34
+ CrossFn,
35
35
  BasePermit,
36
36
  PermitRequirement,
37
37
  ProgressCallback,
38
38
  ProgressEvent,
39
39
  Logger,
40
- ServiceLookup,
40
+ ProvisionLookup,
41
41
  } from './types.js';
42
- export { SURFACE_KEY } from './types.js';
42
+ export { TRAILHEAD_KEY } from './types.js';
43
43
 
44
44
  // Context factory
45
45
  export { createTrailContext } from './context.js';
46
46
 
47
- // Service
47
+ // Provision
48
48
  export {
49
- createServiceLookup,
50
- findDuplicateServiceId,
51
- isService,
52
- service,
53
- } from './service.js';
49
+ createProvisionLookup,
50
+ findDuplicateProvisionId,
51
+ isProvision,
52
+ provision,
53
+ } from './provision.js';
54
54
  export type {
55
- AnyService,
56
- Service,
57
- ServiceContext,
58
- ServiceOverrideMap,
59
- ServiceSpec,
60
- } from './service.js';
55
+ AnyProvision,
56
+ Provision,
57
+ ProvisionContext,
58
+ ProvisionOverrideMap,
59
+ ProvisionSpec,
60
+ } from './provision.js';
61
61
 
62
62
  // Trail
63
63
  export { trail } from './trail.js';
@@ -73,33 +73,64 @@ export type {
73
73
  export type { TrailInput, TrailOutput, TrailResult } from './type-utils.js';
74
74
  export { inputOf, outputOf } from './type-utils.js';
75
75
 
76
- // Event
76
+ // Signal
77
+ export { signal } from './signal.js';
78
+ export type { AnySignal, Signal, SignalSpec } from './signal.js';
77
79
  export { event } from './event.js';
78
80
  export type { AnyEvent, Event, EventSpec } from './event.js';
79
81
 
80
82
  // Topo
81
83
  export { topo } from './topo.js';
82
84
  export type { Topo } from './topo.js';
85
+ export {
86
+ createMockTopoStore,
87
+ createTopoStore,
88
+ topoStore,
89
+ } from './topo-store.js';
90
+ export type {
91
+ MockTopoStoreSeed,
92
+ ReadOnlyTopoStore,
93
+ TopoStoreExportRecord,
94
+ TopoStoreProvisionRecord,
95
+ TopoStoreRef,
96
+ TopoStoreTrailDetailRecord,
97
+ TopoStoreTrailRecord,
98
+ } from './topo-store.js';
99
+
100
+ // Draft state
101
+ export {
102
+ DRAFT_ID_PREFIX,
103
+ analyzeDraftState,
104
+ isDraftId,
105
+ validateEstablishedTopo as validateDraftFreeTopo,
106
+ } from './draft.js';
107
+ export type {
108
+ DraftDependency,
109
+ DraftDependencyKind,
110
+ DraftFinding,
111
+ DraftStateAnalysis,
112
+ } from './draft.js';
83
113
 
84
114
  // Topo validation
85
115
  export { validateTopo } from './validate-topo.js';
86
116
  export type { TopoIssue } from './validate-topo.js';
117
+ export { validateEstablishedTopo } from './validate-established-topo.js';
87
118
 
88
- // Layer
89
- export { composeLayers } from './layer.js';
90
- export type { Layer } from './layer.js';
119
+ // Gate
120
+ export { composeGates } from './gate.js';
121
+ export type { Gate } from './gate.js';
91
122
 
92
123
  // Derive
93
- export { deriveFields } from './derive.js';
124
+ export { deriveCliPath, deriveFields } from './derive.js';
94
125
  export type { Field, FieldOverride } from './derive.js';
95
126
 
96
127
  // Execute
97
128
  export { executeTrail } from './execute.js';
98
129
  export type { ExecuteTrailOptions } from './execute.js';
99
130
 
100
- // Dispatch
101
- export { dispatch } from './dispatch.js';
102
- export type { DispatchOptions } from './dispatch.js';
131
+ // Run
132
+ export { run } from './run.js';
133
+ export type { RunOptions } from './run.js';
103
134
 
104
135
  // Validation
105
136
  export {