@fraczak/k 6.3.2 → 6.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 (156) hide show
  1. package/DOCS/CODECS.md +258 -0
  2. package/DOCS/DICTIONARY.md +1172 -0
  3. package/DOCS/KIR_SPECIALIZATION_DESIGN.md +51 -46
  4. package/DOCS/KIR_V1.md +221 -0
  5. package/DOCS/KVM_EXECUTION_MODEL.md +56 -19
  6. package/DOCS/OBJECT_FILE_AND_PATTERN.md +2 -1
  7. package/DOCS/PROFILING_AND_TRACING.md +196 -0
  8. package/DOCS/REPL.md +76 -14
  9. package/DOCS/WEB_REPL_REQUIREMENTS.md +135 -0
  10. package/DOCS/dependency-graph.md +144 -0
  11. package/Examples/arithmetics.k +51 -48
  12. package/Examples/bnat.k +1 -1
  13. package/Examples/buda.k +44 -0
  14. package/Examples/ieee.k +300 -8671
  15. package/Examples/poly.k +67 -0
  16. package/README.md +68 -19
  17. package/augmentation.mjs +9 -7
  18. package/backend-api.mjs +11 -2
  19. package/backends/arm64/README.md +104 -0
  20. package/backends/arm64/bin/k-arm64-compile.mjs +101 -0
  21. package/backends/arm64/bin/k-arm64-run.mjs +58 -0
  22. package/backends/arm64/bin/k-arm64.mjs +88 -0
  23. package/backends/arm64/scripts/run-tests.mjs +41 -0
  24. package/backends/arm64/src/arm64.mjs +229 -0
  25. package/backends/arm64/src/cli.mjs +155 -0
  26. package/backends/arm64/src/kvm2arm64.mjs +906 -0
  27. package/backends/arm64/src/runtime.c +728 -0
  28. package/backends/arm64/tests/integration.sh +112 -0
  29. package/backends/arm64/tests/test-arm64.mjs +240 -0
  30. package/backends/llvm/README.md +135 -0
  31. package/backends/llvm/bin/k-llvm-build.mjs +71 -0
  32. package/backends/llvm/bin/k-llvm-compile.mjs +68 -0
  33. package/backends/llvm/bin/k-llvm-jit.mjs +160 -0
  34. package/backends/llvm/bin/k-llvm-run.mjs +90 -0
  35. package/backends/llvm/runtime/krt.c +1508 -0
  36. package/backends/llvm/runtime/krt.h +109 -0
  37. package/backends/llvm/scripts/conformance.mjs +76 -0
  38. package/backends/llvm/scripts/run-tests.mjs +28 -0
  39. package/backends/llvm/src/executable.mjs +562 -0
  40. package/backends/llvm/src/kvm2llvm.mjs +998 -0
  41. package/backends/llvm/src/llvm.mjs +1092 -0
  42. package/backends/llvm/tests/composition-driver.c +22 -0
  43. package/backends/llvm/tests/identity-driver.c +27 -0
  44. package/backends/llvm/tests/integration.sh +153 -0
  45. package/backends/llvm/tests/perf-support.mjs +735 -0
  46. package/backends/llvm/tests/product-driver.c +23 -0
  47. package/backends/llvm/tests/projection-driver.c +19 -0
  48. package/backends/llvm/tests/relation-driver.c +29 -0
  49. package/backends/llvm/tests/test-llvm.mjs +240 -0
  50. package/backends/llvm/tests/union-driver.c +31 -0
  51. package/backends/llvm/tests/variant-driver.c +19 -0
  52. package/backends/llvm/tests/variant-projection-driver.c +21 -0
  53. package/backends/wasm/DOCS/USE-WEB-ASSEMBLY.md +233 -0
  54. package/backends/wasm/README.md +97 -0
  55. package/backends/wasm/TECHNICAL-DEBT.md +60 -0
  56. package/backends/wasm/bin/k-wasm-compile.mjs +50 -0
  57. package/backends/wasm/bin/k-wasm-run.mjs +140 -0
  58. package/backends/wasm/bin/k-wasm.mjs +49 -0
  59. package/backends/wasm/demo_ieee.mjs +319 -0
  60. package/backends/wasm/runtime.wat +102 -0
  61. package/backends/wasm/scripts/run-tests.mjs +41 -0
  62. package/backends/wasm/src/cli.mjs +133 -0
  63. package/backends/wasm/src/kvm2wasm.mjs +661 -0
  64. package/backends/wasm/src/wasm.mjs +1010 -0
  65. package/backends/wasm/tests/integration.sh +182 -0
  66. package/backends/wasm/tests/perf-support.mjs +336 -0
  67. package/backends/wasm/tests/test-wasm.mjs +617 -0
  68. package/browser/repl-browser.mjs +1584 -0
  69. package/browser/shims/assert.mjs +19 -0
  70. package/browser/shims/buffer.mjs +224 -0
  71. package/browser/shims/crypto.mjs +103 -0
  72. package/browser/shims/fs.mjs +159 -0
  73. package/browser/shims/os.mjs +17 -0
  74. package/browser/shims/path.mjs +54 -0
  75. package/browser/shims/process.mjs +44 -0
  76. package/browser/shims/readline.mjs +11 -0
  77. package/browser/shims/url.mjs +12 -0
  78. package/browser/vfs-data.mjs +19 -0
  79. package/codecs/README.md +3 -0
  80. package/codecs/json.mjs +16 -2
  81. package/codecs/runtime/show-value.mjs +2 -2
  82. package/conformance/helper-reuse/case.json +8 -0
  83. package/conformance/helper-reuse/expected.kv +1 -0
  84. package/conformance/helper-reuse/input.kv +1 -0
  85. package/conformance/helper-reuse/program.k +2 -0
  86. package/conformance/identity/case.json +8 -0
  87. package/conformance/identity/expected.kv +1 -0
  88. package/conformance/identity/input.kv +1 -0
  89. package/conformance/identity/program.k +1 -0
  90. package/conformance/product-projection/case.json +8 -0
  91. package/conformance/product-projection/expected.kv +1 -0
  92. package/conformance/product-projection/input.kv +1 -0
  93. package/conformance/product-projection/program.k +1 -0
  94. package/conformance/run.mjs +149 -0
  95. package/conformance/variant-construction/case.json +8 -0
  96. package/conformance/variant-construction/expected.kv +1 -0
  97. package/conformance/variant-construction/input.kv +1 -0
  98. package/conformance/variant-construction/program.k +1 -0
  99. package/harness/adapters/arm64.mjs +105 -0
  100. package/harness/adapters/kvm.mjs +144 -0
  101. package/harness/adapters/llvm.mjs +118 -0
  102. package/harness/adapters/native.mjs +77 -0
  103. package/harness/adapters/wasm.mjs +169 -0
  104. package/harness/backend.mjs +95 -0
  105. package/harness/cli.mjs +130 -0
  106. package/harness/format.mjs +95 -0
  107. package/harness/index.mjs +25 -0
  108. package/harness/persistent.mjs +121 -0
  109. package/harness/registry.mjs +44 -0
  110. package/harness/suite.mjs +257 -0
  111. package/harness/suites/poly.mjs +156 -0
  112. package/harness/trace.mjs +50 -0
  113. package/harness/util.mjs +92 -0
  114. package/intrinsics.mjs +41 -0
  115. package/kir.mjs +399 -0
  116. package/kvm.mjs +585 -81
  117. package/objects/README.md +37 -3
  118. package/objects/compile.mjs +15 -22
  119. package/objects/inspect.mjs +96 -0
  120. package/objects/validate.mjs +415 -0
  121. package/package.json +51 -19
  122. package/repl-codecs.mjs +133 -20
  123. package/repl.mjs +408 -59
  124. package/run.mjs +2 -7
  125. package/scripts/benchmark.mjs +406 -22
  126. package/scripts/build-repl-html.mjs +1784 -0
  127. package/scripts/perf-ieee.mjs +586 -0
  128. package/scripts/perf-int.mjs +531 -0
  129. package/scripts/perf-poly.mjs +945 -0
  130. package/scripts/render-benchmark.mjs +12 -8
  131. package/scripts/run-tests.mjs +6 -0
  132. package/tests/integration.sh +19 -2
  133. package/tests/test-arithmetics.mjs +54 -0
  134. package/tests/test-ieee-arithmetic.mjs +6 -2
  135. package/tests/test-kir.mjs +85 -0
  136. package/tests/test-kvm-polymorphic.mjs +278 -0
  137. package/tests/test-kvm.mjs +25 -6
  138. package/tests/test-poly.mjs +129 -0
  139. package/tests/test-repl-html.mjs +303 -0
  140. package/tests/test-repl.mjs +175 -1
  141. package/tests/test-validate-object.mjs +40 -0
  142. package/a.klib +0 -1
  143. package/a.kvm +0 -142676
  144. package/a.wasm +0 -0
  145. package/benchmark-results.html +0 -532
  146. package/benchmark-results.json +0 -480
  147. package/k-vscode/.vscode/launch.json +0 -14
  148. package/k-vscode/README.md +0 -75
  149. package/k-vscode/extension.js +0 -273
  150. package/k-vscode/language-configuration.json +0 -42
  151. package/k-vscode/package.json +0 -79
  152. package/k-vscode/snippets/k.json +0 -92
  153. package/k-vscode/syntaxes/k.tmLanguage.json +0 -599
  154. package/k-vscode/test/background-ranges.test.js +0 -50
  155. package/k-vscode/themes/k-contrast-color-theme.json +0 -104
  156. package/scripts/git-hooks/pre-commit +0 -10
package/package.json CHANGED
@@ -1,41 +1,73 @@
1
1
  {
2
2
  "name": "@fraczak/k",
3
- "version": "6.3.2",
3
+ "version": "6.4.0",
4
4
  "description": "k — a language for composing first-order partial functions over algebraic data types (products and tagged unions); includes runtime, type derivation, REPL, and codec toolchain",
5
5
  "main": "index.mjs",
6
+ "exports": {
7
+ ".": "./index.mjs",
8
+ "./*": "./*"
9
+ },
6
10
  "scripts": {
7
11
  "prepare": "jiwson -m es6 parser.jison -o parser.mjs; jiwson -m es6 valueParser.jison -o valueParser.mjs; ",
8
12
  "test": "node scripts/run-tests.mjs",
13
+ "test:backends": "node backends/llvm/scripts/run-tests.mjs && node backends/wasm/scripts/run-tests.mjs",
14
+ "test:llvm": "node backends/llvm/scripts/run-tests.mjs",
15
+ "test:wasm": "node backends/wasm/scripts/run-tests.mjs",
16
+ "test:arm64": "node backends/arm64/scripts/run-tests.mjs",
17
+ "conformance": "node conformance/run.mjs",
9
18
  "benchmark": "node scripts/benchmark.mjs",
10
19
  "benchmark:html": "node scripts/render-benchmark.mjs",
11
- "hooks:install": "git config core.hooksPath scripts/git-hooks",
20
+ "perf:ieee": "node scripts/perf-ieee.mjs",
21
+ "perf:ieee:full": "node scripts/perf-ieee.mjs --full",
22
+ "perf:int": "node scripts/perf-int.mjs",
23
+ "perf:poly": "node scripts/perf-poly.mjs",
24
+ "perf:poly:trace": "node scripts/perf-poly.mjs --trace",
12
25
  "perf:idempotency": "node scripts/benchmark-idempotency.mjs",
13
- "deps:graph": "node scripts/generate-dependency-graph.mjs"
26
+ "deps:graph": "node scripts/generate-dependency-graph.mjs",
27
+ "compare": "node harness/cli.mjs",
28
+ "build:repl-html": "node scripts/build-repl-html.mjs"
14
29
  },
15
30
  "repository": {
16
31
  "type": "git",
17
- "url": "https://github.com/fraczak/k.git"
32
+ "url": "git+https://github.com/fraczak/k.git"
18
33
  },
19
34
  "author": "Wojciech Fraczak",
20
35
  "license": "ISC",
21
36
  "bin": {
22
- "k": "./k.mjs",
23
- "k-compile": "./objects/compile.mjs",
24
- "k-decompile": "./objects/decompile.mjs",
25
- "k-extract-aliases": "./objects/extract-aliases.mjs",
26
- "k-ieee": "./codecs/ieee.mjs",
27
- "k-int": "./codecs/int.mjs",
28
- "k-json": "./codecs/json.mjs",
29
- "k-parse": "./codecs/k-parse.mjs",
30
- "k-print": "./codecs/k-print.mjs",
31
- "k-repl": "./repl.mjs",
32
- "k-show": "./codecs/show.mjs",
33
- "k-unit": "./codecs/unit.mjs",
34
- "k-utf16": "./codecs/utf16.mjs",
35
- "k-utf8": "./codecs/utf8.mjs",
36
- "k-vm": "./kvm.mjs"
37
+ "k": "k.mjs",
38
+ "k-compile": "objects/compile.mjs",
39
+ "k-decompile": "objects/decompile.mjs",
40
+ "k-extract-aliases": "objects/extract-aliases.mjs",
41
+ "k-inspect-object": "objects/inspect.mjs",
42
+ "k-validate-object": "objects/validate.mjs",
43
+ "k-kir": "kir.mjs",
44
+ "k-llvm-build": "backends/llvm/bin/k-llvm-build.mjs",
45
+ "k-llvm-compile": "backends/llvm/bin/k-llvm-compile.mjs",
46
+ "k-llvm-jit": "backends/llvm/bin/k-llvm-jit.mjs",
47
+ "k-llvm-run": "backends/llvm/bin/k-llvm-run.mjs",
48
+ "k-arm64": "backends/arm64/bin/k-arm64.mjs",
49
+ "k-arm64-compile": "backends/arm64/bin/k-arm64-compile.mjs",
50
+ "k-arm64-run": "backends/arm64/bin/k-arm64-run.mjs",
51
+ "k-wasm": "backends/wasm/bin/k-wasm.mjs",
52
+ "k-wasm-compile": "backends/wasm/bin/k-wasm-compile.mjs",
53
+ "k-wasm-run": "backends/wasm/bin/k-wasm-run.mjs",
54
+ "k-ieee": "codecs/ieee.mjs",
55
+ "k-int": "codecs/int.mjs",
56
+ "k-json": "codecs/json.mjs",
57
+ "k-parse": "codecs/k-parse.mjs",
58
+ "k-print": "codecs/k-print.mjs",
59
+ "k-repl": "repl.mjs",
60
+ "k-show": "codecs/show.mjs",
61
+ "k-unit": "codecs/unit.mjs",
62
+ "k-utf16": "codecs/utf16.mjs",
63
+ "k-utf8": "codecs/utf8.mjs",
64
+ "k-vm": "kvm.mjs"
65
+ },
66
+ "dependencies": {
67
+ "wabt": "^1.0.39"
37
68
  },
38
69
  "devDependencies": {
70
+ "esbuild": "^0.28.2",
39
71
  "jiwson": "^0.1.2"
40
72
  }
41
73
  }
package/repl-codecs.mjs CHANGED
@@ -6,12 +6,28 @@ import { encodeToWire, decodeWire } from "./codecs/runtime/prefix-codec.mjs";
6
6
  import { deriveClosedPattern } from "./codecs/runtime/codec.mjs";
7
7
  import { patternToPropertyList } from "./codecs/runtime/pattern-json.mjs";
8
8
  import { finalize } from "./codes.mjs";
9
+ import * as intCodec from "./codecs/int.mjs";
10
+ import * as utf8Codec from "./codecs/utf8.mjs";
11
+ import * as jsonCodec from "./codecs/json.mjs";
12
+ import * as ieeeCodec from "./codecs/ieee.mjs";
13
+ import * as unitCodec from "./codecs/unit.mjs";
14
+
15
+ const BUILTIN_CODECS = {
16
+ int: intCodec,
17
+ utf8: utf8Codec,
18
+ json: jsonCodec,
19
+ ieee: ieeeCodec,
20
+ unit: unitCodec
21
+ };
22
+
23
+ const UNIVERSAL_CODE = "*";
24
+ const NAME_RE = /^[a-zA-Z0-9_+-][a-zA-Z0-9_?!+-]*$/;
9
25
 
10
26
  function isCanonicalCodeName(name) {
11
27
  return typeof name === "string" && name.startsWith("@");
12
28
  }
13
29
 
14
- function singletonPatternToCodeHash(pattern) {
30
+ function closedPatternToCodeHash(pattern) {
15
31
  if (!Array.isArray(pattern) || pattern.length === 0) {
16
32
  return null;
17
33
  }
@@ -23,7 +39,7 @@ function singletonPatternToCodeHash(pattern) {
23
39
  return null;
24
40
  }
25
41
  if (!Array.isArray(edges)) {
26
- throw new Error(`Invalid singleton pattern node ${i}`);
42
+ throw new Error(`Invalid closed pattern node ${i}`);
27
43
  }
28
44
 
29
45
  const code = kind === "closed-product" ? "product" : "union";
@@ -31,7 +47,7 @@ function singletonPatternToCodeHash(pattern) {
31
47
  code,
32
48
  [code]: Object.fromEntries(edges.map(([label, target]) => {
33
49
  if (!Number.isInteger(target) || target < 0 || target >= pattern.length) {
34
- throw new Error(`Invalid singleton pattern edge target ${target}`);
50
+ throw new Error(`Invalid closed pattern edge target ${target}`);
35
51
  }
36
52
  return [label, `C${target}`];
37
53
  }))
@@ -64,17 +80,18 @@ function valueForCode(value, codeHash, findCode) {
64
80
  function normalizeCodecModule(mod, fallbackName) {
65
81
  const codec = mod.replCodec || mod.codec || mod.default || mod;
66
82
  const name = codec.name || mod.name || fallbackName;
83
+ const universal = codec.universal === true;
67
84
  const patterns = codec.patterns || (codec.pattern ? [codec.pattern] : null);
68
85
  const codes = codec.codes || codec.codeHashes || (codec.code ? [codec.code] : null) ||
69
86
  patterns?.map((pattern, index) => {
70
- const codeHash = singletonPatternToCodeHash(pattern);
71
- if (!codeHash) throw new Error(`Codec '${name}' pattern ${index} is not singleton`);
87
+ const codeHash = closedPatternToCodeHash(pattern);
88
+ if (!codeHash) throw new Error(`Codec '${name}' pattern ${index} must be a closed property-list pattern`);
72
89
  return codeHash;
73
90
  });
74
91
  if (!name || typeof name !== "string") {
75
92
  throw new Error("Codec module must export a string name");
76
93
  }
77
- if (!Array.isArray(codes) || codes.length === 0) {
94
+ if (!universal && (!Array.isArray(codes) || codes.length === 0)) {
78
95
  throw new Error(`Codec '${name}' must export a non-empty codes array`);
79
96
  }
80
97
  if (codec.parse != null && typeof codec.parse !== "function") {
@@ -85,7 +102,8 @@ function normalizeCodecModule(mod, fallbackName) {
85
102
  }
86
103
  return {
87
104
  name,
88
- codes,
105
+ codes: universal ? [UNIVERSAL_CODE] : codes,
106
+ universal,
89
107
  parse: codec.parse,
90
108
  print: codec.print
91
109
  };
@@ -96,17 +114,30 @@ function codecStore(state) {
96
114
  return state.codecs;
97
115
  }
98
116
 
117
+ function resolveCanonicalCodeHash(codeHash, state = null) {
118
+ if (codeHash === UNIVERSAL_CODE) return UNIVERSAL_CODE;
119
+ if (isCanonicalCodeName(codeHash)) return codeHash;
120
+ if (state?.typeAliases) {
121
+ const clean = codeHash.startsWith("$") ? codeHash.slice(1) : codeHash;
122
+ if (state.typeAliases[clean]) return state.typeAliases[clean];
123
+ }
124
+ return codeHash;
125
+ }
126
+
99
127
  function registerCodec(state, codec, source = null) {
100
128
  const registered = [];
101
129
  const store = codecStore(state);
102
- for (const codeHash of codec.codes) {
103
- if (!isCanonicalCodeName(codeHash)) {
130
+ for (const rawCodeHash of codec.codes) {
131
+ const codeHash = resolveCanonicalCodeHash(rawCodeHash, state);
132
+ const universal = codeHash === UNIVERSAL_CODE;
133
+ if (!universal && !isCanonicalCodeName(codeHash)) {
104
134
  throw new Error(`Codec '${codec.name}' has non-canonical code '${codeHash}'`);
105
135
  }
106
136
  if (!store[codeHash]) store[codeHash] = [];
107
137
  const entry = {
108
138
  name: codec.name,
109
139
  source,
140
+ universal,
110
141
  parse: codec.parse,
111
142
  print: codec.print
112
143
  };
@@ -118,18 +149,89 @@ function registerCodec(state, codec, source = null) {
118
149
  } else {
119
150
  store[codeHash][existingIndex] = entry;
120
151
  }
152
+ if (!universal && isCanonicalCodeName(codeHash) && state?.typeAliases && codec.name && NAME_RE.test(codec.name)) {
153
+ state.typeAliases[codec.name] = codeHash;
154
+ }
121
155
  registered.push({ codeHash, ...entry });
122
156
  }
123
157
  return registered;
124
158
  }
125
159
 
160
+ function unregisterCodec(state, codecName) {
161
+ const store = codecStore(state);
162
+ let removedCount = 0;
163
+ for (const [codeHash, codecs] of Object.entries(store)) {
164
+ const remaining = codecs.filter((c) => c.name !== codecName);
165
+ if (remaining.length !== codecs.length) {
166
+ removedCount += codecs.length - remaining.length;
167
+ if (remaining.length === 0) {
168
+ delete store[codeHash];
169
+ } else {
170
+ store[codeHash] = remaining;
171
+ }
172
+ }
173
+ }
174
+ return removedCount;
175
+ }
176
+
177
+ function matchBuiltinCodec(target) {
178
+ const normalized = target.replace(/\\/g, "/").replace(/^\.\//, "").toLowerCase();
179
+ const base = path.basename(normalized, path.extname(normalized));
180
+ if (BUILTIN_CODECS[base]) return { name: base, mod: BUILTIN_CODECS[base] };
181
+ return null;
182
+ }
183
+
126
184
  async function loadCodecModule(state, filePath) {
185
+ const builtin = matchBuiltinCodec(filePath);
186
+ if (builtin) {
187
+ const codec = normalizeCodecModule(builtin.mod, builtin.name);
188
+ return registerCodec(state, codec, "built-in");
189
+ }
190
+
191
+ // Check if file exists on disk or in VFS
192
+ let source = null;
193
+ try {
194
+ if (fs.existsSync(filePath)) {
195
+ source = fs.readFileSync(filePath, "utf8");
196
+ }
197
+ } catch {}
198
+
127
199
  const resolved = path.resolve(filePath);
128
- const url = pathToFileURL(resolved);
129
- url.searchParams.set("mtime", String(fs.statSync(resolved).mtimeMs));
130
- const mod = await import(url.href);
131
- const codec = normalizeCodecModule(mod, path.basename(resolved, path.extname(resolved)));
132
- return registerCodec(state, codec, resolved);
200
+ if (!source && fs.existsSync(resolved)) {
201
+ try {
202
+ source = fs.readFileSync(resolved, "utf8");
203
+ } catch {}
204
+ }
205
+
206
+ // If in Node environment with a real physical file on disk, try native dynamic import
207
+ if (typeof process !== "undefined" && process?.versions?.node && fs.existsSync(resolved)) {
208
+ try {
209
+ const url = pathToFileURL(resolved);
210
+ try {
211
+ const stats = fs.statSync(resolved);
212
+ if (stats?.mtimeMs) url.searchParams.set("mtime", String(stats.mtimeMs));
213
+ } catch {}
214
+ const mod = await import(url.href);
215
+ const codec = normalizeCodecModule(mod, path.basename(resolved, path.extname(resolved)));
216
+ return registerCodec(state, codec, resolved);
217
+ } catch (nodeErr) {
218
+ if (!source) throw nodeErr;
219
+ }
220
+ }
221
+
222
+ if (!source) {
223
+ throw new Error(`Cannot find codec file '${filePath}'`);
224
+ }
225
+
226
+ // Universal data URL loader (works in browser & Node, and in VFS)
227
+ const sanitized = source.replace(
228
+ /import\s+[^;]*from\s+['"][^'"]*['"];?/g,
229
+ "const { Value, isProduct, isVariant, NODE_KIND } = globalThis;"
230
+ );
231
+ const dataUrl = "data:text/javascript;charset=utf-8," + encodeURIComponent(sanitized);
232
+ const mod = await import(dataUrl);
233
+ const codec = normalizeCodecModule(mod, path.basename(filePath, path.extname(filePath)));
234
+ return registerCodec(state, codec, filePath);
133
235
  }
134
236
 
135
237
  function listCodecs(state) {
@@ -137,20 +239,27 @@ function listCodecs(state) {
137
239
  .flatMap(([codeHash, codecs]) => codecs.map((codec) => ({ codeHash, ...codec })))
138
240
  .sort((a, b) => a.name.localeCompare(b.name) || a.codeHash.localeCompare(b.codeHash));
139
241
  if (entries.length === 0) return "(none)";
140
- return entries.map((entry) => `${entry.name} ${entry.codeHash}${entry.source ? ` (${entry.source})` : ""}`).join("\n");
242
+ return entries.map((entry) => `${entry.name} ${entry.codeHash === UNIVERSAL_CODE ? "all" : entry.codeHash}${entry.source ? ` (${entry.source})` : ""}`).join("\n");
141
243
  }
142
244
 
143
245
  function codecNames(state, codeHash = null) {
144
246
  const store = codecStore(state);
145
- const codecs = codeHash ? (store[codeHash] || []) : Object.values(store).flat();
247
+ const codecs = codeHash
248
+ ? [...(store[codeHash] || []), ...(store[UNIVERSAL_CODE] || [])]
249
+ : Object.values(store).flat();
146
250
  return [...new Set(codecs.map((codec) => codec.name))].sort();
147
251
  }
148
252
 
149
253
  function resolveCodec(state, codeHash, codecName = null, capability = null) {
150
- const matches = (codecStore(state)[codeHash] || []).filter((codec) =>
254
+ const store = codecStore(state);
255
+ const matchesCodec = (codec) =>
151
256
  (codecName == null || codec.name === codecName) &&
152
- (capability == null || typeof codec[capability] === "function")
153
- );
257
+ (capability == null || typeof codec[capability] === "function");
258
+ const exactMatches = (store[codeHash] || []).filter(matchesCodec);
259
+ const universalMatches = (store[UNIVERSAL_CODE] || []).filter(matchesCodec);
260
+ const matches = codecName == null && exactMatches.length > 0
261
+ ? exactMatches
262
+ : [...exactMatches, ...universalMatches];
154
263
  if (matches.length === 0) {
155
264
  const suffix = codecName ? ` named '${codecName}'` : "";
156
265
  throw new Error(`No ${capability || "usable"} codec${suffix} for ${codeHash}`);
@@ -162,12 +271,16 @@ function resolveCodec(state, codeHash, codecName = null, capability = null) {
162
271
  }
163
272
 
164
273
  export {
274
+ BUILTIN_CODECS,
165
275
  codecNames,
166
276
  codeHashToPattern,
167
277
  listCodecs,
168
278
  loadCodecModule,
279
+ normalizeCodecModule,
169
280
  registerCodec,
170
281
  resolveCodec,
171
- singletonPatternToCodeHash,
282
+ unregisterCodec,
283
+ closedPatternToCodeHash,
284
+ UNIVERSAL_CODE,
172
285
  valueForCode
173
286
  };