@rcrsr/rill 0.15.0 → 0.16.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 (305) hide show
  1. package/dist/ast-nodes.d.ts +2 -13
  2. package/dist/ast-nodes.js +0 -1
  3. package/dist/ast-unions.d.ts +0 -1
  4. package/dist/ast-unions.js +0 -1
  5. package/dist/constants.d.ts +0 -1
  6. package/dist/constants.js +0 -1
  7. package/dist/error-classes.d.ts +0 -1
  8. package/dist/error-classes.js +0 -1
  9. package/dist/error-formatter.d.ts +0 -1
  10. package/dist/error-formatter.js +0 -1
  11. package/dist/error-registry.d.ts +0 -1
  12. package/dist/error-registry.js +32 -1
  13. package/dist/ext/crypto/index.d.ts +0 -1
  14. package/dist/ext/crypto/index.js +5 -6
  15. package/dist/ext/exec/index.d.ts +0 -1
  16. package/dist/ext/exec/index.js +3 -4
  17. package/dist/ext/exec/runner.d.ts +0 -1
  18. package/dist/ext/exec/runner.js +0 -1
  19. package/dist/ext/fetch/index.d.ts +0 -1
  20. package/dist/ext/fetch/index.js +8 -39
  21. package/dist/ext/fetch/request.d.ts +0 -1
  22. package/dist/ext/fetch/request.js +0 -1
  23. package/dist/ext/fs/index.d.ts +0 -1
  24. package/dist/ext/fs/index.js +26 -27
  25. package/dist/ext/fs/sandbox.d.ts +0 -1
  26. package/dist/ext/fs/sandbox.js +0 -1
  27. package/dist/ext/kv/index.d.ts +0 -1
  28. package/dist/ext/kv/index.js +19 -20
  29. package/dist/ext/kv/store.d.ts +0 -1
  30. package/dist/ext/kv/store.js +0 -1
  31. package/dist/generated/introspection-data.d.ts +0 -1
  32. package/dist/generated/introspection-data.js +0 -1
  33. package/dist/generated/version-data.d.ts +1 -2
  34. package/dist/generated/version-data.js +2 -3
  35. package/dist/highlight-map.d.ts +0 -1
  36. package/dist/highlight-map.js +0 -1
  37. package/dist/index.d.ts +1 -2
  38. package/dist/index.js +1 -2
  39. package/dist/lexer/errors.d.ts +0 -1
  40. package/dist/lexer/errors.js +0 -1
  41. package/dist/lexer/helpers.d.ts +0 -1
  42. package/dist/lexer/helpers.js +0 -1
  43. package/dist/lexer/index.d.ts +0 -1
  44. package/dist/lexer/index.js +0 -1
  45. package/dist/lexer/operators.d.ts +0 -1
  46. package/dist/lexer/operators.js +0 -1
  47. package/dist/lexer/readers.d.ts +0 -1
  48. package/dist/lexer/readers.js +0 -1
  49. package/dist/lexer/state.d.ts +0 -1
  50. package/dist/lexer/state.js +0 -1
  51. package/dist/lexer/tokenizer.d.ts +0 -1
  52. package/dist/lexer/tokenizer.js +0 -1
  53. package/dist/parser/helpers.d.ts +0 -1
  54. package/dist/parser/helpers.js +0 -1
  55. package/dist/parser/index.d.ts +0 -1
  56. package/dist/parser/index.js +0 -1
  57. package/dist/parser/parser-collect.d.ts +0 -1
  58. package/dist/parser/parser-collect.js +0 -1
  59. package/dist/parser/parser-control.d.ts +0 -1
  60. package/dist/parser/parser-control.js +0 -1
  61. package/dist/parser/parser-expr.d.ts +0 -1
  62. package/dist/parser/parser-expr.js +0 -1
  63. package/dist/parser/parser-extract.d.ts +0 -1
  64. package/dist/parser/parser-extract.js +0 -1
  65. package/dist/parser/parser-functions.d.ts +0 -1
  66. package/dist/parser/parser-functions.js +0 -1
  67. package/dist/parser/parser-literals.d.ts +0 -1
  68. package/dist/parser/parser-literals.js +4 -2
  69. package/dist/parser/parser-script.d.ts +0 -1
  70. package/dist/parser/parser-script.js +0 -1
  71. package/dist/parser/parser-shape.d.ts +2 -3
  72. package/dist/parser/parser-shape.js +8 -52
  73. package/dist/parser/parser-types.d.ts +28 -2
  74. package/dist/parser/parser-types.js +64 -13
  75. package/dist/parser/parser-use.d.ts +0 -1
  76. package/dist/parser/parser-use.js +0 -1
  77. package/dist/parser/parser-variables.d.ts +0 -1
  78. package/dist/parser/parser-variables.js +0 -1
  79. package/dist/parser/parser.d.ts +0 -1
  80. package/dist/parser/parser.js +0 -1
  81. package/dist/parser/state.d.ts +0 -1
  82. package/dist/parser/state.js +0 -1
  83. package/dist/runtime/core/callable.d.ts +40 -13
  84. package/dist/runtime/core/callable.js +137 -28
  85. package/dist/runtime/core/context.d.ts +0 -1
  86. package/dist/runtime/core/context.js +1 -2
  87. package/dist/runtime/core/equals.d.ts +0 -1
  88. package/dist/runtime/core/equals.js +35 -3
  89. package/dist/runtime/core/eval/base.d.ts +0 -1
  90. package/dist/runtime/core/eval/base.js +0 -1
  91. package/dist/runtime/core/eval/evaluator.d.ts +0 -1
  92. package/dist/runtime/core/eval/evaluator.js +0 -1
  93. package/dist/runtime/core/eval/index.d.ts +0 -1
  94. package/dist/runtime/core/eval/index.js +0 -1
  95. package/dist/runtime/core/eval/mixins/annotations.d.ts +0 -1
  96. package/dist/runtime/core/eval/mixins/annotations.js +0 -1
  97. package/dist/runtime/core/eval/mixins/closures.d.ts +0 -1
  98. package/dist/runtime/core/eval/mixins/closures.js +82 -60
  99. package/dist/runtime/core/eval/mixins/collections.d.ts +0 -1
  100. package/dist/runtime/core/eval/mixins/collections.js +9 -4
  101. package/dist/runtime/core/eval/mixins/control-flow.d.ts +0 -1
  102. package/dist/runtime/core/eval/mixins/control-flow.js +0 -1
  103. package/dist/runtime/core/eval/mixins/conversion.d.ts +0 -1
  104. package/dist/runtime/core/eval/mixins/conversion.js +153 -86
  105. package/dist/runtime/core/eval/mixins/core.d.ts +0 -1
  106. package/dist/runtime/core/eval/mixins/core.js +0 -1
  107. package/dist/runtime/core/eval/mixins/expressions.d.ts +0 -1
  108. package/dist/runtime/core/eval/mixins/expressions.js +0 -1
  109. package/dist/runtime/core/eval/mixins/extraction.d.ts +0 -1
  110. package/dist/runtime/core/eval/mixins/extraction.js +8 -9
  111. package/dist/runtime/core/eval/mixins/list-dispatch.d.ts +0 -1
  112. package/dist/runtime/core/eval/mixins/list-dispatch.js +0 -1
  113. package/dist/runtime/core/eval/mixins/literals.d.ts +0 -1
  114. package/dist/runtime/core/eval/mixins/literals.js +3 -7
  115. package/dist/runtime/core/eval/mixins/types.d.ts +2 -1
  116. package/dist/runtime/core/eval/mixins/types.js +222 -242
  117. package/dist/runtime/core/eval/mixins/use.d.ts +0 -1
  118. package/dist/runtime/core/eval/mixins/use.js +0 -1
  119. package/dist/runtime/core/eval/mixins/variables.d.ts +0 -1
  120. package/dist/runtime/core/eval/mixins/variables.js +6 -7
  121. package/dist/runtime/core/eval/types.d.ts +0 -1
  122. package/dist/runtime/core/eval/types.js +0 -1
  123. package/dist/runtime/core/execute.d.ts +0 -1
  124. package/dist/runtime/core/execute.js +0 -1
  125. package/dist/runtime/core/field-descriptor.d.ts +2 -3
  126. package/dist/runtime/core/field-descriptor.js +0 -1
  127. package/dist/runtime/core/introspection.d.ts +0 -1
  128. package/dist/runtime/core/introspection.js +0 -1
  129. package/dist/runtime/core/resolvers.d.ts +0 -1
  130. package/dist/runtime/core/resolvers.js +0 -1
  131. package/dist/runtime/core/signals.d.ts +0 -1
  132. package/dist/runtime/core/signals.js +0 -1
  133. package/dist/runtime/core/types.d.ts +0 -1
  134. package/dist/runtime/core/types.js +0 -1
  135. package/dist/runtime/core/values.d.ts +59 -26
  136. package/dist/runtime/core/values.js +289 -77
  137. package/dist/runtime/ext/builtins.d.ts +0 -1
  138. package/dist/runtime/ext/builtins.js +43 -17
  139. package/dist/runtime/ext/extensions.d.ts +0 -1
  140. package/dist/runtime/ext/extensions.js +0 -1
  141. package/dist/runtime/index.d.ts +2 -3
  142. package/dist/runtime/index.js +1 -2
  143. package/dist/signature-parser.d.ts +0 -1
  144. package/dist/signature-parser.js +8 -6
  145. package/dist/source-location.d.ts +0 -1
  146. package/dist/source-location.js +0 -1
  147. package/dist/token-types.d.ts +0 -1
  148. package/dist/token-types.js +0 -1
  149. package/dist/types.d.ts +0 -1
  150. package/dist/types.js +0 -1
  151. package/dist/value-types.d.ts +15 -12
  152. package/dist/value-types.js +0 -1
  153. package/package.json +2 -1
  154. package/dist/ast-nodes.d.ts.map +0 -1
  155. package/dist/ast-nodes.js.map +0 -1
  156. package/dist/ast-unions.d.ts.map +0 -1
  157. package/dist/ast-unions.js.map +0 -1
  158. package/dist/constants.d.ts.map +0 -1
  159. package/dist/constants.js.map +0 -1
  160. package/dist/error-classes.d.ts.map +0 -1
  161. package/dist/error-classes.js.map +0 -1
  162. package/dist/error-formatter.d.ts.map +0 -1
  163. package/dist/error-formatter.js.map +0 -1
  164. package/dist/error-registry.d.ts.map +0 -1
  165. package/dist/error-registry.js.map +0 -1
  166. package/dist/ext/crypto/index.d.ts.map +0 -1
  167. package/dist/ext/crypto/index.js.map +0 -1
  168. package/dist/ext/exec/index.d.ts.map +0 -1
  169. package/dist/ext/exec/index.js.map +0 -1
  170. package/dist/ext/exec/runner.d.ts.map +0 -1
  171. package/dist/ext/exec/runner.js.map +0 -1
  172. package/dist/ext/fetch/index.d.ts.map +0 -1
  173. package/dist/ext/fetch/index.js.map +0 -1
  174. package/dist/ext/fetch/request.d.ts.map +0 -1
  175. package/dist/ext/fetch/request.js.map +0 -1
  176. package/dist/ext/fs/index.d.ts.map +0 -1
  177. package/dist/ext/fs/index.js.map +0 -1
  178. package/dist/ext/fs/sandbox.d.ts.map +0 -1
  179. package/dist/ext/fs/sandbox.js.map +0 -1
  180. package/dist/ext/kv/index.d.ts.map +0 -1
  181. package/dist/ext/kv/index.js.map +0 -1
  182. package/dist/ext/kv/store.d.ts.map +0 -1
  183. package/dist/ext/kv/store.js.map +0 -1
  184. package/dist/generated/introspection-data.d.ts.map +0 -1
  185. package/dist/generated/introspection-data.js.map +0 -1
  186. package/dist/generated/version-data.d.ts.map +0 -1
  187. package/dist/generated/version-data.js.map +0 -1
  188. package/dist/highlight-map.d.ts.map +0 -1
  189. package/dist/highlight-map.js.map +0 -1
  190. package/dist/index.d.ts.map +0 -1
  191. package/dist/index.js.map +0 -1
  192. package/dist/lexer/errors.d.ts.map +0 -1
  193. package/dist/lexer/errors.js.map +0 -1
  194. package/dist/lexer/helpers.d.ts.map +0 -1
  195. package/dist/lexer/helpers.js.map +0 -1
  196. package/dist/lexer/index.d.ts.map +0 -1
  197. package/dist/lexer/index.js.map +0 -1
  198. package/dist/lexer/operators.d.ts.map +0 -1
  199. package/dist/lexer/operators.js.map +0 -1
  200. package/dist/lexer/readers.d.ts.map +0 -1
  201. package/dist/lexer/readers.js.map +0 -1
  202. package/dist/lexer/state.d.ts.map +0 -1
  203. package/dist/lexer/state.js.map +0 -1
  204. package/dist/lexer/tokenizer.d.ts.map +0 -1
  205. package/dist/lexer/tokenizer.js.map +0 -1
  206. package/dist/parser/helpers.d.ts.map +0 -1
  207. package/dist/parser/helpers.js.map +0 -1
  208. package/dist/parser/index.d.ts.map +0 -1
  209. package/dist/parser/index.js.map +0 -1
  210. package/dist/parser/parser-collect.d.ts.map +0 -1
  211. package/dist/parser/parser-collect.js.map +0 -1
  212. package/dist/parser/parser-control.d.ts.map +0 -1
  213. package/dist/parser/parser-control.js.map +0 -1
  214. package/dist/parser/parser-expr.d.ts.map +0 -1
  215. package/dist/parser/parser-expr.js.map +0 -1
  216. package/dist/parser/parser-extract.d.ts.map +0 -1
  217. package/dist/parser/parser-extract.js.map +0 -1
  218. package/dist/parser/parser-functions.d.ts.map +0 -1
  219. package/dist/parser/parser-functions.js.map +0 -1
  220. package/dist/parser/parser-literals.d.ts.map +0 -1
  221. package/dist/parser/parser-literals.js.map +0 -1
  222. package/dist/parser/parser-script.d.ts.map +0 -1
  223. package/dist/parser/parser-script.js.map +0 -1
  224. package/dist/parser/parser-shape.d.ts.map +0 -1
  225. package/dist/parser/parser-shape.js.map +0 -1
  226. package/dist/parser/parser-types.d.ts.map +0 -1
  227. package/dist/parser/parser-types.js.map +0 -1
  228. package/dist/parser/parser-use.d.ts.map +0 -1
  229. package/dist/parser/parser-use.js.map +0 -1
  230. package/dist/parser/parser-variables.d.ts.map +0 -1
  231. package/dist/parser/parser-variables.js.map +0 -1
  232. package/dist/parser/parser.d.ts.map +0 -1
  233. package/dist/parser/parser.js.map +0 -1
  234. package/dist/parser/state.d.ts.map +0 -1
  235. package/dist/parser/state.js.map +0 -1
  236. package/dist/runtime/core/callable.d.ts.map +0 -1
  237. package/dist/runtime/core/callable.js.map +0 -1
  238. package/dist/runtime/core/context.d.ts.map +0 -1
  239. package/dist/runtime/core/context.js.map +0 -1
  240. package/dist/runtime/core/equals.d.ts.map +0 -1
  241. package/dist/runtime/core/equals.js.map +0 -1
  242. package/dist/runtime/core/eval/base.d.ts.map +0 -1
  243. package/dist/runtime/core/eval/base.js.map +0 -1
  244. package/dist/runtime/core/eval/evaluator.d.ts.map +0 -1
  245. package/dist/runtime/core/eval/evaluator.js.map +0 -1
  246. package/dist/runtime/core/eval/index.d.ts.map +0 -1
  247. package/dist/runtime/core/eval/index.js.map +0 -1
  248. package/dist/runtime/core/eval/mixins/annotations.d.ts.map +0 -1
  249. package/dist/runtime/core/eval/mixins/annotations.js.map +0 -1
  250. package/dist/runtime/core/eval/mixins/closures.d.ts.map +0 -1
  251. package/dist/runtime/core/eval/mixins/closures.js.map +0 -1
  252. package/dist/runtime/core/eval/mixins/collections.d.ts.map +0 -1
  253. package/dist/runtime/core/eval/mixins/collections.js.map +0 -1
  254. package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +0 -1
  255. package/dist/runtime/core/eval/mixins/control-flow.js.map +0 -1
  256. package/dist/runtime/core/eval/mixins/conversion.d.ts.map +0 -1
  257. package/dist/runtime/core/eval/mixins/conversion.js.map +0 -1
  258. package/dist/runtime/core/eval/mixins/core.d.ts.map +0 -1
  259. package/dist/runtime/core/eval/mixins/core.js.map +0 -1
  260. package/dist/runtime/core/eval/mixins/expressions.d.ts.map +0 -1
  261. package/dist/runtime/core/eval/mixins/expressions.js.map +0 -1
  262. package/dist/runtime/core/eval/mixins/extraction.d.ts.map +0 -1
  263. package/dist/runtime/core/eval/mixins/extraction.js.map +0 -1
  264. package/dist/runtime/core/eval/mixins/list-dispatch.d.ts.map +0 -1
  265. package/dist/runtime/core/eval/mixins/list-dispatch.js.map +0 -1
  266. package/dist/runtime/core/eval/mixins/literals.d.ts.map +0 -1
  267. package/dist/runtime/core/eval/mixins/literals.js.map +0 -1
  268. package/dist/runtime/core/eval/mixins/types.d.ts.map +0 -1
  269. package/dist/runtime/core/eval/mixins/types.js.map +0 -1
  270. package/dist/runtime/core/eval/mixins/use.d.ts.map +0 -1
  271. package/dist/runtime/core/eval/mixins/use.js.map +0 -1
  272. package/dist/runtime/core/eval/mixins/variables.d.ts.map +0 -1
  273. package/dist/runtime/core/eval/mixins/variables.js.map +0 -1
  274. package/dist/runtime/core/eval/types.d.ts.map +0 -1
  275. package/dist/runtime/core/eval/types.js.map +0 -1
  276. package/dist/runtime/core/execute.d.ts.map +0 -1
  277. package/dist/runtime/core/execute.js.map +0 -1
  278. package/dist/runtime/core/field-descriptor.d.ts.map +0 -1
  279. package/dist/runtime/core/field-descriptor.js.map +0 -1
  280. package/dist/runtime/core/introspection.d.ts.map +0 -1
  281. package/dist/runtime/core/introspection.js.map +0 -1
  282. package/dist/runtime/core/resolvers.d.ts.map +0 -1
  283. package/dist/runtime/core/resolvers.js.map +0 -1
  284. package/dist/runtime/core/signals.d.ts.map +0 -1
  285. package/dist/runtime/core/signals.js.map +0 -1
  286. package/dist/runtime/core/types.d.ts.map +0 -1
  287. package/dist/runtime/core/types.js.map +0 -1
  288. package/dist/runtime/core/values.d.ts.map +0 -1
  289. package/dist/runtime/core/values.js.map +0 -1
  290. package/dist/runtime/ext/builtins.d.ts.map +0 -1
  291. package/dist/runtime/ext/builtins.js.map +0 -1
  292. package/dist/runtime/ext/extensions.d.ts.map +0 -1
  293. package/dist/runtime/ext/extensions.js.map +0 -1
  294. package/dist/runtime/index.d.ts.map +0 -1
  295. package/dist/runtime/index.js.map +0 -1
  296. package/dist/signature-parser.d.ts.map +0 -1
  297. package/dist/signature-parser.js.map +0 -1
  298. package/dist/source-location.d.ts.map +0 -1
  299. package/dist/source-location.js.map +0 -1
  300. package/dist/token-types.d.ts.map +0 -1
  301. package/dist/token-types.js.map +0 -1
  302. package/dist/types.d.ts.map +0 -1
  303. package/dist/types.js.map +0 -1
  304. package/dist/value-types.d.ts.map +0 -1
  305. package/dist/value-types.js.map +0 -1
@@ -7,15 +7,6 @@
7
7
  import { RuntimeError } from '../../types.js';
8
8
  import { VALID_TYPE_NAMES } from '../../constants.js';
9
9
  import { callableEquals, isCallable, isDict, isScriptCallable, } from './callable.js';
10
- /**
11
- * Type guard to distinguish the `{ type, defaultValue }` form of RillFieldType
12
- * from a plain RillType.
13
- */
14
- export function isFieldTypeWithDefault(fieldType) {
15
- return (typeof fieldType === 'object' &&
16
- fieldType !== null &&
17
- 'defaultValue' in fieldType);
18
- }
19
10
  /** Type guard for RillTuple (spread args) */
20
11
  export function isTuple(value) {
21
12
  return (typeof value === 'object' &&
@@ -44,7 +35,11 @@ export function isTypeValue(value) {
44
35
  '__rill_type' in value &&
45
36
  value.__rill_type === true);
46
37
  }
47
- /** Create ordered from entries array (named, preserves insertion order) */
38
+ /**
39
+ * Create ordered from entries array (named, preserves insertion order).
40
+ * Entries may be 2-element [name, value] or 3-element [name, value, default]
41
+ * tuples; the third element carries a default value for `.^input` reflection.
42
+ */
48
43
  export function createOrdered(entries) {
49
44
  return Object.freeze({ __rill_ordered: true, entries: [...entries] });
50
45
  }
@@ -102,15 +97,112 @@ export function inferElementType(elements) {
102
97
  if (elements.length === 0)
103
98
  return { type: 'any' };
104
99
  const firstElem = elements[0];
105
- const firstType = inferStructuralType(firstElem);
100
+ let accType = inferStructuralType(firstElem);
106
101
  for (let i = 1; i < elements.length; i++) {
107
102
  const elem = elements[i];
108
103
  const elemType = inferStructuralType(elem);
109
- if (!structuralTypeEquals(firstType, elemType)) {
110
- throw new RuntimeError('RILL-R002', `List elements must be the same type: expected ${formatStructuralType(firstType)}, got ${formatStructuralType(elemType)} at index ${i}`);
104
+ const merged = commonType(accType, elemType);
105
+ if (merged === null) {
106
+ throw new RuntimeError('RILL-R002', `List elements must be the same type: expected ${formatStructuralType(accType)}, got ${formatStructuralType(elemType)} at index ${i}`);
107
+ }
108
+ accType = merged;
109
+ }
110
+ return accType;
111
+ }
112
+ /**
113
+ * Merge uniform value types from two sides of the same compound type.
114
+ * Sub-case A: both carry valueType -> recurse commonType.
115
+ * Sub-case B: both carry structural fields -> extract value types, merge all.
116
+ * Returns the merged RillType on success, undefined when no uniform merge applies.
117
+ */
118
+ function mergeUniformValueType(aValue, bValue, aFields, bFields) {
119
+ // Sub-case A: both carry valueType
120
+ if (aValue !== undefined && bValue !== undefined) {
121
+ const merged = commonType(aValue, bValue);
122
+ if (merged !== null)
123
+ return merged;
124
+ return undefined;
125
+ }
126
+ // Sub-case B: both carry structural fields
127
+ if (aFields !== undefined && bFields !== undefined) {
128
+ const allTypes = [
129
+ ...aFields.map((f) => f.type),
130
+ ...bFields.map((f) => f.type),
131
+ ];
132
+ if (allTypes.length === 0)
133
+ return undefined;
134
+ let merged = allTypes[0];
135
+ for (let i = 1; i < allTypes.length; i++) {
136
+ const next = commonType(merged, allTypes[i]);
137
+ if (next === null)
138
+ return undefined;
139
+ merged = next;
140
+ }
141
+ return merged;
142
+ }
143
+ return undefined;
144
+ }
145
+ /**
146
+ * Return the most specific shared type for two RillType values.
147
+ * Returns null when types are incompatible at the top level.
148
+ *
149
+ * Cascade priority:
150
+ * 1. Any-narrowing: if either side is `any`, return the other
151
+ * 2. Structural match: delegate to structuralTypeEquals; on true, return a
152
+ * 3. Recursive list: merge inner element types
153
+ * 3b. Uniform valueType: merge dict/tuple/ordered value types
154
+ * 4. Bare type fallback: same compound type but structural mismatch
155
+ * 5. Incompatible: different top-level types return null
156
+ */
157
+ export function commonType(a, b) {
158
+ // 1. Any-narrowing
159
+ if (a.type === 'any')
160
+ return b;
161
+ if (b.type === 'any')
162
+ return a;
163
+ // 5. Incompatible top-level types (checked early to short-circuit)
164
+ if (a.type !== b.type)
165
+ return null;
166
+ // 2. Structural match
167
+ if (structuralTypeEquals(a, b))
168
+ return a;
169
+ // 3. Recursive list element merging
170
+ if (a.type === 'list' && b.type === 'list') {
171
+ if (a.element !== undefined && b.element !== undefined) {
172
+ const inner = commonType(a.element, b.element);
173
+ if (inner !== null)
174
+ return { type: 'list', element: inner };
111
175
  }
176
+ return { type: 'list' };
177
+ }
178
+ // 3b. Uniform valueType merging for dict/tuple/ordered
179
+ if (a.type === 'dict' && b.type === 'dict') {
180
+ const merged = mergeUniformValueType(a.valueType, b.valueType, a.fields ? Object.values(a.fields) : undefined, b.fields ? Object.values(b.fields) : undefined);
181
+ if (merged !== undefined)
182
+ return { type: 'dict', valueType: merged };
183
+ }
184
+ if (a.type === 'tuple' && b.type === 'tuple') {
185
+ const merged = mergeUniformValueType(a.valueType, b.valueType, a.elements, b.elements);
186
+ if (merged !== undefined)
187
+ return { type: 'tuple', valueType: merged };
112
188
  }
113
- return firstType;
189
+ if (a.type === 'ordered' && b.type === 'ordered') {
190
+ const merged = mergeUniformValueType(a.valueType, b.valueType, a.fields, b.fields);
191
+ if (merged !== undefined)
192
+ return { type: 'ordered', valueType: merged };
193
+ }
194
+ // 4. Bare type fallback for compound types.
195
+ // The cast is safe for closure/dict/tuple/ordered (all sub-fields optional).
196
+ // For union, members is required by RillType but omitted here intentionally:
197
+ // bare union signals structural incompatibility without enumerating members.
198
+ if (a.type === 'closure' ||
199
+ a.type === 'dict' ||
200
+ a.type === 'tuple' ||
201
+ a.type === 'ordered' ||
202
+ a.type === 'union') {
203
+ return { type: a.type };
204
+ }
205
+ return null;
114
206
  }
115
207
  /** Compare two structural types for equality. */
116
208
  export function structuralTypeEquals(a, b) {
@@ -133,6 +225,15 @@ export function structuralTypeEquals(a, b) {
133
225
  return structuralTypeEquals(a.element, b.element);
134
226
  }
135
227
  if (a.type === 'dict' && b.type === 'dict') {
228
+ // Uniform valueType comparison (mirrors list element at line 308)
229
+ const aHasValue = a.valueType !== undefined;
230
+ const bHasValue = b.valueType !== undefined;
231
+ if (aHasValue || bHasValue) {
232
+ if (!aHasValue || !bHasValue)
233
+ return false;
234
+ return structuralTypeEquals(a.valueType, b.valueType);
235
+ }
236
+ // Structural fields comparison
136
237
  if (a.fields === undefined && b.fields === undefined)
137
238
  return true;
138
239
  if (a.fields === undefined || b.fields === undefined)
@@ -147,13 +248,11 @@ export function structuralTypeEquals(a, b) {
147
248
  return false;
148
249
  const aField = a.fields[key];
149
250
  const bField = b.fields[key];
150
- const aHasDefault = isFieldTypeWithDefault(aField);
151
- const bHasDefault = isFieldTypeWithDefault(bField);
251
+ const aHasDefault = aField.defaultValue !== undefined;
252
+ const bHasDefault = bField.defaultValue !== undefined;
152
253
  if (aHasDefault !== bHasDefault)
153
254
  return false;
154
- const aType = aHasDefault ? aField.type : aField;
155
- const bType = bHasDefault ? bField.type : bField;
156
- if (!structuralTypeEquals(aType, bType))
255
+ if (!structuralTypeEquals(aField.type, bField.type))
157
256
  return false;
158
257
  if (aHasDefault && bHasDefault) {
159
258
  if (!deepEquals(aField.defaultValue, bField.defaultValue))
@@ -163,6 +262,15 @@ export function structuralTypeEquals(a, b) {
163
262
  return true;
164
263
  }
165
264
  if (a.type === 'tuple' && b.type === 'tuple') {
265
+ // Uniform valueType comparison (mirrors list element at line 308)
266
+ const aHasValue = a.valueType !== undefined;
267
+ const bHasValue = b.valueType !== undefined;
268
+ if (aHasValue || bHasValue) {
269
+ if (!aHasValue || !bHasValue)
270
+ return false;
271
+ return structuralTypeEquals(a.valueType, b.valueType);
272
+ }
273
+ // Structural elements comparison
166
274
  if (a.elements === undefined && b.elements === undefined)
167
275
  return true;
168
276
  if (a.elements === undefined || b.elements === undefined)
@@ -172,10 +280,10 @@ export function structuralTypeEquals(a, b) {
172
280
  for (let i = 0; i < a.elements.length; i++) {
173
281
  const aElem = a.elements[i];
174
282
  const bElem = b.elements[i];
175
- if (!structuralTypeEquals(aElem[0], bElem[0]))
283
+ if (!structuralTypeEquals(aElem.type, bElem.type))
176
284
  return false;
177
- const aDefault = aElem[1];
178
- const bDefault = bElem[1];
285
+ const aDefault = aElem.defaultValue;
286
+ const bDefault = bElem.defaultValue;
179
287
  if (aDefault === undefined && bDefault === undefined)
180
288
  continue;
181
289
  if (aDefault === undefined || bDefault === undefined)
@@ -186,6 +294,15 @@ export function structuralTypeEquals(a, b) {
186
294
  return true;
187
295
  }
188
296
  if (a.type === 'ordered' && b.type === 'ordered') {
297
+ // Uniform valueType comparison (mirrors list element at line 308)
298
+ const aHasValue = a.valueType !== undefined;
299
+ const bHasValue = b.valueType !== undefined;
300
+ if (aHasValue || bHasValue) {
301
+ if (!aHasValue || !bHasValue)
302
+ return false;
303
+ return structuralTypeEquals(a.valueType, b.valueType);
304
+ }
305
+ // Structural fields comparison
189
306
  if (a.fields === undefined && b.fields === undefined)
190
307
  return true;
191
308
  if (a.fields === undefined || b.fields === undefined)
@@ -195,12 +312,12 @@ export function structuralTypeEquals(a, b) {
195
312
  for (let i = 0; i < a.fields.length; i++) {
196
313
  const aField = a.fields[i];
197
314
  const bField = b.fields[i];
198
- if (aField[0] !== bField[0])
315
+ if (aField.name !== bField.name)
199
316
  return false;
200
- if (!structuralTypeEquals(aField[1], bField[1]))
317
+ if (!structuralTypeEquals(aField.type, bField.type))
201
318
  return false;
202
- const aDefault = aField[2];
203
- const bDefault = bField[2];
319
+ const aDefault = aField.defaultValue;
320
+ const bDefault = bField.defaultValue;
204
321
  if (aDefault === undefined && bDefault === undefined)
205
322
  continue;
206
323
  if (aDefault === undefined || bDefault === undefined)
@@ -232,12 +349,12 @@ export function structuralTypeEquals(a, b) {
232
349
  for (let i = 0; i < a.params.length; i++) {
233
350
  const aParam = a.params[i];
234
351
  const bParam = b.params[i];
235
- if (aParam[0] !== bParam[0])
352
+ if (aParam.name !== bParam.name)
236
353
  return false;
237
- if (!structuralTypeEquals(aParam[1], bParam[1]))
354
+ if (!structuralTypeEquals(aParam.type, bParam.type))
238
355
  return false;
239
- const aDefault = aParam[2];
240
- const bDefault = bParam[2];
356
+ const aDefault = aParam.defaultValue;
357
+ const bDefault = bParam.defaultValue;
241
358
  if (aDefault === undefined && bDefault === undefined)
242
359
  continue;
243
360
  if (aDefault === undefined || bDefault === undefined)
@@ -274,25 +391,25 @@ export function inferStructuralType(value) {
274
391
  if (isTuple(value)) {
275
392
  return {
276
393
  type: 'tuple',
277
- elements: value.entries.map((e) => [
278
- inferStructuralType(e),
279
- ]),
394
+ elements: value.entries.map((e) => ({
395
+ type: inferStructuralType(e),
396
+ })),
280
397
  };
281
398
  }
282
399
  if (isOrdered(value)) {
283
400
  return {
284
401
  type: 'ordered',
285
- fields: value.entries.map(([k, v]) => [
286
- k,
287
- inferStructuralType(v),
288
- ]),
402
+ fields: value.entries.map(([k, v]) => ({
403
+ name: k,
404
+ type: inferStructuralType(v),
405
+ })),
289
406
  };
290
407
  }
291
408
  if (isVector(value)) {
292
409
  return { type: 'vector' };
293
410
  }
294
411
  if (isCallable(value)) {
295
- const params = (value.params ?? []).map((p) => paramToTypeTuple(p.name, p.type ?? { type: 'any' }, p.defaultValue));
412
+ const params = (value.params ?? []).map((p) => paramToFieldDef(p.name, p.type ?? { type: 'any' }, p.defaultValue));
296
413
  const ret = value.returnType.structure;
297
414
  return { type: 'closure', params, ret };
298
415
  }
@@ -300,7 +417,7 @@ export function inferStructuralType(value) {
300
417
  const dict = value;
301
418
  const fields = {};
302
419
  for (const [k, v] of Object.entries(dict)) {
303
- fields[k] = inferStructuralType(v);
420
+ fields[k] = { type: inferStructuralType(v) };
304
421
  }
305
422
  return { type: 'dict', fields };
306
423
  }
@@ -337,6 +454,11 @@ export function structuralTypeMatches(value, type) {
337
454
  if (type.type === 'dict') {
338
455
  if (!isDict(value))
339
456
  return false;
457
+ // Uniform value type check: every value must match valueType
458
+ if (type.valueType !== undefined) {
459
+ const vals = Object.values(value);
460
+ return vals.every((v) => structuralTypeMatches(v, type.valueType));
461
+ }
340
462
  // Absent fields sub-field: matches any dict value
341
463
  if (type.fields === undefined)
342
464
  return true;
@@ -346,13 +468,14 @@ export function structuralTypeMatches(value, type) {
346
468
  return true;
347
469
  const dict = value;
348
470
  for (const key of dictKeys) {
349
- if (!(key in dict))
471
+ if (!(key in dict)) {
472
+ const field = type.fields[key];
473
+ if (field.defaultValue !== undefined)
474
+ continue;
350
475
  return false;
351
- const fieldType = type.fields[key];
352
- const resolvedType = isFieldTypeWithDefault(fieldType)
353
- ? fieldType.type
354
- : fieldType;
355
- if (!structuralTypeMatches(dict[key], resolvedType))
476
+ }
477
+ const field = type.fields[key];
478
+ if (!structuralTypeMatches(dict[key], field.type))
356
479
  return false;
357
480
  }
358
481
  return true;
@@ -360,15 +483,28 @@ export function structuralTypeMatches(value, type) {
360
483
  if (type.type === 'tuple') {
361
484
  if (!isTuple(value))
362
485
  return false;
486
+ // Uniform value type check: every entry must match valueType
487
+ if (type.valueType !== undefined) {
488
+ return value.entries.every((v) => structuralTypeMatches(v, type.valueType));
489
+ }
363
490
  // Absent elements sub-field: matches any tuple value
364
491
  if (type.elements === undefined)
365
492
  return true;
366
493
  if (type.elements.length === 0)
367
494
  return value.entries.length === 0;
368
- if (value.entries.length !== type.elements.length)
495
+ // Reject if value has more entries than type elements
496
+ if (value.entries.length > type.elements.length)
369
497
  return false;
370
- for (let i = 0; i < type.elements.length; i++) {
371
- if (!structuralTypeMatches(value.entries[i], type.elements[i][0]))
498
+ // Reject if value is shorter and any trailing missing element lacks a default
499
+ if (value.entries.length < type.elements.length) {
500
+ for (let i = value.entries.length; i < type.elements.length; i++) {
501
+ const field = type.elements[i];
502
+ if (field.defaultValue === undefined)
503
+ return false;
504
+ }
505
+ }
506
+ for (let i = 0; i < value.entries.length; i++) {
507
+ if (!structuralTypeMatches(value.entries[i], type.elements[i].type))
372
508
  return false;
373
509
  }
374
510
  return true;
@@ -376,19 +512,32 @@ export function structuralTypeMatches(value, type) {
376
512
  if (type.type === 'ordered') {
377
513
  if (!isOrdered(value))
378
514
  return false;
515
+ // Uniform value type check: every entry value must match valueType
516
+ if (type.valueType !== undefined) {
517
+ return value.entries.every(([, v]) => structuralTypeMatches(v, type.valueType));
518
+ }
379
519
  // Absent fields sub-field: matches any ordered value
380
520
  if (type.fields === undefined)
381
521
  return true;
382
522
  if (type.fields.length === 0)
383
523
  return value.entries.length === 0;
384
- if (value.entries.length !== type.fields.length)
524
+ // Reject if value has more entries than type fields
525
+ if (value.entries.length > type.fields.length)
385
526
  return false;
386
- for (let i = 0; i < type.fields.length; i++) {
387
- const [expectedName, expectedType] = type.fields[i];
527
+ // Reject if value is shorter and any trailing missing field lacks a default
528
+ if (value.entries.length < type.fields.length) {
529
+ for (let i = value.entries.length; i < type.fields.length; i++) {
530
+ const field = type.fields[i];
531
+ if (field.defaultValue === undefined)
532
+ return false;
533
+ }
534
+ }
535
+ for (let i = 0; i < value.entries.length; i++) {
536
+ const field = type.fields[i];
388
537
  const [actualName, actualValue] = value.entries[i];
389
- if (actualName !== expectedName)
538
+ if (actualName !== field.name)
390
539
  return false;
391
- if (!structuralTypeMatches(actualValue, expectedType))
540
+ if (!structuralTypeMatches(actualValue, field.type))
392
541
  return false;
393
542
  }
394
543
  return true;
@@ -403,12 +552,12 @@ export function structuralTypeMatches(value, type) {
403
552
  if (valueParams.length !== type.params.length)
404
553
  return false;
405
554
  for (let i = 0; i < type.params.length; i++) {
406
- const [expectedName, expectedType] = type.params[i];
555
+ const field = type.params[i];
407
556
  const param = valueParams[i];
408
- if (param.name !== expectedName)
557
+ if (param.name !== field.name)
409
558
  return false;
410
559
  const paramType = param.type ?? { type: 'any' };
411
- if (!structuralTypeEquals(paramType, expectedType))
560
+ if (!structuralTypeEquals(paramType, field.type))
412
561
  return false;
413
562
  }
414
563
  const retType = value.returnType.structure;
@@ -421,9 +570,12 @@ export function structuralTypeMatches(value, type) {
421
570
  }
422
571
  return false;
423
572
  }
424
- /** Build a closure param tuple, omitting the optional third element when no default. */
425
- export function paramToTypeTuple(name, type, defaultValue) {
426
- return defaultValue !== undefined ? [name, type, defaultValue] : [name, type];
573
+ /** Build a closure param field definition from name, type, and optional default. */
574
+ export function paramToFieldDef(name, type, defaultValue) {
575
+ const field = { name, type };
576
+ if (defaultValue !== undefined)
577
+ field.defaultValue = defaultValue;
578
+ return field;
427
579
  }
428
580
  /** Format a RillValue as a rill literal for use in type signatures. */
429
581
  function formatRillLiteral(value) {
@@ -455,38 +607,47 @@ export function formatStructuralType(type) {
455
607
  return `list(${formatStructuralType(type.element)})`;
456
608
  }
457
609
  if (type.type === 'dict') {
610
+ if (type.valueType !== undefined && type.fields === undefined) {
611
+ return `dict(${formatStructuralType(type.valueType)})`;
612
+ }
458
613
  if (type.fields === undefined)
459
614
  return 'dict';
460
615
  const parts = Object.keys(type.fields)
461
616
  .sort()
462
617
  .map((k) => {
463
- const fieldType = type.fields[k];
464
- if (isFieldTypeWithDefault(fieldType)) {
465
- return `${k}: ${formatStructuralType(fieldType.type)} = ${formatRillLiteral(fieldType.defaultValue)}`;
466
- }
467
- return `${k}: ${formatStructuralType(fieldType)}`;
618
+ const field = type.fields[k];
619
+ const base = `${k}: ${formatStructuralType(field.type)}`;
620
+ if (field.defaultValue === undefined)
621
+ return base;
622
+ return `${base} = ${formatRillLiteral(field.defaultValue)}`;
468
623
  });
469
624
  return `dict(${parts.join(', ')})`;
470
625
  }
471
626
  if (type.type === 'tuple') {
627
+ if (type.valueType !== undefined && type.elements === undefined) {
628
+ return `tuple(${formatStructuralType(type.valueType)})`;
629
+ }
472
630
  if (type.elements === undefined)
473
631
  return 'tuple';
474
- const parts = type.elements.map(([t, defaultVal]) => {
475
- const base = formatStructuralType(t);
476
- if (defaultVal === undefined)
632
+ const parts = type.elements.map((field) => {
633
+ const base = formatStructuralType(field.type);
634
+ if (field.defaultValue === undefined)
477
635
  return base;
478
- return `${base} = ${formatRillLiteral(defaultVal)}`;
636
+ return `${base} = ${formatRillLiteral(field.defaultValue)}`;
479
637
  });
480
638
  return `tuple(${parts.join(', ')})`;
481
639
  }
482
640
  if (type.type === 'ordered') {
641
+ if (type.valueType !== undefined && type.fields === undefined) {
642
+ return `ordered(${formatStructuralType(type.valueType)})`;
643
+ }
483
644
  if (type.fields === undefined)
484
645
  return 'ordered';
485
- const parts = type.fields.map(([k, t, defaultVal]) => {
486
- const base = `${k}: ${formatStructuralType(t)}`;
487
- if (defaultVal === undefined)
646
+ const parts = type.fields.map((field) => {
647
+ const base = `${field.name}: ${formatStructuralType(field.type)}`;
648
+ if (field.defaultValue === undefined)
488
649
  return base;
489
- return `${base} = ${formatRillLiteral(defaultVal)}`;
650
+ return `${base} = ${formatRillLiteral(field.defaultValue)}`;
490
651
  });
491
652
  return `ordered(${parts.join(', ')})`;
492
653
  }
@@ -494,11 +655,11 @@ export function formatStructuralType(type) {
494
655
  if (type.params === undefined)
495
656
  return 'closure';
496
657
  const params = type.params
497
- .map(([name, t, defaultVal]) => {
498
- const base = `${name}: ${formatStructuralType(t)}`;
499
- if (defaultVal === undefined)
658
+ .map((field) => {
659
+ const base = `${field.name}: ${formatStructuralType(field.type)}`;
660
+ if (field.defaultValue === undefined)
500
661
  return base;
501
- return `${base} = ${formatRillLiteral(defaultVal)}`;
662
+ return `${base} = ${formatRillLiteral(field.defaultValue)}`;
502
663
  })
503
664
  .join(', ');
504
665
  const ret = type.ret !== undefined ? formatStructuralType(type.ret) : 'any';
@@ -855,6 +1016,29 @@ export function rillTypeToTypeValue(type) {
855
1016
  structure: type,
856
1017
  });
857
1018
  }
1019
+ /**
1020
+ * Check if a type is a collection (dict, ordered, tuple) with defined
1021
+ * fields or elements. Used to decide if an empty collection can be
1022
+ * synthesized and hydrated.
1023
+ */
1024
+ export function hasCollectionFields(type) {
1025
+ return ((type.type === 'dict' && (!!type.fields || !!type.valueType)) ||
1026
+ (type.type === 'ordered' && (!!type.fields || !!type.valueType)) ||
1027
+ (type.type === 'tuple' && (!!type.elements || !!type.valueType)));
1028
+ }
1029
+ /**
1030
+ * Create an empty collection value matching the given RillType.
1031
+ * Assumes the type is dict, ordered, or tuple.
1032
+ */
1033
+ export function emptyForType(type) {
1034
+ if (type.type === 'dict')
1035
+ return {};
1036
+ if (type.type === 'ordered')
1037
+ return createOrdered([]);
1038
+ if (type.type === 'tuple')
1039
+ return createTuple([]);
1040
+ return {};
1041
+ }
858
1042
  /** Check if a key name is reserved */
859
1043
  export function isReservedMethod(name) {
860
1044
  return RESERVED_DICT_METHODS.includes(name);
@@ -879,4 +1063,32 @@ export function isRillIterator(value) {
879
1063
  return false;
880
1064
  return true;
881
1065
  }
882
- //# sourceMappingURL=values.js.map
1066
+ /**
1067
+ * Deep copy a RillValue, producing a new independent value.
1068
+ * Handles primitives, arrays, plain dicts, and null.
1069
+ * Special markers (closures, tuples, ordered, vectors, type values) are returned
1070
+ * as-is since they are immutable by contract.
1071
+ */
1072
+ export function deepCopyRillValue(value) {
1073
+ if (value === null || typeof value !== 'object') {
1074
+ return value;
1075
+ }
1076
+ if (Array.isArray(value)) {
1077
+ return value.map(deepCopyRillValue);
1078
+ }
1079
+ // Plain dict: copy recursively. Special markers (RillTuple, RillOrdered, etc.)
1080
+ // carry __rill_* own properties and are treated as immutable; return as-is.
1081
+ if (!('__rill_tuple' in value) &&
1082
+ !('__rill_ordered' in value) &&
1083
+ !('__rill_vector' in value) &&
1084
+ !('__rill_type' in value) &&
1085
+ !('__type' in value) &&
1086
+ !('__rill_field_descriptor' in value)) {
1087
+ const copy = {};
1088
+ for (const [k, v] of Object.entries(value)) {
1089
+ copy[k] = deepCopyRillValue(v);
1090
+ }
1091
+ return copy;
1092
+ }
1093
+ return value;
1094
+ }
@@ -19,4 +19,3 @@ export declare const BUILTIN_METHODS: {
19
19
  bool: Record<string, RillFunction>;
20
20
  vector: Record<string, RillFunction>;
21
21
  };
22
- //# sourceMappingURL=builtins.d.ts.map