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

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 (314) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/README.md +73 -24
  3. package/package.json +11 -4
  4. package/src/activation-provenance.ts +111 -0
  5. package/src/activation-source-compatibility.ts +430 -0
  6. package/src/activation-source-projection.ts +221 -0
  7. package/src/activation-source.ts +91 -0
  8. package/src/blob-ref.ts +51 -0
  9. package/src/branded.ts +1 -1
  10. package/src/context.ts +28 -4
  11. package/src/contour.ts +344 -0
  12. package/src/cross-batch.ts +69 -0
  13. package/src/cross-schema.ts +36 -0
  14. package/src/detours.ts +8 -0
  15. package/src/draft.ts +60 -52
  16. package/src/error-projection.ts +51 -0
  17. package/src/errors.ts +245 -48
  18. package/src/execute.ts +1250 -40
  19. package/src/fire.ts +1169 -0
  20. package/src/index.ts +383 -49
  21. package/src/internal/fork-ctx.ts +69 -0
  22. package/src/layer-projection.ts +192 -0
  23. package/src/layer.ts +81 -0
  24. package/src/observe.ts +361 -0
  25. package/src/path-security.ts +1 -1
  26. package/src/permits.ts +12 -0
  27. package/src/redaction/patterns.ts +6 -3
  28. package/src/resilience.ts +11 -11
  29. package/src/resource-config.ts +792 -0
  30. package/src/resource.ts +175 -0
  31. package/src/result.ts +18 -0
  32. package/src/run.ts +7 -6
  33. package/src/schedule-runtime.ts +689 -0
  34. package/src/schedule.ts +324 -0
  35. package/src/serialization.ts +90 -55
  36. package/src/signal-diagnostics.ts +633 -0
  37. package/src/signal-ref.ts +87 -0
  38. package/src/signal.ts +37 -0
  39. package/src/store/accessor-protocol.ts +56 -0
  40. package/src/store/index.ts +4 -0
  41. package/src/structured-examples.ts +245 -0
  42. package/src/surface-derivation.ts +91 -0
  43. package/src/surface-filter.ts +176 -0
  44. package/src/topo.ts +710 -59
  45. package/src/tracing.ts +345 -0
  46. package/src/trail.ts +347 -33
  47. package/src/trails/derive-trail.ts +842 -0
  48. package/src/trails/index.ts +9 -0
  49. package/src/trails/ingest.ts +138 -0
  50. package/src/{internal/trails-db.ts → trails-db.ts} +50 -31
  51. package/src/transport-error-map.ts +174 -0
  52. package/src/type-utils.ts +17 -2
  53. package/src/types.ts +208 -17
  54. package/src/validate-established-topo.ts +8 -2
  55. package/src/validate-topo.ts +244 -13
  56. package/src/validation.ts +58 -1
  57. package/src/webhook.ts +276 -0
  58. package/src/workspace.ts +1 -1
  59. package/src/zod-wrappers.ts +72 -0
  60. package/.turbo/turbo-build.log +0 -1
  61. package/.turbo/turbo-lint.log +0 -3
  62. package/.turbo/turbo-typecheck.log +0 -1
  63. package/dist/adapters.d.ts +0 -39
  64. package/dist/adapters.d.ts.map +0 -1
  65. package/dist/adapters.js +0 -2
  66. package/dist/adapters.js.map +0 -1
  67. package/dist/blob-ref.d.ts +0 -20
  68. package/dist/blob-ref.d.ts.map +0 -1
  69. package/dist/blob-ref.js +0 -22
  70. package/dist/blob-ref.js.map +0 -1
  71. package/dist/branded.d.ts +0 -36
  72. package/dist/branded.d.ts.map +0 -1
  73. package/dist/branded.js +0 -89
  74. package/dist/branded.js.map +0 -1
  75. package/dist/collections.d.ts +0 -31
  76. package/dist/collections.d.ts.map +0 -1
  77. package/dist/collections.js +0 -60
  78. package/dist/collections.js.map +0 -1
  79. package/dist/context.d.ts +0 -10
  80. package/dist/context.d.ts.map +0 -1
  81. package/dist/context.js +0 -21
  82. package/dist/context.js.map +0 -1
  83. package/dist/derive.d.ts +0 -44
  84. package/dist/derive.d.ts.map +0 -1
  85. package/dist/derive.js +0 -149
  86. package/dist/derive.js.map +0 -1
  87. package/dist/dispatch.d.ts +0 -27
  88. package/dist/dispatch.d.ts.map +0 -1
  89. package/dist/dispatch.js +0 -34
  90. package/dist/dispatch.js.map +0 -1
  91. package/dist/draft.d.ts +0 -28
  92. package/dist/draft.d.ts.map +0 -1
  93. package/dist/draft.js +0 -156
  94. package/dist/draft.js.map +0 -1
  95. package/dist/errors.d.ts +0 -83
  96. package/dist/errors.d.ts.map +0 -1
  97. package/dist/errors.js +0 -142
  98. package/dist/errors.js.map +0 -1
  99. package/dist/event.d.ts +0 -8
  100. package/dist/event.d.ts.map +0 -1
  101. package/dist/event.js +0 -7
  102. package/dist/event.js.map +0 -1
  103. package/dist/execute.d.ts +0 -35
  104. package/dist/execute.d.ts.map +0 -1
  105. package/dist/execute.js +0 -90
  106. package/dist/execute.js.map +0 -1
  107. package/dist/fetch.d.ts +0 -15
  108. package/dist/fetch.d.ts.map +0 -1
  109. package/dist/fetch.js +0 -102
  110. package/dist/fetch.js.map +0 -1
  111. package/dist/gate.d.ts +0 -17
  112. package/dist/gate.d.ts.map +0 -1
  113. package/dist/gate.js +0 -21
  114. package/dist/gate.js.map +0 -1
  115. package/dist/guards.d.ts +0 -17
  116. package/dist/guards.d.ts.map +0 -1
  117. package/dist/guards.js +0 -25
  118. package/dist/guards.js.map +0 -1
  119. package/dist/health.d.ts +0 -18
  120. package/dist/health.d.ts.map +0 -1
  121. package/dist/health.js +0 -5
  122. package/dist/health.js.map +0 -1
  123. package/dist/index.d.ts +0 -48
  124. package/dist/index.d.ts.map +0 -1
  125. package/dist/index.js +0 -51
  126. package/dist/index.js.map +0 -1
  127. package/dist/internal/topo-saves.d.ts +0 -47
  128. package/dist/internal/topo-saves.d.ts.map +0 -1
  129. package/dist/internal/topo-saves.js +0 -310
  130. package/dist/internal/topo-saves.js.map +0 -1
  131. package/dist/internal/topo-store-read.d.ts +0 -67
  132. package/dist/internal/topo-store-read.d.ts.map +0 -1
  133. package/dist/internal/topo-store-read.js +0 -222
  134. package/dist/internal/topo-store-read.js.map +0 -1
  135. package/dist/internal/topo-store.d.ts +0 -12
  136. package/dist/internal/topo-store.d.ts.map +0 -1
  137. package/dist/internal/topo-store.js +0 -571
  138. package/dist/internal/topo-store.js.map +0 -1
  139. package/dist/internal/trails-db.d.ts +0 -16
  140. package/dist/internal/trails-db.d.ts.map +0 -1
  141. package/dist/internal/trails-db.js +0 -118
  142. package/dist/internal/trails-db.js.map +0 -1
  143. package/dist/job.d.ts +0 -24
  144. package/dist/job.d.ts.map +0 -1
  145. package/dist/job.js +0 -17
  146. package/dist/job.js.map +0 -1
  147. package/dist/layer.d.ts +0 -6
  148. package/dist/layer.d.ts.map +0 -1
  149. package/dist/layer.js +0 -4
  150. package/dist/layer.js.map +0 -1
  151. package/dist/path-security.d.ts +0 -28
  152. package/dist/path-security.d.ts.map +0 -1
  153. package/dist/path-security.js +0 -63
  154. package/dist/path-security.js.map +0 -1
  155. package/dist/patterns/bulk.d.ts +0 -15
  156. package/dist/patterns/bulk.d.ts.map +0 -1
  157. package/dist/patterns/bulk.js +0 -14
  158. package/dist/patterns/bulk.js.map +0 -1
  159. package/dist/patterns/change.d.ts +0 -10
  160. package/dist/patterns/change.d.ts.map +0 -1
  161. package/dist/patterns/change.js +0 -10
  162. package/dist/patterns/change.js.map +0 -1
  163. package/dist/patterns/date-range.d.ts +0 -10
  164. package/dist/patterns/date-range.d.ts.map +0 -1
  165. package/dist/patterns/date-range.js +0 -10
  166. package/dist/patterns/date-range.js.map +0 -1
  167. package/dist/patterns/index.d.ts +0 -9
  168. package/dist/patterns/index.d.ts.map +0 -1
  169. package/dist/patterns/index.js +0 -9
  170. package/dist/patterns/index.js.map +0 -1
  171. package/dist/patterns/pagination.d.ts +0 -18
  172. package/dist/patterns/pagination.d.ts.map +0 -1
  173. package/dist/patterns/pagination.js +0 -18
  174. package/dist/patterns/pagination.js.map +0 -1
  175. package/dist/patterns/progress.d.ts +0 -11
  176. package/dist/patterns/progress.d.ts.map +0 -1
  177. package/dist/patterns/progress.js +0 -11
  178. package/dist/patterns/progress.js.map +0 -1
  179. package/dist/patterns/sorting.d.ts +0 -13
  180. package/dist/patterns/sorting.d.ts.map +0 -1
  181. package/dist/patterns/sorting.js +0 -10
  182. package/dist/patterns/sorting.js.map +0 -1
  183. package/dist/patterns/status.d.ts +0 -15
  184. package/dist/patterns/status.d.ts.map +0 -1
  185. package/dist/patterns/status.js +0 -9
  186. package/dist/patterns/status.js.map +0 -1
  187. package/dist/patterns/timestamps.d.ts +0 -10
  188. package/dist/patterns/timestamps.d.ts.map +0 -1
  189. package/dist/patterns/timestamps.js +0 -10
  190. package/dist/patterns/timestamps.js.map +0 -1
  191. package/dist/provision-config.d.ts +0 -22
  192. package/dist/provision-config.d.ts.map +0 -1
  193. package/dist/provision-config.js +0 -210
  194. package/dist/provision-config.js.map +0 -1
  195. package/dist/provision.d.ts +0 -71
  196. package/dist/provision.d.ts.map +0 -1
  197. package/dist/provision.js +0 -56
  198. package/dist/provision.js.map +0 -1
  199. package/dist/redaction/index.d.ts +0 -4
  200. package/dist/redaction/index.d.ts.map +0 -1
  201. package/dist/redaction/index.js +0 -3
  202. package/dist/redaction/index.js.map +0 -1
  203. package/dist/redaction/patterns.d.ts +0 -9
  204. package/dist/redaction/patterns.d.ts.map +0 -1
  205. package/dist/redaction/patterns.js +0 -39
  206. package/dist/redaction/patterns.js.map +0 -1
  207. package/dist/redaction/redactor.d.ts +0 -27
  208. package/dist/redaction/redactor.d.ts.map +0 -1
  209. package/dist/redaction/redactor.js +0 -89
  210. package/dist/redaction/redactor.js.map +0 -1
  211. package/dist/resilience.d.ts +0 -34
  212. package/dist/resilience.d.ts.map +0 -1
  213. package/dist/resilience.js +0 -164
  214. package/dist/resilience.js.map +0 -1
  215. package/dist/result.d.ts +0 -57
  216. package/dist/result.d.ts.map +0 -1
  217. package/dist/result.js +0 -156
  218. package/dist/result.js.map +0 -1
  219. package/dist/run.d.ts +0 -27
  220. package/dist/run.d.ts.map +0 -1
  221. package/dist/run.js +0 -34
  222. package/dist/run.js.map +0 -1
  223. package/dist/serialization.d.ts +0 -27
  224. package/dist/serialization.d.ts.map +0 -1
  225. package/dist/serialization.js +0 -153
  226. package/dist/serialization.js.map +0 -1
  227. package/dist/service-config.d.ts +0 -22
  228. package/dist/service-config.d.ts.map +0 -1
  229. package/dist/service-config.js +0 -210
  230. package/dist/service-config.js.map +0 -1
  231. package/dist/service.d.ts +0 -71
  232. package/dist/service.d.ts.map +0 -1
  233. package/dist/service.js +0 -56
  234. package/dist/service.js.map +0 -1
  235. package/dist/signal.d.ts +0 -33
  236. package/dist/signal.d.ts.map +0 -1
  237. package/dist/signal.js +0 -17
  238. package/dist/signal.js.map +0 -1
  239. package/dist/topo-store.d.ts +0 -48
  240. package/dist/topo-store.d.ts.map +0 -1
  241. package/dist/topo-store.js +0 -175
  242. package/dist/topo-store.js.map +0 -1
  243. package/dist/topo.d.ts +0 -25
  244. package/dist/topo.d.ts.map +0 -1
  245. package/dist/topo.js +0 -112
  246. package/dist/topo.js.map +0 -1
  247. package/dist/trail.d.ts +0 -96
  248. package/dist/trail.d.ts.map +0 -1
  249. package/dist/trail.js +0 -20
  250. package/dist/trail.js.map +0 -1
  251. package/dist/type-utils.d.ts +0 -24
  252. package/dist/type-utils.d.ts.map +0 -1
  253. package/dist/type-utils.js +0 -12
  254. package/dist/type-utils.js.map +0 -1
  255. package/dist/types.d.ts +0 -71
  256. package/dist/types.d.ts.map +0 -1
  257. package/dist/types.js +0 -3
  258. package/dist/types.js.map +0 -1
  259. package/dist/validate-established-topo.d.ts +0 -76
  260. package/dist/validate-established-topo.d.ts.map +0 -1
  261. package/dist/validate-established-topo.js +0 -43
  262. package/dist/validate-established-topo.js.map +0 -1
  263. package/dist/validate-topo.d.ts +0 -24
  264. package/dist/validate-topo.d.ts.map +0 -1
  265. package/dist/validate-topo.js +0 -176
  266. package/dist/validate-topo.js.map +0 -1
  267. package/dist/validation.d.ts +0 -27
  268. package/dist/validation.d.ts.map +0 -1
  269. package/dist/validation.js +0 -165
  270. package/dist/validation.js.map +0 -1
  271. package/dist/workspace.d.ts +0 -25
  272. package/dist/workspace.d.ts.map +0 -1
  273. package/dist/workspace.js +0 -57
  274. package/dist/workspace.js.map +0 -1
  275. package/src/__tests__/blob-ref.test.ts +0 -103
  276. package/src/__tests__/branded.test.ts +0 -148
  277. package/src/__tests__/collections.test.ts +0 -126
  278. package/src/__tests__/context.test.ts +0 -77
  279. package/src/__tests__/derive.test.ts +0 -260
  280. package/src/__tests__/errors.test.ts +0 -309
  281. package/src/__tests__/execute.test.ts +0 -525
  282. package/src/__tests__/fetch.test.ts +0 -217
  283. package/src/__tests__/gate.test.ts +0 -125
  284. package/src/__tests__/guards.test.ts +0 -102
  285. package/src/__tests__/path-security.test.ts +0 -114
  286. package/src/__tests__/patterns.test.ts +0 -273
  287. package/src/__tests__/redaction.test.ts +0 -244
  288. package/src/__tests__/resilience.test.ts +0 -246
  289. package/src/__tests__/result.test.ts +0 -155
  290. package/src/__tests__/run.test.ts +0 -181
  291. package/src/__tests__/serialization.test.ts +0 -401
  292. package/src/__tests__/service-config.test.ts +0 -228
  293. package/src/__tests__/service.test.ts +0 -197
  294. package/src/__tests__/signal.test.ts +0 -82
  295. package/src/__tests__/topo-store-read.test.ts +0 -251
  296. package/src/__tests__/topo-store.test.ts +0 -469
  297. package/src/__tests__/topo.test.ts +0 -277
  298. package/src/__tests__/trail-permit.test.ts +0 -60
  299. package/src/__tests__/trail.test.ts +0 -261
  300. package/src/__tests__/trails-db.test.ts +0 -191
  301. package/src/__tests__/type-utils.test.ts +0 -90
  302. package/src/__tests__/validate-topo.test.ts +0 -489
  303. package/src/__tests__/validation.test.ts +0 -336
  304. package/src/__tests__/workspace.test.ts +0 -183
  305. package/src/event.ts +0 -15
  306. package/src/gate.ts +0 -44
  307. package/src/internal/topo-saves.ts +0 -429
  308. package/src/internal/topo-store-read.ts +0 -473
  309. package/src/internal/topo-store.ts +0 -1087
  310. package/src/provision-config.ts +0 -373
  311. package/src/provision.ts +0 -148
  312. package/src/topo-store.ts +0 -301
  313. package/tsconfig.json +0 -9
  314. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,175 @@
1
+ import { InternalError } from './errors.js';
2
+ import type { Result } from './result.js';
3
+ import type { AnySignal } from './signal.js';
4
+ import type { ResourceLookup, TrailContext } from './types.js';
5
+ import type { z } from 'zod';
6
+
7
+ /**
8
+ * Stable process-scoped fields available when constructing a resource.
9
+ *
10
+ * Resources are app-level singletons, so they intentionally do not receive
11
+ * the full per-request TrailContext. When a resource declares a `config` schema,
12
+ * the validated config is passed as `svc.config`.
13
+ */
14
+ export type ResourceContext<C = unknown> = Pick<
15
+ TrailContext,
16
+ 'cwd' | 'env' | 'workspaceRoot'
17
+ > & {
18
+ readonly config: C;
19
+ };
20
+
21
+ /** Explicit marker for resources that intentionally cannot provide a mock. */
22
+ export interface ResourceUnmockable {
23
+ readonly reason: string;
24
+ }
25
+
26
+ /**
27
+ * Everything needed to describe a resource before a factory is introduced.
28
+ *
29
+ * When `config` is a Zod schema, the `create` callback receives
30
+ * `ResourceContext<C>` with the validated config value.
31
+ */
32
+ export interface ResourceSpec<T, C = unknown> {
33
+ /** Create the resource instance from stable process-scoped context. */
34
+ readonly create: (
35
+ svc: ResourceContext<C>
36
+ ) => Result<T, Error> | Promise<Result<T, Error>>;
37
+ /** Config schema — when present, config is validated and passed to `create`. */
38
+ readonly config?: z.ZodType<C> | undefined;
39
+ /** Optional cleanup performed when the host application shuts down. */
40
+ readonly dispose?: ((resource: T) => void | Promise<void>) | undefined;
41
+ /** Optional operational readiness probe for introspection tooling. */
42
+ readonly health?:
43
+ | ((
44
+ resource: T
45
+ ) => Result<unknown, Error> | Promise<Result<unknown, Error>>)
46
+ | undefined;
47
+ /** Optional test factory used by higher-level helpers. */
48
+ readonly mock?: (() => T | Promise<T>) | undefined;
49
+ /** Document why this resource intentionally cannot provide a test mock. */
50
+ readonly unmockable?: ResourceUnmockable | undefined;
51
+ /** Human-readable description. */
52
+ readonly description?: string | undefined;
53
+ /** Arbitrary meta for tooling and filtering. */
54
+ readonly meta?: Readonly<Record<string, unknown>> | undefined;
55
+ /** Signals projected or owned by this resource. */
56
+ readonly signals?: readonly AnySignal[] | undefined;
57
+ }
58
+
59
+ /** A typed resource definition. */
60
+ export interface Resource<T> extends ResourceSpec<T> {
61
+ readonly kind: 'resource';
62
+ readonly id: string;
63
+ /** Read the resolved resource instance from a trail context. */
64
+ from(ctx: TrailContext): T;
65
+ }
66
+
67
+ /**
68
+ * Existential type for heterogeneous resource collections.
69
+ *
70
+ * `Resource<T>` includes function parameters in `dispose`/`health`, so
71
+ * `unknown` is too narrow for mixed resource arrays. `any` is the correct
72
+ * existential here.
73
+ */
74
+ // oxlint-disable-next-line no-explicit-any -- existential type for heterogeneous resource collections
75
+ export type AnyResource = Resource<any>;
76
+
77
+ /** Explicit runtime overrides keyed by resource ID. */
78
+ export type ResourceOverrideMap = Readonly<Record<string, unknown>>;
79
+
80
+ const getResourceId = <T>(
81
+ resourceOrId: string | Pick<Resource<T>, 'id'>
82
+ ): string =>
83
+ typeof resourceOrId === 'string' ? resourceOrId : resourceOrId.id;
84
+
85
+ const getResourceInstance = <T>(
86
+ ctx: Pick<TrailContext, 'extensions'>,
87
+ resourceOrId: string | Pick<Resource<T>, 'id'>
88
+ ): T => {
89
+ const id = getResourceId(resourceOrId);
90
+ return ctx.extensions?.[id] as T;
91
+ };
92
+
93
+ const hasResourceInstance = (
94
+ ctx: Pick<TrailContext, 'extensions'>,
95
+ resourceOrId: string | Pick<AnyResource, 'id'>
96
+ ): boolean => Object.hasOwn(ctx.extensions ?? {}, getResourceId(resourceOrId));
97
+
98
+ /** Create a `ctx.resource(...)` accessor bound to a concrete context snapshot. */
99
+ export const createResourceLookup = (
100
+ getContext: () => Pick<TrailContext, 'extensions'>
101
+ ): ResourceLookup =>
102
+ ((resourceOrId: string | Pick<AnyResource, 'id'>) => {
103
+ const id = getResourceId(resourceOrId);
104
+ const ctx = getContext();
105
+ if (!hasResourceInstance(ctx, id)) {
106
+ throw new InternalError(`Resource "${id}" not provisioned in context`);
107
+ }
108
+ return getResourceInstance(ctx, id);
109
+ }) as ResourceLookup;
110
+
111
+ /**
112
+ * Create a typed resource definition.
113
+ *
114
+ * The resource object is inert until a later execution branch resolves concrete
115
+ * instances into TrailContext extensions.
116
+ */
117
+ export const resource = <T>(id: string, spec: ResourceSpec<T>): Resource<T> =>
118
+ (() => {
119
+ if (id.includes(':')) {
120
+ throw new InternalError(
121
+ `Resource "${id}" is invalid because resource ids may not contain ":"`
122
+ );
123
+ }
124
+ if (spec.mock !== undefined && spec.unmockable !== undefined) {
125
+ throw new InternalError(
126
+ `Resource "${id}" cannot define both mock and unmockable`
127
+ );
128
+ }
129
+ if (
130
+ spec.unmockable !== undefined &&
131
+ spec.unmockable.reason.trim().length === 0
132
+ ) {
133
+ throw new InternalError(
134
+ `Resource "${id}" is invalid because unmockable.reason must not be empty`
135
+ );
136
+ }
137
+
138
+ return Object.freeze({
139
+ ...spec,
140
+ from(ctx: TrailContext): T {
141
+ const lookup = ctx.resource ?? createResourceLookup(() => ctx);
142
+ return lookup(this);
143
+ },
144
+ id,
145
+ kind: 'resource' as const,
146
+ });
147
+ })();
148
+
149
+ /** Narrow unknown values to resource definitions during topo discovery. */
150
+ export const isResource = (value: unknown): value is AnyResource => {
151
+ if (typeof value !== 'object' || value === null) {
152
+ return false;
153
+ }
154
+ const v = value as { kind?: unknown; id?: unknown };
155
+ return v.kind === 'resource' && typeof v.id === 'string';
156
+ };
157
+
158
+ /**
159
+ * Return the first duplicate resource ID in a collection, if any.
160
+ *
161
+ * This supports later topo registration without each caller duplicating the
162
+ * same scan logic.
163
+ */
164
+ export const findDuplicateResourceId = (
165
+ resources: readonly Pick<AnyResource, 'id'>[]
166
+ ): string | undefined => {
167
+ const seen = new Set<string>();
168
+ for (const candidate of resources) {
169
+ if (seen.has(candidate.id)) {
170
+ return candidate.id;
171
+ }
172
+ seen.add(candidate.id);
173
+ }
174
+ return undefined;
175
+ };
package/src/result.ts CHANGED
@@ -4,6 +4,24 @@
4
4
 
5
5
  import { InternalError, ValidationError } from './errors.js';
6
6
 
7
+ export const resultAccessorNames = [
8
+ 'error',
9
+ 'flatMap',
10
+ 'isErr',
11
+ 'isOk',
12
+ 'map',
13
+ 'mapErr',
14
+ 'match',
15
+ 'unwrap',
16
+ 'unwrapOr',
17
+ 'value',
18
+ ] as const satisfies readonly (
19
+ | keyof Ok<unknown, unknown>
20
+ | keyof Err<unknown>
21
+ )[];
22
+
23
+ export type ResultAccessorName = (typeof resultAccessorNames)[number];
24
+
7
25
  class Ok<T, E> {
8
26
  readonly value: T;
9
27
 
package/src/run.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Headless trail execution without mounting a trailhead.
2
+ * Headless trail execution without surface registration.
3
3
  *
4
4
  * Looks up a trail by ID in a topo, then delegates to `executeTrail`.
5
5
  * Returns a `Result` and never throws.
@@ -23,12 +23,13 @@ export type RunOptions = ExecuteTrailOptions;
23
23
  // ---------------------------------------------------------------------------
24
24
 
25
25
  /**
26
- * Execute a trail by ID from a topo without mounting a trailhead.
26
+ * Execute a trail by ID from a topo without registering it on a surface.
27
27
  *
28
28
  * Resolves the trail from the topo, then runs it through the standard
29
- * `executeTrail` pipeline. Returns `Result.err(NotFoundError)` if the
30
- * trail ID is not registered. Never throws — unexpected exceptions are
31
- * returned as `Result.err(InternalError)`.
29
+ * `executeTrail` pipeline with `topo` threaded so `ctx.fire()` is bound
30
+ * to the producer's context inside `executeTrail`. Returns
31
+ * `Result.err(NotFoundError)` if the trail ID is not registered. Never
32
+ * throws — unexpected exceptions are returned as `Result.err(InternalError)`.
32
33
  *
33
34
  * @example
34
35
  * ```typescript
@@ -50,5 +51,5 @@ export const run = (
50
51
  )
51
52
  );
52
53
  }
53
- return executeTrail(trail, input, options);
54
+ return executeTrail(trail, input, { ...options, topo });
54
55
  };