semantifold 0.3.0 → 0.4.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 (297) hide show
  1. package/README.md +58 -15
  2. package/build/index.d.ts +48 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +57 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/c-validation.d.ts.map +1 -1
  11. package/build/src/backends/c-validation.js +7 -3
  12. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  13. package/build/src/backends/cpp-validation.js +7 -3
  14. package/build/src/backends/csharp.js +7 -1
  15. package/build/src/backends/dart-runtime.d.ts +2 -0
  16. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  17. package/build/src/backends/dart-runtime.js +41 -0
  18. package/build/src/backends/dart.d.ts +20 -0
  19. package/build/src/backends/dart.d.ts.map +1 -0
  20. package/build/src/backends/dart.js +321 -0
  21. package/build/src/backends/effects.d.ts +60 -0
  22. package/build/src/backends/effects.d.ts.map +1 -0
  23. package/build/src/backends/effects.js +746 -0
  24. package/build/src/backends/go.js +18 -4
  25. package/build/src/backends/identifiers.d.ts +36 -4
  26. package/build/src/backends/identifiers.d.ts.map +1 -1
  27. package/build/src/backends/identifiers.js +154 -10
  28. package/build/src/backends/index.d.ts.map +1 -1
  29. package/build/src/backends/index.js +27 -4
  30. package/build/src/backends/ios.d.ts +68 -0
  31. package/build/src/backends/ios.d.ts.map +1 -0
  32. package/build/src/backends/ios.js +1503 -0
  33. package/build/src/backends/java.d.ts.map +1 -1
  34. package/build/src/backends/java.js +429 -36
  35. package/build/src/backends/javascript.d.ts +6 -0
  36. package/build/src/backends/javascript.d.ts.map +1 -1
  37. package/build/src/backends/javascript.js +380 -24
  38. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  39. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  40. package/build/src/backends/kotlin-runtime.js +29 -0
  41. package/build/src/backends/kotlin.d.ts +23 -0
  42. package/build/src/backends/kotlin.d.ts.map +1 -0
  43. package/build/src/backends/kotlin.js +136 -0
  44. package/build/src/backends/native-validation.d.ts +2 -2
  45. package/build/src/backends/native-validation.d.ts.map +1 -1
  46. package/build/src/backends/native-validation.js +2 -2
  47. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  48. package/build/src/backends/ordered-expressions.js +39 -7
  49. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  50. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  51. package/build/src/backends/php-stdlib-support.js +227 -0
  52. package/build/src/backends/php.d.ts.map +1 -1
  53. package/build/src/backends/php.js +448 -33
  54. package/build/src/backends/program.d.ts +81 -0
  55. package/build/src/backends/program.d.ts.map +1 -0
  56. package/build/src/backends/program.js +1308 -0
  57. package/build/src/backends/python.js +7 -1
  58. package/build/src/backends/ruby.d.ts.map +1 -1
  59. package/build/src/backends/ruby.js +310 -24
  60. package/build/src/backends/rust-runtime.d.ts +7 -0
  61. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  62. package/build/src/backends/rust-runtime.js +32 -0
  63. package/build/src/backends/rust-validation.d.ts +9 -0
  64. package/build/src/backends/rust-validation.d.ts.map +1 -0
  65. package/build/src/backends/rust-validation.js +78 -0
  66. package/build/src/backends/rust.d.ts +24 -0
  67. package/build/src/backends/rust.d.ts.map +1 -0
  68. package/build/src/backends/rust.js +344 -0
  69. package/build/src/backends/scalars.d.ts +14 -6
  70. package/build/src/backends/scalars.d.ts.map +1 -1
  71. package/build/src/backends/scalars.js +167 -17
  72. package/build/src/backends/shared.d.ts +23 -4
  73. package/build/src/backends/shared.d.ts.map +1 -1
  74. package/build/src/backends/shared.js +2158 -62
  75. package/build/src/backends/stdlib-support.d.ts +14 -0
  76. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  77. package/build/src/backends/stdlib-support.js +237 -0
  78. package/build/src/backends/swift-runtime.d.ts +3 -0
  79. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  80. package/build/src/backends/swift-runtime.js +14 -0
  81. package/build/src/backends/swift.d.ts +8 -0
  82. package/build/src/backends/swift.d.ts.map +1 -0
  83. package/build/src/backends/swift.js +127 -0
  84. package/build/src/backends/typescript.d.ts.map +1 -1
  85. package/build/src/backends/typescript.js +344 -24
  86. package/build/src/backends/wasm.d.ts +43 -0
  87. package/build/src/backends/wasm.d.ts.map +1 -0
  88. package/build/src/backends/wasm.js +2164 -0
  89. package/build/src/backends/writer.d.ts +235 -4
  90. package/build/src/backends/writer.d.ts.map +1 -1
  91. package/build/src/backends/writer.js +468 -3
  92. package/build/src/diagnostic.d.ts +4 -3
  93. package/build/src/diagnostic.d.ts.map +1 -1
  94. package/build/src/diagnostic.js +5 -3
  95. package/build/src/frontends/c.d.ts.map +1 -1
  96. package/build/src/frontends/c.js +5 -3
  97. package/build/src/frontends/cpp.d.ts.map +1 -1
  98. package/build/src/frontends/cpp.js +5 -3
  99. package/build/src/frontends/csharp.d.ts.map +1 -1
  100. package/build/src/frontends/csharp.js +7 -3
  101. package/build/src/frontends/dart.d.ts +10 -0
  102. package/build/src/frontends/dart.d.ts.map +1 -0
  103. package/build/src/frontends/dart.js +913 -0
  104. package/build/src/frontends/index.d.ts +3 -1
  105. package/build/src/frontends/index.d.ts.map +1 -1
  106. package/build/src/frontends/index.js +15 -5
  107. package/build/src/frontends/java.d.ts +110 -1
  108. package/build/src/frontends/java.d.ts.map +1 -1
  109. package/build/src/frontends/java.js +1725 -70
  110. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  111. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  112. package/build/src/frontends/javascript-typescript.js +1825 -93
  113. package/build/src/frontends/kotlin.d.ts +10 -0
  114. package/build/src/frontends/kotlin.d.ts.map +1 -0
  115. package/build/src/frontends/kotlin.js +685 -0
  116. package/build/src/frontends/php.d.ts +118 -1
  117. package/build/src/frontends/php.d.ts.map +1 -1
  118. package/build/src/frontends/php.js +1583 -76
  119. package/build/src/frontends/program.d.ts +74 -0
  120. package/build/src/frontends/program.d.ts.map +1 -0
  121. package/build/src/frontends/program.js +989 -0
  122. package/build/src/frontends/ruby.d.ts +68 -1
  123. package/build/src/frontends/ruby.d.ts.map +1 -1
  124. package/build/src/frontends/ruby.js +1446 -101
  125. package/build/src/frontends/rust-parser.d.ts +11 -0
  126. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  127. package/build/src/frontends/rust-parser.js +15 -0
  128. package/build/src/frontends/rust.d.ts +14 -0
  129. package/build/src/frontends/rust.d.ts.map +1 -0
  130. package/build/src/frontends/rust.js +715 -0
  131. package/build/src/frontends/scalars.d.ts +10 -0
  132. package/build/src/frontends/scalars.d.ts.map +1 -1
  133. package/build/src/frontends/scalars.js +28 -2
  134. package/build/src/frontends/swift.d.ts +10 -0
  135. package/build/src/frontends/swift.d.ts.map +1 -0
  136. package/build/src/frontends/swift.js +860 -0
  137. package/build/src/frontends/types.d.ts +186 -0
  138. package/build/src/frontends/types.d.ts.map +1 -0
  139. package/build/src/frontends/types.js +634 -0
  140. package/build/src/language-registry.d.ts +46 -4
  141. package/build/src/language-registry.d.ts.map +1 -1
  142. package/build/src/language-registry.js +167 -13
  143. package/build/src/mapping.d.ts +2 -2
  144. package/build/src/mapping.d.ts.map +1 -1
  145. package/build/src/mapping.js +31 -10
  146. package/build/src/semantic/capabilities.d.ts +66 -0
  147. package/build/src/semantic/capabilities.d.ts.map +1 -0
  148. package/build/src/semantic/capabilities.js +649 -0
  149. package/build/src/semantic/effects.d.ts +26 -0
  150. package/build/src/semantic/effects.d.ts.map +1 -0
  151. package/build/src/semantic/effects.js +764 -0
  152. package/build/src/semantic/generics.d.ts +23 -0
  153. package/build/src/semantic/generics.d.ts.map +1 -0
  154. package/build/src/semantic/generics.js +61 -0
  155. package/build/src/semantic/lifetime.d.ts +37 -0
  156. package/build/src/semantic/lifetime.d.ts.map +1 -0
  157. package/build/src/semantic/lifetime.js +527 -0
  158. package/build/src/semantic/provenance.d.ts +9 -2
  159. package/build/src/semantic/provenance.d.ts.map +1 -1
  160. package/build/src/semantic/provenance.js +462 -20
  161. package/build/src/semantic/scalars.d.ts +11 -0
  162. package/build/src/semantic/scalars.d.ts.map +1 -1
  163. package/build/src/semantic/scalars.js +16 -1
  164. package/build/src/semantic/stdlib.d.ts +254 -0
  165. package/build/src/semantic/stdlib.d.ts.map +1 -0
  166. package/build/src/semantic/stdlib.js +880 -0
  167. package/build/src/semantic/types.d.ts +2952 -202
  168. package/build/src/semantic/types.d.ts.map +1 -1
  169. package/build/src/semantic/types.js +688 -15
  170. package/build/src/semantic/validate.d.ts +85 -5
  171. package/build/src/semantic/validate.d.ts.map +1 -1
  172. package/build/src/semantic/validate.js +2576 -98
  173. package/build/src/stdlib-facades.d.ts +304 -0
  174. package/build/src/stdlib-facades.d.ts.map +1 -0
  175. package/build/src/stdlib-facades.js +1167 -0
  176. package/build/src/stdlib-negotiation.d.ts +69 -0
  177. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  178. package/build/src/stdlib-negotiation.js +403 -0
  179. package/build/src/stdlib-providers.d.ts +72 -0
  180. package/build/src/stdlib-providers.d.ts.map +1 -0
  181. package/build/src/stdlib-providers.js +339 -0
  182. package/build/src/toolchains.d.ts +55 -1
  183. package/build/src/toolchains.d.ts.map +1 -1
  184. package/build/src/toolchains.js +15 -4
  185. package/docs/architecture.md +45 -13
  186. package/docs/dart.md +60 -0
  187. package/docs/goals.md +3 -3
  188. package/docs/ios.md +121 -0
  189. package/docs/kotlin.md +42 -0
  190. package/docs/language-support.md +231 -26
  191. package/docs/multi-file-modules.md +52 -0
  192. package/docs/parser-qualification.md +121 -8
  193. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  194. package/docs/rust.md +88 -0
  195. package/docs/source-maps.md +15 -7
  196. package/docs/standard-library-portability.md +39 -8
  197. package/docs/swift.md +44 -0
  198. package/docs/testing.md +366 -4
  199. package/docs/webassembly.md +52 -0
  200. package/index.js +63 -8
  201. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  202. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  203. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  204. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  205. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  231. package/package.json +5 -2
  232. package/src/artifact-path.js +47 -2
  233. package/src/artifacts.js +67 -0
  234. package/src/backends/c-validation.js +6 -1
  235. package/src/backends/cpp-validation.js +6 -1
  236. package/src/backends/csharp.js +3 -0
  237. package/src/backends/dart-runtime.js +41 -0
  238. package/src/backends/dart.js +326 -0
  239. package/src/backends/effects.js +705 -0
  240. package/src/backends/go.js +14 -2
  241. package/src/backends/identifiers.js +160 -9
  242. package/src/backends/index.js +27 -2
  243. package/src/backends/ios.js +1612 -0
  244. package/src/backends/java.js +454 -36
  245. package/src/backends/javascript.js +389 -23
  246. package/src/backends/kotlin-runtime.js +29 -0
  247. package/src/backends/kotlin.js +141 -0
  248. package/src/backends/native-validation.js +1 -1
  249. package/src/backends/ordered-expressions.js +40 -6
  250. package/src/backends/php-stdlib-support.js +239 -0
  251. package/src/backends/php.js +469 -32
  252. package/src/backends/program.js +1407 -0
  253. package/src/backends/python.js +3 -0
  254. package/src/backends/ruby.js +326 -23
  255. package/src/backends/rust-runtime.js +34 -0
  256. package/src/backends/rust-validation.js +75 -0
  257. package/src/backends/rust.js +335 -0
  258. package/src/backends/scalars.js +141 -16
  259. package/src/backends/shared.js +2304 -124
  260. package/src/backends/stdlib-support.js +234 -0
  261. package/src/backends/swift-runtime.js +14 -0
  262. package/src/backends/swift.js +132 -0
  263. package/src/backends/typescript.js +349 -23
  264. package/src/backends/wasm.js +2208 -0
  265. package/src/backends/writer.js +520 -2
  266. package/src/diagnostic.js +4 -2
  267. package/src/frontends/c.js +4 -2
  268. package/src/frontends/cpp.js +4 -2
  269. package/src/frontends/csharp.js +4 -2
  270. package/src/frontends/dart.js +963 -0
  271. package/src/frontends/index.js +14 -4
  272. package/src/frontends/java.js +1977 -69
  273. package/src/frontends/javascript-typescript.js +2046 -102
  274. package/src/frontends/kotlin.js +713 -0
  275. package/src/frontends/php.js +1725 -79
  276. package/src/frontends/program.js +1062 -0
  277. package/src/frontends/ruby.js +1624 -98
  278. package/src/frontends/rust-parser.js +18 -0
  279. package/src/frontends/rust.js +714 -0
  280. package/src/frontends/scalars.js +31 -1
  281. package/src/frontends/swift.js +893 -0
  282. package/src/frontends/types.js +750 -0
  283. package/src/language-registry.js +172 -12
  284. package/src/mapping.js +33 -9
  285. package/src/semantic/capabilities.js +671 -0
  286. package/src/semantic/effects.js +737 -0
  287. package/src/semantic/generics.js +58 -0
  288. package/src/semantic/lifetime.js +517 -0
  289. package/src/semantic/provenance.js +412 -19
  290. package/src/semantic/scalars.js +17 -0
  291. package/src/semantic/stdlib.js +921 -0
  292. package/src/semantic/types.js +765 -14
  293. package/src/semantic/validate.js +2934 -209
  294. package/src/stdlib-facades.js +1211 -0
  295. package/src/stdlib-negotiation.js +446 -0
  296. package/src/stdlib-providers.js +377 -0
  297. package/src/toolchains.js +16 -3
@@ -0,0 +1,446 @@
1
+ // @ts-check
2
+
3
+ import {isDenseArray} from "./array.js"
4
+ import {SemantifoldDiagnostic} from "./diagnostic.js"
5
+ import {
6
+ compareStdlibVersions,
7
+ createStdlibContractRegistry,
8
+ intersectStdlibVersionRanges,
9
+ parseStdlibVersion,
10
+ parseStdlibVersionRange,
11
+ stdlibVersionSatisfies
12
+ } from "./semantic/stdlib.js"
13
+ import {stdlibProviderRegistry} from "./stdlib-providers.js"
14
+
15
+ /** @typedef {import("./semantic/stdlib.js").StdlibContractRegistry} StdlibContractRegistry */
16
+ /** @typedef {import("./stdlib-providers.js").StdlibProviderRecord} StdlibProviderRecord */
17
+ /** @typedef {import("./semantic/stdlib.js").VersionRange} VersionRange */
18
+
19
+ /** @type {Readonly<VersionRange>} */
20
+ const universalRange = Object.freeze({lower: /** @type {[number, number, number]} */ (Object.freeze([0, 0, 0])), upper: null})
21
+ const builtinContracts = createStdlibContractRegistry()
22
+
23
+ /**
24
+ * @typedef StdlibNegotiationRequirement
25
+ * @property {string} module - Canonical module identity.
26
+ * @property {string[]} operations - Required canonical operations.
27
+ * @property {string | undefined} [range] - Declared version range.
28
+ */
29
+
30
+ /**
31
+ * @typedef StdlibNegotiationResult
32
+ * @property {string} target - Negotiated target language.
33
+ * @property {readonly {identity: string, operations: string[], version: string}[]} modules - Linked modules in identity order.
34
+ * @property {readonly {identity: string, target: string, module: string, version: string, operations: string[], nativeEntries: Readonly<Record<string, string>>, runtimeProfile: string}[]} providers - Selected providers in identity order.
35
+ */
36
+
37
+ /**
38
+ * Negotiates the complete transitive stdlib provider closure for one target.
39
+ * @param {{contracts?: StdlibContractRegistry, providers?: {providersFor(target: string, module: string, version: string): readonly StdlibProviderRecord[]}, requirements: StdlibNegotiationRequirement[], target: string}} input - Negotiation request.
40
+ * @returns {Readonly<StdlibNegotiationResult>} Frozen negotiation result.
41
+ */
42
+ export function negotiateStdlibProviders({contracts = builtinContracts, providers = stdlibProviderRegistry, requirements, target}) {
43
+ if (!isDenseArray(requirements)) invalidRequirement("Stdlib negotiation requirements must be an ordered dense array.")
44
+ /** @type {Map<string, VersionRange>} */
45
+ const ranges = new Map()
46
+ /** @type {Map<string, string>} */
47
+ const rangeKeys = new Map()
48
+ /** @type {Map<string, Set<string>>} */
49
+ const usedOperations = new Map()
50
+
51
+ /**
52
+ * Intersects one declared range into the per-module closure.
53
+ * @param {string} module - Canonical module identity.
54
+ * @param {VersionRange} range - Declared version range.
55
+ * @returns {boolean} Whether the combined range changed.
56
+ */
57
+ function addRange(module, range) {
58
+ const current = ranges.get(module) ?? universalRange
59
+ const next = intersectStdlibVersionRanges(current, range)
60
+
61
+ if (next === null) throw new SemantifoldDiagnostic({
62
+ code: "STDLIB_VERSION_INCOMPATIBLE",
63
+ language: module,
64
+ message: `Canonical module '${module}' has no version satisfying every declared range.`
65
+ })
66
+ const key = rangeKey(next)
67
+
68
+ if (rangeKeys.get(module) == key) return false
69
+ ranges.set(module, next)
70
+ rangeKeys.set(module, key)
71
+ return true
72
+ }
73
+
74
+ /**
75
+ * Rejects a module identity absent from the contract registry.
76
+ * @param {string} module - Canonical module identity.
77
+ * @returns {void}
78
+ */
79
+ function requireModule(module) {
80
+ if (!contracts.modules.some(({identity}) => identity == module)) {
81
+ throw new SemantifoldDiagnostic({
82
+ code: "STDLIB_MODULE_UNKNOWN",
83
+ language: module,
84
+ message: `Canonical module '${module}' is not registered.`
85
+ })
86
+ }
87
+ }
88
+
89
+ for (const requirement of requirements) {
90
+ if (!isPlainObject(requirement)) invalidRequirement("Every stdlib negotiation requirement must be a plain object.")
91
+ const module = /** @type {string} */ (requirement.module)
92
+ const operations = /** @type {unknown} */ (requirement.operations)
93
+
94
+ if (typeof module != "string") {
95
+ throw new SemantifoldDiagnostic({code: "STDLIB_MODULE_UNKNOWN", language: String(module), message: "Canonical module identity is missing."})
96
+ }
97
+ if (!isDenseArray(operations) || !operations.every((operation) => typeof operation == "string")) {
98
+ invalidRequirement(`Requirement for module '${module}' declares invalid operations.`)
99
+ }
100
+ if (operations.length == 0) continue
101
+ requireModule(module)
102
+ for (const operation of /** @type {string[]} */ (operations)) {
103
+ const used = usedOperations.get(module) ?? new Set()
104
+
105
+ used.add(operation)
106
+ usedOperations.set(module, used)
107
+ }
108
+ if (requirement.range !== undefined) {
109
+ const range = parseStdlibVersionRange(requirement.range)
110
+
111
+ if (range === null) malformedRange(String(requirement.range))
112
+ addRange(module, range)
113
+ }
114
+ }
115
+
116
+ let changed = true
117
+
118
+ while (changed) {
119
+ changed = false
120
+
121
+ for (const module of [...usedOperations.keys()].sort()) {
122
+ const contract = resolveModuleVersion(contracts, module, ranges.get(module) ?? universalRange)
123
+ const declared = new Map(contract.operations.map(({dependencies, name}) => [name, dependencies]))
124
+
125
+ for (const dependency of contract.dependencies) {
126
+ requireModule(dependency.module)
127
+ if (addRange(dependency.module, asVersionRange(dependency.range))) changed = true
128
+ if (!usedOperations.has(dependency.module)) {
129
+ usedOperations.set(dependency.module, new Set())
130
+ changed = true
131
+ }
132
+ }
133
+
134
+ for (const operation of [.../** @type {Set<string>} */ (usedOperations.get(module))].sort()) {
135
+ const dependencies = declared.get(operation)
136
+
137
+ if (dependencies === undefined) undeclaredOperation(module, operation)
138
+ for (const dependency of dependencies) {
139
+ const {module: dependencyModule, operation: dependencyOperation, range} = dependency
140
+
141
+ requireModule(dependencyModule)
142
+ if (addRange(dependencyModule, asVersionRange(range))) changed = true
143
+ const used = usedOperations.get(dependencyModule) ?? new Set()
144
+
145
+ if (!used.has(dependencyOperation)) {
146
+ used.add(dependencyOperation)
147
+ usedOperations.set(dependencyModule, used)
148
+ changed = true
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ /** @type {Map<string, StdlibProviderRecord>} */
156
+ const selectedProviders = new Map()
157
+ let stable = false
158
+
159
+ while (!stable) {
160
+ stable = true
161
+ selectedProviders.clear()
162
+
163
+ for (const module of [...usedOperations.keys()].sort()) {
164
+ const contract = resolveModuleVersion(contracts, module, ranges.get(module) ?? universalRange)
165
+ const candidates = providers.providersFor(target, module, contract.version)
166
+
167
+ if (candidates.length == 0) {
168
+ throw new SemantifoldDiagnostic({
169
+ code: "STDLIB_PROVIDER_MISSING",
170
+ language: target,
171
+ message: `No registered provider serves module '${module}' version '${contract.version}'.`
172
+ })
173
+ }
174
+ if (candidates.length > 1) {
175
+ throw new SemantifoldDiagnostic({
176
+ code: "STDLIB_PROVIDER_AMBIGUOUS",
177
+ language: target,
178
+ message: `Multiple registered providers serve module '${module}' version '${contract.version}'.`
179
+ })
180
+ }
181
+ const provider = /** @type {StdlibProviderRecord} */ (candidates[0])
182
+
183
+ selectedProviders.set(module, provider)
184
+ for (const dependency of provider.dependencies) {
185
+ if (!contracts.modules.some(({identity}) => identity == dependency.module)) {
186
+ throw new SemantifoldDiagnostic({
187
+ code: "STDLIB_PROVIDER_DEPENDENCY_MISSING",
188
+ language: provider.identity,
189
+ message: `Provider dependency module '${dependency.module}' is not registered.`
190
+ })
191
+ }
192
+ if (addRange(dependency.module, asVersionRange(dependency.range))) stable = false
193
+ if (!usedOperations.has(dependency.module)) {
194
+ usedOperations.set(dependency.module, new Set())
195
+ stable = false
196
+ }
197
+ }
198
+ }
199
+ }
200
+ for (const module of [...usedOperations.keys()].sort()) {
201
+ const provider = /** @type {StdlibProviderRecord} */ (selectedProviders.get(module))
202
+ const provided = new Set(provider.provides[0].operations)
203
+ const missing = [.../** @type {Set<string>} */ (usedOperations.get(module))].sort()
204
+ .filter((operation) => !provided.has(operation))
205
+
206
+ if (missing.length > 0) {
207
+ throw new SemantifoldDiagnostic({
208
+ code: "STDLIB_PROVIDER_MISSING",
209
+ language: target,
210
+ message: `Provider '${provider.identity}' does not provide operation${missing.length > 1 ? "s" : ""} '${missing.join("', '")}' of module '${module}'.`
211
+ })
212
+ }
213
+ }
214
+ assertAcyclic(contracts, ranges, usedOperations, selectedProviders)
215
+ /** @type {{identity: string, operations: string[], version: string}[]} */
216
+ const modules = [...usedOperations.keys()].sort().map((identity) => {
217
+ const contract = resolveModuleVersion(contracts, identity, ranges.get(identity) ?? universalRange)
218
+ const used = /** @type {Set<string>} */ (usedOperations.get(identity))
219
+
220
+ return {
221
+ identity,
222
+ operations: contract.operations.map(({name}) => name).filter((name) => used.has(name)),
223
+ version: contract.version
224
+ }
225
+ })
226
+ /** @type {{identity: string, target: string, module: string, version: string, operations: string[], nativeEntries: Record<string, string>, runtimeProfile: string}[]} */
227
+ const providerResults = [...selectedProviders.values()].sort((left, right) =>
228
+ left.identity < right.identity ? -1 : left.identity > right.identity ? 1 : 0).map((provider) => {
229
+ const module = provider.provides[0].module
230
+ const contract = resolveModuleVersion(contracts, module, ranges.get(module) ?? universalRange)
231
+ const used = /** @type {Set<string>} */ (usedOperations.get(module))
232
+ const operations = contract.operations.map(({name}) => name).filter((name) => used.has(name))
233
+
234
+ return {
235
+ identity: provider.identity,
236
+ module,
237
+ nativeEntries: Object.fromEntries(operations.map((operation) => [
238
+ operation,
239
+ /** @type {string} */ (provider.nativeEntries[operation])
240
+ ])),
241
+ operations,
242
+ runtimeProfile: provider.runtimeProfile,
243
+ target: provider.target,
244
+ version: provider.provides[0].version
245
+ }
246
+ })
247
+ return deepFreeze(/** @type {StdlibNegotiationResult} */ ({modules, providers: providerResults, target}))
248
+ }
249
+
250
+ /**
251
+ * Resolves the highest registered contract version satisfying one combined range.
252
+ * @param {StdlibContractRegistry} contracts - Canonical contract registry.
253
+ * @param {string} module - Canonical module identity.
254
+ * @param {VersionRange} range - Combined half-open range.
255
+ * @returns {import("./semantic/stdlib.js").StdlibContract} Exact-version contract.
256
+ */
257
+ function resolveModuleVersion(contracts, module, range) {
258
+ const listed = contracts.modules.find(({identity}) => identity == module)
259
+
260
+ if (!listed) {
261
+ throw new SemantifoldDiagnostic({code: "STDLIB_MODULE_UNKNOWN", language: module, message: `Canonical module '${module}' is not registered.`})
262
+ }
263
+ /** @type {[number, number, number] | null} */
264
+ let resolved = null
265
+
266
+ for (const version of listed.versions) {
267
+ const tuple = /** @type {[number, number, number]} */ (parseStdlibVersion(version))
268
+
269
+ if (stdlibVersionSatisfies(tuple, range) && (resolved === null || compareStdlibVersions(tuple, resolved) > 0)) {
270
+ resolved = tuple
271
+ }
272
+ }
273
+ if (resolved === null) {
274
+ throw new SemantifoldDiagnostic({
275
+ code: "STDLIB_VERSION_INCOMPATIBLE",
276
+ language: module,
277
+ message: `Canonical module '${module}' has no registered version satisfying the combined range.`
278
+ })
279
+ }
280
+ return contracts.resolveModule(module, `${resolved[0]}.${resolved[1]}.${resolved[2]}`)
281
+ }
282
+
283
+ /**
284
+ * Fails deterministically when canonical operation dependencies or selected provider
285
+ * module dependencies cycle.
286
+ * @param {StdlibContractRegistry} contracts - Canonical contract registry.
287
+ * @param {Map<string, VersionRange>} ranges - Combined ranges per module.
288
+ * @param {Map<string, Set<string>>} usedOperations - Used operations per module.
289
+ * @param {Map<string, StdlibProviderRecord>} selectedProviders - Selected provider per module.
290
+ * @returns {void}
291
+ */
292
+ function assertAcyclic(contracts, ranges, usedOperations, selectedProviders) {
293
+ /** @type {Map<string, string[]>} */
294
+ const edges = new Map()
295
+
296
+ for (const module of [...usedOperations.keys()].sort()) {
297
+ const contract = resolveModuleVersion(contracts, module, ranges.get(module) ?? universalRange)
298
+ const declared = new Map(contract.operations.map(({dependencies, name}) => [name, dependencies]))
299
+ const used = /** @type {Set<string>} */ (usedOperations.get(module))
300
+
301
+ for (const operation of [...used].sort()) {
302
+ const nodeKey = `${module}\u0000${operation}`
303
+ const targets = /** @type {string[]} */ (edges.get(nodeKey) ?? [])
304
+
305
+ for (const dependency of /** @type {{module: string, operation: string}[]} */ (declared.get(operation))) {
306
+ targets.push(`${dependency.module}\u0000${dependency.operation}`)
307
+ }
308
+ edges.set(nodeKey, targets.sort())
309
+ }
310
+ const moduleNodeKey = `${module}\u0000\u0000`
311
+ const moduleTargets = /** @type {string[]} */ (edges.get(moduleNodeKey) ?? [])
312
+
313
+ for (const dependency of contract.dependencies) moduleTargets.push(`${dependency.module}\u0000\u0000`)
314
+ edges.set(moduleNodeKey, moduleTargets.sort())
315
+ }
316
+ for (const module of [...selectedProviders.keys()].sort()) {
317
+ const provider = /** @type {StdlibProviderRecord} */ (selectedProviders.get(module))
318
+ const nodeKey = `${module}\u0000\u0000`
319
+ const targets = /** @type {string[]} */ (edges.get(nodeKey) ?? [])
320
+
321
+ for (const dependency of provider.dependencies) {
322
+ targets.push(`${dependency.module}\u0000\u0000`)
323
+ }
324
+ edges.set(nodeKey, targets.sort())
325
+ }
326
+ /** @type {Map<string, number>} */
327
+ const colors = new Map()
328
+ /**
329
+ * Walks the dependency edges in deterministic order, rejecting cycles.
330
+ * @param {string} nodeKey - Node key.
331
+ * @returns {void}
332
+ */
333
+ function visit(nodeKey) {
334
+ colors.set(nodeKey, 1)
335
+
336
+ for (const target of /** @type {string[]} */ (edges.get(nodeKey) ?? [])) {
337
+ const color = colors.get(target) ?? 0
338
+
339
+ if (color == 1) throw new SemantifoldDiagnostic({
340
+ code: "STDLIB_PROVIDER_CYCLE",
341
+ language: target.split("\u0000")[0],
342
+ message: "Canonical stdlib dependencies form a cycle."
343
+ })
344
+ if (color == 0) visit(target)
345
+ }
346
+ colors.set(nodeKey, 2)
347
+ }
348
+
349
+ for (const nodeKey of [...edges.keys()].sort()) {
350
+ if ((colors.get(nodeKey) ?? 0) == 0) visit(nodeKey)
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Normalizes a declared dependency range, accepting canonical strings or parsed ranges.
356
+ * @param {unknown} value - Candidate range.
357
+ * @returns {VersionRange} Half-open range.
358
+ */
359
+ function asVersionRange(value) {
360
+ if (typeof value == "string") {
361
+ const parsed = parseStdlibVersionRange(value)
362
+
363
+ if (parsed === null) malformedRange(value)
364
+ return parsed
365
+ }
366
+ if (isPlainObject(value) && Array.isArray(value.lower) && value.lower.length == 3 &&
367
+ value.lower.every((part) => Number.isInteger(part)) &&
368
+ (value.upper === null || (Array.isArray(value.upper) && value.upper.length == 3 &&
369
+ value.upper.every((part) => Number.isInteger(part))))) {
370
+ return {lower: /** @type {[number, number, number]} */ (value.lower), upper: value.upper === null ? null : /** @type {[number, number, number]} */ (value.upper)}
371
+ }
372
+ return malformedRange(String(value))
373
+ }
374
+
375
+ /**
376
+ * Encodes one half-open range deterministically.
377
+ * @param {VersionRange} range - Half-open range.
378
+ * @returns {string} Stable key.
379
+ */
380
+ function rangeKey(range) {
381
+ return `${range.lower.join(".")}..${range.upper === null ? "" : range.upper.join(".")}`
382
+ }
383
+
384
+ /**
385
+ * Throws a malformed-version-range diagnostic.
386
+ * @param {string} range - Candidate range.
387
+ * @returns {never} Always throws.
388
+ */
389
+ function malformedRange(range) {
390
+ throw new SemantifoldDiagnostic({
391
+ code: "STDLIB_VERSION_MALFORMED",
392
+ language: "stdlib",
393
+ message: `Stdlib version range '${range}' is not canonical.`
394
+ })
395
+ }
396
+
397
+ /**
398
+ * Throws an undeclared-operation diagnostic.
399
+ * @param {string} module - Canonical module identity.
400
+ * @param {string} operation - Missing operation.
401
+ * @returns {never} Always throws.
402
+ */
403
+ function undeclaredOperation(module, operation) {
404
+ throw new SemantifoldDiagnostic({
405
+ code: "STDLIB_OPERATION_UNDECLARED",
406
+ language: module,
407
+ message: `Operation '${operation}' is not declared by canonical module '${module}'.`
408
+ })
409
+ }
410
+
411
+ /**
412
+ * Throws a requirement-shape diagnostic.
413
+ * @param {string} message - Failure detail.
414
+ * @returns {never} Always throws.
415
+ */
416
+ function invalidRequirement(message) {
417
+ throw new SemantifoldDiagnostic({code: "STDLIB_CONTRACT_INVALID", language: "stdlib", message})
418
+ }
419
+
420
+ /**
421
+ * Checks for an ordinary string-keyed object.
422
+ * @param {unknown} value - Candidate value.
423
+ * @returns {value is Record<string, unknown>} Whether the value is a plain object.
424
+ */
425
+ function isPlainObject(value) {
426
+ if (typeof value != "object" || value === null) return false
427
+ const prototype = Object.getPrototypeOf(value)
428
+
429
+ return prototype === Object.prototype || prototype === null
430
+ }
431
+
432
+ /**
433
+ * Deep-freezes a detached value.
434
+ * @template T
435
+ * @param {T} value - Detached value.
436
+ * @returns {Readonly<T>} Frozen value.
437
+ */
438
+ function deepFreeze(value) {
439
+ if (typeof value != "object" || value === null || Object.isFrozen(value)) return /** @type {Readonly<T>} */ (value)
440
+ Object.freeze(value)
441
+
442
+ for (const property of Object.getOwnPropertyNames(value)) {
443
+ deepFreeze(/** @type {unknown} */ ((/** @type {Record<string, unknown>} */ (value))[property]))
444
+ }
445
+ return /** @type {Readonly<T>} */ (value)
446
+ }