@ontrails/core 1.0.0-beta.4 → 1.0.0-beta.41

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 (247) hide show
  1. package/CHANGELOG.md +412 -12
  2. package/README.md +112 -28
  3. package/package.json +11 -1
  4. package/src/activation-provenance.ts +116 -0
  5. package/src/activation-source-compatibility.ts +430 -0
  6. package/src/activation-source-projection.ts +227 -0
  7. package/src/activation-source.ts +93 -0
  8. package/src/blob-ref.ts +51 -0
  9. package/src/branded.ts +1 -1
  10. package/src/compose-batch.ts +69 -0
  11. package/src/compose-schema.ts +36 -0
  12. package/src/context.ts +59 -11
  13. package/src/derive.ts +271 -19
  14. package/src/detours.ts +8 -0
  15. package/src/diagnostics.ts +21 -0
  16. package/src/draft.ts +350 -0
  17. package/src/entity.ts +346 -0
  18. package/src/error-projection.ts +51 -0
  19. package/src/errors.ts +335 -48
  20. package/src/execute.ts +1577 -0
  21. package/src/fire.ts +1172 -0
  22. package/src/glob.ts +81 -0
  23. package/src/index.ts +568 -32
  24. package/src/internal/fork-ctx.ts +69 -0
  25. package/src/layer-projection.ts +193 -0
  26. package/src/layer.ts +43 -6
  27. package/src/observe.ts +361 -0
  28. package/src/path-scope.ts +66 -0
  29. package/src/path-security.ts +11 -3
  30. package/src/permits.ts +12 -0
  31. package/src/queue.ts +163 -0
  32. package/src/redaction/patterns.ts +6 -3
  33. package/src/resilience.ts +11 -11
  34. package/src/resource-config.ts +804 -0
  35. package/src/resource.ts +194 -0
  36. package/src/result.ts +18 -0
  37. package/src/run.ts +76 -0
  38. package/src/runtime-builtins.ts +69 -0
  39. package/src/schedule-runtime.ts +689 -0
  40. package/src/schedule.ts +326 -0
  41. package/src/serialization.ts +92 -55
  42. package/src/sha256.ts +136 -0
  43. package/src/signal-diagnostics.ts +633 -0
  44. package/src/signal-ref.ts +111 -0
  45. package/src/signal.ts +104 -0
  46. package/src/store/accessor-protocol.ts +56 -0
  47. package/src/store/index.ts +4 -0
  48. package/src/structured-examples.ts +248 -0
  49. package/src/surface-derivation.ts +91 -0
  50. package/src/surface-filter.ts +101 -0
  51. package/src/surface-overlay.ts +694 -0
  52. package/src/surface-versioning.ts +42 -0
  53. package/src/topo.ts +762 -38
  54. package/src/tracing.ts +346 -0
  55. package/src/trail-id-glob.ts +15 -0
  56. package/src/trail.ts +1244 -34
  57. package/src/trails/derive-trail.ts +835 -0
  58. package/src/trails/index.ts +9 -0
  59. package/src/trails/ingest.ts +152 -0
  60. package/src/trails-db.ts +212 -0
  61. package/src/transport-error-map.ts +174 -0
  62. package/src/type-utils.ts +87 -0
  63. package/src/types.ts +254 -12
  64. package/src/validate-established-topo.ts +73 -0
  65. package/src/validate-topo.ts +569 -55
  66. package/src/validation.ts +152 -4
  67. package/src/version-marker.ts +716 -0
  68. package/src/version-resolution.ts +308 -0
  69. package/src/version-runtime.ts +120 -0
  70. package/src/webhook.ts +461 -0
  71. package/src/workspace.ts +183 -16
  72. package/src/zod-wrappers.ts +72 -0
  73. package/.turbo/turbo-build.log +0 -1
  74. package/.turbo/turbo-lint.log +0 -3
  75. package/.turbo/turbo-typecheck.log +0 -1
  76. package/dist/adapters.d.ts +0 -39
  77. package/dist/adapters.d.ts.map +0 -1
  78. package/dist/adapters.js +0 -2
  79. package/dist/adapters.js.map +0 -1
  80. package/dist/blob-ref.d.ts +0 -20
  81. package/dist/blob-ref.d.ts.map +0 -1
  82. package/dist/blob-ref.js +0 -22
  83. package/dist/blob-ref.js.map +0 -1
  84. package/dist/branded.d.ts +0 -36
  85. package/dist/branded.d.ts.map +0 -1
  86. package/dist/branded.js +0 -89
  87. package/dist/branded.js.map +0 -1
  88. package/dist/collections.d.ts +0 -31
  89. package/dist/collections.d.ts.map +0 -1
  90. package/dist/collections.js +0 -60
  91. package/dist/collections.js.map +0 -1
  92. package/dist/context.d.ts +0 -10
  93. package/dist/context.d.ts.map +0 -1
  94. package/dist/context.js +0 -15
  95. package/dist/context.js.map +0 -1
  96. package/dist/derive.d.ts +0 -33
  97. package/dist/derive.d.ts.map +0 -1
  98. package/dist/derive.js +0 -125
  99. package/dist/derive.js.map +0 -1
  100. package/dist/errors.d.ts +0 -83
  101. package/dist/errors.d.ts.map +0 -1
  102. package/dist/errors.js +0 -142
  103. package/dist/errors.js.map +0 -1
  104. package/dist/event.d.ts +0 -45
  105. package/dist/event.d.ts.map +0 -1
  106. package/dist/event.js +0 -17
  107. package/dist/event.js.map +0 -1
  108. package/dist/fetch.d.ts +0 -15
  109. package/dist/fetch.d.ts.map +0 -1
  110. package/dist/fetch.js +0 -102
  111. package/dist/fetch.js.map +0 -1
  112. package/dist/guards.d.ts +0 -17
  113. package/dist/guards.d.ts.map +0 -1
  114. package/dist/guards.js +0 -25
  115. package/dist/guards.js.map +0 -1
  116. package/dist/health.d.ts +0 -18
  117. package/dist/health.d.ts.map +0 -1
  118. package/dist/health.js +0 -5
  119. package/dist/health.js.map +0 -1
  120. package/dist/index.d.ts +0 -34
  121. package/dist/index.d.ts.map +0 -1
  122. package/dist/index.js +0 -38
  123. package/dist/index.js.map +0 -1
  124. package/dist/job.d.ts +0 -24
  125. package/dist/job.d.ts.map +0 -1
  126. package/dist/job.js +0 -17
  127. package/dist/job.js.map +0 -1
  128. package/dist/layer.d.ts +0 -17
  129. package/dist/layer.d.ts.map +0 -1
  130. package/dist/layer.js +0 -21
  131. package/dist/layer.js.map +0 -1
  132. package/dist/path-security.d.ts +0 -28
  133. package/dist/path-security.d.ts.map +0 -1
  134. package/dist/path-security.js +0 -63
  135. package/dist/path-security.js.map +0 -1
  136. package/dist/patterns/bulk.d.ts +0 -15
  137. package/dist/patterns/bulk.d.ts.map +0 -1
  138. package/dist/patterns/bulk.js +0 -14
  139. package/dist/patterns/bulk.js.map +0 -1
  140. package/dist/patterns/change.d.ts +0 -10
  141. package/dist/patterns/change.d.ts.map +0 -1
  142. package/dist/patterns/change.js +0 -10
  143. package/dist/patterns/change.js.map +0 -1
  144. package/dist/patterns/date-range.d.ts +0 -10
  145. package/dist/patterns/date-range.d.ts.map +0 -1
  146. package/dist/patterns/date-range.js +0 -10
  147. package/dist/patterns/date-range.js.map +0 -1
  148. package/dist/patterns/index.d.ts +0 -9
  149. package/dist/patterns/index.d.ts.map +0 -1
  150. package/dist/patterns/index.js +0 -9
  151. package/dist/patterns/index.js.map +0 -1
  152. package/dist/patterns/pagination.d.ts +0 -18
  153. package/dist/patterns/pagination.d.ts.map +0 -1
  154. package/dist/patterns/pagination.js +0 -18
  155. package/dist/patterns/pagination.js.map +0 -1
  156. package/dist/patterns/progress.d.ts +0 -11
  157. package/dist/patterns/progress.d.ts.map +0 -1
  158. package/dist/patterns/progress.js +0 -11
  159. package/dist/patterns/progress.js.map +0 -1
  160. package/dist/patterns/sorting.d.ts +0 -13
  161. package/dist/patterns/sorting.d.ts.map +0 -1
  162. package/dist/patterns/sorting.js +0 -10
  163. package/dist/patterns/sorting.js.map +0 -1
  164. package/dist/patterns/status.d.ts +0 -15
  165. package/dist/patterns/status.d.ts.map +0 -1
  166. package/dist/patterns/status.js +0 -9
  167. package/dist/patterns/status.js.map +0 -1
  168. package/dist/patterns/timestamps.d.ts +0 -10
  169. package/dist/patterns/timestamps.d.ts.map +0 -1
  170. package/dist/patterns/timestamps.js +0 -10
  171. package/dist/patterns/timestamps.js.map +0 -1
  172. package/dist/redaction/index.d.ts +0 -4
  173. package/dist/redaction/index.d.ts.map +0 -1
  174. package/dist/redaction/index.js +0 -3
  175. package/dist/redaction/index.js.map +0 -1
  176. package/dist/redaction/patterns.d.ts +0 -9
  177. package/dist/redaction/patterns.d.ts.map +0 -1
  178. package/dist/redaction/patterns.js +0 -39
  179. package/dist/redaction/patterns.js.map +0 -1
  180. package/dist/redaction/redactor.d.ts +0 -27
  181. package/dist/redaction/redactor.d.ts.map +0 -1
  182. package/dist/redaction/redactor.js +0 -89
  183. package/dist/redaction/redactor.js.map +0 -1
  184. package/dist/resilience.d.ts +0 -34
  185. package/dist/resilience.d.ts.map +0 -1
  186. package/dist/resilience.js +0 -164
  187. package/dist/resilience.js.map +0 -1
  188. package/dist/result.d.ts +0 -57
  189. package/dist/result.d.ts.map +0 -1
  190. package/dist/result.js +0 -156
  191. package/dist/result.js.map +0 -1
  192. package/dist/serialization.d.ts +0 -27
  193. package/dist/serialization.d.ts.map +0 -1
  194. package/dist/serialization.js +0 -153
  195. package/dist/serialization.js.map +0 -1
  196. package/dist/topo.d.ts +0 -16
  197. package/dist/topo.d.ts.map +0 -1
  198. package/dist/topo.js +0 -66
  199. package/dist/topo.js.map +0 -1
  200. package/dist/trail.d.ts +0 -89
  201. package/dist/trail.d.ts.map +0 -1
  202. package/dist/trail.js +0 -18
  203. package/dist/trail.js.map +0 -1
  204. package/dist/types.d.ts +0 -46
  205. package/dist/types.d.ts.map +0 -1
  206. package/dist/types.js +0 -2
  207. package/dist/types.js.map +0 -1
  208. package/dist/validate-topo.d.ts +0 -24
  209. package/dist/validate-topo.d.ts.map +0 -1
  210. package/dist/validate-topo.js +0 -158
  211. package/dist/validate-topo.js.map +0 -1
  212. package/dist/validation.d.ts +0 -27
  213. package/dist/validation.d.ts.map +0 -1
  214. package/dist/validation.js +0 -134
  215. package/dist/validation.js.map +0 -1
  216. package/dist/workspace.d.ts +0 -25
  217. package/dist/workspace.d.ts.map +0 -1
  218. package/dist/workspace.js +0 -57
  219. package/dist/workspace.js.map +0 -1
  220. package/src/__tests__/blob-ref.test.ts +0 -103
  221. package/src/__tests__/branded.test.ts +0 -148
  222. package/src/__tests__/collections.test.ts +0 -126
  223. package/src/__tests__/context.test.ts +0 -66
  224. package/src/__tests__/derive.test.ts +0 -203
  225. package/src/__tests__/errors.test.ts +0 -309
  226. package/src/__tests__/event.test.ts +0 -82
  227. package/src/__tests__/fetch.test.ts +0 -217
  228. package/src/__tests__/guards.test.ts +0 -102
  229. package/src/__tests__/job.test.ts +0 -98
  230. package/src/__tests__/layer.test.ts +0 -212
  231. package/src/__tests__/path-security.test.ts +0 -114
  232. package/src/__tests__/patterns.test.ts +0 -273
  233. package/src/__tests__/redaction.test.ts +0 -244
  234. package/src/__tests__/resilience.test.ts +0 -246
  235. package/src/__tests__/result.test.ts +0 -155
  236. package/src/__tests__/serialization.test.ts +0 -401
  237. package/src/__tests__/topo.test.ts +0 -181
  238. package/src/__tests__/trail.test.ts +0 -217
  239. package/src/__tests__/validate-topo.test.ts +0 -278
  240. package/src/__tests__/validation.test.ts +0 -283
  241. package/src/__tests__/workspace.test.ts +0 -183
  242. package/src/adapters.ts +0 -68
  243. package/src/event.ts +0 -77
  244. package/src/health.ts +0 -23
  245. package/src/job.ts +0 -20
  246. package/tsconfig.json +0 -9
  247. package/tsconfig.tsbuildinfo +0 -1
package/src/validation.ts CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  import type { z } from 'zod';
9
9
 
10
+ import { BLOB_REF_SCHEMA_META_KEY, blobRefJsonSchema } from './blob-ref.js';
10
11
  import { ValidationError } from './errors.js';
11
12
  import { Result } from './result.js';
12
13
 
@@ -31,10 +32,66 @@ type JsonSchemaConverter = (schema: z.ZodType) => JsonSchema;
31
32
  // ---------------------------------------------------------------------------
32
33
 
33
34
  const isOptionalLike = (s: ZodInternals): boolean => {
34
- const defType = s._zod.def['type'] as string;
35
+ let current = s;
36
+ const seen = new Set<ZodInternals>();
37
+ while (
38
+ current._zod.def['type'] === 'readonly' &&
39
+ !seen.has(current) &&
40
+ current._zod.def['innerType'] !== undefined
41
+ ) {
42
+ seen.add(current);
43
+ current = current._zod.def['innerType'] as ZodInternals;
44
+ }
45
+ const defType = current._zod.def['type'] as string;
35
46
  return defType === 'optional' || defType === 'default';
36
47
  };
37
48
 
49
+ const getSchemaMeta = (
50
+ schema: z.ZodType
51
+ ): Readonly<Record<string, unknown>> | undefined => {
52
+ const maybeMeta = (schema as unknown as { meta?: () => unknown }).meta;
53
+ if (typeof maybeMeta !== 'function') {
54
+ return undefined;
55
+ }
56
+ const meta = maybeMeta.call(schema);
57
+ return typeof meta === 'object' && meta !== null
58
+ ? (meta as Readonly<Record<string, unknown>>)
59
+ : undefined;
60
+ };
61
+
62
+ const getSchemaJsonSchemaOverride = (
63
+ schema: z.ZodType
64
+ ): JsonSchema | undefined => {
65
+ const meta = getSchemaMeta(schema);
66
+ if (meta?.[BLOB_REF_SCHEMA_META_KEY] === true) {
67
+ const override: JsonSchema = {
68
+ properties: Object.fromEntries(
69
+ Object.entries(blobRefJsonSchema.properties).map(([key, value]) => [
70
+ key,
71
+ { ...value },
72
+ ])
73
+ ),
74
+ required: [...blobRefJsonSchema.required],
75
+ type: blobRefJsonSchema.type,
76
+ };
77
+ const { description } = schema as unknown as ZodInternals;
78
+ if (description) {
79
+ override['description'] = description;
80
+ }
81
+ return override;
82
+ }
83
+ return undefined;
84
+ };
85
+
86
+ /**
87
+ * Whether a schema has a deterministic JSON-schema override projection (for
88
+ * example `blobRefSchema`, a `z.custom(...)` carrying the descriptor metadata).
89
+ * Such schemas project to a canonical descriptor regardless of their underlying
90
+ * Zod internals, so marker derivation can treat them as supported.
91
+ */
92
+ export const schemaHasJsonSchemaOverride = (schema: z.ZodType): boolean =>
93
+ getSchemaJsonSchemaOverride(schema) !== undefined;
94
+
38
95
  // ---------------------------------------------------------------------------
39
96
  // Issue formatting
40
97
  // ---------------------------------------------------------------------------
@@ -94,6 +151,86 @@ export const validateOutput = <T>(
94
151
  // Zod → JSON Schema (public API)
95
152
  // ---------------------------------------------------------------------------
96
153
 
154
+ /**
155
+ * Sentinel indicating a dynamic default that should be omitted from schema
156
+ * exports. Zod v4 wraps all defaults in getters; dynamic ones (functions)
157
+ * produce new values on each access. We detect this by reading the getter
158
+ * twice and comparing with `Object.is`. If values differ, the default is
159
+ * dynamic and we cache this sentinel to skip it in future calls.
160
+ */
161
+ const DYNAMIC_DEFAULT = Symbol('DYNAMIC_DEFAULT');
162
+ const defaultValueCache = new WeakMap<object, unknown>();
163
+
164
+ const defaultsMatch = (left: unknown, right: unknown): boolean => {
165
+ if (Object.is(left, right)) {
166
+ return true;
167
+ }
168
+ try {
169
+ return JSON.stringify(left) === JSON.stringify(right);
170
+ } catch {
171
+ return false;
172
+ }
173
+ };
174
+
175
+ const waitForClockAdvance = (): void => {
176
+ const wallStart = Date.now();
177
+ const monotonicStart = performance.now();
178
+ while (Date.now() === wallStart && performance.now() - monotonicStart < 4) {
179
+ // Zod hides default factories behind a getter. A bounded sync wait lets
180
+ // Date.now()-style factories reveal themselves without making the API async.
181
+ }
182
+ };
183
+
184
+ const readDefaultWithDateNowOffset = (
185
+ def: Record<string, unknown>
186
+ ): unknown => {
187
+ const originalDateNow = Date.now;
188
+ try {
189
+ Date.now = () => originalDateNow() + 86_400_000;
190
+ return def['defaultValue'];
191
+ } finally {
192
+ Date.now = originalDateNow;
193
+ }
194
+ };
195
+
196
+ /**
197
+ * Read a Zod v4 default getter and decide if it is stable.
198
+ *
199
+ * Uses Object.is for primitives and JSON.stringify for objects/arrays. A delayed
200
+ * third read catches default factories such as `() => Date.now()` that can return
201
+ * equal values for immediate back-to-back reads. A Date.now() probe catches
202
+ * coarser clock factories without requiring marker derivation to wait for the
203
+ * next second/day boundary.
204
+ */
205
+ const resolveDefault = (def: Record<string, unknown>): unknown => {
206
+ try {
207
+ const a = def['defaultValue'];
208
+ const b = def['defaultValue'];
209
+ if (!defaultsMatch(a, b)) {
210
+ return DYNAMIC_DEFAULT;
211
+ }
212
+ waitForClockAdvance();
213
+ const c = def['defaultValue'];
214
+ if (!defaultsMatch(a, c)) {
215
+ return DYNAMIC_DEFAULT;
216
+ }
217
+ const d = readDefaultWithDateNowOffset(def);
218
+ return defaultsMatch(a, d) ? a : DYNAMIC_DEFAULT;
219
+ } catch {
220
+ // BigInt, circular refs, or other non-serializable defaults
221
+ return DYNAMIC_DEFAULT;
222
+ }
223
+ };
224
+
225
+ export const zodDefaultValueIsDynamic = (
226
+ def: Record<string, unknown>
227
+ ): boolean => {
228
+ if (!defaultValueCache.has(def)) {
229
+ defaultValueCache.set(def, resolveDefault(def));
230
+ }
231
+ return defaultValueCache.get(def) === DYNAMIC_DEFAULT;
232
+ };
233
+
97
234
  /**
98
235
  * Convert common Zod types to a JSON Schema object.
99
236
  *
@@ -104,6 +241,11 @@ export const validateOutput = <T>(
104
241
  export const zodToJsonSchema: JsonSchemaConverter = (
105
242
  schema: z.ZodType
106
243
  ): JsonSchema => {
244
+ const jsonSchemaOverride = getSchemaJsonSchemaOverride(schema);
245
+ if (jsonSchemaOverride !== undefined) {
246
+ return jsonSchemaOverride;
247
+ }
248
+
107
249
  const s = schema as unknown as ZodInternals;
108
250
 
109
251
  const collectObjectFields = (shape: Record<string, ZodInternals>) => {
@@ -142,9 +284,11 @@ export const zodToJsonSchema: JsonSchemaConverter = (
142
284
  default: (value) => {
143
285
  const inner = value._zod.def['innerType'] as unknown as z.ZodType;
144
286
  const innerSchema = zodToJsonSchema(inner);
145
- const rawDefault = value._zod.def['defaultValue'];
146
- innerSchema['default'] =
147
- typeof rawDefault === 'function' ? rawDefault() : rawDefault;
287
+ zodDefaultValueIsDynamic(value._zod.def);
288
+ const cached = defaultValueCache.get(value._zod.def);
289
+ if (cached !== DYNAMIC_DEFAULT) {
290
+ innerSchema['default'] = cached;
291
+ }
148
292
  return innerSchema;
149
293
  },
150
294
  enum: (value) => {
@@ -165,6 +309,10 @@ export const zodToJsonSchema: JsonSchemaConverter = (
165
309
  const inner = value._zod.def['innerType'] as unknown as z.ZodType;
166
310
  return zodToJsonSchema(inner);
167
311
  },
312
+ readonly: (value) => {
313
+ const inner = value._zod.def['innerType'] as unknown as z.ZodType;
314
+ return zodToJsonSchema(inner);
315
+ },
168
316
  string: () => ({ type: 'string' }),
169
317
  union: (value) => {
170
318
  const options = value._zod.def['options'] as unknown as z.ZodType[];