@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.
- package/DOCS/CODECS.md +258 -0
- package/DOCS/DICTIONARY.md +1172 -0
- package/DOCS/KIR_SPECIALIZATION_DESIGN.md +51 -46
- package/DOCS/KIR_V1.md +221 -0
- package/DOCS/KVM_EXECUTION_MODEL.md +56 -19
- package/DOCS/OBJECT_FILE_AND_PATTERN.md +2 -1
- package/DOCS/PROFILING_AND_TRACING.md +196 -0
- package/DOCS/REPL.md +76 -14
- package/DOCS/WEB_REPL_REQUIREMENTS.md +135 -0
- package/DOCS/dependency-graph.md +144 -0
- package/Examples/arithmetics.k +51 -48
- package/Examples/bnat.k +1 -1
- package/Examples/buda.k +44 -0
- package/Examples/ieee.k +300 -8671
- package/Examples/poly.k +67 -0
- package/README.md +68 -19
- package/augmentation.mjs +9 -7
- package/backend-api.mjs +11 -2
- package/backends/arm64/README.md +104 -0
- package/backends/arm64/bin/k-arm64-compile.mjs +101 -0
- package/backends/arm64/bin/k-arm64-run.mjs +58 -0
- package/backends/arm64/bin/k-arm64.mjs +88 -0
- package/backends/arm64/scripts/run-tests.mjs +41 -0
- package/backends/arm64/src/arm64.mjs +229 -0
- package/backends/arm64/src/cli.mjs +155 -0
- package/backends/arm64/src/kvm2arm64.mjs +906 -0
- package/backends/arm64/src/runtime.c +728 -0
- package/backends/arm64/tests/integration.sh +112 -0
- package/backends/arm64/tests/test-arm64.mjs +240 -0
- package/backends/llvm/README.md +135 -0
- package/backends/llvm/bin/k-llvm-build.mjs +71 -0
- package/backends/llvm/bin/k-llvm-compile.mjs +68 -0
- package/backends/llvm/bin/k-llvm-jit.mjs +160 -0
- package/backends/llvm/bin/k-llvm-run.mjs +90 -0
- package/backends/llvm/runtime/krt.c +1508 -0
- package/backends/llvm/runtime/krt.h +109 -0
- package/backends/llvm/scripts/conformance.mjs +76 -0
- package/backends/llvm/scripts/run-tests.mjs +28 -0
- package/backends/llvm/src/executable.mjs +562 -0
- package/backends/llvm/src/kvm2llvm.mjs +998 -0
- package/backends/llvm/src/llvm.mjs +1092 -0
- package/backends/llvm/tests/composition-driver.c +22 -0
- package/backends/llvm/tests/identity-driver.c +27 -0
- package/backends/llvm/tests/integration.sh +153 -0
- package/backends/llvm/tests/perf-support.mjs +735 -0
- package/backends/llvm/tests/product-driver.c +23 -0
- package/backends/llvm/tests/projection-driver.c +19 -0
- package/backends/llvm/tests/relation-driver.c +29 -0
- package/backends/llvm/tests/test-llvm.mjs +240 -0
- package/backends/llvm/tests/union-driver.c +31 -0
- package/backends/llvm/tests/variant-driver.c +19 -0
- package/backends/llvm/tests/variant-projection-driver.c +21 -0
- package/backends/wasm/DOCS/USE-WEB-ASSEMBLY.md +233 -0
- package/backends/wasm/README.md +97 -0
- package/backends/wasm/TECHNICAL-DEBT.md +60 -0
- package/backends/wasm/bin/k-wasm-compile.mjs +50 -0
- package/backends/wasm/bin/k-wasm-run.mjs +140 -0
- package/backends/wasm/bin/k-wasm.mjs +49 -0
- package/backends/wasm/demo_ieee.mjs +319 -0
- package/backends/wasm/runtime.wat +102 -0
- package/backends/wasm/scripts/run-tests.mjs +41 -0
- package/backends/wasm/src/cli.mjs +133 -0
- package/backends/wasm/src/kvm2wasm.mjs +661 -0
- package/backends/wasm/src/wasm.mjs +1010 -0
- package/backends/wasm/tests/integration.sh +182 -0
- package/backends/wasm/tests/perf-support.mjs +336 -0
- package/backends/wasm/tests/test-wasm.mjs +617 -0
- package/browser/repl-browser.mjs +1584 -0
- package/browser/shims/assert.mjs +19 -0
- package/browser/shims/buffer.mjs +224 -0
- package/browser/shims/crypto.mjs +103 -0
- package/browser/shims/fs.mjs +159 -0
- package/browser/shims/os.mjs +17 -0
- package/browser/shims/path.mjs +54 -0
- package/browser/shims/process.mjs +44 -0
- package/browser/shims/readline.mjs +11 -0
- package/browser/shims/url.mjs +12 -0
- package/browser/vfs-data.mjs +19 -0
- package/codecs/README.md +3 -0
- package/codecs/json.mjs +16 -2
- package/codecs/runtime/show-value.mjs +2 -2
- package/conformance/helper-reuse/case.json +8 -0
- package/conformance/helper-reuse/expected.kv +1 -0
- package/conformance/helper-reuse/input.kv +1 -0
- package/conformance/helper-reuse/program.k +2 -0
- package/conformance/identity/case.json +8 -0
- package/conformance/identity/expected.kv +1 -0
- package/conformance/identity/input.kv +1 -0
- package/conformance/identity/program.k +1 -0
- package/conformance/product-projection/case.json +8 -0
- package/conformance/product-projection/expected.kv +1 -0
- package/conformance/product-projection/input.kv +1 -0
- package/conformance/product-projection/program.k +1 -0
- package/conformance/run.mjs +149 -0
- package/conformance/variant-construction/case.json +8 -0
- package/conformance/variant-construction/expected.kv +1 -0
- package/conformance/variant-construction/input.kv +1 -0
- package/conformance/variant-construction/program.k +1 -0
- package/harness/adapters/arm64.mjs +105 -0
- package/harness/adapters/kvm.mjs +144 -0
- package/harness/adapters/llvm.mjs +118 -0
- package/harness/adapters/native.mjs +77 -0
- package/harness/adapters/wasm.mjs +169 -0
- package/harness/backend.mjs +95 -0
- package/harness/cli.mjs +130 -0
- package/harness/format.mjs +95 -0
- package/harness/index.mjs +25 -0
- package/harness/persistent.mjs +121 -0
- package/harness/registry.mjs +44 -0
- package/harness/suite.mjs +257 -0
- package/harness/suites/poly.mjs +156 -0
- package/harness/trace.mjs +50 -0
- package/harness/util.mjs +92 -0
- package/intrinsics.mjs +41 -0
- package/kir.mjs +399 -0
- package/kvm.mjs +585 -81
- package/objects/README.md +37 -3
- package/objects/compile.mjs +15 -22
- package/objects/inspect.mjs +96 -0
- package/objects/validate.mjs +415 -0
- package/package.json +51 -19
- package/repl-codecs.mjs +133 -20
- package/repl.mjs +408 -59
- package/run.mjs +2 -7
- package/scripts/benchmark.mjs +406 -22
- package/scripts/build-repl-html.mjs +1784 -0
- package/scripts/perf-ieee.mjs +586 -0
- package/scripts/perf-int.mjs +531 -0
- package/scripts/perf-poly.mjs +945 -0
- package/scripts/render-benchmark.mjs +12 -8
- package/scripts/run-tests.mjs +6 -0
- package/tests/integration.sh +19 -2
- package/tests/test-arithmetics.mjs +54 -0
- package/tests/test-ieee-arithmetic.mjs +6 -2
- package/tests/test-kir.mjs +85 -0
- package/tests/test-kvm-polymorphic.mjs +278 -0
- package/tests/test-kvm.mjs +25 -6
- package/tests/test-poly.mjs +129 -0
- package/tests/test-repl-html.mjs +303 -0
- package/tests/test-repl.mjs +175 -1
- package/tests/test-validate-object.mjs +40 -0
- package/a.klib +0 -1
- package/a.kvm +0 -142676
- package/a.wasm +0 -0
- package/benchmark-results.html +0 -532
- package/benchmark-results.json +0 -480
- package/k-vscode/.vscode/launch.json +0 -14
- package/k-vscode/README.md +0 -75
- package/k-vscode/extension.js +0 -273
- package/k-vscode/language-configuration.json +0 -42
- package/k-vscode/package.json +0 -79
- package/k-vscode/snippets/k.json +0 -92
- package/k-vscode/syntaxes/k.tmLanguage.json +0 -599
- package/k-vscode/test/background-ranges.test.js +0 -50
- package/k-vscode/themes/k-contrast-color-theme.json +0 -104
- 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
|
+
"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
|
-
"
|
|
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": "
|
|
23
|
-
"k-compile": "
|
|
24
|
-
"k-decompile": "
|
|
25
|
-
"k-extract-aliases": "
|
|
26
|
-
"k-
|
|
27
|
-
"k-
|
|
28
|
-
"k-
|
|
29
|
-
"k-
|
|
30
|
-
"k-
|
|
31
|
-
"k-
|
|
32
|
-
"k-
|
|
33
|
-
"k-
|
|
34
|
-
"k-
|
|
35
|
-
"k-
|
|
36
|
-
"k-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
71
|
-
if (!codeHash) throw new Error(`Codec '${name}' pattern ${index}
|
|
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
|
|
103
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
282
|
+
unregisterCodec,
|
|
283
|
+
closedPatternToCodeHash,
|
|
284
|
+
UNIVERSAL_CODE,
|
|
172
285
|
valueForCode
|
|
173
286
|
};
|