@rcrsr/rill 0.16.0 → 0.18.0

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 (97) hide show
  1. package/README.md +37 -21
  2. package/dist/ast-nodes.d.ts +14 -4
  3. package/dist/ast-unions.d.ts +1 -1
  4. package/dist/constants.d.ts +1 -1
  5. package/dist/constants.js +1 -0
  6. package/dist/error-registry.js +228 -0
  7. package/dist/ext/crypto/index.d.ts +3 -3
  8. package/dist/ext/crypto/index.js +62 -59
  9. package/dist/ext/exec/index.d.ts +3 -3
  10. package/dist/ext/exec/index.js +15 -9
  11. package/dist/ext/fetch/index.d.ts +3 -3
  12. package/dist/ext/fetch/index.js +17 -12
  13. package/dist/ext/fetch/request.js +1 -1
  14. package/dist/ext/fs/index.d.ts +3 -3
  15. package/dist/ext/fs/index.js +256 -266
  16. package/dist/ext/fs/sandbox.d.ts +18 -0
  17. package/dist/ext/fs/sandbox.js +33 -0
  18. package/dist/ext/kv/index.d.ts +3 -3
  19. package/dist/ext/kv/index.js +198 -196
  20. package/dist/ext/kv/store.d.ts +1 -1
  21. package/dist/ext/kv/store.js +2 -1
  22. package/dist/ext-parse-bridge.d.ts +10 -0
  23. package/dist/ext-parse-bridge.js +10 -0
  24. package/dist/generated/introspection-data.d.ts +1 -1
  25. package/dist/generated/introspection-data.js +385 -296
  26. package/dist/generated/version-data.d.ts +1 -1
  27. package/dist/generated/version-data.js +2 -2
  28. package/dist/highlight-map.js +1 -0
  29. package/dist/index.d.ts +1 -4
  30. package/dist/index.js +1 -5
  31. package/dist/lexer/operators.js +1 -0
  32. package/dist/parser/helpers.js +1 -0
  33. package/dist/parser/parser-expr.js +44 -5
  34. package/dist/parser/parser-literals.js +111 -4
  35. package/dist/parser/parser-shape.js +2 -2
  36. package/dist/parser/parser-types.js +12 -0
  37. package/dist/parser/parser-use.js +26 -3
  38. package/dist/parser/parser.d.ts +2 -0
  39. package/dist/parser/parser.js +2 -0
  40. package/dist/runtime/core/callable.d.ts +24 -13
  41. package/dist/runtime/core/callable.js +71 -38
  42. package/dist/runtime/core/context.d.ts +2 -13
  43. package/dist/runtime/core/context.js +80 -79
  44. package/dist/runtime/core/eval/base.d.ts +2 -2
  45. package/dist/runtime/core/eval/base.js +2 -0
  46. package/dist/runtime/core/eval/evaluator.d.ts +1 -1
  47. package/dist/runtime/core/eval/index.d.ts +3 -3
  48. package/dist/runtime/core/eval/index.js +11 -0
  49. package/dist/runtime/core/eval/mixins/closures.js +381 -41
  50. package/dist/runtime/core/eval/mixins/collections.js +81 -6
  51. package/dist/runtime/core/eval/mixins/control-flow.js +1 -1
  52. package/dist/runtime/core/eval/mixins/conversion.js +61 -115
  53. package/dist/runtime/core/eval/mixins/core.js +17 -4
  54. package/dist/runtime/core/eval/mixins/expressions.js +36 -27
  55. package/dist/runtime/core/eval/mixins/extraction.js +2 -3
  56. package/dist/runtime/core/eval/mixins/list-dispatch.js +1 -1
  57. package/dist/runtime/core/eval/mixins/literals.js +17 -6
  58. package/dist/runtime/core/eval/mixins/types.js +73 -54
  59. package/dist/runtime/core/eval/mixins/variables.js +12 -8
  60. package/dist/runtime/core/execute.d.ts +1 -1
  61. package/dist/runtime/core/field-descriptor.d.ts +3 -3
  62. package/dist/runtime/core/field-descriptor.js +2 -1
  63. package/dist/runtime/core/introspection.d.ts +2 -2
  64. package/dist/runtime/core/introspection.js +7 -6
  65. package/dist/runtime/core/resolvers.d.ts +1 -1
  66. package/dist/runtime/core/signals.d.ts +6 -1
  67. package/dist/runtime/core/signals.js +9 -0
  68. package/dist/runtime/core/types/constructors.d.ts +54 -0
  69. package/dist/runtime/core/types/constructors.js +201 -0
  70. package/dist/runtime/core/types/guards.d.ts +42 -0
  71. package/dist/runtime/core/types/guards.js +88 -0
  72. package/dist/runtime/core/types/index.d.ts +18 -0
  73. package/dist/runtime/core/types/index.js +19 -0
  74. package/dist/runtime/core/types/markers.d.ts +12 -0
  75. package/dist/runtime/core/types/markers.js +7 -0
  76. package/dist/runtime/core/types/operations.d.ts +98 -0
  77. package/dist/runtime/core/types/operations.js +804 -0
  78. package/dist/runtime/core/types/registrations.d.ts +126 -0
  79. package/dist/runtime/core/types/registrations.js +751 -0
  80. package/dist/runtime/core/{types.d.ts → types/runtime.d.ts} +22 -10
  81. package/dist/runtime/core/types/structures.d.ts +146 -0
  82. package/dist/runtime/core/types/structures.js +12 -0
  83. package/dist/runtime/core/values.d.ts +29 -209
  84. package/dist/runtime/core/values.js +56 -968
  85. package/dist/runtime/ext/builtins.js +88 -68
  86. package/dist/runtime/ext/extensions.d.ts +31 -125
  87. package/dist/runtime/ext/extensions.js +2 -94
  88. package/dist/runtime/ext/test-context.d.ts +28 -0
  89. package/dist/runtime/ext/test-context.js +155 -0
  90. package/dist/runtime/index.d.ts +12 -12
  91. package/dist/runtime/index.js +13 -5
  92. package/dist/signature-parser.d.ts +2 -2
  93. package/dist/signature-parser.js +14 -14
  94. package/dist/token-types.d.ts +1 -0
  95. package/dist/token-types.js +1 -0
  96. package/package.json +1 -1
  97. /package/dist/runtime/core/{types.js → types/runtime.js} +0 -0
@@ -25,7 +25,10 @@
25
25
  * @internal
26
26
  */
27
27
  import { RuntimeError } from '../../../../types.js';
28
- import { anyTypeValue, deepEquals, formatValue, inferElementType, isReservedMethod, isTypeValue, isVector, } from '../../values.js';
28
+ import { deepEquals, formatValue } from '../../types/registrations.js';
29
+ import { isTypeValue, isVector } from '../../types/guards.js';
30
+ import { inferElementType } from '../../types/operations.js';
31
+ import { anyTypeValue, isReservedMethod } from '../../values.js';
29
32
  import { isCallable, } from '../../callable.js';
30
33
  import { getVariable } from '../../context.js';
31
34
  /**
@@ -642,13 +645,13 @@ function createLiteralsMixin(Base) {
642
645
  if (resolvedType === undefined && defaultValue !== undefined) {
643
646
  const defaultKind = typeof defaultValue;
644
647
  if (defaultKind === 'string') {
645
- resolvedType = { type: 'string' };
648
+ resolvedType = { kind: 'string' };
646
649
  }
647
650
  else if (defaultKind === 'number') {
648
- resolvedType = { type: 'number' };
651
+ resolvedType = { kind: 'number' };
649
652
  }
650
653
  else if (defaultKind === 'boolean') {
651
- resolvedType = { type: 'bool' };
654
+ resolvedType = { kind: 'bool' };
652
655
  }
653
656
  }
654
657
  // Evaluate per-param annotations inline
@@ -667,12 +670,20 @@ function createLiteralsMixin(Base) {
667
670
  }
668
671
  const isProperty = rillParams.length === 0;
669
672
  // Evaluate returnTypeTarget at closure creation time (IR-4).
673
+ // TypeConstructorNode → resolve via evaluateTypeConstructor() (e.g., stream(T):R).
670
674
  // TypeRef → resolve via resolveTypeRef() — returns RillTypeValue.
671
675
  // Absent → returnType defaults to anyTypeValue (omission implies :any, AC-17, AC-18, AC-19).
672
676
  let returnType = anyTypeValue;
673
677
  if (node.returnTypeTarget !== undefined) {
674
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
675
- returnType = await this.resolveTypeRef(node.returnTypeTarget, (name) => getVariable(this.ctx, name));
678
+ if ('type' in node.returnTypeTarget &&
679
+ node.returnTypeTarget.type === 'TypeConstructor') {
680
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
681
+ returnType = await this.evaluateTypeConstructor(node.returnTypeTarget);
682
+ }
683
+ else {
684
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
685
+ returnType = await this.resolveTypeRef(node.returnTypeTarget, (name) => getVariable(this.ctx, name));
686
+ }
676
687
  }
677
688
  return {
678
689
  __type: 'callable',
@@ -23,21 +23,11 @@
23
23
  * @internal
24
24
  */
25
25
  import { RuntimeError } from '../../../../types.js';
26
- import { inferType, checkType, isTypeValue, structuralTypeMatches, inferStructuralType, formatStructuralType, } from '../../values.js';
26
+ import { inferType } from '../../types/registrations.js';
27
+ import { isTypeValue } from '../../types/guards.js';
28
+ import { structureMatches, inferStructure, formatStructure, } from '../../types/operations.js';
29
+ import { checkType, structureToTypeValue } from '../../values.js';
27
30
  import { getVariable } from '../../context.js';
28
- /**
29
- * Leaf types that reject all type arguments.
30
- * Extracted as module-level constant to avoid per-call allocation.
31
- */
32
- const LEAF_TYPES = new Set([
33
- 'string',
34
- 'number',
35
- 'bool',
36
- 'vector',
37
- 'type',
38
- 'any',
39
- 'closure',
40
- ]);
41
31
  /**
42
32
  * TypesMixin implementation.
43
33
  *
@@ -87,7 +77,7 @@ function createTypesMixin(Base) {
87
77
  throw new RuntimeError('RILL-R004', 'list() requires exactly 1 type argument', location);
88
78
  }
89
79
  const element = await resolveArg(args[0]);
90
- const structure = { type: 'list', element };
80
+ const structure = { kind: 'list', element };
91
81
  return Object.freeze({
92
82
  __rill_type: true,
93
83
  typeName: name,
@@ -107,11 +97,11 @@ function createTypesMixin(Base) {
107
97
  // EC-B6: Default type mismatch on uniform single-arg path
108
98
  if (positional[0].defaultValue !== undefined) {
109
99
  const defaultVal = await evaluateDefault(positional[0].defaultValue);
110
- if (!structuralTypeMatches(defaultVal, valueType)) {
111
- throw new RuntimeError('RILL-R004', `Default value for ${name} element must be ${formatStructuralType(valueType)}, got ${inferType(defaultVal)}`, location);
100
+ if (!structureMatches(defaultVal, valueType)) {
101
+ throw new RuntimeError('RILL-R004', `Default value for ${name} element must be ${formatStructure(valueType)}, got ${inferType(defaultVal)}`, location);
112
102
  }
113
103
  }
114
- const structure = { type: name, valueType };
104
+ const structure = { kind: name, valueType };
115
105
  return Object.freeze({
116
106
  __rill_type: true,
117
107
  typeName: name,
@@ -131,14 +121,14 @@ function createTypesMixin(Base) {
131
121
  if (arg.defaultValue !== undefined) {
132
122
  const defaultVal = await evaluateDefault(arg.defaultValue);
133
123
  // EC-B6: Default type mismatch
134
- if (!structuralTypeMatches(defaultVal, resolvedType)) {
135
- throw new RuntimeError('RILL-R004', `Default value for field '${arg.name}' must be ${formatStructuralType(resolvedType)}, got ${inferType(defaultVal)}`, location);
124
+ if (!structureMatches(defaultVal, resolvedType)) {
125
+ throw new RuntimeError('RILL-R004', `Default value for field '${arg.name}' must be ${formatStructure(resolvedType)}, got ${inferType(defaultVal)}`, location);
136
126
  }
137
127
  fieldDef.defaultValue = defaultVal;
138
128
  }
139
129
  fields[arg.name] = fieldDef;
140
130
  }
141
- const structure = { type: 'dict', fields };
131
+ const structure = { kind: 'dict', fields };
142
132
  return Object.freeze({
143
133
  __rill_type: true,
144
134
  typeName: name,
@@ -156,14 +146,17 @@ function createTypesMixin(Base) {
156
146
  if (arg.defaultValue !== undefined) {
157
147
  const defaultVal = await evaluateDefault(arg.defaultValue);
158
148
  // EC-B6: Default type mismatch
159
- if (!structuralTypeMatches(defaultVal, resolvedType)) {
160
- throw new RuntimeError('RILL-R004', `Default value for field '${arg.name}' must be ${formatStructuralType(resolvedType)}, got ${inferType(defaultVal)}`, location);
149
+ if (!structureMatches(defaultVal, resolvedType)) {
150
+ throw new RuntimeError('RILL-R004', `Default value for field '${arg.name}' must be ${formatStructure(resolvedType)}, got ${inferType(defaultVal)}`, location);
161
151
  }
162
152
  fieldDef.defaultValue = defaultVal;
163
153
  }
164
154
  orderedFields.push(fieldDef);
165
155
  }
166
- const structure = { type: 'ordered', fields: orderedFields };
156
+ const structure = {
157
+ kind: 'ordered',
158
+ fields: orderedFields,
159
+ };
167
160
  return Object.freeze({
168
161
  __rill_type: true,
169
162
  typeName: name,
@@ -183,11 +176,11 @@ function createTypesMixin(Base) {
183
176
  // EC-B6: Default type mismatch on uniform single-arg path
184
177
  if (args[0].defaultValue !== undefined) {
185
178
  const defaultVal = await evaluateDefault(args[0].defaultValue);
186
- if (!structuralTypeMatches(defaultVal, valueType)) {
187
- throw new RuntimeError('RILL-R004', `Default value for tuple element must be ${formatStructuralType(valueType)}, got ${inferType(defaultVal)}`, location);
179
+ if (!structureMatches(defaultVal, valueType)) {
180
+ throw new RuntimeError('RILL-R004', `Default value for tuple element must be ${formatStructure(valueType)}, got ${inferType(defaultVal)}`, location);
188
181
  }
189
182
  }
190
- const structure = { type: 'tuple', valueType };
183
+ const structure = { kind: 'tuple', valueType };
191
184
  return Object.freeze({
192
185
  __rill_type: true,
193
186
  typeName: 'tuple',
@@ -202,8 +195,8 @@ function createTypesMixin(Base) {
202
195
  if (arg.defaultValue !== undefined) {
203
196
  const defaultVal = await evaluateDefault(arg.defaultValue);
204
197
  // EC-B6: Default type mismatch
205
- if (!structuralTypeMatches(defaultVal, resolvedType)) {
206
- throw new RuntimeError('RILL-R004', `Default value for tuple element must be ${formatStructuralType(resolvedType)}, got ${inferType(defaultVal)}`, location);
198
+ if (!structureMatches(defaultVal, resolvedType)) {
199
+ throw new RuntimeError('RILL-R004', `Default value for tuple element must be ${formatStructure(resolvedType)}, got ${inferType(defaultVal)}`, location);
207
200
  }
208
201
  fieldDef.defaultValue = defaultVal;
209
202
  }
@@ -221,7 +214,7 @@ function createTypesMixin(Base) {
221
214
  throw new RuntimeError('RILL-R004', `tuple() default values must be trailing: element at position ${i} has no default but a preceding element does`, location);
222
215
  }
223
216
  }
224
- const structure = { type: 'tuple', elements };
217
+ const structure = { kind: 'tuple', elements };
225
218
  return Object.freeze({
226
219
  __rill_type: true,
227
220
  typeName: 'tuple',
@@ -254,13 +247,26 @@ function createTypesMixin(Base) {
254
247
  return Object.freeze({
255
248
  __rill_type: true,
256
249
  typeName,
257
- structure: { type: typeName },
250
+ structure: { kind: typeName },
258
251
  });
259
252
  }
260
- // EC-B1: Leaf types reject all type arguments
261
- if (LEAF_TYPES.has(typeName)) {
253
+ // EC-B1: Leaf types reject all type arguments (AC-4: derived from registrations)
254
+ if (this.ctx.leafTypes.has(typeName)) {
262
255
  throw new RuntimeError('RILL-R004', `${typeName} does not accept type arguments`);
263
256
  }
257
+ // Stream type: extract chunk/ret from args if present
258
+ if (typeName === 'stream') {
259
+ const streamStructure = { kind: 'stream' };
260
+ if (args.length > 0 && args[0] !== undefined) {
261
+ const chunkResolved = await this.resolveTypeRef(args[0].value, getVariableFn);
262
+ streamStructure.chunk = chunkResolved.structure;
263
+ }
264
+ if (args.length > 1 && args[1] !== undefined) {
265
+ const retResolved = await this.resolveTypeRef(args[1].value, getVariableFn);
266
+ streamStructure.ret = retResolved.structure;
267
+ }
268
+ return structureToTypeValue(streamStructure);
269
+ }
264
270
  // Delegate to buildCollectionType with recursive resolveTypeRef
265
271
  return this.buildCollectionType(typeName, args, async (arg) => {
266
272
  const resolved = await this.resolveTypeRef(arg.value, getVariableFn);
@@ -271,7 +277,7 @@ function createTypesMixin(Base) {
271
277
  });
272
278
  }
273
279
  // Union type ref: (A | B) -- resolve each member recursively and
274
- // return a RillTypeValue with structure: { type: 'union', members: [...] }.
280
+ // return a RillTypeValue with structure: { kind: 'union', members: [...] }.
275
281
  // typeName is set to a display string for error messages; the structure
276
282
  // field carries the authoritative type shape for validation (DR-1).
277
283
  if (typeRef.kind === 'union') {
@@ -280,9 +286,9 @@ function createTypesMixin(Base) {
280
286
  const resolved = await this.resolveTypeRef(member, getVariableFn);
281
287
  members.push(resolved.structure);
282
288
  }
283
- const structure = { type: 'union', members };
289
+ const structure = { kind: 'union', members };
284
290
  const displayName = members
285
- .map(formatStructuralType)
291
+ .map(formatStructure)
286
292
  .join('|');
287
293
  return Object.freeze({
288
294
  __rill_type: true,
@@ -301,13 +307,13 @@ function createTypesMixin(Base) {
301
307
  /**
302
308
  * Assert that a value is of the expected type.
303
309
  * Returns the value unchanged if assertion passes, throws on mismatch.
304
- * Accepts a bare RillTypeName or a full RillType.
305
- * When expected is a RillType with sub-fields (element, fields, elements),
306
- * dispatches to structuralTypeMatches for deep validation.
310
+ * Accepts a bare RillTypeName or a full TypeStructure.
311
+ * When expected is a TypeStructure with sub-fields (element, fields, elements),
312
+ * dispatches to structureMatches for deep validation.
307
313
  * Exported for use by type assertion evaluation.
308
314
  */
309
315
  assertType(value, expected, location) {
310
- // Structural path: expected is a RillType object
316
+ // Structural path: expected is a TypeStructure object
311
317
  if (typeof expected !== 'string') {
312
318
  const hasSubFields = 'element' in expected ||
313
319
  'fields' in expected ||
@@ -315,15 +321,15 @@ function createTypesMixin(Base) {
315
321
  'members' in expected ||
316
322
  'valueType' in expected;
317
323
  if (hasSubFields) {
318
- if (!structuralTypeMatches(value, expected)) {
319
- const expectedStr = formatStructuralType(expected);
320
- const actualStr = formatStructuralType(inferStructuralType(value));
324
+ if (!structureMatches(value, expected)) {
325
+ const expectedStr = formatStructure(expected);
326
+ const actualStr = formatStructure(inferStructure(value));
321
327
  throw new RuntimeError('RILL-R004', `Type assertion failed: expected ${expectedStr}, got ${actualStr}`, location, { expectedType: expectedStr, actualType: actualStr });
322
328
  }
323
329
  return value;
324
330
  }
325
331
  // Bare structural type (no sub-fields): fall through using type name
326
- expected = expected.type;
332
+ expected = expected.kind;
327
333
  }
328
334
  // Bare type name path
329
335
  if (expected === 'any')
@@ -366,7 +372,7 @@ function createTypesMixin(Base) {
366
372
  'members' in resolved.structure ||
367
373
  'valueType' in resolved.structure;
368
374
  if (hasSubFields) {
369
- return structuralTypeMatches(value, resolved.structure);
375
+ return structureMatches(value, resolved.structure);
370
376
  }
371
377
  return checkType(value, resolved.typeName);
372
378
  }
@@ -407,11 +413,24 @@ function createTypesMixin(Base) {
407
413
  async evaluateTypeConstructor(node) {
408
414
  const name = node.constructorName;
409
415
  const location = node.span.start;
416
+ // Stream type constructor: extract chunk type (arg 0) and ret type (arg 1)
417
+ if (name === 'stream') {
418
+ const streamStructure = { kind: 'stream' };
419
+ if (node.args.length > 0 && node.args[0] !== undefined) {
420
+ const chunkResolved = await this.resolveTypeRef(node.args[0].value, (varName) => getVariable(this.ctx, varName));
421
+ streamStructure.chunk = chunkResolved.structure;
422
+ }
423
+ if (node.args.length > 1 && node.args[1] !== undefined) {
424
+ const retResolved = await this.resolveTypeRef(node.args[1].value, (varName) => getVariable(this.ctx, varName));
425
+ streamStructure.ret = retResolved.structure;
426
+ }
427
+ return structureToTypeValue(streamStructure);
428
+ }
410
429
  return this.buildCollectionType(name, node.args, async (arg) => {
411
430
  const resolved = await this.resolveTypeRef(arg.value, (varName) => getVariable(this.ctx, varName));
412
- return resolved.structure.type === 'any' &&
431
+ return resolved.structure.kind === 'any' &&
413
432
  resolved.typeName !== 'any'
414
- ? { type: resolved.typeName }
433
+ ? { kind: resolved.typeName }
415
434
  : resolved.structure;
416
435
  }, async (node) => {
417
436
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -422,7 +441,7 @@ function createTypesMixin(Base) {
422
441
  * Evaluate a closure signature literal into a RillTypeValue [IR-8].
423
442
  *
424
443
  * Creates a closure type value from |param: T, ...|: R syntax.
425
- * Each parameter produces a [name, RillType] entry.
444
+ * Each parameter produces a [name, TypeStructure] entry.
426
445
  *
427
446
  * Error contracts:
428
447
  * - EC-8: missing return type -> RILL-R004 (enforced at parse time; node always has returnType)
@@ -430,14 +449,14 @@ function createTypesMixin(Base) {
430
449
  */
431
450
  async evaluateClosureSigLiteral(node) {
432
451
  const location = node.span.start;
433
- // Helper: evaluate a type expression and extract RillType
452
+ // Helper: evaluate a type expression and extract TypeStructure
434
453
  const resolveTypeExpr = async (argVal) => {
435
454
  if (!isTypeValue(argVal)) {
436
455
  throw new RuntimeError('RILL-R004', `Parameter type must be a type value, got ${inferType(argVal)}`, location);
437
456
  }
438
- return argVal.structure.type === 'any' &&
457
+ return argVal.structure.kind === 'any' &&
439
458
  argVal.typeName !== 'any'
440
- ? { type: argVal.typeName }
459
+ ? { kind: argVal.typeName }
441
460
  : argVal.structure;
442
461
  };
443
462
  // Evaluate parameter types
@@ -456,11 +475,11 @@ function createTypesMixin(Base) {
456
475
  if (!isTypeValue(retVal)) {
457
476
  throw new RuntimeError('RILL-R004', `Closure type literal requires return type after |, got ${inferType(retVal)}`, location);
458
477
  }
459
- const ret = retVal.structure.type === 'any' &&
478
+ const ret = retVal.structure.kind === 'any' &&
460
479
  retVal.typeName !== 'any'
461
- ? { type: retVal.typeName }
480
+ ? { kind: retVal.typeName }
462
481
  : retVal.structure;
463
- const structure = { type: 'closure', params, ret };
482
+ const structure = { kind: 'closure', params, ret };
464
483
  return Object.freeze({
465
484
  __rill_type: true,
466
485
  typeName: 'closure',
@@ -31,7 +31,9 @@
31
31
  * @internal
32
32
  */
33
33
  import { RuntimeError } from '../../../../types.js';
34
- import { formatStructuralType, inferType, isTypeValue, structuralTypeMatches, } from '../../values.js';
34
+ import { inferType } from '../../types/registrations.js';
35
+ import { isTypeValue } from '../../types/guards.js';
36
+ import { formatStructure, structureMatches } from '../../types/operations.js';
35
37
  import { getVariable, hasVariable } from '../../context.js';
36
38
  import { isDict, isCallable } from '../../callable.js';
37
39
  /**
@@ -69,8 +71,8 @@ function createVariablesMixin(Base) {
69
71
  if (explicitType !== undefined) {
70
72
  if (typeof explicitType === 'object') {
71
73
  // Structural type check
72
- if (!structuralTypeMatches(value, explicitType)) {
73
- const expectedLabel = formatStructuralType(explicitType);
74
+ if (!structureMatches(value, explicitType)) {
75
+ const expectedLabel = formatStructure(explicitType);
74
76
  throw new RuntimeError('RILL-R001', `Type mismatch: cannot assign ${valueType} to $${name}:${expectedLabel}`, location, {
75
77
  variableName: name,
76
78
  expectedType: expectedLabel,
@@ -98,8 +100,8 @@ function createVariablesMixin(Base) {
98
100
  if (lockedType !== undefined && lockedType !== 'any') {
99
101
  if (typeof lockedType === 'object') {
100
102
  // Structural locked type — validate full shape
101
- if (!structuralTypeMatches(value, lockedType)) {
102
- const expectedLabel = formatStructuralType(lockedType);
103
+ if (!structureMatches(value, lockedType)) {
104
+ const expectedLabel = formatStructure(lockedType);
103
105
  throw new RuntimeError('RILL-R001', `Type mismatch: cannot assign ${valueType} to $${name} (locked as ${expectedLabel})`, location, {
104
106
  variableName: name,
105
107
  expectedType: expectedLabel,
@@ -120,7 +122,9 @@ function createVariablesMixin(Base) {
120
122
  if (!this.ctx.variableTypes.has(name)) {
121
123
  // Store structural type (object) directly so re-assignment checks
122
124
  // validate the full shape. Fall back to valueType when no annotation.
123
- const lockType = explicitType !== undefined ? explicitType : valueType;
125
+ const lockType = explicitType !== undefined
126
+ ? explicitType
127
+ : valueType;
124
128
  this.ctx.variableTypes.set(name, lockType);
125
129
  }
126
130
  }
@@ -260,7 +264,7 @@ function createVariablesMixin(Base) {
260
264
  value = value.typeName;
261
265
  }
262
266
  else if (field === 'signature') {
263
- value = formatStructuralType(value.structure);
267
+ value = formatStructure(value.structure);
264
268
  }
265
269
  else {
266
270
  throw new RuntimeError('RILL-R003', `Type value has no property "${field}"`, this.getNodeLocation(node));
@@ -322,7 +326,7 @@ function createVariablesMixin(Base) {
322
326
  return true;
323
327
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
324
328
  const resolved = await this.resolveTypeRef(typeRef, (name) => getVariable(this.ctx, name));
325
- return structuralTypeMatches(fieldValue, resolved.structure);
329
+ return structureMatches(fieldValue, resolved.structure);
326
330
  };
327
331
  if (finalAccess.kind === 'literal') {
328
332
  // Check if literal field exists in dict
@@ -5,7 +5,7 @@
5
5
  * Provides both full execution and step-by-step execution.
6
6
  */
7
7
  import type { ScriptNode } from '../../types.js';
8
- import type { ExecutionResult, ExecutionStepper, RuntimeContext } from './types.js';
8
+ import type { ExecutionResult, ExecutionStepper, RuntimeContext } from './types/runtime.js';
9
9
  /**
10
10
  * Execute a parsed Rill script.
11
11
  *
@@ -8,7 +8,7 @@
8
8
  * @internal
9
9
  */
10
10
  import type { SourceLocation } from '../../types.js';
11
- import type { RillFieldDef, RillType } from './values.js';
11
+ import type { RillFieldDef, TypeStructure } from './types/structures.js';
12
12
  /**
13
13
  * Field descriptor — carries field name and structural type when accessing a
14
14
  * dict-kind RillType field.
@@ -23,6 +23,6 @@ export interface RillFieldDescriptor {
23
23
  *
24
24
  * EC-1: Throws RILL-R003 when fieldName is absent from structuralType.fields.
25
25
  */
26
- export declare function buildFieldDescriptor(structuralType: RillType & {
27
- type: 'dict';
26
+ export declare function buildFieldDescriptor(structuralType: TypeStructure & {
27
+ kind: 'dict';
28
28
  }, fieldName: string, location: SourceLocation): RillFieldDescriptor;
@@ -14,7 +14,8 @@ import { RuntimeError } from '../../types.js';
14
14
  * EC-1: Throws RILL-R003 when fieldName is absent from structuralType.fields.
15
15
  */
16
16
  export function buildFieldDescriptor(structuralType, fieldName, location) {
17
- const fieldType = structuralType.fields?.[fieldName];
17
+ const fields = structuralType.fields;
18
+ const fieldType = fields?.[fieldName];
18
19
  if (fieldType === undefined) {
19
20
  throw new RuntimeError('RILL-R003', `Shape has no field "${fieldName}"`, location);
20
21
  }
@@ -4,8 +4,8 @@
4
4
  * Functions for inspecting runtime context at runtime.
5
5
  * These enable host applications to discover available functions and their signatures.
6
6
  */
7
- import type { RuntimeContext } from './types.js';
8
- import type { RillValue } from './values.js';
7
+ import type { RuntimeContext } from './types/runtime.js';
8
+ import type { RillValue } from './types/structures.js';
9
9
  /**
10
10
  * Metadata describing a function's signature and documentation.
11
11
  * Returned by introspection APIs like getFunctions().
@@ -4,7 +4,8 @@
4
4
  * Functions for inspecting runtime context at runtime.
5
5
  * These enable host applications to discover available functions and their signatures.
6
6
  */
7
- import { formatStructuralType, formatValue } from './values.js';
7
+ import { formatStructure } from './types/operations.js';
8
+ import { formatValue } from './types/registrations.js';
8
9
  import { isApplicationCallable, isRuntimeCallable, isScriptCallable, } from './callable.js';
9
10
  import { LANGUAGE_REFERENCE } from '../../generated/introspection-data.js';
10
11
  import { BUILTIN_FUNCTIONS } from '../ext/builtins.js';
@@ -40,7 +41,7 @@ export function getFunctions(ctx) {
40
41
  if (callable.params) {
41
42
  const params = callable.params.map((p) => ({
42
43
  name: p.name,
43
- type: p.type !== undefined ? formatStructuralType(p.type) : 'any',
44
+ type: p.type !== undefined ? formatStructure(p.type) : 'any',
44
45
  description: typeof p.annotations['description'] === 'string'
45
46
  ? p.annotations['description']
46
47
  : '',
@@ -50,7 +51,7 @@ export function getFunctions(ctx) {
50
51
  name,
51
52
  description: callable.annotations?.['description'] ?? '',
52
53
  params,
53
- returnType: formatStructuralType(callable.returnType.structure),
54
+ returnType: formatStructure(callable.returnType.structure),
54
55
  });
55
56
  }
56
57
  else {
@@ -93,7 +94,7 @@ export function getFunctions(ctx) {
93
94
  // Convert params to ParamMetadata using RillParam.type (IC-5)
94
95
  const params = value.params.map((p) => ({
95
96
  name: p.name,
96
- type: p.type !== undefined ? formatStructuralType(p.type) : 'any',
97
+ type: p.type !== undefined ? formatStructure(p.type) : 'any',
97
98
  description: typeof p.annotations['description'] === 'string'
98
99
  ? p.annotations['description']
99
100
  : '',
@@ -131,7 +132,7 @@ function serializeParam(p) {
131
132
  parts.push(`^(description: "${desc}") `);
132
133
  }
133
134
  // Name and type
134
- const typeName = p.type !== undefined ? formatStructuralType(p.type) : 'any';
135
+ const typeName = p.type !== undefined ? formatStructure(p.type) : 'any';
135
136
  parts.push(`${p.name}: ${typeName}`);
136
137
  // Default value
137
138
  if (p.defaultValue !== undefined) {
@@ -189,7 +190,7 @@ export function generateManifest(ctx) {
189
190
  if (!isApplicationCallable(callable) || callable.params === undefined) {
190
191
  continue;
191
192
  }
192
- const signature = serializeClosureSignature(callable.params, formatStructuralType(callable.returnType.structure), callable.annotations?.['description'] ?? undefined);
193
+ const signature = serializeClosureSignature(callable.params, formatStructure(callable.returnType.structure), callable.annotations?.['description'] ?? undefined);
193
194
  entries.push(` "${name}": ${signature}`);
194
195
  }
195
196
  if (entries.length === 0) {
@@ -4,7 +4,7 @@
4
4
  * moduleResolver — reads Rill source files from the filesystem.
5
5
  * extResolver — returns extension values from a host-provided config map.
6
6
  */
7
- import type { SchemeResolver } from './types.js';
7
+ import type { SchemeResolver } from './types/runtime.js';
8
8
  /**
9
9
  * Resolves a module ID to Rill source text by reading a file.
10
10
  *
@@ -5,7 +5,7 @@
5
5
  * These are part of the public API for host applications that
6
6
  * need to catch and handle control flow.
7
7
  */
8
- import type { RillValue } from './values.js';
8
+ import type { RillValue } from './types/structures.js';
9
9
  /** Signal thrown by `break` to exit loops */
10
10
  export declare class BreakSignal extends Error {
11
11
  readonly value: RillValue;
@@ -16,3 +16,8 @@ export declare class ReturnSignal extends Error {
16
16
  readonly value: RillValue;
17
17
  constructor(value: RillValue);
18
18
  }
19
+ /** Signal thrown when a stream yields a chunk value */
20
+ export declare class YieldSignal extends Error {
21
+ readonly value: RillValue;
22
+ constructor(value: RillValue);
23
+ }
@@ -23,3 +23,12 @@ export class ReturnSignal extends Error {
23
23
  this.name = 'ReturnSignal';
24
24
  }
25
25
  }
26
+ /** Signal thrown when a stream yields a chunk value */
27
+ export class YieldSignal extends Error {
28
+ value;
29
+ constructor(value) {
30
+ super('yield');
31
+ this.value = value;
32
+ this.name = 'YieldSignal';
33
+ }
34
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Value Constructors
3
+ *
4
+ * Factory functions for creating Rill compound values (tuples, ordered,
5
+ * vectors) and collection utilities (emptyForType, copyValue).
6
+ *
7
+ * Import constraints:
8
+ * - Imports from ./structures.js and ./guards.js
9
+ * - No imports from values.ts or callable.ts
10
+ */
11
+ import type { RillOrdered, RillStream, RillTuple, RillValue, RillVector, TypeStructure } from './structures.js';
12
+ /**
13
+ * Create ordered from entries array (named, preserves insertion order).
14
+ * Entries may be 2-element [name, value] or 3-element [name, value, default]
15
+ * tuples; the third element carries a default value for `.^input` reflection.
16
+ */
17
+ export declare function createOrdered(entries: [string, RillValue, RillValue?][]): RillOrdered;
18
+ /** Create tuple from entries array (positional, preserves order) */
19
+ export declare function createTuple(entries: RillValue[]): RillTuple;
20
+ /**
21
+ * Create vector from Float32Array with model name.
22
+ * @throws {RuntimeError} RILL-R074 if data.length is 0 (zero-dimension vectors not allowed)
23
+ */
24
+ export declare function createVector(data: Float32Array, model: string): RillVector;
25
+ /**
26
+ * Create an empty collection value matching the given TypeStructure.
27
+ * Assumes the type is dict, ordered, or tuple.
28
+ */
29
+ export declare function emptyForType(type: TypeStructure): RillValue;
30
+ /**
31
+ * Create a RillStream from an AsyncIterable of chunks and a resolve function.
32
+ *
33
+ * The stream is a linked-list of steps. Each `.next` call advances to the
34
+ * next chunk. Once exhausted, `done` becomes true and re-iteration throws
35
+ * RILL-R002. The `resolve` function is called after chunk exhaustion (or on
36
+ * direct invocation) and caches its result for idempotent access.
37
+ *
38
+ * @throws {RuntimeError} RILL-R003 if chunks is not an AsyncIterable
39
+ * @throws {RuntimeError} RILL-R003 if resolve is not a function
40
+ */
41
+ export declare function createRillStream(options: {
42
+ chunks: AsyncIterable<RillValue>;
43
+ resolve: () => Promise<RillValue>;
44
+ dispose?: (() => void) | undefined;
45
+ chunkType?: TypeStructure | undefined;
46
+ retType?: TypeStructure | undefined;
47
+ }): RillStream;
48
+ /**
49
+ * Copy a RillValue.
50
+ * Primitives and immutable compound values return the same reference.
51
+ * Mutable values (list, dict) copy recursively.
52
+ * Iterators return the same reference (not meaningfully copyable).
53
+ */
54
+ export declare function copyValue(value: RillValue): RillValue;