@ontrails/core 1.0.0-beta.19 → 1.0.0-beta.21

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @ontrails/core
2
2
 
3
+ ## 1.0.0-beta.21
4
+
5
+ ### Patch Changes
6
+
7
+ - 99523f2: Clean up resource context naming in shipped source and examples so resource
8
+ factories consistently use resource vocabulary.
9
+
10
+ ## 1.0.0-beta.20
11
+
12
+ ### Patch Changes
13
+
14
+ - 851a2a3: Derive trail caller and blaze input types from the authored input schema while keeping one public input contract.
15
+
3
16
  ## 1.0.0-beta.19
4
17
 
5
18
  ### Major Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ontrails/core",
3
- "version": "1.0.0-beta.19",
3
+ "version": "1.0.0-beta.21",
4
4
  "files": [
5
5
  "src/**/*.ts",
6
6
  "!src/**/__tests__/**",
package/src/resource.ts CHANGED
@@ -9,7 +9,7 @@ import type { z } from 'zod';
9
9
  *
10
10
  * Resources are app-level singletons, so they intentionally do not receive
11
11
  * the full per-request TrailContext. When a resource declares a `config` schema,
12
- * the validated config is passed as `svc.config`.
12
+ * the validated config is passed as `resourceCtx.config`.
13
13
  */
14
14
  export type ResourceContext<C = unknown> = Pick<
15
15
  TrailContext,
@@ -32,7 +32,7 @@ export interface ResourceUnmockable {
32
32
  export interface ResourceSpec<T, C = unknown> {
33
33
  /** Create the resource instance from stable process-scoped context. */
34
34
  readonly create: (
35
- svc: ResourceContext<C>
35
+ resourceCtx: ResourceContext<C>
36
36
  ) => Result<T, Error> | Promise<Result<T, Error>>;
37
37
  /** Config schema — when present, config is validated and passed to `create`. */
38
38
  readonly config?: z.ZodType<C> | undefined;
package/src/trail.ts CHANGED
@@ -86,6 +86,102 @@ export type BlazeInput<I, CI> = [CI] extends [never] ? I : I & CI;
86
86
 
87
87
  type TrailRef = string | { readonly id: string };
88
88
 
89
+ type ComposeSchemaOutput<TSchema extends z.ZodType | undefined> =
90
+ TSchema extends z.ZodType ? z.output<TSchema> : never;
91
+
92
+ type SchemaOwnedTrailSpec<
93
+ TInputSchema extends z.ZodType,
94
+ O,
95
+ TComposeInputSchema extends z.ZodType | undefined = undefined,
96
+ C extends readonly TrailRef[] | undefined = undefined,
97
+ > = Omit<
98
+ TrailSpec<
99
+ z.output<TInputSchema>,
100
+ O,
101
+ ComposeSchemaOutput<TComposeInputSchema>,
102
+ C
103
+ >,
104
+ 'blaze' | 'composeInput' | 'detours' | 'examples' | 'input' | 'versions'
105
+ > & {
106
+ /** Zod schema for validating caller input and materializing blaze input. */
107
+ readonly input: TInputSchema;
108
+ /** The pure function receives schema-materialized input after validation/defaults. */
109
+ readonly blaze: Implementation<
110
+ BlazeInput<
111
+ z.output<TInputSchema>,
112
+ ComposeSchemaOutput<TComposeInputSchema>
113
+ >,
114
+ O,
115
+ ComposeContextFor<C>
116
+ >;
117
+ /** Named examples use caller-side input; schema defaults may be omitted. */
118
+ readonly examples?:
119
+ | readonly TrailExample<z.input<TInputSchema>, O>[]
120
+ | undefined;
121
+ /** Recovery paths see the same materialized input as the blaze. */
122
+ readonly detours?:
123
+ | readonly Detour<z.output<TInputSchema>, O, TrailsError>[]
124
+ | undefined;
125
+ /** Composition-only schema, merged internally for ctx.compose() calls. */
126
+ readonly composeInput?: TComposeInputSchema | undefined;
127
+ /** Explicit historical trail versions. Current stays top-level. */
128
+ readonly versions?: TrailVersions<z.output<TInputSchema>, O> | undefined;
129
+ };
130
+
131
+ type SchemaOwnedOutputTrailSpec<
132
+ TInputSchema extends z.ZodType,
133
+ TOutputSchema extends z.ZodType,
134
+ TComposeInputSchema extends z.ZodType | undefined = undefined,
135
+ C extends readonly TrailRef[] | undefined = undefined,
136
+ > = Omit<
137
+ SchemaOwnedTrailSpec<
138
+ TInputSchema,
139
+ z.output<TOutputSchema>,
140
+ TComposeInputSchema,
141
+ C
142
+ >,
143
+ 'output'
144
+ > & {
145
+ readonly output: TOutputSchema;
146
+ };
147
+
148
+ type SchemaOwnedTrail<
149
+ TInputSchema extends z.ZodType,
150
+ O,
151
+ TComposeInputSchema extends z.ZodType | undefined,
152
+ > = Trail<
153
+ z.output<TInputSchema>,
154
+ O,
155
+ ComposeSchemaOutput<TComposeInputSchema>
156
+ > & {
157
+ readonly input: TInputSchema;
158
+ readonly composeInput?: TComposeInputSchema | undefined;
159
+ };
160
+
161
+ type LegacyOutputTrailSpec<
162
+ I,
163
+ O,
164
+ CI,
165
+ C extends readonly TrailRef[] | undefined,
166
+ > = Omit<TrailSpec<I, O, CI, C>, 'blaze' | 'output'> & {
167
+ readonly blaze: Implementation<
168
+ BlazeInput<I, CI>,
169
+ NoInfer<O>,
170
+ ComposeContextFor<C>
171
+ >;
172
+ readonly output: z.ZodType<O>;
173
+ };
174
+
175
+ type LegacyOutputlessTrailSpec<
176
+ I,
177
+ O,
178
+ CI,
179
+ C extends readonly TrailRef[] | undefined,
180
+ > = Omit<TrailSpec<I, O, CI, C>, 'blaze' | 'output'> & {
181
+ readonly blaze: Implementation<BlazeInput<I, CI>, O, ComposeContextFor<C>>;
182
+ readonly output?: undefined;
183
+ };
184
+
89
185
  // ---------------------------------------------------------------------------
90
186
  // Trail versioning
91
187
  // ---------------------------------------------------------------------------
@@ -1015,18 +1111,75 @@ const normalizeCollections = <
1015
1111
  * });
1016
1112
  * ```
1017
1113
  */
1114
+ export function trail<
1115
+ const TInputSchema extends z.ZodType,
1116
+ const TOutputSchema extends z.ZodType,
1117
+ const TComposeInputSchema extends z.ZodType | undefined = undefined,
1118
+ const C extends readonly TrailRef[] | undefined = undefined,
1119
+ >(
1120
+ id: string,
1121
+ spec: SchemaOwnedOutputTrailSpec<
1122
+ TInputSchema,
1123
+ TOutputSchema,
1124
+ TComposeInputSchema,
1125
+ C
1126
+ >
1127
+ ): SchemaOwnedTrail<TInputSchema, z.output<TOutputSchema>, TComposeInputSchema>;
1128
+ export function trail<
1129
+ const TInputSchema extends z.ZodType,
1130
+ const TOutputSchema extends z.ZodType,
1131
+ const TComposeInputSchema extends z.ZodType | undefined = undefined,
1132
+ const C extends readonly TrailRef[] | undefined = undefined,
1133
+ >(
1134
+ spec: SchemaOwnedOutputTrailSpec<
1135
+ TInputSchema,
1136
+ TOutputSchema,
1137
+ TComposeInputSchema,
1138
+ C
1139
+ > & {
1140
+ readonly id: string;
1141
+ }
1142
+ ): SchemaOwnedTrail<TInputSchema, z.output<TOutputSchema>, TComposeInputSchema>;
1143
+ export function trail<
1144
+ const TInputSchema extends z.ZodType,
1145
+ O,
1146
+ const TComposeInputSchema extends z.ZodType | undefined = undefined,
1147
+ const C extends readonly TrailRef[] | undefined = undefined,
1148
+ >(
1149
+ id: string,
1150
+ spec: SchemaOwnedTrailSpec<TInputSchema, O, TComposeInputSchema, C>
1151
+ ): SchemaOwnedTrail<TInputSchema, O, TComposeInputSchema>;
1152
+ export function trail<
1153
+ const TInputSchema extends z.ZodType,
1154
+ O,
1155
+ const TComposeInputSchema extends z.ZodType | undefined = undefined,
1156
+ const C extends readonly TrailRef[] | undefined = undefined,
1157
+ >(
1158
+ spec: SchemaOwnedTrailSpec<TInputSchema, O, TComposeInputSchema, C> & {
1159
+ readonly id: string;
1160
+ }
1161
+ ): SchemaOwnedTrail<TInputSchema, O, TComposeInputSchema>;
1018
1162
  export function trail<
1019
1163
  I,
1020
1164
  O,
1021
1165
  CI = never,
1022
1166
  const C extends readonly TrailRef[] | undefined = undefined,
1023
- >(id: string, spec: TrailSpec<I, O, CI, C>): Trail<I, O, CI>;
1167
+ >(
1168
+ id: string,
1169
+ spec:
1170
+ | LegacyOutputTrailSpec<I, O, CI, C>
1171
+ | LegacyOutputlessTrailSpec<I, O, CI, C>
1172
+ ): Trail<I, O, CI>;
1024
1173
  export function trail<
1025
1174
  I,
1026
1175
  O,
1027
1176
  CI = never,
1028
1177
  const C extends readonly TrailRef[] | undefined = undefined,
1029
- >(spec: TrailSpec<I, O, CI, C> & { readonly id: string }): Trail<I, O, CI>;
1178
+ >(
1179
+ spec:
1180
+ | (LegacyOutputTrailSpec<I, O, CI, C> & { readonly id: string })
1181
+ | (LegacyOutputlessTrailSpec<I, O, CI, C> & { readonly id: string })
1182
+ ): Trail<I, O, CI>;
1030
1183
  export function trail<
1031
1184
  I,
1032
1185
  O,
@@ -114,16 +114,17 @@ export const ingest = <
114
114
  id,
115
115
  transform
116
116
  );
117
- const baseTrail = trail(id, {
117
+ const baseSpec = {
118
118
  ...trailSpec,
119
- blaze: baseBlaze,
119
+ blaze: baseBlaze as TrailSpec<unknown, unknown>['blaze'],
120
120
  examples: deriveExamples(schema as ExampleBearingSchema<TSchema>, signalId),
121
121
  fires: [signal],
122
- input: schema as z.ZodType<SchemaValue<TSchema>>,
122
+ input: schema as z.ZodType<unknown>,
123
123
  intent: 'write',
124
124
  output: z.void(),
125
125
  pattern: 'ingest',
126
- }) as Trail<SchemaValue<TSchema>, void>;
126
+ } as TrailSpec<unknown, unknown>;
127
+ const baseTrail = trail(id, baseSpec) as Trail<SchemaValue<TSchema>, void>;
127
128
 
128
129
  if (verify === undefined) {
129
130
  return baseTrail;
package/src/type-utils.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import type { Result } from './result.js';
6
- import type { AnyTrail } from './trail.js';
6
+ import type { AnyTrail, Trail } from './trail.js';
7
7
  import type { Implementation } from './types.js';
8
8
  import type { z } from 'zod';
9
9
 
@@ -13,11 +13,31 @@ import type { z } from 'zod';
13
13
 
14
14
  /* oxlint-disable no-explicit-any -- `any` required for conditional type inference; `unknown` breaks inference */
15
15
 
16
+ type SchemaInputOrFallback<TSchema extends z.ZodType, TFallback> =
17
+ unknown extends z.input<TSchema> ? TFallback : z.input<TSchema>;
18
+
19
+ type ComposeSchemaOf<T extends AnyTrail> = T extends {
20
+ readonly composeInput?: (infer TComposeSchema) | undefined;
21
+ }
22
+ ? NonNullable<TComposeSchema>
23
+ : never;
24
+
25
+ type ComposeInputPart<T extends AnyTrail> =
26
+ ComposeSchemaOf<T> extends z.ZodType
27
+ ? T extends Trail<any, any, infer CI>
28
+ ? SchemaInputOrFallback<ComposeSchemaOf<T>, CI>
29
+ : z.input<ComposeSchemaOf<T>>
30
+ : T extends Trail<any, any, infer CI>
31
+ ? CI
32
+ : never;
33
+
16
34
  /** Extract the input type from a Trail. */
17
35
  export type TrailInput<T extends AnyTrail> = T extends {
18
- readonly input: z.ZodType<infer I>;
36
+ readonly input: infer TInputSchema extends z.ZodType;
19
37
  }
20
- ? I
38
+ ? T extends Trail<infer I, any, any>
39
+ ? SchemaInputOrFallback<TInputSchema, I>
40
+ : z.input<TInputSchema>
21
41
  : never;
22
42
 
23
43
  /** Extract the output type from a Trail. */
@@ -35,12 +55,11 @@ export type TrailOutput<T extends AnyTrail> = T extends {
35
55
  * merges both schemas so the compiler enforces the full shape at the call
36
56
  * site. Falls back to plain `TrailInput<T>` when no `composeInput` exists.
37
57
  */
38
- export type ComposeInput<T extends AnyTrail> =
39
- NonNullable<T['composeInput']> extends z.ZodType<infer CI>
40
- ? [CI] extends [never]
41
- ? TrailInput<T>
42
- : TrailInput<T> & CI
43
- : TrailInput<T>;
58
+ export type ComposeInput<T extends AnyTrail> = [ComposeInputPart<T>] extends [
59
+ never,
60
+ ]
61
+ ? TrailInput<T>
62
+ : TrailInput<T> & ComposeInputPart<T>;
44
63
 
45
64
  /**
46
65
  * Extracts the full `Result<Output, Error>` type from a trail definition.