@fraczak/k 8.0.0 → 8.1.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/codecs/README.md CHANGED
@@ -105,9 +105,7 @@ as `k-parse.mjs`, keep that name. Every installed codec binary supports
105
105
  | `k-print` | `k-print.mjs` | Read a binary pattern+value stream and write the decoded JSON-like value. Use `--debug` to include the decoded pattern. |
106
106
  | `k-show` | `show.mjs` | Pass the wire stream through unchanged on stdout while printing the decoded value and filter to stderr. |
107
107
  | `k-json` | `json.mjs` | Convert JSON to/from the binary stream with `--parse` or `--print`. |
108
- | `k-djson` | `djson.mjs` | Convert JSON to/from a universal dynamic JSON singleton pattern with `--parse` or `--print`. |
109
- | `k-djson-btrie` | `djson-btrie.mjs` | Binary bit-trie dynamic JSON. |
110
- | `k-djson-ptrie` | `djson-ptrie.mjs` | Radix trie dynamic JSON. |
108
+ | `k-djson` | `djson.mjs` | Dynamic binary bit-trie JSON codec. |
111
109
  | `k-int` | `int.mjs` | Convert decimal integers to/from the binary stream with `--parse` or `--print`. |
112
110
  | `k-ieee` | `ieee.mjs` | Convert float literals to/from the binary stream with `--parse` or `--print`. |
113
111
  | `k-unit` | `unit.mjs` | Write or validate the unit value `{}` with `--parse` or `--print`. |
package/codecs/djson.mjs CHANGED
@@ -1,19 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Dynamic JSON (djson) codec with universal singleton pattern.
4
+ * Dynamic JSON (djson) binary bit-trie codec.
5
5
  *
6
- * Translates arbitrary JSON data to/from self-describing enveloped k
7
- * values using a single recursive AST pattern:
6
+ * Uses a unified binary bit-trie for both JSON arrays (list) and JSON
7
+ * objects (object):
8
8
  *
9
- * JSON = <
10
- * float64 number,
11
- * str string,
12
- * <{} true, {} false> bool,
13
- * {} null,
14
- * <{} nil, {JSON car, LIST cdr} cons> = LIST list,
15
- * <{} nil, {{str key, JSON val} car, OBJ cdr} cons> = OBJ object
9
+ * TRIE = <
10
+ * {} nil,
11
+ * {
12
+ * < {} nil, JSON val > val,
13
+ * TRIE 0,
14
+ * TRIE 1
15
+ * } trie
16
16
  * >
17
+ *
18
+ * - In `list`, element at index i >= 0 is stored at the canonical binary
19
+ * bit-path of i (0 -> [0], 1 -> [1], 2 -> [1,0], 3 -> [1,1], ...).
20
+ * - In `object`, entry with key k is stored at the prefix-free Unicode
21
+ * character bit-path of k.
17
22
  */
18
23
 
19
24
  import {
@@ -26,22 +31,24 @@ import {
26
31
  } from "./runtime/codec-sdk.mjs";
27
32
  import { encodeNumberToValue, decodeValueToNumber } from "./ieee.mjs";
28
33
  import {
34
+ codePointToUnicodeValue,
35
+ unicodeValueToCodePoint,
29
36
  textToStringValue,
30
37
  stringValueToText
31
38
  } from "./runtime/unicode-string.mjs";
32
39
 
33
40
  export const doc = `
34
- Dynamic JSON (djson) codec with universal singleton pattern.
41
+ Dynamic JSON (djson) binary bit-trie codec.
35
42
 
36
- Translates any JSON value to/from self-describing enveloped k values
37
- conforming to the universal recursive JSON AST type:
38
- JSON = <
39
- float64 number,
40
- str string,
41
- <{} true, {} false> bool,
42
- {} null,
43
- <{} nil, {JSON car, LIST cdr} cons> = LIST list,
44
- <{} nil, {{str key, JSON val} car, OBJ cdr} cons> = OBJ object
43
+ Represents both JSON arrays (list) and JSON objects (object) using a
44
+ unified binary bit-trie:
45
+ TRIE = <
46
+ {} nil,
47
+ {
48
+ < {} nil, JSON val > val,
49
+ TRIE 0,
50
+ TRIE 1
51
+ } trie
45
52
  >
46
53
  `;
47
54
 
@@ -122,13 +129,21 @@ export const DJSON_PATTERN = patternFromFilter(`
122
129
  < {} true, {} false > bool,
123
130
  {} null,
124
131
 
125
- < {} nil, { JSON car, LIST cdr } cons > = LIST list,
132
+ <
133
+ {} nil,
134
+ {
135
+ < {} nil, JSON val > val,
136
+ TRIE 0,
137
+ TRIE 1
138
+ } trie
139
+ > = TRIE list,
126
140
 
127
- < {} nil, { { Str key, JSON val } car, OBJ cdr } cons > = OBJ object
141
+ TRIE object
128
142
  > = JSON
129
143
  `);
130
144
 
131
145
  const UNIT = Value.product({});
146
+ const NIL = Value.variant("nil", UNIT);
132
147
 
133
148
  function requireProduct(value, where) {
134
149
  if (!isProduct(value)) {
@@ -137,37 +152,298 @@ function requireProduct(value, where) {
137
152
  return value.product;
138
153
  }
139
154
 
140
- function listToK(items) {
141
- let result = Value.variant("nil", UNIT);
142
- for (let i = items.length - 1; i >= 0; i--) {
143
- result = Value.variant("cons", Value.product({
144
- car: items[i],
145
- cdr: result
146
- }));
147
- }
148
- return result;
155
+ function pushBitsMSB(out, width, n) {
156
+ for (let i = width - 1; i >= 0; i--) {
157
+ out.push((n >> i) & 1);
158
+ }
159
+ }
160
+
161
+ function readBitsMSB(bits, offset, width) {
162
+ let n = 0;
163
+ for (let i = 0; i < width; i++) {
164
+ n = (n << 1) | bits[offset + i];
165
+ }
166
+ return n;
167
+ }
168
+
169
+ export function indexToBitPath(index) {
170
+ if (index === 0) return [0];
171
+ const bits = [];
172
+ let n = index;
173
+ while (n > 0) {
174
+ bits.push(n & 1);
175
+ n = Math.floor(n / 2);
176
+ }
177
+ bits.reverse();
178
+ return bits;
179
+ }
180
+
181
+ export function bitPathToIndex(bits) {
182
+ if (bits.length === 1 && bits[0] === 0) return 0;
183
+ let n = 0;
184
+ for (const b of bits) {
185
+ n = n * 2 + b;
186
+ }
187
+ return n;
188
+ }
189
+
190
+ export function codePointToBitPath(cp, out = []) {
191
+ if (cp <= 0x7f) {
192
+ out.push(0);
193
+ pushBitsMSB(out, 7, cp);
194
+ return out;
195
+ }
196
+ if (cp <= 0x7ff) {
197
+ out.push(1, 0);
198
+ pushBitsMSB(out, 11, cp);
199
+ return out;
200
+ }
201
+ if (cp <= 0xffff) {
202
+ const hi = (cp >> 8) & 0xff;
203
+ const lo = cp & 0xff;
204
+ if (hi >= 0xe0 && hi <= 0xf8) {
205
+ out.push(1, 1, 1, 0);
206
+ if (hi <= 0xef) {
207
+ out.push(0);
208
+ pushBitsMSB(out, 4, hi - 0xe0);
209
+ } else if (hi <= 0xf7) {
210
+ out.push(1, 0);
211
+ pushBitsMSB(out, 3, hi - 0xf0);
212
+ } else {
213
+ out.push(1, 1);
214
+ }
215
+ pushBitsMSB(out, 8, lo);
216
+ return out;
217
+ }
218
+ out.push(1, 1, 0);
219
+ if (hi >= 0x08 && hi <= 0x0f) {
220
+ out.push(0, 0, 0);
221
+ pushBitsMSB(out, 3, hi - 0x08);
222
+ } else if (hi >= 0x10 && hi <= 0x7f) {
223
+ out.push(0, 0, 1);
224
+ pushBitsMSB(out, 7, hi - 0x10);
225
+ } else if (hi >= 0x80 && hi <= 0xcf) {
226
+ out.push(0, 1, 0);
227
+ pushBitsMSB(out, 7, hi - 0x80);
228
+ } else if (hi >= 0xd0 && hi <= 0xd7) {
229
+ out.push(0, 1, 1);
230
+ pushBitsMSB(out, 3, hi - 0xd0);
231
+ } else if (hi === 0xf9) {
232
+ out.push(1, 0, 0);
233
+ } else if (hi >= 0xfa && hi <= 0xfb) {
234
+ out.push(1, 0, 1);
235
+ pushBitsMSB(out, 1, hi - 0xfa);
236
+ } else if (hi >= 0xfc && hi <= 0xfd) {
237
+ out.push(1, 1, 0);
238
+ pushBitsMSB(out, 1, hi - 0xfc);
239
+ } else if (hi >= 0xfe && hi <= 0xff) {
240
+ out.push(1, 1, 1);
241
+ pushBitsMSB(out, 1, hi - 0xfe);
242
+ } else {
243
+ throw new Error(`Unsupported BMP hi byte: ${hi}`);
244
+ }
245
+ pushBitsMSB(out, 8, lo);
246
+ return out;
247
+ }
248
+ const mid = (cp >> 8) & 0xff;
249
+ const lo = cp & 0xff;
250
+ if (cp <= 0x1ffff) {
251
+ out.push(1, 1, 1, 1, 0);
252
+ pushBitsMSB(out, 8, mid);
253
+ pushBitsMSB(out, 8, lo);
254
+ return out;
255
+ }
256
+ const plane = cp >> 16;
257
+ out.push(1, 1, 1, 1, 1);
258
+ if (plane >= 2 && plane <= 3) {
259
+ out.push(0, 0);
260
+ pushBitsMSB(out, 1, plane - 2);
261
+ } else if (plane >= 4 && plane <= 7) {
262
+ out.push(0, 1);
263
+ pushBitsMSB(out, 2, plane - 4);
264
+ } else if (plane >= 8 && plane <= 15) {
265
+ out.push(1, 0);
266
+ pushBitsMSB(out, 3, plane - 8);
267
+ } else if (plane === 16) {
268
+ out.push(1, 1);
269
+ } else {
270
+ throw new Error(`Unsupported plane: ${plane}`);
271
+ }
272
+ pushBitsMSB(out, 8, mid);
273
+ pushBitsMSB(out, 8, lo);
274
+ return out;
149
275
  }
150
276
 
151
- function listFromK(value, where) {
152
- const result = [];
153
- let current = value;
154
- while (true) {
155
- if (!isVariant(current)) {
156
- throw new Error(`${where}: expected list variant (nil or cons)`);
277
+ export function stringToBitPath(str) {
278
+ const out = [];
279
+ for (const ch of str) {
280
+ codePointToBitPath(ch.codePointAt(0), out);
281
+ }
282
+ return out;
283
+ }
284
+
285
+ export function bitPathToString(bits) {
286
+ let i = 0;
287
+ let out = "";
288
+ while (i < bits.length) {
289
+ if (bits[i] === 0) {
290
+ const cp = readBitsMSB(bits, i + 1, 7);
291
+ out += String.fromCodePoint(cp);
292
+ i += 8;
293
+ continue;
157
294
  }
158
- if (current.tag === "nil") {
159
- requireProduct(current.value, `${where}.nil`);
160
- return result;
295
+ if (bits[i + 1] === 0) {
296
+ const cp = readBitsMSB(bits, i + 2, 11);
297
+ out += String.fromCodePoint(cp);
298
+ i += 13;
299
+ continue;
161
300
  }
162
- if (current.tag !== "cons") {
163
- throw new Error(
164
- `${where}: expected nil or cons, got ${current.tag}`
165
- );
301
+ if (bits[i + 2] === 0) {
302
+ i += 3;
303
+ const tag = readBitsMSB(bits, i, 3);
304
+ i += 3;
305
+ let hi;
306
+ if (tag === 0) {
307
+ hi = 0x08 + readBitsMSB(bits, i, 3);
308
+ i += 3;
309
+ } else if (tag === 1) {
310
+ hi = 0x10 + readBitsMSB(bits, i, 7);
311
+ i += 7;
312
+ } else if (tag === 2) {
313
+ hi = 0x80 + readBitsMSB(bits, i, 7);
314
+ i += 7;
315
+ } else if (tag === 3) {
316
+ hi = 0xd0 + readBitsMSB(bits, i, 3);
317
+ i += 3;
318
+ } else if (tag === 4) {
319
+ hi = 0xf9;
320
+ } else if (tag === 5) {
321
+ hi = 0xfa + readBitsMSB(bits, i, 1);
322
+ i += 1;
323
+ } else if (tag === 6) {
324
+ hi = 0xfc + readBitsMSB(bits, i, 1);
325
+ i += 1;
326
+ } else {
327
+ hi = 0xfe + readBitsMSB(bits, i, 1);
328
+ i += 1;
329
+ }
330
+ const lo = readBitsMSB(bits, i, 8);
331
+ i += 8;
332
+ out += String.fromCodePoint((hi << 8) | lo);
333
+ continue;
334
+ }
335
+ if (bits[i + 3] === 0) {
336
+ i += 4;
337
+ let hi;
338
+ if (bits[i] === 0) {
339
+ hi = 0xe0 + readBitsMSB(bits, i + 1, 4);
340
+ i += 5;
341
+ } else if (bits[i + 1] === 0) {
342
+ hi = 0xf0 + readBitsMSB(bits, i + 2, 3);
343
+ i += 5;
344
+ } else {
345
+ hi = 0xf8;
346
+ i += 2;
347
+ }
348
+ const lo = readBitsMSB(bits, i, 8);
349
+ i += 8;
350
+ out += String.fromCodePoint((hi << 8) | lo);
351
+ continue;
352
+ }
353
+ if (bits[i + 4] === 0) {
354
+ i += 5;
355
+ const mid = readBitsMSB(bits, i, 8);
356
+ const lo = readBitsMSB(bits, i + 8, 8);
357
+ i += 16;
358
+ out += String.fromCodePoint((1 << 16) | (mid << 8) | lo);
359
+ continue;
360
+ }
361
+ i += 5;
362
+ let plane;
363
+ if (bits[i] === 0 && bits[i + 1] === 0) {
364
+ plane = 2 + readBitsMSB(bits, i + 2, 1);
365
+ i += 3;
366
+ } else if (bits[i] === 0 && bits[i + 1] === 1) {
367
+ plane = 4 + readBitsMSB(bits, i + 2, 2);
368
+ i += 4;
369
+ } else if (bits[i] === 1 && bits[i + 1] === 0) {
370
+ plane = 8 + readBitsMSB(bits, i + 2, 3);
371
+ i += 5;
372
+ } else {
373
+ plane = 16;
374
+ i += 2;
375
+ }
376
+ const mid = readBitsMSB(bits, i, 8);
377
+ const lo = readBitsMSB(bits, i + 8, 8);
378
+ i += 16;
379
+ out += String.fromCodePoint((plane << 16) | (mid << 8) | lo);
380
+ }
381
+ return out;
382
+ }
383
+
384
+ function makeMutableNode() {
385
+ return { val: null, b0: null, b1: null };
386
+ }
387
+
388
+ function insertMutableTrie(root, bits, kVal) {
389
+ let curr = root;
390
+ for (let i = 0; i < bits.length; i++) {
391
+ if (bits[i] === 0) {
392
+ if (!curr.b0) curr.b0 = makeMutableNode();
393
+ curr = curr.b0;
394
+ } else {
395
+ if (!curr.b1) curr.b1 = makeMutableNode();
396
+ curr = curr.b1;
166
397
  }
167
- const pair = requireProduct(current.value, `${where}.cons`);
168
- result.push(pair.car);
169
- current = pair.cdr;
170
398
  }
399
+ curr.val = kVal;
400
+ }
401
+
402
+ function mutableNodeToK(node) {
403
+ if (!node) return NIL;
404
+ const valField = node.val !== null
405
+ ? Value.variant("val", node.val)
406
+ : NIL;
407
+ const b0 = mutableNodeToK(node.b0);
408
+ const b1 = mutableNodeToK(node.b1);
409
+ if (node.val === null && b0 === NIL && b1 === NIL) {
410
+ return NIL;
411
+ }
412
+ return Value.variant("trie", Value.product({
413
+ val: valField,
414
+ 0: b0,
415
+ 1: b1
416
+ }));
417
+ }
418
+
419
+ function collectTrieEntries(kNode, pathBits = [], entries = []) {
420
+ if (!isVariant(kNode)) {
421
+ throw new Error("djson: expected variant (nil or trie)");
422
+ }
423
+ if (kNode.tag === "nil") {
424
+ return entries;
425
+ }
426
+ if (kNode.tag !== "trie") {
427
+ throw new Error(`djson: unexpected tag ${kNode.tag}`);
428
+ }
429
+ const prod = requireProduct(kNode.value, "djson.trie");
430
+ if (!isVariant(prod.val)) {
431
+ throw new Error("djson.trie.val: expected variant");
432
+ }
433
+ if (prod.val.tag === "val") {
434
+ entries.push({ bits: pathBits.slice(), val: prod.val.value });
435
+ } else if (prod.val.tag !== "nil") {
436
+ throw new Error(
437
+ `djson.trie.val: unexpected tag ${prod.val.tag}`
438
+ );
439
+ }
440
+ pathBits.push(0);
441
+ collectTrieEntries(prod[0], pathBits, entries);
442
+ pathBits.pop();
443
+ pathBits.push(1);
444
+ collectTrieEntries(prod[1], pathBits, entries);
445
+ pathBits.pop();
446
+ return entries;
171
447
  }
172
448
 
173
449
  export function fromJsonValue(value) {
@@ -190,81 +466,96 @@ export function fromJsonValue(value) {
190
466
  return Value.variant("string", textToStringValue(value));
191
467
  }
192
468
  if (Array.isArray(value)) {
193
- return Value.variant("list", listToK(value.map(fromJsonValue)));
469
+ if (value.length === 0) {
470
+ return Value.variant("list", NIL);
471
+ }
472
+ const root = makeMutableNode();
473
+ for (let i = 0; i < value.length; i++) {
474
+ insertMutableTrie(root, indexToBitPath(i), fromJsonValue(value[i]));
475
+ }
476
+ return Value.variant("list", mutableNodeToK(root));
194
477
  }
195
478
  if (value && typeof value === "object") {
196
- const keys = Object.keys(value).sort();
197
- const entries = keys.map((k) =>
198
- Value.product({
199
- key: textToStringValue(k),
200
- val: fromJsonValue(value[k])
201
- })
202
- );
203
- return Value.variant("object", listToK(entries));
479
+ const keys = Object.keys(value);
480
+ if (keys.length === 0) {
481
+ return Value.variant("object", NIL);
482
+ }
483
+ const root = makeMutableNode();
484
+ for (const k of keys) {
485
+ insertMutableTrie(
486
+ root,
487
+ stringToBitPath(k),
488
+ fromJsonValue(value[k])
489
+ );
490
+ }
491
+ return Value.variant("object", mutableNodeToK(root));
204
492
  }
205
493
  throw new Error(`Unsupported JSON value: ${value}`);
206
494
  }
207
495
 
208
496
  export function toJsonValue(value) {
209
497
  if (!isVariant(value)) {
210
- throw new Error("djson.value: expected top-level Variant");
498
+ throw new Error("djson: expected top-level Variant");
211
499
  }
212
-
213
500
  if (value.tag === "null") {
214
501
  requireProduct(value.value, "djson.null");
215
502
  return null;
216
503
  }
217
-
218
504
  if (value.tag === "bool") {
219
505
  if (!isVariant(value.value)) {
220
506
  throw new Error("djson.bool: expected variant");
221
507
  }
222
- if (value.value.tag === "true") {
223
- requireProduct(value.value.value, "djson.bool.true");
224
- return true;
225
- }
226
- if (value.value.tag === "false") {
227
- requireProduct(value.value.value, "djson.bool.false");
228
- return false;
229
- }
508
+ if (value.value.tag === "true") return true;
509
+ if (value.value.tag === "false") return false;
230
510
  throw new Error(`djson.bool: invalid tag ${value.value.tag}`);
231
511
  }
232
-
233
512
  if (value.tag === "number") {
234
513
  return decodeValueToNumber(value.value);
235
514
  }
236
-
237
515
  if (value.tag === "string") {
238
516
  return stringValueToText(value.value);
239
517
  }
240
-
241
518
  if (value.tag === "list") {
242
- const items = listFromK(value.value, "djson.list");
243
- return items.map(toJsonValue);
519
+ const entries = collectTrieEntries(value.value);
520
+ entries.sort((a, b) =>
521
+ bitPathToIndex(a.bits) - bitPathToIndex(b.bits)
522
+ );
523
+ return entries.map((e) => toJsonValue(e.val));
244
524
  }
245
-
246
525
  if (value.tag === "object") {
247
- const pairs = listFromK(value.value, "djson.object");
526
+ const entries = collectTrieEntries(value.value);
248
527
  const result = {};
249
- for (const pairValue of pairs) {
250
- const pair = requireProduct(pairValue, "djson.object.pair");
251
- const key = stringValueToText(pair.key);
252
- result[key] = toJsonValue(pair.val);
528
+ for (const e of entries) {
529
+ result[bitPathToString(e.bits)] = toJsonValue(e.val);
253
530
  }
254
531
  return result;
255
532
  }
256
-
257
- throw new Error(`Unsupported djson tag: ${value.tag}`);
533
+ throw new Error(`djson: unsupported tag ${value.tag}`);
258
534
  }
259
535
 
260
- export function parse(text) {
261
- const json = JSON.parse(text);
262
- const value = fromJsonValue(json);
263
- return withPattern(value, DJSON_PATTERN);
536
+ export const DJSON_BTRIE_PATTERN = DJSON_PATTERN;
537
+ export const pattern = DJSON_PATTERN;
538
+
539
+ export function parse(rawText) {
540
+ const text = String(rawText).trim();
541
+ if (!text) throw new Error("Empty JSON input");
542
+ const parsed = JSON.parse(text);
543
+ const val = fromJsonValue(parsed);
544
+ return withPattern(val, DJSON_PATTERN);
264
545
  }
265
546
 
266
547
  export function print(value) {
267
548
  return JSON.stringify(toJsonValue(value));
268
549
  }
269
550
 
551
+ export const codec = {
552
+ name: "djson",
553
+ doc,
554
+ pattern: DJSON_PATTERN,
555
+ parse,
556
+ print
557
+ };
558
+
559
+ export default codec;
560
+
270
561
  runCodecCLI(import.meta.url, { parse, print, doc });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fraczak/k",
3
- "version": "8.0.0",
3
+ "version": "8.1.0",
4
4
  "description": "k — a language for content-addressable schemas and data transformations over algebraic data types (products and tagged unions); includes runtime, contract derivation, REPL, and codec toolchain",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -33,7 +33,6 @@
33
33
  "perf:poly:pkir": "BACKENDS=pkir node scripts/perf-poly.mjs",
34
34
  "perf:poly:llvm-pkir": "BACKENDS=llvm-pkir node scripts/perf-poly.mjs",
35
35
  "perf:poly:trace": "node scripts/perf-poly.mjs --trace",
36
- "perf:djson": "node scripts/perf-djson.mjs",
37
36
  "perf:idempotency": "node scripts/benchmark-idempotency.mjs",
38
37
  "deps:graph": "node scripts/generate-dependency-graph.mjs",
39
38
  "compare": "node harness/cli.mjs",
@@ -60,8 +59,6 @@
60
59
  "k-wasm-compile": "backends/wasm/bin/k-wasm-compile.mjs",
61
60
  "k-wasm-run": "backends/wasm/bin/k-wasm-run.mjs",
62
61
  "k-djson": "codecs/djson.mjs",
63
- "k-djson-btrie": "codecs/djson-btrie.mjs",
64
- "k-djson-ptrie": "codecs/djson-ptrie.mjs",
65
62
  "k-ieee": "codecs/ieee.mjs",
66
63
  "k-int": "codecs/int.mjs",
67
64
  "k-json": "codecs/json.mjs",
@@ -84,9 +84,7 @@ const verifiedExamples = [
84
84
  "ieee.k",
85
85
  "poly.k",
86
86
  "karatsuba-mult.k",
87
- "djson.k",
88
- "djson-btrie.k",
89
- "djson-ptrie.k"
87
+ "djson.k"
90
88
  ];
91
89
  const examplesDir = path.join(projectRoot, "Examples");
92
90
  for (const filename of verifiedExamples) {
@@ -102,8 +100,6 @@ for (const filename of verifiedExamples) {
102
100
  const verifiedCodecs = [
103
101
  "json.mjs",
104
102
  "djson.mjs",
105
- "djson-btrie.mjs",
106
- "djson-ptrie.mjs",
107
103
  "utf8.mjs",
108
104
  "int.mjs",
109
105
  "unit.mjs",
@@ -1698,8 +1694,6 @@ const htmlContent = `<!DOCTYPE html>
1698
1694
  <option value="poly.k">poly.k</option>
1699
1695
  <option value="karatsuba-mult.k">karatsuba-mult.k</option>
1700
1696
  <option value="djson.k">djson.k</option>
1701
- <option value="djson-btrie.k">djson-btrie.k</option>
1702
- <option value="djson-ptrie.k">djson-ptrie.k</option>
1703
1697
  </optgroup>
1704
1698
  <optgroup label="Quick Expressions">
1705
1699
  <option value="expr:{} | ok">{} | ok</option>
@@ -1720,14 +1714,10 @@ const htmlContent = `<!DOCTYPE html>
1720
1714
  <option value="expr::codec load utf8.mjs">:codec load utf8.mjs</option>
1721
1715
  <option value="expr::codec load json.mjs">:codec load json.mjs</option>
1722
1716
  <option value="expr::codec load djson.mjs">:codec load djson.mjs</option>
1723
- <option value="expr::codec load djson-btrie.mjs">:codec load djson-btrie.mjs</option>
1724
- <option value="expr::codec load djson-ptrie.mjs">:codec load djson-ptrie.mjs</option>
1725
1717
  <option value="expr::codec load ieee.mjs">:codec load ieee.mjs</option>
1726
1718
  <option value="expr::codec load unit.mjs">:codec load unit.mjs</option>
1727
1719
  <option value="expr::input json.mjs {&quot;a&quot;:12,&quot;b&quot;:&quot;hello&quot;}">:input json.mjs {"a":12,"b":"hello"}</option>
1728
1720
  <option value="expr::input djson.mjs {&quot;a&quot;:12,&quot;b&quot;:&quot;hello&quot;}">:input djson.mjs {"a":12,"b":"hello"}</option>
1729
- <option value="expr::input djson-btrie.mjs {&quot;a&quot;:12,&quot;b&quot;:&quot;hello&quot;}">:input djson-btrie.mjs {"a":12,"b":"hello"}</option>
1730
- <option value="expr::input djson-ptrie.mjs {&quot;a&quot;:12,&quot;b&quot;:&quot;hello&quot;}">:input djson-ptrie.mjs {"a":12,"b":"hello"}</option>
1731
1721
  <option value="expr::input int.mjs [0,1,2]">:input int.mjs [0,1,2]</option>
1732
1722
  </optgroup>
1733
1723
  </select>
@@ -43,6 +43,11 @@ const tests = [
43
43
  ["tests/test-hash-normalization.mjs", node, ["tests/test-hash-normalization.mjs"]],
44
44
  ["tests/test-structural-values.mjs", node, ["tests/test-structural-values.mjs"]],
45
45
  ["tests/test-codecs.mjs", node, ["tests/test-codecs.mjs"]],
46
+ [
47
+ "tests/test-djson-methods.mjs",
48
+ node,
49
+ ["tests/test-djson-methods.mjs"]
50
+ ],
46
51
  ["tests/test-deep-wire-value.mjs", node, ["tests/test-deep-wire-value.mjs"]],
47
52
  ["tests/test-k-object.mjs", node, ["tests/test-k-object.mjs"]],
48
53
  ["tests/test-kir.mjs", node, ["tests/test-kir.mjs"]],