@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.
- package/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +65 -35
- package/README.md +21 -20
- package/dist/context.d.ts +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +5 -4
- package/dist/context.js.map +1 -1
- package/dist/derive.d.ts +14 -3
- package/dist/derive.d.ts.map +1 -1
- package/dist/derive.js +36 -12
- package/dist/derive.js.map +1 -1
- package/dist/draft.d.ts +28 -0
- package/dist/draft.d.ts.map +1 -0
- package/dist/draft.js +156 -0
- package/dist/draft.js.map +1 -0
- package/dist/event.d.ts +4 -41
- package/dist/event.d.ts.map +1 -1
- package/dist/event.js +4 -14
- package/dist/event.js.map +1 -1
- package/dist/execute.d.ts +10 -10
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +35 -28
- package/dist/execute.js.map +1 -1
- package/dist/gate.d.ts +17 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +21 -0
- package/dist/gate.js.map +1 -0
- package/dist/index.d.ts +16 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -9
- package/dist/index.js.map +1 -1
- package/dist/internal/topo-saves.d.ts +47 -0
- package/dist/internal/topo-saves.d.ts.map +1 -0
- package/dist/internal/topo-saves.js +310 -0
- package/dist/internal/topo-saves.js.map +1 -0
- package/dist/internal/topo-store-read.d.ts +67 -0
- package/dist/internal/topo-store-read.d.ts.map +1 -0
- package/dist/internal/topo-store-read.js +222 -0
- package/dist/internal/topo-store-read.js.map +1 -0
- package/dist/internal/topo-store.d.ts +12 -0
- package/dist/internal/topo-store.d.ts.map +1 -0
- package/dist/internal/topo-store.js +571 -0
- package/dist/internal/topo-store.js.map +1 -0
- package/dist/internal/trails-db.d.ts +16 -0
- package/dist/internal/trails-db.d.ts.map +1 -0
- package/dist/internal/trails-db.js +118 -0
- package/dist/internal/trails-db.js.map +1 -0
- package/dist/layer.d.ts +5 -16
- package/dist/layer.d.ts.map +1 -1
- package/dist/layer.js +3 -20
- package/dist/layer.js.map +1 -1
- package/dist/provision-config.d.ts +22 -0
- package/dist/provision-config.d.ts.map +1 -0
- package/dist/provision-config.js +210 -0
- package/dist/provision-config.js.map +1 -0
- package/dist/provision.d.ts +71 -0
- package/dist/provision.d.ts.map +1 -0
- package/dist/provision.js +56 -0
- package/dist/provision.js.map +1 -0
- package/dist/run.d.ts +27 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +34 -0
- package/dist/run.js.map +1 -0
- package/dist/service-config.d.ts +7 -7
- package/dist/service-config.d.ts.map +1 -1
- package/dist/service-config.js +75 -73
- package/dist/service-config.js.map +1 -1
- package/dist/service.d.ts +32 -36
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +21 -21
- package/dist/service.js.map +1 -1
- package/dist/signal.d.ts +33 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +17 -0
- package/dist/signal.js.map +1 -0
- package/dist/topo-store.d.ts +48 -0
- package/dist/topo-store.d.ts.map +1 -0
- package/dist/topo-store.js +175 -0
- package/dist/topo-store.js.map +1 -0
- package/dist/topo.d.ts +10 -10
- package/dist/topo.d.ts.map +1 -1
- package/dist/topo.js +48 -35
- package/dist/topo.js.map +1 -1
- package/dist/trail.d.ts +16 -16
- package/dist/trail.d.ts.map +1 -1
- package/dist/trail.js +5 -4
- package/dist/trail.js.map +1 -1
- package/dist/types.d.ts +10 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/dist/validate-established-topo.d.ts +76 -0
- package/dist/validate-established-topo.d.ts.map +1 -0
- package/dist/validate-established-topo.js +43 -0
- package/dist/validate-established-topo.js.map +1 -0
- package/dist/validate-topo.d.ts +2 -2
- package/dist/validate-topo.d.ts.map +1 -1
- package/dist/validate-topo.js +34 -32
- package/dist/validate-topo.js.map +1 -1
- package/package.json +4 -1
- package/src/__tests__/context.test.ts +8 -8
- package/src/__tests__/derive.test.ts +58 -1
- package/src/__tests__/execute.test.ts +124 -122
- package/src/__tests__/{layer.test.ts → gate.test.ts} +26 -26
- package/src/__tests__/{dispatch.test.ts → run.test.ts} +39 -39
- package/src/__tests__/service-config.test.ts +41 -37
- package/src/__tests__/service.test.ts +71 -71
- package/src/__tests__/{event.test.ts → signal.test.ts} +15 -15
- package/src/__tests__/topo-store-read.test.ts +251 -0
- package/src/__tests__/topo-store.test.ts +469 -0
- package/src/__tests__/topo.test.ts +54 -54
- package/src/__tests__/trail-permit.test.ts +4 -4
- package/src/__tests__/trail.test.ts +58 -58
- package/src/__tests__/trails-db.test.ts +191 -0
- package/src/__tests__/type-utils.test.ts +3 -3
- package/src/__tests__/validate-topo.test.ts +205 -38
- package/src/context.ts +5 -4
- package/src/derive.ts +47 -16
- package/src/draft.ts +334 -0
- package/src/event.ts +11 -73
- package/src/execute.ts +56 -40
- package/src/{layer.ts → gate.ts} +13 -13
- package/src/index.ts +54 -23
- package/src/internal/topo-saves.ts +429 -0
- package/src/internal/topo-store-read.ts +473 -0
- package/src/internal/topo-store.ts +1087 -0
- package/src/internal/trails-db.ts +189 -0
- package/src/{service-config.ts → provision-config.ts} +124 -105
- package/src/provision.ts +148 -0
- package/src/{dispatch.ts → run.ts} +8 -8
- package/src/signal.ts +65 -0
- package/src/topo-store.ts +301 -0
- package/src/topo.ts +74 -52
- package/src/trail.ts +23 -22
- package/src/types.ts +11 -11
- package/src/validate-established-topo.ts +63 -0
- package/src/validate-topo.ts +38 -34
- package/tsconfig.tsbuildinfo +1 -1
- 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
|
|
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 {
|
|
11
|
-
import type {
|
|
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 {
|
|
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 {
|
|
19
|
-
import {
|
|
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
|
|
36
|
-
/**
|
|
37
|
-
readonly
|
|
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
|
|
43
|
-
readonly
|
|
44
|
-
/** Config values for
|
|
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
|
-
|
|
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
|
-
):
|
|
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
|
-
|
|
77
|
-
|
|
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
|
|
81
|
-
resolved.
|
|
76
|
+
options?.ctx?.extensions === undefined &&
|
|
77
|
+
resolved.provision !== undefined
|
|
82
78
|
) {
|
|
83
|
-
|
|
84
|
-
bound.service = createServiceLookup(() => bound);
|
|
85
|
-
return bound;
|
|
79
|
+
return resolved as TrailContext;
|
|
86
80
|
}
|
|
87
81
|
|
|
88
|
-
|
|
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
|
|
112
|
+
return await resolveProvisions(
|
|
97
113
|
trail,
|
|
98
114
|
baseCtx,
|
|
99
|
-
options?.
|
|
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
|
-
|
|
124
|
+
gates: readonly Gate[]
|
|
109
125
|
): Promise<Result<unknown, Error>> => {
|
|
110
|
-
const impl =
|
|
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-
|
|
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?.
|
|
160
|
+
options?.gates ?? []
|
|
145
161
|
);
|
|
146
162
|
} catch (error: unknown) {
|
|
147
163
|
const message = error instanceof Error ? error.message : String(error);
|
package/src/{layer.ts → gate.ts}
RENAMED
|
@@ -2,15 +2,15 @@ import type { Trail } from './trail.js';
|
|
|
2
2
|
import type { Implementation } from './types.js';
|
|
3
3
|
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
|
-
//
|
|
5
|
+
// Gate interface
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
7
7
|
|
|
8
|
-
/** A composable
|
|
9
|
-
export interface
|
|
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
|
|
25
|
+
* Apply gates outermost-first: gates[0] wraps gates[1] wraps ... wraps
|
|
26
26
|
* the base implementation.
|
|
27
27
|
*
|
|
28
|
-
* An empty
|
|
28
|
+
* An empty gates array returns the implementation unchanged.
|
|
29
29
|
*/
|
|
30
|
-
export const
|
|
31
|
-
|
|
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
|
|
35
|
+
// Fold right so gates[0] is the outermost wrapper.
|
|
36
36
|
let result = implementation;
|
|
37
|
-
for (let i =
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
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
|
-
|
|
34
|
+
CrossFn,
|
|
35
35
|
BasePermit,
|
|
36
36
|
PermitRequirement,
|
|
37
37
|
ProgressCallback,
|
|
38
38
|
ProgressEvent,
|
|
39
39
|
Logger,
|
|
40
|
-
|
|
40
|
+
ProvisionLookup,
|
|
41
41
|
} from './types.js';
|
|
42
|
-
export {
|
|
42
|
+
export { TRAILHEAD_KEY } from './types.js';
|
|
43
43
|
|
|
44
44
|
// Context factory
|
|
45
45
|
export { createTrailContext } from './context.js';
|
|
46
46
|
|
|
47
|
-
//
|
|
47
|
+
// Provision
|
|
48
48
|
export {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} from './
|
|
49
|
+
createProvisionLookup,
|
|
50
|
+
findDuplicateProvisionId,
|
|
51
|
+
isProvision,
|
|
52
|
+
provision,
|
|
53
|
+
} from './provision.js';
|
|
54
54
|
export type {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
} from './
|
|
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
|
-
//
|
|
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
|
-
//
|
|
89
|
-
export {
|
|
90
|
-
export type {
|
|
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
|
-
//
|
|
101
|
-
export {
|
|
102
|
-
export type {
|
|
131
|
+
// Run
|
|
132
|
+
export { run } from './run.js';
|
|
133
|
+
export type { RunOptions } from './run.js';
|
|
103
134
|
|
|
104
135
|
// Validation
|
|
105
136
|
export {
|