@rcrsr/rill 0.14.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 -11
  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 +50 -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 -40
  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 -31
  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 -69
  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 +263 -16
  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 -200
  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 -8
  136. package/dist/runtime/core/values.js +338 -36
  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 -4
  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
@@ -35,7 +35,11 @@ export function isTypeValue(value) {
35
35
  '__rill_type' in value &&
36
36
  value.__rill_type === true);
37
37
  }
38
- /** 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
+ */
39
43
  export function createOrdered(entries) {
40
44
  return Object.freeze({ __rill_ordered: true, entries: [...entries] });
41
45
  }
@@ -93,15 +97,112 @@ export function inferElementType(elements) {
93
97
  if (elements.length === 0)
94
98
  return { type: 'any' };
95
99
  const firstElem = elements[0];
96
- const firstType = inferStructuralType(firstElem);
100
+ let accType = inferStructuralType(firstElem);
97
101
  for (let i = 1; i < elements.length; i++) {
98
102
  const elem = elements[i];
99
103
  const elemType = inferStructuralType(elem);
100
- if (!structuralTypeEquals(firstType, elemType)) {
101
- 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 };
102
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 };
103
183
  }
104
- return firstType;
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 };
188
+ }
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;
105
206
  }
106
207
  /** Compare two structural types for equality. */
107
208
  export function structuralTypeEquals(a, b) {
@@ -124,6 +225,15 @@ export function structuralTypeEquals(a, b) {
124
225
  return structuralTypeEquals(a.element, b.element);
125
226
  }
126
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
127
237
  if (a.fields === undefined && b.fields === undefined)
128
238
  return true;
129
239
  if (a.fields === undefined || b.fields === undefined)
@@ -138,12 +248,29 @@ export function structuralTypeEquals(a, b) {
138
248
  return false;
139
249
  const aField = a.fields[key];
140
250
  const bField = b.fields[key];
141
- if (!structuralTypeEquals(aField, bField))
251
+ const aHasDefault = aField.defaultValue !== undefined;
252
+ const bHasDefault = bField.defaultValue !== undefined;
253
+ if (aHasDefault !== bHasDefault)
142
254
  return false;
255
+ if (!structuralTypeEquals(aField.type, bField.type))
256
+ return false;
257
+ if (aHasDefault && bHasDefault) {
258
+ if (!deepEquals(aField.defaultValue, bField.defaultValue))
259
+ return false;
260
+ }
143
261
  }
144
262
  return true;
145
263
  }
146
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
147
274
  if (a.elements === undefined && b.elements === undefined)
148
275
  return true;
149
276
  if (a.elements === undefined || b.elements === undefined)
@@ -151,12 +278,31 @@ export function structuralTypeEquals(a, b) {
151
278
  if (a.elements.length !== b.elements.length)
152
279
  return false;
153
280
  for (let i = 0; i < a.elements.length; i++) {
154
- if (!structuralTypeEquals(a.elements[i], b.elements[i]))
281
+ const aElem = a.elements[i];
282
+ const bElem = b.elements[i];
283
+ if (!structuralTypeEquals(aElem.type, bElem.type))
284
+ return false;
285
+ const aDefault = aElem.defaultValue;
286
+ const bDefault = bElem.defaultValue;
287
+ if (aDefault === undefined && bDefault === undefined)
288
+ continue;
289
+ if (aDefault === undefined || bDefault === undefined)
290
+ return false;
291
+ if (!deepEquals(aDefault, bDefault))
155
292
  return false;
156
293
  }
157
294
  return true;
158
295
  }
159
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
160
306
  if (a.fields === undefined && b.fields === undefined)
161
307
  return true;
162
308
  if (a.fields === undefined || b.fields === undefined)
@@ -166,9 +312,17 @@ export function structuralTypeEquals(a, b) {
166
312
  for (let i = 0; i < a.fields.length; i++) {
167
313
  const aField = a.fields[i];
168
314
  const bField = b.fields[i];
169
- if (aField[0] !== bField[0])
315
+ if (aField.name !== bField.name)
170
316
  return false;
171
- if (!structuralTypeEquals(aField[1], bField[1]))
317
+ if (!structuralTypeEquals(aField.type, bField.type))
318
+ return false;
319
+ const aDefault = aField.defaultValue;
320
+ const bDefault = bField.defaultValue;
321
+ if (aDefault === undefined && bDefault === undefined)
322
+ continue;
323
+ if (aDefault === undefined || bDefault === undefined)
324
+ return false;
325
+ if (!deepEquals(aDefault, bDefault))
172
326
  return false;
173
327
  }
174
328
  return true;
@@ -195,9 +349,17 @@ export function structuralTypeEquals(a, b) {
195
349
  for (let i = 0; i < a.params.length; i++) {
196
350
  const aParam = a.params[i];
197
351
  const bParam = b.params[i];
198
- if (aParam[0] !== bParam[0])
352
+ if (aParam.name !== bParam.name)
353
+ return false;
354
+ if (!structuralTypeEquals(aParam.type, bParam.type))
355
+ return false;
356
+ const aDefault = aParam.defaultValue;
357
+ const bDefault = bParam.defaultValue;
358
+ if (aDefault === undefined && bDefault === undefined)
359
+ continue;
360
+ if (aDefault === undefined || bDefault === undefined)
199
361
  return false;
200
- if (!structuralTypeEquals(aParam[1], bParam[1]))
362
+ if (!deepEquals(aDefault, bDefault))
201
363
  return false;
202
364
  }
203
365
  }
@@ -229,23 +391,25 @@ export function inferStructuralType(value) {
229
391
  if (isTuple(value)) {
230
392
  return {
231
393
  type: 'tuple',
232
- elements: value.entries.map(inferStructuralType),
394
+ elements: value.entries.map((e) => ({
395
+ type: inferStructuralType(e),
396
+ })),
233
397
  };
234
398
  }
235
399
  if (isOrdered(value)) {
236
400
  return {
237
401
  type: 'ordered',
238
- fields: value.entries.map(([k, v]) => [k, inferStructuralType(v)]),
402
+ fields: value.entries.map(([k, v]) => ({
403
+ name: k,
404
+ type: inferStructuralType(v),
405
+ })),
239
406
  };
240
407
  }
241
408
  if (isVector(value)) {
242
409
  return { type: 'vector' };
243
410
  }
244
411
  if (isCallable(value)) {
245
- const params = (value.params ?? []).map((p) => [
246
- p.name,
247
- p.type ?? { type: 'any' },
248
- ]);
412
+ const params = (value.params ?? []).map((p) => paramToFieldDef(p.name, p.type ?? { type: 'any' }, p.defaultValue));
249
413
  const ret = value.returnType.structure;
250
414
  return { type: 'closure', params, ret };
251
415
  }
@@ -253,7 +417,7 @@ export function inferStructuralType(value) {
253
417
  const dict = value;
254
418
  const fields = {};
255
419
  for (const [k, v] of Object.entries(dict)) {
256
- fields[k] = inferStructuralType(v);
420
+ fields[k] = { type: inferStructuralType(v) };
257
421
  }
258
422
  return { type: 'dict', fields };
259
423
  }
@@ -290,6 +454,11 @@ export function structuralTypeMatches(value, type) {
290
454
  if (type.type === 'dict') {
291
455
  if (!isDict(value))
292
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
+ }
293
462
  // Absent fields sub-field: matches any dict value
294
463
  if (type.fields === undefined)
295
464
  return true;
@@ -299,9 +468,14 @@ export function structuralTypeMatches(value, type) {
299
468
  return true;
300
469
  const dict = value;
301
470
  for (const key of dictKeys) {
302
- if (!(key in dict))
471
+ if (!(key in dict)) {
472
+ const field = type.fields[key];
473
+ if (field.defaultValue !== undefined)
474
+ continue;
303
475
  return false;
304
- if (!structuralTypeMatches(dict[key], type.fields[key]))
476
+ }
477
+ const field = type.fields[key];
478
+ if (!structuralTypeMatches(dict[key], field.type))
305
479
  return false;
306
480
  }
307
481
  return true;
@@ -309,15 +483,28 @@ export function structuralTypeMatches(value, type) {
309
483
  if (type.type === 'tuple') {
310
484
  if (!isTuple(value))
311
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
+ }
312
490
  // Absent elements sub-field: matches any tuple value
313
491
  if (type.elements === undefined)
314
492
  return true;
315
493
  if (type.elements.length === 0)
316
494
  return value.entries.length === 0;
317
- 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)
318
497
  return false;
319
- for (let i = 0; i < type.elements.length; i++) {
320
- if (!structuralTypeMatches(value.entries[i], type.elements[i]))
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))
321
508
  return false;
322
509
  }
323
510
  return true;
@@ -325,19 +512,32 @@ export function structuralTypeMatches(value, type) {
325
512
  if (type.type === 'ordered') {
326
513
  if (!isOrdered(value))
327
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
+ }
328
519
  // Absent fields sub-field: matches any ordered value
329
520
  if (type.fields === undefined)
330
521
  return true;
331
522
  if (type.fields.length === 0)
332
523
  return value.entries.length === 0;
333
- 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)
334
526
  return false;
335
- for (let i = 0; i < type.fields.length; i++) {
336
- 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];
337
537
  const [actualName, actualValue] = value.entries[i];
338
- if (actualName !== expectedName)
538
+ if (actualName !== field.name)
339
539
  return false;
340
- if (!structuralTypeMatches(actualValue, expectedType))
540
+ if (!structuralTypeMatches(actualValue, field.type))
341
541
  return false;
342
542
  }
343
543
  return true;
@@ -352,12 +552,12 @@ export function structuralTypeMatches(value, type) {
352
552
  if (valueParams.length !== type.params.length)
353
553
  return false;
354
554
  for (let i = 0; i < type.params.length; i++) {
355
- const [expectedName, expectedType] = type.params[i];
555
+ const field = type.params[i];
356
556
  const param = valueParams[i];
357
- if (param.name !== expectedName)
557
+ if (param.name !== field.name)
358
558
  return false;
359
559
  const paramType = param.type ?? { type: 'any' };
360
- if (!structuralTypeEquals(paramType, expectedType))
560
+ if (!structuralTypeEquals(paramType, field.type))
361
561
  return false;
362
562
  }
363
563
  const retType = value.returnType.structure;
@@ -370,6 +570,27 @@ export function structuralTypeMatches(value, type) {
370
570
  }
371
571
  return false;
372
572
  }
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;
579
+ }
580
+ /** Format a RillValue as a rill literal for use in type signatures. */
581
+ function formatRillLiteral(value) {
582
+ if (typeof value === 'string') {
583
+ const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
584
+ return `"${escaped}"`;
585
+ }
586
+ if (typeof value === 'number')
587
+ return String(value);
588
+ if (typeof value === 'boolean')
589
+ return value ? 'true' : 'false';
590
+ if (value === null)
591
+ return 'null';
592
+ return formatValue(value);
593
+ }
373
594
  /** Format a structural type descriptor as a human-readable string. */
374
595
  export function formatStructuralType(type) {
375
596
  if (type.type === 'any' ||
@@ -386,30 +607,60 @@ export function formatStructuralType(type) {
386
607
  return `list(${formatStructuralType(type.element)})`;
387
608
  }
388
609
  if (type.type === 'dict') {
610
+ if (type.valueType !== undefined && type.fields === undefined) {
611
+ return `dict(${formatStructuralType(type.valueType)})`;
612
+ }
389
613
  if (type.fields === undefined)
390
614
  return 'dict';
391
615
  const parts = Object.keys(type.fields)
392
616
  .sort()
393
- .map((k) => `${k}: ${formatStructuralType(type.fields[k])}`);
617
+ .map((k) => {
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)}`;
623
+ });
394
624
  return `dict(${parts.join(', ')})`;
395
625
  }
396
626
  if (type.type === 'tuple') {
627
+ if (type.valueType !== undefined && type.elements === undefined) {
628
+ return `tuple(${formatStructuralType(type.valueType)})`;
629
+ }
397
630
  if (type.elements === undefined)
398
631
  return 'tuple';
399
- const parts = type.elements.map(formatStructuralType);
632
+ const parts = type.elements.map((field) => {
633
+ const base = formatStructuralType(field.type);
634
+ if (field.defaultValue === undefined)
635
+ return base;
636
+ return `${base} = ${formatRillLiteral(field.defaultValue)}`;
637
+ });
400
638
  return `tuple(${parts.join(', ')})`;
401
639
  }
402
640
  if (type.type === 'ordered') {
641
+ if (type.valueType !== undefined && type.fields === undefined) {
642
+ return `ordered(${formatStructuralType(type.valueType)})`;
643
+ }
403
644
  if (type.fields === undefined)
404
645
  return 'ordered';
405
- const parts = type.fields.map(([k, t]) => `${k}: ${formatStructuralType(t)}`);
646
+ const parts = type.fields.map((field) => {
647
+ const base = `${field.name}: ${formatStructuralType(field.type)}`;
648
+ if (field.defaultValue === undefined)
649
+ return base;
650
+ return `${base} = ${formatRillLiteral(field.defaultValue)}`;
651
+ });
406
652
  return `ordered(${parts.join(', ')})`;
407
653
  }
408
654
  if (type.type === 'closure') {
409
655
  if (type.params === undefined)
410
656
  return 'closure';
411
657
  const params = type.params
412
- .map(([name, t]) => `${name}: ${formatStructuralType(t)}`)
658
+ .map((field) => {
659
+ const base = `${field.name}: ${formatStructuralType(field.type)}`;
660
+ if (field.defaultValue === undefined)
661
+ return base;
662
+ return `${base} = ${formatRillLiteral(field.defaultValue)}`;
663
+ })
413
664
  .join(', ');
414
665
  const ret = type.ret !== undefined ? formatStructuralType(type.ret) : 'any';
415
666
  return `|${params}| :${ret}`;
@@ -765,6 +1016,29 @@ export function rillTypeToTypeValue(type) {
765
1016
  structure: type,
766
1017
  });
767
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
+ }
768
1042
  /** Check if a key name is reserved */
769
1043
  export function isReservedMethod(name) {
770
1044
  return RESERVED_DICT_METHODS.includes(name);
@@ -789,4 +1063,32 @@ export function isRillIterator(value) {
789
1063
  return false;
790
1064
  return true;
791
1065
  }
792
- //# 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