@ontrails/core 1.0.0-beta.10 → 1.0.0-beta.11

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 (55) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/CHANGELOG.md +20 -0
  3. package/README.md +1 -0
  4. package/dist/context.d.ts +2 -2
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +12 -7
  7. package/dist/context.js.map +1 -1
  8. package/dist/execute.d.ts +6 -3
  9. package/dist/execute.d.ts.map +1 -1
  10. package/dist/execute.js +149 -6
  11. package/dist/execute.js.map +1 -1
  12. package/dist/index.d.ts +3 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/service.d.ts +69 -0
  17. package/dist/service.d.ts.map +1 -0
  18. package/dist/service.js +56 -0
  19. package/dist/service.js.map +1 -0
  20. package/dist/topo.d.ts +7 -0
  21. package/dist/topo.d.ts.map +1 -1
  22. package/dist/topo.js +37 -8
  23. package/dist/topo.js.map +1 -1
  24. package/dist/trail.d.ts +6 -1
  25. package/dist/trail.d.ts.map +1 -1
  26. package/dist/trail.js +2 -1
  27. package/dist/trail.js.map +1 -1
  28. package/dist/types.d.ts +9 -0
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/validate-topo.d.ts.map +1 -1
  31. package/dist/validate-topo.js +16 -0
  32. package/dist/validate-topo.js.map +1 -1
  33. package/dist/validation.d.ts.map +1 -1
  34. package/dist/validation.js +34 -3
  35. package/dist/validation.js.map +1 -1
  36. package/package.json +1 -1
  37. package/src/__tests__/context.test.ts +12 -0
  38. package/src/__tests__/dispatch.test.ts +29 -2
  39. package/src/__tests__/execute.test.ts +318 -3
  40. package/src/__tests__/layer.test.ts +3 -2
  41. package/src/__tests__/service.test.ts +197 -0
  42. package/src/__tests__/topo.test.ts +71 -0
  43. package/src/__tests__/trail.test.ts +46 -2
  44. package/src/__tests__/validate-topo.test.ts +45 -1
  45. package/src/__tests__/validation.test.ts +53 -0
  46. package/src/context.ts +18 -9
  47. package/src/execute.ts +258 -9
  48. package/src/index.ts +17 -0
  49. package/src/service.ts +139 -0
  50. package/src/topo.ts +53 -9
  51. package/src/trail.ts +14 -2
  52. package/src/types.ts +11 -0
  53. package/src/validate-topo.ts +22 -0
  54. package/src/validation.ts +35 -3
  55. package/tsconfig.tsbuildinfo +1 -1
package/src/types.ts CHANGED
@@ -17,6 +17,11 @@ export type FollowFn = <O>(
17
17
  input: unknown
18
18
  ) => Promise<Result<O, Error>>;
19
19
 
20
+ /** Resolve a service instance from the current trail context. */
21
+ export type ServiceLookup = <T = unknown>(
22
+ serviceOrId: { readonly id: string } | string
23
+ ) => T;
24
+
20
25
  /** Callback for reporting progress from long-running trails */
21
26
  export type ProgressCallback = (event: ProgressEvent) => void;
22
27
 
@@ -53,4 +58,10 @@ export interface TrailContext {
53
58
  readonly cwd?: string | undefined;
54
59
  readonly env?: Record<string, string | undefined> | undefined;
55
60
  readonly extensions?: Readonly<Record<string, unknown>> | undefined;
61
+ readonly service?: ServiceLookup | undefined;
56
62
  }
63
+
64
+ /** Input shape used to seed a runtime TrailContext before resolution. */
65
+ export type TrailContextInit = Omit<TrailContext, 'service'> & {
66
+ readonly service?: ServiceLookup | undefined;
67
+ };
@@ -113,6 +113,27 @@ const checkFollows = (
113
113
  return issues;
114
114
  };
115
115
 
116
+ const checkServices = (
117
+ trails: ReadonlyMap<string, AnyTrail>,
118
+ topo: Topo
119
+ ): TopoIssue[] => {
120
+ const issues: TopoIssue[] = [];
121
+
122
+ for (const [id, trail] of trails) {
123
+ for (const declaredService of trail.services) {
124
+ if (!topo.hasService(declaredService.id)) {
125
+ issues.push({
126
+ message: `Service "${declaredService.id}" is not in the topo`,
127
+ rule: 'service-exists',
128
+ trailId: id,
129
+ });
130
+ }
131
+ }
132
+ }
133
+
134
+ return issues;
135
+ };
136
+
116
137
  const checkOneExample = (
117
138
  id: string,
118
139
  example: {
@@ -192,6 +213,7 @@ const checkEventOrigins = (
192
213
  export const validateTopo = (topo: Topo): Result<void, ValidationError> => {
193
214
  const issues = [
194
215
  ...checkFollows(topo.trails, topo),
216
+ ...checkServices(topo.trails, topo),
195
217
  ...checkExamples(topo.trails),
196
218
  ...checkEventOrigins(topo.events, topo),
197
219
  ];
package/src/validation.ts CHANGED
@@ -94,6 +94,34 @@ export const validateOutput = <T>(
94
94
  // Zod → JSON Schema (public API)
95
95
  // ---------------------------------------------------------------------------
96
96
 
97
+ /**
98
+ * Sentinel indicating a dynamic default that should be omitted from schema
99
+ * exports. Zod v4 wraps all defaults in getters; dynamic ones (functions)
100
+ * produce new values on each access. We detect this by reading the getter
101
+ * twice and comparing with `Object.is`. If values differ, the default is
102
+ * dynamic and we cache this sentinel to skip it in future calls.
103
+ */
104
+ const DYNAMIC_DEFAULT = Symbol('DYNAMIC_DEFAULT');
105
+ const defaultValueCache = new WeakMap<object, unknown>();
106
+
107
+ /** Read a Zod v4 default getter twice and decide if it's stable.
108
+ * Uses Object.is for primitives and JSON.stringify for objects/arrays. */
109
+ const resolveDefault = (def: Record<string, unknown>): unknown => {
110
+ try {
111
+ const a = def['defaultValue'];
112
+ const b = def['defaultValue'];
113
+ if (Object.is(a, b)) {
114
+ return a;
115
+ }
116
+ // Object/array defaults produce new references each call but may
117
+ // still be structurally identical (e.g. `() => ({ key: 'val' })`).
118
+ return JSON.stringify(a) === JSON.stringify(b) ? a : DYNAMIC_DEFAULT;
119
+ } catch {
120
+ // BigInt, circular refs, or other non-serializable defaults
121
+ return DYNAMIC_DEFAULT;
122
+ }
123
+ };
124
+
97
125
  /**
98
126
  * Convert common Zod types to a JSON Schema object.
99
127
  *
@@ -142,9 +170,13 @@ export const zodToJsonSchema: JsonSchemaConverter = (
142
170
  default: (value) => {
143
171
  const inner = value._zod.def['innerType'] as unknown as z.ZodType;
144
172
  const innerSchema = zodToJsonSchema(inner);
145
- const rawDefault = value._zod.def['defaultValue'];
146
- innerSchema['default'] =
147
- typeof rawDefault === 'function' ? rawDefault() : rawDefault;
173
+ if (!defaultValueCache.has(value._zod.def)) {
174
+ defaultValueCache.set(value._zod.def, resolveDefault(value._zod.def));
175
+ }
176
+ const cached = defaultValueCache.get(value._zod.def);
177
+ if (cached !== DYNAMIC_DEFAULT) {
178
+ innerSchema['default'] = cached;
179
+ }
148
180
  return innerSchema;
149
181
  },
150
182
  enum: (value) => {
@@ -1 +1 @@
1
- {"root":["./src/blob-ref.ts","./src/branded.ts","./src/collections.ts","./src/context.ts","./src/derive.ts","./src/dispatch.ts","./src/errors.ts","./src/event.ts","./src/execute.ts","./src/fetch.ts","./src/guards.ts","./src/index.ts","./src/layer.ts","./src/path-security.ts","./src/resilience.ts","./src/result.ts","./src/serialization.ts","./src/topo.ts","./src/trail.ts","./src/type-utils.ts","./src/types.ts","./src/validate-topo.ts","./src/validation.ts","./src/workspace.ts","./src/patterns/bulk.ts","./src/patterns/change.ts","./src/patterns/date-range.ts","./src/patterns/index.ts","./src/patterns/pagination.ts","./src/patterns/progress.ts","./src/patterns/sorting.ts","./src/patterns/status.ts","./src/patterns/timestamps.ts","./src/redaction/index.ts","./src/redaction/patterns.ts","./src/redaction/redactor.ts"],"version":"5.9.3"}
1
+ {"root":["./src/blob-ref.ts","./src/branded.ts","./src/collections.ts","./src/context.ts","./src/derive.ts","./src/dispatch.ts","./src/errors.ts","./src/event.ts","./src/execute.ts","./src/fetch.ts","./src/guards.ts","./src/index.ts","./src/layer.ts","./src/path-security.ts","./src/resilience.ts","./src/result.ts","./src/serialization.ts","./src/service.ts","./src/topo.ts","./src/trail.ts","./src/type-utils.ts","./src/types.ts","./src/validate-topo.ts","./src/validation.ts","./src/workspace.ts","./src/patterns/bulk.ts","./src/patterns/change.ts","./src/patterns/date-range.ts","./src/patterns/index.ts","./src/patterns/pagination.ts","./src/patterns/progress.ts","./src/patterns/sorting.ts","./src/patterns/status.ts","./src/patterns/timestamps.ts","./src/redaction/index.ts","./src/redaction/patterns.ts","./src/redaction/redactor.ts"],"version":"5.9.3"}