@rcrsr/rill 0.17.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 (83) hide show
  1. package/dist/ast-nodes.d.ts +14 -4
  2. package/dist/ast-unions.d.ts +1 -1
  3. package/dist/constants.d.ts +1 -1
  4. package/dist/constants.js +1 -0
  5. package/dist/error-registry.js +228 -0
  6. package/dist/ext/crypto/index.js +5 -5
  7. package/dist/ext/exec/index.js +3 -3
  8. package/dist/ext/fetch/index.js +4 -4
  9. package/dist/ext/fetch/request.js +1 -1
  10. package/dist/ext/fs/index.js +101 -114
  11. package/dist/ext/fs/sandbox.d.ts +18 -0
  12. package/dist/ext/fs/sandbox.js +33 -0
  13. package/dist/ext/kv/index.js +12 -12
  14. package/dist/ext/kv/store.d.ts +1 -1
  15. package/dist/ext/kv/store.js +1 -1
  16. package/dist/generated/version-data.d.ts +1 -1
  17. package/dist/generated/version-data.js +2 -2
  18. package/dist/highlight-map.js +1 -0
  19. package/dist/index.d.ts +1 -15
  20. package/dist/index.js +1 -14
  21. package/dist/lexer/operators.js +1 -0
  22. package/dist/parser/helpers.js +1 -0
  23. package/dist/parser/parser-expr.js +44 -5
  24. package/dist/parser/parser-literals.js +111 -4
  25. package/dist/parser/parser-shape.js +2 -2
  26. package/dist/parser/parser-use.js +19 -2
  27. package/dist/parser/parser.d.ts +2 -0
  28. package/dist/parser/parser.js +2 -0
  29. package/dist/runtime/core/callable.d.ts +5 -6
  30. package/dist/runtime/core/callable.js +10 -17
  31. package/dist/runtime/core/context.d.ts +2 -2
  32. package/dist/runtime/core/context.js +8 -8
  33. package/dist/runtime/core/eval/base.d.ts +2 -2
  34. package/dist/runtime/core/eval/base.js +2 -0
  35. package/dist/runtime/core/eval/evaluator.d.ts +1 -1
  36. package/dist/runtime/core/eval/index.d.ts +2 -2
  37. package/dist/runtime/core/eval/mixins/closures.js +367 -27
  38. package/dist/runtime/core/eval/mixins/collections.js +81 -6
  39. package/dist/runtime/core/eval/mixins/control-flow.js +1 -1
  40. package/dist/runtime/core/eval/mixins/conversion.js +17 -12
  41. package/dist/runtime/core/eval/mixins/core.js +15 -2
  42. package/dist/runtime/core/eval/mixins/expressions.js +3 -2
  43. package/dist/runtime/core/eval/mixins/extraction.js +2 -3
  44. package/dist/runtime/core/eval/mixins/list-dispatch.js +1 -1
  45. package/dist/runtime/core/eval/mixins/literals.js +14 -3
  46. package/dist/runtime/core/eval/mixins/types.js +30 -1
  47. package/dist/runtime/core/eval/mixins/variables.js +3 -1
  48. package/dist/runtime/core/execute.d.ts +1 -1
  49. package/dist/runtime/core/field-descriptor.d.ts +1 -1
  50. package/dist/runtime/core/introspection.d.ts +2 -2
  51. package/dist/runtime/core/introspection.js +2 -1
  52. package/dist/runtime/core/resolvers.d.ts +1 -1
  53. package/dist/runtime/core/signals.d.ts +6 -1
  54. package/dist/runtime/core/signals.js +9 -0
  55. package/dist/runtime/core/types/constructors.d.ts +54 -0
  56. package/dist/runtime/core/types/constructors.js +201 -0
  57. package/dist/runtime/core/types/guards.d.ts +42 -0
  58. package/dist/runtime/core/types/guards.js +88 -0
  59. package/dist/runtime/core/types/index.d.ts +18 -0
  60. package/dist/runtime/core/types/index.js +19 -0
  61. package/dist/runtime/core/types/operations.d.ts +98 -0
  62. package/dist/runtime/core/types/operations.js +804 -0
  63. package/dist/runtime/core/{type-registrations.d.ts → types/registrations.d.ts} +12 -22
  64. package/dist/runtime/core/{type-registrations.js → types/registrations.js} +94 -92
  65. package/dist/runtime/core/{types.d.ts → types/runtime.d.ts} +8 -8
  66. package/dist/runtime/core/{type-structures.d.ts → types/structures.d.ts} +21 -3
  67. package/dist/runtime/core/values.d.ts +13 -102
  68. package/dist/runtime/core/values.js +26 -722
  69. package/dist/runtime/ext/builtins.js +9 -8
  70. package/dist/runtime/ext/extensions.d.ts +2 -2
  71. package/dist/runtime/ext/extensions.js +2 -1
  72. package/dist/runtime/ext/test-context.d.ts +2 -2
  73. package/dist/runtime/ext/test-context.js +3 -2
  74. package/dist/runtime/index.d.ts +8 -22
  75. package/dist/runtime/index.js +10 -16
  76. package/dist/signature-parser.d.ts +1 -1
  77. package/dist/token-types.d.ts +1 -0
  78. package/dist/token-types.js +1 -0
  79. package/package.json +1 -1
  80. /package/dist/runtime/core/{markers.d.ts → types/markers.d.ts} +0 -0
  81. /package/dist/runtime/core/{markers.js → types/markers.js} +0 -0
  82. /package/dist/runtime/core/{types.js → types/runtime.js} +0 -0
  83. /package/dist/runtime/core/{type-structures.js → types/structures.js} +0 -0
@@ -4,691 +4,27 @@
4
4
  * Core value types that flow through Rill programs.
5
5
  * Public API for host applications.
6
6
  *
7
+ * Structural operations (structureEquals, structureMatches, formatStructure,
8
+ * inferStructure, commonType) live in types/operations.ts and are re-exported.
9
+ *
7
10
  * Dispatch functions (inferType, formatValue, deepEquals, serializeValue,
8
11
  * copyValue) re-export from type-registrations.ts protocol implementations.
9
12
  */
10
- import { RuntimeError } from '../../types.js';
11
13
  import { VALID_TYPE_NAMES } from '../../constants.js';
12
- import { isCallable, isDict } from './callable.js';
13
- import { inferType as registryInferType, formatValue as registryFormatValue, deepEquals as registryDeepEquals, serializeValue as registrySerializeValue, copyValue as registryCopyValue, } from './type-registrations.js';
14
- /**
15
- * Normalize a TypeStructure that may use the legacy `.type` discriminator.
16
- * During migration, some code (builtins.ts, ext/) constructs objects with
17
- * `{ type: 'string' }` instead of `{ kind: 'string' }`. This function
18
- * converts legacy format to current format on the fly.
19
- */
20
- function normalizeStructure(ts) {
21
- if (ts.kind !== undefined)
22
- return ts;
23
- // Legacy format: { type: 'string' } { kind: 'string' }
24
- const legacy = ts;
25
- if (typeof legacy['type'] === 'string') {
26
- return { ...legacy, kind: legacy['type'] };
27
- }
28
- return ts;
29
- }
30
- /** Type guard for RillTuple (spread args) */
31
- export function isTuple(value) {
32
- return (typeof value === 'object' &&
33
- value !== null &&
34
- '__rill_tuple' in value &&
35
- value.__rill_tuple === true);
36
- }
37
- /** Type guard for RillVector */
38
- export function isVector(value) {
39
- return (typeof value === 'object' &&
40
- value !== null &&
41
- '__rill_vector' in value &&
42
- value.__rill_vector === true);
43
- }
44
- /** Type guard for RillOrdered (named spread args) */
45
- export function isOrdered(value) {
46
- return (typeof value === 'object' &&
47
- value !== null &&
48
- '__rill_ordered' in value &&
49
- value.__rill_ordered === true);
50
- }
51
- /** Type guard for RillTypeValue */
52
- export function isTypeValue(value) {
53
- return (typeof value === 'object' &&
54
- value !== null &&
55
- '__rill_type' in value &&
56
- value.__rill_type === true);
57
- }
58
- /**
59
- * Create ordered from entries array (named, preserves insertion order).
60
- * Entries may be 2-element [name, value] or 3-element [name, value, default]
61
- * tuples; the third element carries a default value for `.^input` reflection.
62
- */
63
- export function createOrdered(entries) {
64
- return Object.freeze({ __rill_ordered: true, entries: [...entries] });
65
- }
66
- /** Create tuple from entries array (positional, preserves order) */
67
- export function createTuple(entries) {
68
- return Object.freeze({ __rill_tuple: true, entries: [...entries] });
69
- }
70
- /**
71
- * Create vector from Float32Array with model name.
72
- * @throws {Error} if data.length is 0 (zero-dimension vectors not allowed)
73
- */
74
- export function createVector(data, model) {
75
- if (data.length === 0) {
76
- throw new Error('Vector data must have at least one dimension');
77
- }
78
- return { __rill_vector: true, data, model };
79
- }
14
+ import { isCallable as _isCallableGuard, isDict, isIterator, isOrdered, isStream, isTuple, isTypeValue, isVector, } from './types/guards.js';
15
+ /** isCallable guard widened to narrow to full RillCallable (not just CallableMarker) */
16
+ const isCallable = _isCallableGuard;
17
+ import { inferType as registryInferType, formatValue as registryFormatValue, deepEquals as registryDeepEquals, serializeValue as registrySerializeValue, } from './types/registrations.js';
18
+ // Re-export guards from canonical source (types/guards.ts)
19
+ export { isCallable, isDict, isIterator, isOrdered, isStream, isTuple, isTypeValue, isVector, };
20
+ // Value constructors re-exported from canonical source (types/constructors.ts)
21
+ export { copyValue, createOrdered, createTuple, createVector, emptyForType, } from './types/constructors.js';
22
+ // Structural operations re-exported from types/operations.ts
23
+ export { commonType, compareStructuredFields, formatStructure, inferElementType, inferStructure, paramToFieldDef, structureEquals, structureMatches, } from './types/operations.js';
24
+ // Re-import for local use (toNative, structureToTypeValue)
25
+ import { formatStructure, inferStructure } from './types/operations.js';
80
26
  /** Infer the Rill type from a runtime value. Delegates to type-registrations. */
81
27
  export const inferType = registryInferType;
82
- /**
83
- * Infer the element type for a homogeneous list.
84
- * Empty arrays return { kind: 'any' }.
85
- * Mixed types throw RILL-R002.
86
- */
87
- export function inferElementType(elements) {
88
- if (elements.length === 0)
89
- return { kind: 'any' };
90
- const firstElem = elements[0];
91
- let accType = inferStructure(firstElem);
92
- for (let i = 1; i < elements.length; i++) {
93
- const elem = elements[i];
94
- const elemType = inferStructure(elem);
95
- const merged = commonType(accType, elemType);
96
- if (merged === null) {
97
- throw new RuntimeError('RILL-R002', `List elements must be the same type: expected ${formatStructure(accType)}, got ${formatStructure(elemType)} at index ${i}`);
98
- }
99
- accType = merged;
100
- }
101
- return accType;
102
- }
103
- /**
104
- * Merge uniform value types from two sides of the same compound type.
105
- * Sub-case A: both carry valueType -> recurse commonType.
106
- * Sub-case B: both carry structural fields -> extract value types, merge all.
107
- * Returns the merged TypeStructure on success, undefined when no uniform merge applies.
108
- */
109
- function mergeUniformValueType(aValue, bValue, aFields, bFields) {
110
- // Sub-case A: both carry valueType
111
- if (aValue !== undefined && bValue !== undefined) {
112
- const merged = commonType(aValue, bValue);
113
- if (merged !== null)
114
- return merged;
115
- return undefined;
116
- }
117
- // Sub-case B: both carry structural fields
118
- if (aFields !== undefined && bFields !== undefined) {
119
- const allTypes = [
120
- ...aFields.map((f) => f.type),
121
- ...bFields.map((f) => f.type),
122
- ];
123
- if (allTypes.length === 0)
124
- return undefined;
125
- let merged = allTypes[0];
126
- for (let i = 1; i < allTypes.length; i++) {
127
- const next = commonType(merged, allTypes[i]);
128
- if (next === null)
129
- return undefined;
130
- merged = next;
131
- }
132
- return merged;
133
- }
134
- return undefined;
135
- }
136
- /**
137
- * Return the most specific shared type for two TypeStructure values.
138
- * Returns null when types are incompatible at the top level.
139
- *
140
- * Cascade priority:
141
- * 1. Any-narrowing: if either side is `any`, return the other
142
- * 2. Structural match: delegate to structureEquals; on true, return a
143
- * 3. Recursive list: merge inner element types
144
- * 3b. Uniform valueType: merge dict/tuple/ordered value types
145
- * 4. Bare type fallback: same compound type but structural mismatch
146
- * 5. Incompatible: different top-level types return null
147
- */
148
- export function commonType(a, b) {
149
- // 1. Any-narrowing
150
- if (a.kind === 'any')
151
- return b;
152
- if (b.kind === 'any')
153
- return a;
154
- // 5. Incompatible top-level types (checked early to short-circuit)
155
- if (a.kind !== b.kind)
156
- return null;
157
- // 2. Structural match
158
- if (structureEquals(a, b))
159
- return a;
160
- // 3. Recursive list element merging
161
- if (a.kind === 'list' && b.kind === 'list') {
162
- const aList = a;
163
- const bList = b;
164
- if (aList.element !== undefined && bList.element !== undefined) {
165
- const inner = commonType(aList.element, bList.element);
166
- if (inner !== null)
167
- return { kind: 'list', element: inner };
168
- }
169
- return { kind: 'list' };
170
- }
171
- // 3b. Uniform valueType merging for dict/tuple/ordered
172
- if (a.kind === 'dict' && b.kind === 'dict') {
173
- const aDict = a;
174
- const bDict = b;
175
- const merged = mergeUniformValueType(aDict.valueType, bDict.valueType, aDict.fields ? Object.values(aDict.fields) : undefined, bDict.fields ? Object.values(bDict.fields) : undefined);
176
- if (merged !== undefined)
177
- return { kind: 'dict', valueType: merged };
178
- }
179
- if (a.kind === 'tuple' && b.kind === 'tuple') {
180
- const aTuple = a;
181
- const bTuple = b;
182
- const merged = mergeUniformValueType(aTuple.valueType, bTuple.valueType, aTuple.elements, bTuple.elements);
183
- if (merged !== undefined)
184
- return { kind: 'tuple', valueType: merged };
185
- }
186
- if (a.kind === 'ordered' && b.kind === 'ordered') {
187
- const aOrd = a;
188
- const bOrd = b;
189
- const merged = mergeUniformValueType(aOrd.valueType, bOrd.valueType, aOrd.fields, bOrd.fields);
190
- if (merged !== undefined)
191
- return { kind: 'ordered', valueType: merged };
192
- }
193
- // 4. Bare type fallback for compound types.
194
- // The cast is safe for closure/dict/tuple/ordered (all sub-fields optional).
195
- // For union, members is required by TypeStructure but omitted here intentionally:
196
- // bare union signals structural incompatibility without enumerating members.
197
- if (a.kind === 'closure' ||
198
- a.kind === 'dict' ||
199
- a.kind === 'tuple' ||
200
- a.kind === 'ordered' ||
201
- a.kind === 'union') {
202
- return { kind: a.kind };
203
- }
204
- return null;
205
- }
206
- /** Compare two structural types for equality. */
207
- export function structureEquals(a, b) {
208
- if (a.kind !== b.kind)
209
- return false;
210
- // Leaf variants compare by kind alone
211
- if (a.kind === 'number' ||
212
- a.kind === 'string' ||
213
- a.kind === 'bool' ||
214
- a.kind === 'vector' ||
215
- a.kind === 'type' ||
216
- a.kind === 'any') {
217
- return true;
218
- }
219
- if (a.kind === 'list' && b.kind === 'list') {
220
- const aList = a;
221
- const bList = b;
222
- if (aList.element === undefined && bList.element === undefined)
223
- return true;
224
- if (aList.element === undefined || bList.element === undefined)
225
- return false;
226
- return structureEquals(aList.element, bList.element);
227
- }
228
- if (a.kind === 'dict' && b.kind === 'dict') {
229
- const aDict = a;
230
- const bDict = b;
231
- // Uniform valueType comparison
232
- const aHasValue = aDict.valueType !== undefined;
233
- const bHasValue = bDict.valueType !== undefined;
234
- if (aHasValue || bHasValue) {
235
- if (!aHasValue || !bHasValue)
236
- return false;
237
- return structureEquals(aDict.valueType, bDict.valueType);
238
- }
239
- // Structural fields comparison
240
- if (aDict.fields === undefined && bDict.fields === undefined)
241
- return true;
242
- if (aDict.fields === undefined || bDict.fields === undefined)
243
- return false;
244
- const aKeys = Object.keys(aDict.fields).sort();
245
- const bKeys = Object.keys(bDict.fields).sort();
246
- if (aKeys.length !== bKeys.length)
247
- return false;
248
- for (let i = 0; i < aKeys.length; i++) {
249
- const key = aKeys[i];
250
- if (key !== bKeys[i])
251
- return false;
252
- const aField = aDict.fields[key];
253
- const bField = bDict.fields[key];
254
- const aHasDefault = aField.defaultValue !== undefined;
255
- const bHasDefault = bField.defaultValue !== undefined;
256
- if (aHasDefault !== bHasDefault)
257
- return false;
258
- if (!structureEquals(aField.type, bField.type))
259
- return false;
260
- if (aHasDefault && bHasDefault) {
261
- if (!deepEquals(aField.defaultValue, bField.defaultValue))
262
- return false;
263
- }
264
- }
265
- return true;
266
- }
267
- if (a.kind === 'tuple' && b.kind === 'tuple') {
268
- const aTuple = a;
269
- const bTuple = b;
270
- // Uniform valueType comparison
271
- const aHasValue = aTuple.valueType !== undefined;
272
- const bHasValue = bTuple.valueType !== undefined;
273
- if (aHasValue || bHasValue) {
274
- if (!aHasValue || !bHasValue)
275
- return false;
276
- return structureEquals(aTuple.valueType, bTuple.valueType);
277
- }
278
- // Structural elements comparison
279
- if (aTuple.elements === undefined && bTuple.elements === undefined)
280
- return true;
281
- if (aTuple.elements === undefined || bTuple.elements === undefined)
282
- return false;
283
- if (aTuple.elements.length !== bTuple.elements.length)
284
- return false;
285
- for (let i = 0; i < aTuple.elements.length; i++) {
286
- const aElem = aTuple.elements[i];
287
- const bElem = bTuple.elements[i];
288
- if (!structureEquals(aElem.type, bElem.type))
289
- return false;
290
- const aDefault = aElem.defaultValue;
291
- const bDefault = bElem.defaultValue;
292
- if (aDefault === undefined && bDefault === undefined)
293
- continue;
294
- if (aDefault === undefined || bDefault === undefined)
295
- return false;
296
- if (!deepEquals(aDefault, bDefault))
297
- return false;
298
- }
299
- return true;
300
- }
301
- if (a.kind === 'ordered' && b.kind === 'ordered') {
302
- const aOrd = a;
303
- const bOrd = b;
304
- // Uniform valueType comparison
305
- const aHasValue = aOrd.valueType !== undefined;
306
- const bHasValue = bOrd.valueType !== undefined;
307
- if (aHasValue || bHasValue) {
308
- if (!aHasValue || !bHasValue)
309
- return false;
310
- return structureEquals(aOrd.valueType, bOrd.valueType);
311
- }
312
- // Structural fields comparison
313
- if (aOrd.fields === undefined && bOrd.fields === undefined)
314
- return true;
315
- if (aOrd.fields === undefined || bOrd.fields === undefined)
316
- return false;
317
- if (aOrd.fields.length !== bOrd.fields.length)
318
- return false;
319
- for (let i = 0; i < aOrd.fields.length; i++) {
320
- const aField = aOrd.fields[i];
321
- const bField = bOrd.fields[i];
322
- if (aField.name !== bField.name)
323
- return false;
324
- if (!structureEquals(aField.type, bField.type))
325
- return false;
326
- const aDefault = aField.defaultValue;
327
- const bDefault = bField.defaultValue;
328
- if (aDefault === undefined && bDefault === undefined)
329
- continue;
330
- if (aDefault === undefined || bDefault === undefined)
331
- return false;
332
- if (!deepEquals(aDefault, bDefault))
333
- return false;
334
- }
335
- return true;
336
- }
337
- if (a.kind === 'union' && b.kind === 'union') {
338
- const aUnion = a;
339
- const bUnion = b;
340
- if (aUnion.members.length !== bUnion.members.length)
341
- return false;
342
- for (let i = 0; i < aUnion.members.length; i++) {
343
- if (!structureEquals(aUnion.members[i], bUnion.members[i]))
344
- return false;
345
- }
346
- return true;
347
- }
348
- if (a.kind === 'closure' && b.kind === 'closure') {
349
- const aCls = a;
350
- const bCls = b;
351
- if (aCls.params === undefined && bCls.params === undefined) {
352
- // Both absent: compare ret
353
- }
354
- else if (aCls.params === undefined || bCls.params === undefined) {
355
- return false;
356
- }
357
- else {
358
- if (aCls.params.length !== bCls.params.length)
359
- return false;
360
- for (let i = 0; i < aCls.params.length; i++) {
361
- const aParam = aCls.params[i];
362
- const bParam = bCls.params[i];
363
- if (aParam.name !== bParam.name)
364
- return false;
365
- if (!structureEquals(aParam.type, bParam.type))
366
- return false;
367
- const aDefault = aParam.defaultValue;
368
- const bDefault = bParam.defaultValue;
369
- if (aDefault === undefined && bDefault === undefined)
370
- continue;
371
- if (aDefault === undefined || bDefault === undefined)
372
- return false;
373
- if (!deepEquals(aDefault, bDefault))
374
- return false;
375
- }
376
- }
377
- if (aCls.ret === undefined && bCls.ret === undefined)
378
- return true;
379
- if (aCls.ret === undefined || bCls.ret === undefined)
380
- return false;
381
- return structureEquals(aCls.ret, bCls.ret);
382
- }
383
- return false;
384
- }
385
- /** @deprecated Use structureEquals instead. */
386
- export const structuralTypeEquals = structureEquals;
387
- /** Infer the structural type descriptor for any Rill value. */
388
- export function inferStructure(value) {
389
- if (value === null || typeof value === 'string') {
390
- return { kind: 'string' };
391
- }
392
- if (typeof value === 'number') {
393
- return { kind: 'number' };
394
- }
395
- if (typeof value === 'boolean') {
396
- return { kind: 'bool' };
397
- }
398
- if (isTypeValue(value)) {
399
- return { kind: 'type' };
400
- }
401
- if (Array.isArray(value)) {
402
- return { kind: 'list', element: inferElementType(value) };
403
- }
404
- if (isTuple(value)) {
405
- return {
406
- kind: 'tuple',
407
- elements: value.entries.map((e) => ({
408
- type: inferStructure(e),
409
- })),
410
- };
411
- }
412
- if (isOrdered(value)) {
413
- return {
414
- kind: 'ordered',
415
- fields: value.entries.map(([k, v]) => ({
416
- name: k,
417
- type: inferStructure(v),
418
- })),
419
- };
420
- }
421
- if (isVector(value)) {
422
- return { kind: 'vector' };
423
- }
424
- if (isCallable(value)) {
425
- const params = (value.params ?? []).map((p) => paramToFieldDef(p.name, p.type ?? { kind: 'any' }, p.defaultValue));
426
- const ret = value.returnType.structure;
427
- return { kind: 'closure', params, ret };
428
- }
429
- if (typeof value === 'object') {
430
- const dict = value;
431
- const fields = {};
432
- for (const [k, v] of Object.entries(dict)) {
433
- fields[k] = { type: inferStructure(v) };
434
- }
435
- return { kind: 'dict', fields };
436
- }
437
- throw new RuntimeError('RILL-R004', `Cannot infer structural type for ${formatValue(value)}`);
438
- }
439
- /** @deprecated Use inferStructure instead. */
440
- export const inferStructuralType = inferStructure;
441
- /**
442
- * Check if a value matches a structural type descriptor.
443
- * Used for runtime type checking (`:?` operator).
444
- */
445
- export function structureMatches(value, type) {
446
- type = normalizeStructure(type);
447
- if (typeof value === 'undefined') {
448
- throw new RuntimeError('RILL-R004', 'Cannot type-check non-value');
449
- }
450
- if (type.kind === 'any')
451
- return true;
452
- // Leaf primitive variants: match by inferred type name
453
- if (type.kind === 'number' ||
454
- type.kind === 'string' ||
455
- type.kind === 'bool' ||
456
- type.kind === 'vector' ||
457
- type.kind === 'type') {
458
- return inferType(value) === type.kind;
459
- }
460
- if (type.kind === 'list') {
461
- const t = type;
462
- if (!Array.isArray(value))
463
- return false;
464
- if (t.element === undefined)
465
- return true;
466
- if (t.element.kind === 'any')
467
- return true;
468
- return value.every((elem) => structureMatches(elem, t.element));
469
- }
470
- if (type.kind === 'dict') {
471
- const t = type;
472
- if (!isDict(value))
473
- return false;
474
- if (t.valueType !== undefined) {
475
- const vals = Object.values(value);
476
- return vals.every((v) => structureMatches(v, t.valueType));
477
- }
478
- if (t.fields === undefined)
479
- return true;
480
- const dictKeys = Object.keys(t.fields);
481
- if (dictKeys.length === 0)
482
- return true;
483
- const dict = value;
484
- for (const key of dictKeys) {
485
- if (!(key in dict)) {
486
- const field = t.fields[key];
487
- if (field.defaultValue !== undefined)
488
- continue;
489
- return false;
490
- }
491
- const field = t.fields[key];
492
- if (!structureMatches(dict[key], field.type))
493
- return false;
494
- }
495
- return true;
496
- }
497
- if (type.kind === 'tuple') {
498
- const t = type;
499
- if (!isTuple(value))
500
- return false;
501
- if (t.valueType !== undefined) {
502
- return value.entries.every((v) => structureMatches(v, t.valueType));
503
- }
504
- if (t.elements === undefined)
505
- return true;
506
- if (t.elements.length === 0)
507
- return value.entries.length === 0;
508
- if (value.entries.length > t.elements.length)
509
- return false;
510
- if (value.entries.length < t.elements.length) {
511
- for (let i = value.entries.length; i < t.elements.length; i++) {
512
- const field = t.elements[i];
513
- if (field.defaultValue === undefined)
514
- return false;
515
- }
516
- }
517
- for (let i = 0; i < value.entries.length; i++) {
518
- if (!structureMatches(value.entries[i], t.elements[i].type))
519
- return false;
520
- }
521
- return true;
522
- }
523
- if (type.kind === 'ordered') {
524
- const t = type;
525
- if (!isOrdered(value))
526
- return false;
527
- if (t.valueType !== undefined) {
528
- return value.entries.every(([, v]) => structureMatches(v, t.valueType));
529
- }
530
- if (t.fields === undefined)
531
- return true;
532
- if (t.fields.length === 0)
533
- return value.entries.length === 0;
534
- if (value.entries.length > t.fields.length)
535
- return false;
536
- if (value.entries.length < t.fields.length) {
537
- for (let i = value.entries.length; i < t.fields.length; i++) {
538
- const field = t.fields[i];
539
- if (field.defaultValue === undefined)
540
- return false;
541
- }
542
- }
543
- for (let i = 0; i < value.entries.length; i++) {
544
- const field = t.fields[i];
545
- const [actualName, actualValue] = value.entries[i];
546
- if (actualName !== field.name)
547
- return false;
548
- if (!structureMatches(actualValue, field.type))
549
- return false;
550
- }
551
- return true;
552
- }
553
- if (type.kind === 'closure') {
554
- const t = type;
555
- if (!isCallable(value))
556
- return false;
557
- if (t.params === undefined)
558
- return true;
559
- const valueParams = value.params ?? [];
560
- if (valueParams.length !== t.params.length)
561
- return false;
562
- for (let i = 0; i < t.params.length; i++) {
563
- const field = t.params[i];
564
- const param = valueParams[i];
565
- if (param.name !== field.name)
566
- return false;
567
- const paramType = param.type ?? { kind: 'any' };
568
- if (!structureEquals(paramType, field.type))
569
- return false;
570
- }
571
- const retType = value.returnType.structure;
572
- if (t.ret === undefined)
573
- return true;
574
- return structureEquals(retType, t.ret);
575
- }
576
- if (type.kind === 'union') {
577
- const t = type;
578
- return t.members.some((member) => structureMatches(value, member));
579
- }
580
- return false;
581
- }
582
- /** @deprecated Use structureMatches instead. */
583
- export const structuralTypeMatches = structureMatches;
584
- /** Build a closure param field definition from name, type, and optional default. */
585
- export function paramToFieldDef(name, type, defaultValue) {
586
- const field = { name, type };
587
- if (defaultValue !== undefined)
588
- field.defaultValue = defaultValue;
589
- return field;
590
- }
591
- /** Format a RillValue as a rill literal for use in type signatures. */
592
- function formatRillLiteral(value) {
593
- if (typeof value === 'string') {
594
- const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
595
- return `"${escaped}"`;
596
- }
597
- if (typeof value === 'number')
598
- return String(value);
599
- if (typeof value === 'boolean')
600
- return value ? 'true' : 'false';
601
- if (value === null)
602
- return 'null';
603
- return formatValue(value);
604
- }
605
- /** Format a structural type descriptor as a human-readable string. */
606
- export function formatStructure(type) {
607
- if (type.kind === 'any' ||
608
- type.kind === 'number' ||
609
- type.kind === 'string' ||
610
- type.kind === 'bool' ||
611
- type.kind === 'vector' ||
612
- type.kind === 'type') {
613
- return type.kind;
614
- }
615
- if (type.kind === 'list') {
616
- const t = type;
617
- if (t.element === undefined)
618
- return 'list';
619
- return `list(${formatStructure(t.element)})`;
620
- }
621
- if (type.kind === 'dict') {
622
- const t = type;
623
- if (t.valueType !== undefined && t.fields === undefined) {
624
- return `dict(${formatStructure(t.valueType)})`;
625
- }
626
- if (t.fields === undefined)
627
- return 'dict';
628
- const parts = Object.keys(t.fields)
629
- .sort()
630
- .map((k) => {
631
- const field = t.fields[k];
632
- const base = `${k}: ${formatStructure(field.type)}`;
633
- if (field.defaultValue === undefined)
634
- return base;
635
- return `${base} = ${formatRillLiteral(field.defaultValue)}`;
636
- });
637
- return `dict(${parts.join(', ')})`;
638
- }
639
- if (type.kind === 'tuple') {
640
- const t = type;
641
- if (t.valueType !== undefined && t.elements === undefined) {
642
- return `tuple(${formatStructure(t.valueType)})`;
643
- }
644
- if (t.elements === undefined)
645
- return 'tuple';
646
- const parts = t.elements.map((field) => {
647
- const base = formatStructure(field.type);
648
- if (field.defaultValue === undefined)
649
- return base;
650
- return `${base} = ${formatRillLiteral(field.defaultValue)}`;
651
- });
652
- return `tuple(${parts.join(', ')})`;
653
- }
654
- if (type.kind === 'ordered') {
655
- const t = type;
656
- if (t.valueType !== undefined && t.fields === undefined) {
657
- return `ordered(${formatStructure(t.valueType)})`;
658
- }
659
- if (t.fields === undefined)
660
- return 'ordered';
661
- const parts = t.fields.map((field) => {
662
- const base = `${field.name}: ${formatStructure(field.type)}`;
663
- if (field.defaultValue === undefined)
664
- return base;
665
- return `${base} = ${formatRillLiteral(field.defaultValue)}`;
666
- });
667
- return `ordered(${parts.join(', ')})`;
668
- }
669
- if (type.kind === 'closure') {
670
- const t = type;
671
- if (t.params === undefined)
672
- return 'closure';
673
- const params = t.params
674
- .map((field) => {
675
- const base = `${field.name}: ${formatStructure(field.type)}`;
676
- if (field.defaultValue === undefined)
677
- return base;
678
- return `${base} = ${formatRillLiteral(field.defaultValue)}`;
679
- })
680
- .join(', ');
681
- const ret = t.ret !== undefined ? formatStructure(t.ret) : 'any';
682
- return `|${params}| :${ret}`;
683
- }
684
- if (type.kind === 'union') {
685
- const t = type;
686
- return t.members.map(formatStructure).join('|');
687
- }
688
- return 'any';
689
- }
690
- /** @deprecated Use formatStructure instead. */
691
- export const formatStructuralType = formatStructure;
692
28
  /**
693
29
  * Check if a value is of the expected type.
694
30
  * Returns true if the value matches the expected type, false otherwise.
@@ -729,8 +65,6 @@ export function isEmpty(value) {
729
65
  export const formatValue = registryFormatValue;
730
66
  /** Serialize a Rill value for JSON transport. Delegates to type-registrations. */
731
67
  export const serializeValue = registrySerializeValue;
732
- /** @deprecated Use serializeValue instead. */
733
- export const valueToJSON = serializeValue;
734
68
  /**
735
69
  * Convert a RillValue to a NativeResult for host consumption.
736
70
  * Non-representable types (closures, vectors, type values, iterators) produce descriptor objects.
@@ -776,6 +110,17 @@ function toNativeValue(value) {
776
110
  signature: formatStructure(value.structure),
777
111
  };
778
112
  }
113
+ if (isStream(value)) {
114
+ const descriptor = {
115
+ __type: 'stream',
116
+ done: value.done,
117
+ };
118
+ const chunkType = value['__rill_stream_chunk_type'];
119
+ const retType = value['__rill_stream_ret_type'];
120
+ descriptor['chunkType'] = chunkType ? formatStructure(chunkType) : null;
121
+ descriptor['resolutionType'] = retType ? formatStructure(retType) : null;
122
+ return descriptor;
123
+ }
779
124
  if (isIterator(value)) {
780
125
  return { done: value.done };
781
126
  }
@@ -815,8 +160,6 @@ export function structureToTypeValue(type) {
815
160
  structure: type,
816
161
  });
817
162
  }
818
- /** @deprecated Use structureToTypeValue instead. */
819
- export const rillTypeToTypeValue = structureToTypeValue;
820
163
  /**
821
164
  * Check if a type is a collection (dict, ordered, tuple) with defined
822
165
  * fields or elements. Used to decide if an empty collection can be
@@ -833,46 +176,7 @@ export function hasCollectionFields(type) {
833
176
  (!!type.elements ||
834
177
  !!type.valueType)));
835
178
  }
836
- /**
837
- * Create an empty collection value matching the given TypeStructure.
838
- * Assumes the type is dict, ordered, or tuple.
839
- */
840
- export function emptyForType(type) {
841
- if (type.kind === 'dict')
842
- return {};
843
- if (type.kind === 'ordered')
844
- return createOrdered([]);
845
- if (type.kind === 'tuple')
846
- return createTuple([]);
847
- return {};
848
- }
849
179
  /** Check if a key name is reserved */
850
180
  export function isReservedMethod(name) {
851
181
  return RESERVED_DICT_METHODS.includes(name);
852
182
  }
853
- /**
854
- * Type guard for Rill iterator (lazy sequence).
855
- * An iterator is a dict with:
856
- * - done: boolean - whether iteration is complete
857
- * - next: callable - function to get next iterator
858
- * - value: any (only required when not done) - current element
859
- */
860
- export function isIterator(value) {
861
- if (!isDict(value))
862
- return false;
863
- const dict = value;
864
- if (!('done' in dict && typeof dict['done'] === 'boolean'))
865
- return false;
866
- if (!('next' in dict && isCallable(dict['next'])))
867
- return false;
868
- // 'value' field only required when not done
869
- if (!dict['done'] && !('value' in dict))
870
- return false;
871
- return true;
872
- }
873
- /** @deprecated Use isIterator instead. */
874
- export const isRillIterator = isIterator;
875
- /** Copy a RillValue. Delegates to type-registrations. */
876
- export const copyValue = registryCopyValue;
877
- /** @deprecated Use copyValue instead. */
878
- export const deepCopyRillValue = copyValue;