@hviana/sema 0.1.5 → 0.1.6

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 (160) hide show
  1. package/AGENTS.md +6 -5
  2. package/CITATION.cff +49 -0
  3. package/HOW_IT_WORKS.md +11 -12
  4. package/README.md +7 -5
  5. package/dist/example/demo.js +25 -25
  6. package/dist/example/train_base.d.ts +19 -21
  7. package/dist/example/train_base.js +1687 -1952
  8. package/dist/src/alphabet.d.ts +3 -3
  9. package/dist/src/alphabet.js +24 -27
  10. package/dist/src/alu/src/alu.d.ts +169 -194
  11. package/dist/src/alu/src/alu.js +374 -414
  12. package/dist/src/alu/src/expr.d.ts +36 -43
  13. package/dist/src/alu/src/expr.js +252 -278
  14. package/dist/src/alu/src/index.d.ts +9 -98
  15. package/dist/src/alu/src/index.js +10 -64
  16. package/dist/src/alu/src/kernel-arith.d.ts +1 -5
  17. package/dist/src/alu/src/kernel-arith.js +195 -285
  18. package/dist/src/alu/src/kernel-bits.d.ts +1 -5
  19. package/dist/src/alu/src/kernel-bits.js +81 -115
  20. package/dist/src/alu/src/kernel-logic.js +33 -63
  21. package/dist/src/alu/src/kernel-nd.js +155 -195
  22. package/dist/src/alu/src/kernel-numeric.d.ts +16 -80
  23. package/dist/src/alu/src/kernel-numeric.js +259 -331
  24. package/dist/src/alu/src/operation.d.ts +112 -132
  25. package/dist/src/alu/src/operation.js +149 -163
  26. package/dist/src/alu/src/parser.d.ts +168 -175
  27. package/dist/src/alu/src/parser.js +382 -421
  28. package/dist/src/alu/src/resonance.d.ts +16 -25
  29. package/dist/src/alu/src/resonance.js +49 -56
  30. package/dist/src/alu/src/text.d.ts +3 -7
  31. package/dist/src/alu/src/text.js +31 -37
  32. package/dist/src/alu/src/value.d.ts +14 -14
  33. package/dist/src/alu/src/value.js +150 -160
  34. package/dist/src/alu/test/alu.test.js +543 -656
  35. package/dist/src/bytes.d.ts +1 -5
  36. package/dist/src/bytes.js +33 -40
  37. package/dist/src/config.d.ts +99 -102
  38. package/dist/src/config.js +78 -83
  39. package/dist/src/derive/src/deduction.d.ts +60 -62
  40. package/dist/src/derive/src/deduction.js +103 -109
  41. package/dist/src/derive/src/index.d.ts +1 -7
  42. package/dist/src/derive/src/priority-queue.d.ts +8 -8
  43. package/dist/src/derive/src/priority-queue.js +57 -61
  44. package/dist/src/derive/src/rewrite.d.ts +15 -18
  45. package/dist/src/derive/src/rewrite.js +59 -67
  46. package/dist/src/derive/src/trie.d.ts +56 -56
  47. package/dist/src/derive/src/trie.js +175 -179
  48. package/dist/src/derive/test/derive.test.js +96 -100
  49. package/dist/src/extension.d.ts +13 -16
  50. package/dist/src/geometry.d.ts +17 -42
  51. package/dist/src/geometry.js +235 -266
  52. package/dist/src/index.d.ts +2 -17
  53. package/dist/src/index.js +2 -12
  54. package/dist/src/ingest-cache.d.ts +25 -30
  55. package/dist/src/ingest-cache.js +108 -127
  56. package/dist/src/mind/articulation.d.ts +1 -5
  57. package/dist/src/mind/articulation.js +77 -112
  58. package/dist/src/mind/attention.d.ts +40 -108
  59. package/dist/src/mind/attention.js +749 -871
  60. package/dist/src/mind/canonical.d.ts +4 -19
  61. package/dist/src/mind/canonical.js +27 -31
  62. package/dist/src/mind/graph-search.d.ts +201 -225
  63. package/dist/src/mind/graph-search.js +742 -821
  64. package/dist/src/mind/index.d.ts +2 -10
  65. package/dist/src/mind/junction.d.ts +31 -58
  66. package/dist/src/mind/junction.js +172 -237
  67. package/dist/src/mind/learning.d.ts +16 -52
  68. package/dist/src/mind/learning.js +143 -165
  69. package/dist/src/mind/match.d.ts +20 -69
  70. package/dist/src/mind/match.js +259 -318
  71. package/dist/src/mind/mechanisms/alu.js +16 -16
  72. package/dist/src/mind/mechanisms/cast.d.ts +9 -13
  73. package/dist/src/mind/mechanisms/cast.js +363 -456
  74. package/dist/src/mind/mechanisms/confluence.d.ts +8 -12
  75. package/dist/src/mind/mechanisms/confluence.js +152 -183
  76. package/dist/src/mind/mechanisms/cover.d.ts +2 -8
  77. package/dist/src/mind/mechanisms/cover.js +148 -210
  78. package/dist/src/mind/mechanisms/extraction.d.ts +8 -34
  79. package/dist/src/mind/mechanisms/extraction.js +234 -288
  80. package/dist/src/mind/mechanisms/recall.d.ts +6 -10
  81. package/dist/src/mind/mechanisms/recall.js +126 -185
  82. package/dist/src/mind/mind.d.ts +129 -154
  83. package/dist/src/mind/mind.js +258 -288
  84. package/dist/src/mind/pipeline-mechanism.d.ts +112 -124
  85. package/dist/src/mind/pipeline-mechanism.js +161 -172
  86. package/dist/src/mind/pipeline.d.ts +4 -14
  87. package/dist/src/mind/pipeline.js +125 -189
  88. package/dist/src/mind/primitives.d.ts +8 -32
  89. package/dist/src/mind/primitives.js +99 -117
  90. package/dist/src/mind/rationale.d.ts +86 -98
  91. package/dist/src/mind/rationale.js +113 -121
  92. package/dist/src/mind/reasoning.d.ts +2 -13
  93. package/dist/src/mind/reasoning.js +129 -166
  94. package/dist/src/mind/recognition.d.ts +1 -4
  95. package/dist/src/mind/recognition.js +183 -208
  96. package/dist/src/mind/resonance.d.ts +5 -22
  97. package/dist/src/mind/resonance.js +0 -0
  98. package/dist/src/mind/trace.d.ts +6 -25
  99. package/dist/src/mind/trace.js +50 -58
  100. package/dist/src/mind/traverse.d.ts +16 -58
  101. package/dist/src/mind/traverse.js +304 -357
  102. package/dist/src/mind/types.d.ts +120 -127
  103. package/dist/src/mind/types.js +60 -69
  104. package/dist/src/rabitq-ivf/src/database.d.ts +113 -0
  105. package/dist/src/rabitq-ivf/src/database.js +201 -0
  106. package/dist/src/rabitq-ivf/src/index.d.ts +7 -0
  107. package/dist/src/{rabitq-hnsw → rabitq-ivf}/src/index.js +1 -3
  108. package/dist/src/rabitq-ivf/src/ivf.d.ts +200 -0
  109. package/dist/src/rabitq-ivf/src/ivf.js +1165 -0
  110. package/dist/src/rabitq-ivf/src/prng.d.ts +19 -0
  111. package/dist/src/rabitq-ivf/src/prng.js +36 -0
  112. package/dist/src/rabitq-ivf/src/rabitq.d.ts +95 -0
  113. package/dist/src/rabitq-ivf/src/rabitq.js +283 -0
  114. package/dist/src/sema.d.ts +9 -13
  115. package/dist/src/sema.js +26 -40
  116. package/dist/src/store-sqlite.d.ts +169 -166
  117. package/dist/src/store-sqlite.js +762 -662
  118. package/dist/src/store.d.ts +586 -630
  119. package/dist/src/store.js +1423 -1581
  120. package/dist/src/vec.d.ts +5 -9
  121. package/dist/src/vec.js +61 -73
  122. package/example/train_base.ts +13 -10
  123. package/package.json +1 -1
  124. package/src/alu/README.md +1 -1
  125. package/src/alu/src/index.ts +1 -1
  126. package/src/config.ts +19 -27
  127. package/src/index.ts +6 -11
  128. package/src/rabitq-ivf/README.md +56 -0
  129. package/src/rabitq-ivf/src/database.ts +276 -0
  130. package/src/{rabitq-hnsw → rabitq-ivf}/src/index.ts +2 -5
  131. package/src/rabitq-ivf/src/ivf.ts +1330 -0
  132. package/src/{rabitq-hnsw → rabitq-ivf}/src/prng.ts +1 -1
  133. package/src/store-sqlite.ts +196 -9
  134. package/src/store.ts +8 -32
  135. package/test/08-storage.test.mjs +3 -3
  136. package/test/14-scaling.test.mjs +2 -2
  137. package/test/35-ivf.test.mjs +263 -0
  138. package/test/36-bloom.test.mjs +123 -0
  139. package/dist/src/rabitq-hnsw/src/database.d.ts +0 -202
  140. package/dist/src/rabitq-hnsw/src/database.js +0 -405
  141. package/dist/src/rabitq-hnsw/src/heap.d.ts +0 -22
  142. package/dist/src/rabitq-hnsw/src/heap.js +0 -94
  143. package/dist/src/rabitq-hnsw/src/hnsw.d.ts +0 -125
  144. package/dist/src/rabitq-hnsw/src/hnsw.js +0 -500
  145. package/dist/src/rabitq-hnsw/src/index.d.ts +0 -15
  146. package/dist/src/rabitq-hnsw/src/prng.d.ts +0 -19
  147. package/dist/src/rabitq-hnsw/src/prng.js +0 -38
  148. package/dist/src/rabitq-hnsw/src/rabitq.d.ts +0 -95
  149. package/dist/src/rabitq-hnsw/src/rabitq.js +0 -299
  150. package/dist/src/rabitq-hnsw/src/store.d.ts +0 -162
  151. package/dist/src/rabitq-hnsw/src/store.js +0 -916
  152. package/dist/src/rabitq-hnsw/test/hnsw.test.d.ts +0 -1
  153. package/dist/src/rabitq-hnsw/test/hnsw.test.js +0 -1197
  154. package/src/rabitq-hnsw/README.md +0 -303
  155. package/src/rabitq-hnsw/src/database.ts +0 -492
  156. package/src/rabitq-hnsw/src/heap.ts +0 -90
  157. package/src/rabitq-hnsw/src/hnsw.ts +0 -514
  158. package/src/rabitq-hnsw/src/store.ts +0 -994
  159. package/src/rabitq-hnsw/test/hnsw.test.ts +0 -1213
  160. /package/src/{rabitq-hnsw → rabitq-ivf}/src/rabitq.ts +0 -0
@@ -3,8 +3,8 @@ import type { ResonanceSync } from "./operation.js";
3
3
  * surface forms, as bytes. The host resonates opaque spans against these to
4
4
  * answer "which operation does this span MEAN?" (see parser.ts AluHost). */
5
5
  export interface ConceptAnchor {
6
- name: string;
7
- form: Uint8Array;
6
+ name: string;
7
+ form: Uint8Array;
8
8
  }
9
9
  /** The async resonance capability the host provides. Both methods may return
10
10
  * null when resonance finds nothing above the host's own threshold — ALU then
@@ -12,17 +12,17 @@ export interface ConceptAnchor {
12
12
  * keeps synthesis graph-evidenced: ALU never invents meaning resonance did not
13
13
  * supply. */
14
14
  export interface AluResonance {
15
- /** The canonical operation a span's MEANING names, found by resonance over the
16
- * operation concepts — the GENERIC, modality-agnostic recognition path. This
17
- * is how an operation that is NOT literally spelled (no "∫" for an integral,
18
- * no "+" for a sum drawn or spoken) is still recognised: the span's gist
19
- * resonates with the operation's concept. Returns the canonical op name, or
20
- * null when nothing resonates above threshold. */
21
- recogniseOp(bytes: Uint8Array): Promise<string | null>;
22
- /** The resonant opposite of a symbol's bytes (its antonym / inverse in the
23
- * resonance space, any modality), or null. The host finds it by halo
24
- * resonance over the negated concept. */
25
- opposite(bytes: Uint8Array): Promise<Uint8Array | null>;
15
+ /** The canonical operation a span's MEANING names, found by resonance over the
16
+ * operation concepts — the GENERIC, modality-agnostic recognition path. This
17
+ * is how an operation that is NOT literally spelled (no "∫" for an integral,
18
+ * no "+" for a sum drawn or spoken) is still recognised: the span's gist
19
+ * resonates with the operation's concept. Returns the canonical op name, or
20
+ * null when nothing resonates above threshold. */
21
+ recogniseOp(bytes: Uint8Array): Promise<string | null>;
22
+ /** The resonant opposite of a symbol's bytes (its antonym / inverse in the
23
+ * resonance space, any modality), or null. The host finds it by halo
24
+ * resonance over the negated concept. */
25
+ opposite(bytes: Uint8Array): Promise<Uint8Array | null>;
26
26
  }
27
27
  /** A AluResonance that knows nothing — the default when the host wires none in,
28
28
  * so the kernel runs fully decoupled (operations resolve by literal forms only,
@@ -34,10 +34,7 @@ export declare const NO_ALU_RESONANCE: AluResonance;
34
34
  * of the bytes (a lossless, stable string key — the same device the search's
35
35
  * chart uses). This is the async→sync bridge for the polymorphic inverse,
36
36
  * mirroring how a concept hop's target is pre-resolved and read synchronously. */
37
- export declare function prefetchOpposites(
38
- resonance: AluResonance,
39
- symbols: Iterable<Uint8Array>,
40
- ): Promise<ResonanceSync>;
37
+ export declare function prefetchOpposites(resonance: AluResonance, symbols: Iterable<Uint8Array>): Promise<ResonanceSync>;
41
38
  /** Pre-resolve BOTH capabilities a computation may need synchronously — the
42
39
  * resonant opposite of a symbol (for the polymorphic inverse) AND the operation
43
40
  * a symbol's MEANING names (for a higher-order nd op's function argument) — over
@@ -47,10 +44,7 @@ export declare function prefetchOpposites(
47
44
  * inverse operands and as a reduce/map/filter operator. Either lookup yields
48
45
  * null for a span that resonates with nothing, so callbacks decline rather than
49
46
  * guess. */
50
- export declare function prefetchResonance(
51
- resonance: AluResonance,
52
- spans: Iterable<Uint8Array>,
53
- ): Promise<ResonanceSync>;
47
+ export declare function prefetchResonance(resonance: AluResonance, spans: Iterable<Uint8Array>): Promise<ResonanceSync>;
54
48
  /** Pre-resolve, for each candidate span, the operation its MEANING names —
55
49
  * awaiting the host's async gist resonance once per distinct span — and return
56
50
  * a synchronous map keyed by the span's latin1 bytes → canonical op name. This
@@ -58,7 +52,4 @@ export declare function prefetchResonance(
58
52
  * the literal scan could not classify (no operator symbol) but whose gist
59
53
  * resonates with an operation's concept. Spans that resonate with nothing are
60
54
  * omitted, so the caller treats a miss as "not an operation". */
61
- export declare function prefetchRecognisedOps(
62
- resonance: AluResonance,
63
- spans: Iterable<Uint8Array>,
64
- ): Promise<Map<string, string>>;
55
+ export declare function prefetchRecognisedOps(resonance: AluResonance, spans: Iterable<Uint8Array>): Promise<Map<string, string>>;
@@ -43,8 +43,8 @@ import { latin1 } from "../../bytes.js";
43
43
  * so the kernel runs fully decoupled (operations resolve by literal forms only,
44
44
  * and a symbol inverse is left unchanged). */
45
45
  export const NO_ALU_RESONANCE = {
46
- recogniseOp: async () => null,
47
- opposite: async () => null,
46
+ recogniseOp: async () => null,
47
+ opposite: async () => null,
48
48
  };
49
49
  /** Pre-resolve the resonant opposite of each symbol in `symbols`, awaiting the
50
50
  * host's async resonance once per distinct span, and return a SYNCHRONOUS
@@ -53,25 +53,23 @@ export const NO_ALU_RESONANCE = {
53
53
  * chart uses). This is the async→sync bridge for the polymorphic inverse,
54
54
  * mirroring how a concept hop's target is pre-resolved and read synchronously. */
55
55
  export async function prefetchOpposites(resonance, symbols) {
56
- const table = new Map();
57
- const seen = new Set();
58
- for (const bytes of symbols) {
59
- const key = latin1(bytes);
60
- if (seen.has(key)) {
61
- continue;
56
+ const table = new Map();
57
+ const seen = new Set();
58
+ for (const bytes of symbols) {
59
+ const key = latin1(bytes);
60
+ if (seen.has(key))
61
+ continue;
62
+ seen.add(key);
63
+ const opp = await resonance.opposite(bytes);
64
+ if (opp)
65
+ table.set(key, opp);
62
66
  }
63
- seen.add(key);
64
- const opp = await resonance.opposite(bytes);
65
- if (opp) {
66
- table.set(key, opp);
67
- }
68
- }
69
- return {
70
- opposite: (bytes) => table.get(latin1(bytes)) ?? null,
71
- // Opposites-only prefetch carries no op recognition; a higher-order nd op
72
- // resolving through this falls back to literal forms / canonical names.
73
- recogniseOp: () => null,
74
- };
67
+ return {
68
+ opposite: (bytes) => table.get(latin1(bytes)) ?? null,
69
+ // Opposites-only prefetch carries no op recognition; a higher-order nd op
70
+ // resolving through this falls back to literal forms / canonical names.
71
+ recogniseOp: () => null,
72
+ };
75
73
  }
76
74
  /** Pre-resolve BOTH capabilities a computation may need synchronously — the
77
75
  * resonant opposite of a symbol (for the polymorphic inverse) AND the operation
@@ -83,30 +81,27 @@ export async function prefetchOpposites(resonance, symbols) {
83
81
  * null for a span that resonates with nothing, so callbacks decline rather than
84
82
  * guess. */
85
83
  export async function prefetchResonance(resonance, spans) {
86
- const opposites = new Map();
87
- const ops = new Map();
88
- const seen = new Set();
89
- for (const bytes of spans) {
90
- const key = latin1(bytes);
91
- if (seen.has(key)) {
92
- continue;
93
- }
94
- seen.add(key);
95
- const [opp, op] = await Promise.all([
96
- resonance.opposite(bytes),
97
- resonance.recogniseOp(bytes),
98
- ]);
99
- if (opp) {
100
- opposites.set(key, opp);
84
+ const opposites = new Map();
85
+ const ops = new Map();
86
+ const seen = new Set();
87
+ for (const bytes of spans) {
88
+ const key = latin1(bytes);
89
+ if (seen.has(key))
90
+ continue;
91
+ seen.add(key);
92
+ const [opp, op] = await Promise.all([
93
+ resonance.opposite(bytes),
94
+ resonance.recogniseOp(bytes),
95
+ ]);
96
+ if (opp)
97
+ opposites.set(key, opp);
98
+ if (op)
99
+ ops.set(key, op);
101
100
  }
102
- if (op) {
103
- ops.set(key, op);
104
- }
105
- }
106
- return {
107
- opposite: (bytes) => opposites.get(latin1(bytes)) ?? null,
108
- recogniseOp: (bytes) => ops.get(latin1(bytes)) ?? null,
109
- };
101
+ return {
102
+ opposite: (bytes) => opposites.get(latin1(bytes)) ?? null,
103
+ recogniseOp: (bytes) => ops.get(latin1(bytes)) ?? null,
104
+ };
110
105
  }
111
106
  /** Pre-resolve, for each candidate span, the operation its MEANING names —
112
107
  * awaiting the host's async gist resonance once per distinct span — and return
@@ -116,18 +111,16 @@ export async function prefetchResonance(resonance, spans) {
116
111
  * resonates with an operation's concept. Spans that resonate with nothing are
117
112
  * omitted, so the caller treats a miss as "not an operation". */
118
113
  export async function prefetchRecognisedOps(resonance, spans) {
119
- const table = new Map();
120
- const seen = new Set();
121
- for (const bytes of spans) {
122
- const key = latin1(bytes);
123
- if (seen.has(key)) {
124
- continue;
125
- }
126
- seen.add(key);
127
- const op = await resonance.recogniseOp(bytes);
128
- if (op) {
129
- table.set(key, op);
114
+ const table = new Map();
115
+ const seen = new Set();
116
+ for (const bytes of spans) {
117
+ const key = latin1(bytes);
118
+ if (seen.has(key))
119
+ continue;
120
+ seen.add(key);
121
+ const op = await resonance.recogniseOp(bytes);
122
+ if (op)
123
+ table.set(key, op);
130
124
  }
131
- }
132
- return table;
125
+ return table;
133
126
  }
@@ -25,11 +25,7 @@ export declare function matchBracket(b: Uint8Array, open: number): number;
25
25
  /** The maximal non-whitespace runs of `bytes` within [from, to) — the spacing
26
26
  * floor's reading of "the tokens", shared by the structural host's segmenter
27
27
  * and the parser's term lexing so neither re-implements the walk. */
28
- export declare function nonSpaceRuns(
29
- bytes: Uint8Array,
30
- from?: number,
31
- to?: number,
32
- ): Array<{
33
- i: number;
34
- j: number;
28
+ export declare function nonSpaceRuns(bytes: Uint8Array, from?: number, to?: number): Array<{
29
+ i: number;
30
+ j: number;
35
31
  }>;
@@ -18,62 +18,56 @@ export const OPEN = 0x5b; // "["
18
18
  export const CLOSE = 0x5d; // "]"
19
19
  /** ASCII whitespace (space, tab, newline, carriage return) — the one spacing
20
20
  * convention bytes of every textual modality share. */
21
- export const isSpaceByte = (c) =>
22
- c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d;
21
+ export const isSpaceByte = (c) => c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d;
23
22
  /** A byte that DELIMITS list elements inside an explicit container: whitespace,
24
23
  * a comma, or a semicolon. Deliberately excludes anything that can sit inside
25
24
  * a numeral or a symbol token (letters, digits, sign/decimal `+ - .`) and the
26
25
  * brackets themselves, so an element's own bytes are never split. */
27
- export const isSepByte = (c) =>
28
- isSpaceByte(c) || c === 0x2c /* , */ || c === 0x3b /* ; */;
26
+ export const isSepByte = (c) => isSpaceByte(c) || c === 0x2c /* , */ || c === 0x3b /* ; */;
29
27
  /** The index of the first non-whitespace byte (or the length, if all space). */
30
28
  export function trimStart(b) {
31
- let i = 0;
32
- while (i < b.length && isSpaceByte(b[i])) {
33
- i++;
34
- }
35
- return i;
29
+ let i = 0;
30
+ while (i < b.length && isSpaceByte(b[i]))
31
+ i++;
32
+ return i;
36
33
  }
37
34
  /** The index one past the last non-whitespace byte (or 0, if all space). */
38
35
  export function trimEnd(b) {
39
- let j = b.length;
40
- const lo = trimStart(b);
41
- while (j > lo && isSpaceByte(b[j - 1])) {
42
- j--;
43
- }
44
- return j;
36
+ let j = b.length;
37
+ const lo = trimStart(b);
38
+ while (j > lo && isSpaceByte(b[j - 1]))
39
+ j--;
40
+ return j;
45
41
  }
46
42
  /** The index of the `]` matching the `[` at `open`, bracket-depth aware, or -1
47
43
  * when it is unbalanced — used to test whether a span is one explicit list
48
44
  * CONTAINER (its opening bracket closing exactly at its end). */
49
45
  export function matchBracket(b, open) {
50
- let depth = 0;
51
- for (let i = open; i < b.length; i++) {
52
- if (b[i] === OPEN) {
53
- depth++;
54
- } else if (b[i] === CLOSE && --depth === 0) {
55
- return i;
46
+ let depth = 0;
47
+ for (let i = open; i < b.length; i++) {
48
+ if (b[i] === OPEN)
49
+ depth++;
50
+ else if (b[i] === CLOSE && --depth === 0)
51
+ return i;
56
52
  }
57
- }
58
- return -1;
53
+ return -1;
59
54
  }
60
55
  /** The maximal non-whitespace runs of `bytes` within [from, to) — the spacing
61
56
  * floor's reading of "the tokens", shared by the structural host's segmenter
62
57
  * and the parser's term lexing so neither re-implements the walk. */
63
58
  export function nonSpaceRuns(bytes, from = 0, to = bytes.length) {
64
- const out = [];
65
- let i = from;
66
- while (i < to) {
67
- if (isSpaceByte(bytes[i])) {
68
- i++;
69
- continue;
59
+ const out = [];
60
+ let i = from;
61
+ while (i < to) {
62
+ if (isSpaceByte(bytes[i])) {
63
+ i++;
64
+ continue;
65
+ }
66
+ let j = i;
67
+ while (j < to && !isSpaceByte(bytes[j]))
68
+ j++;
69
+ out.push({ i, j });
70
+ i = j;
70
71
  }
71
- let j = i;
72
- while (j < to && !isSpaceByte(bytes[j])) {
73
- j++;
74
- }
75
- out.push({ i, j });
76
- i = j;
77
- }
78
- return out;
72
+ return out;
79
73
  }
@@ -6,20 +6,20 @@ export type Domain = "bit" | "int" | "real" | "symbol" | "nd";
6
6
  * Values of any domain, so nesting (a matrix = an nd of nd) and heterogeneity
7
7
  * (a list mixing numbers, symbols, sub-lists) are the same case. */
8
8
  export type Value = {
9
- domain: "bit";
10
- b: 0 | 1;
9
+ domain: "bit";
10
+ b: 0 | 1;
11
11
  } | {
12
- domain: "int";
13
- n: bigint;
12
+ domain: "int";
13
+ n: bigint;
14
14
  } | {
15
- domain: "real";
16
- x: number;
15
+ domain: "real";
16
+ x: number;
17
17
  } | {
18
- domain: "symbol";
19
- bytes: Uint8Array;
18
+ domain: "symbol";
19
+ bytes: Uint8Array;
20
20
  } | {
21
- domain: "nd";
22
- items: Value[];
21
+ domain: "nd";
22
+ items: Value[];
23
23
  };
24
24
  export declare const bit: (b: 0 | 1) => Value;
25
25
  export declare const int: (n: bigint) => Value;
@@ -36,8 +36,8 @@ export declare const tagOf: (v: Value) => Domain;
36
36
  export declare function isNumeric(v: Value): boolean;
37
37
  /** Whether a value is the n-dimensional container. */
38
38
  export declare function isNd(v: Value): v is {
39
- domain: "nd";
40
- items: Value[];
39
+ domain: "nd";
40
+ items: Value[];
41
41
  };
42
42
  /** Collect, into `out`, every SYMBOL byte span reachable inside a value — itself
43
43
  * when it is a symbol, or each element recursively when it is an nd. These are
@@ -70,8 +70,8 @@ export declare function joinDomain(args: Value[]): "bit" | "int" | "real";
70
70
  * bytes only through this, so the surrounding system owns how a number is
71
71
  * spelled. A default ({@link decimalCodec}) is provided. */
72
72
  export interface ValueCodec {
73
- encode(v: Value): Uint8Array;
74
- decode(bytes: Uint8Array): Value | null;
73
+ encode(v: Value): Uint8Array;
74
+ decode(bytes: Uint8Array): Value | null;
75
75
  }
76
76
  /** Parse a byte span into a SCALAR value: a clean integer numeral → exact int, a
77
77
  * fractional/exponent numeral → real, anything else → a symbol carrying its