zkjson 0.4.1 → 0.5.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/encoder-v2.js CHANGED
@@ -1,1048 +1,884 @@
1
- const {
2
- clone,
3
- uniq,
4
- sortBy,
5
- map,
6
- concat,
7
- compose,
8
- is,
9
- descend,
10
- ascend,
11
- sortWith,
12
- prop,
13
- equals,
14
- append,
15
- isNil,
16
- includes,
17
- splitEvery,
18
- flatten,
19
- } = require("ramda")
20
- const ops = {
21
- $eq: 10,
22
- $ne: 11,
23
- $gt: 12,
24
- $gte: 13,
25
- $lt: 14,
26
- $lte: 15,
27
- $in: 16,
28
- $nin: 17,
29
- $contains: 18,
30
- $contains_any: 19,
31
- $contains_all: 20,
32
- $contains_none: 21,
33
- }
34
- const opMap = {}
35
- for (let k in ops) opMap[ops[k]] = k
36
-
37
- const base64Map = {
38
- A: "00",
39
- B: "01",
40
- C: "02",
41
- D: "03",
42
- E: "04",
43
- F: "05",
44
- G: "06",
45
- H: "07",
46
- I: "08",
47
- J: "09",
48
- K: "10",
49
- L: "11",
50
- M: "12",
51
- N: "13",
52
- O: "14",
53
- P: "15",
54
- Q: "16",
55
- R: "17",
56
- S: "18",
57
- T: "19",
58
- U: "20",
59
- V: "21",
60
- W: "22",
61
- X: "23",
62
- Y: "24",
63
- Z: "25",
64
- a: "26",
65
- b: "27",
66
- c: "28",
67
- d: "29",
68
- e: "30",
69
- f: "31",
70
- g: "32",
71
- h: "33",
72
- i: "34",
73
- j: "35",
74
- k: "36",
75
- l: "37",
76
- m: "38",
77
- n: "39",
78
- o: "40",
79
- p: "41",
80
- q: "42",
81
- r: "43",
82
- s: "44",
83
- t: "45",
84
- u: "46",
85
- v: "47",
86
- w: "48",
87
- x: "49",
88
- y: "50",
89
- z: "51",
90
- 0: "52",
91
- 1: "53",
92
- 2: "54",
93
- 3: "55",
94
- 4: "56",
95
- 5: "57",
96
- 6: "58",
97
- 7: "59",
98
- 8: "60",
99
- 9: "61",
100
- "-": "62",
101
- _: "63",
102
- }
103
-
104
- let strMap = {}
105
- for (const k in base64Map) strMap[base64Map[k]] = k
106
-
107
- function pad(arr, max = 0) {
108
- arr = arr.map(n => n.toString())
109
- for (let i = arr.length; i < max; i++) {
110
- arr.push("0")
1
+ const { bits, tobits, strmap, base64 } = require("./utils.js")
2
+
3
+ class u8 {
4
+ constructor(size = 100, log = false) {
5
+ this.log = log
6
+
7
+ this.kc_counts = new Uint32Array(32)
8
+ this.vc_counts = new Uint32Array(32)
9
+ this.kc_diffs = new Uint32Array(4)
10
+ this.vc_diffs = new Uint32Array(4)
11
+ this.vlinks = new Uint32Array(32)
12
+ this.klinks = new Uint32Array(32)
13
+ this.vflags = new Uint32Array(16)
14
+ this.kflags = new Uint32Array(16)
15
+ this.bools = new Uint32Array(16)
16
+ this.keys = new Uint32Array(32)
17
+ this.types = new Uint32Array(32)
18
+ this.nums = new Uint32Array(32)
19
+ this.dc = new Uint32Array(32)
20
+ this.kvals = new Uint32Array(64)
21
+ this.vals = new Uint32Array(64)
22
+
23
+ this.strMap = new Map()
24
+
25
+ this.bitsLookup = new Uint8Array(17)
26
+ for (let i = 0; i < 17; i++) {
27
+ this.bitsLookup[i] = i === 0 ? 1 : 32 - Math.clz32(i)
28
+ }
29
+ }
30
+ fastBits(n) {
31
+ return n < 17 ? this.bitsLookup[n] : bits(n)
111
32
  }
112
- return arr
113
- }
114
33
 
115
- function encodePath(path) {
116
- const parts = []
117
- let str = ""
118
- let num = 0
119
- for (const s of path) {
120
- if (num == 2 && !(s == "." || s == "[")) throw Error()
121
- if (s == ".") {
122
- if (num == 2) {
123
- num = 0
124
- } else {
125
- parts.push(str)
126
- str = ""
127
- }
128
- } else if (s == "[") {
129
- if (num != 2) {
130
- if (str != "" || parts.length > 0) parts.push(str)
131
- str = ""
132
- }
133
- num = 1
134
- } else if (s == "]") {
135
- if (num != 1) throw Error()
136
- num = 2
137
- if (str == "" || Number.isNaN(+str)) throw Error()
138
- parts.push(+str)
139
- str = ""
34
+ vc_diffs_set(index, value) {
35
+ const wordIndex = index >>> 5
36
+ const bitOffset = index & 31
37
+ if (value) {
38
+ this.vc_diffs[wordIndex] |= 1 << bitOffset
140
39
  } else {
141
- str += s
40
+ this.vc_diffs[wordIndex] &= ~(1 << bitOffset)
142
41
  }
143
42
  }
144
- if (str != "") parts.push(str)
145
- if (parts.length == 0) parts.push("")
146
- let encoded = [parts.length]
147
- for (const p of parts) {
148
- if (typeof p == "number") {
149
- encoded = encoded.concat([0, 0, p])
43
+ vc_diffs_get(index) {
44
+ const wordIndex = index >>> 5
45
+ const bitOffset = index & 31
46
+ return (this.vc_diffs[wordIndex] >>> bitOffset) & 1
47
+ }
48
+ kc_diffs_set(index, value) {
49
+ const wordIndex = index >>> 5
50
+ const bitOffset = index & 31
51
+ if (value) {
52
+ this.kc_diffs[wordIndex] |= 1 << bitOffset
150
53
  } else {
151
- let plen = [p.length]
152
- if (p.length == 0) plen.push(1)
153
- encoded = encoded.concat([
154
- ...plen,
155
- ...p.split("").map(c => c.charCodeAt(0)),
156
- ])
54
+ this.kc_diffs[wordIndex] &= ~(1 << bitOffset)
157
55
  }
158
56
  }
159
- return encoded
160
- }
57
+ kc_diffs_get(index) {
58
+ const wordIndex = index >>> 5
59
+ const bitOffset = index & 31
60
+ return (this.kc_diffs[wordIndex] >>> bitOffset) & 1
61
+ }
161
62
 
162
- function decodePath(path) {
163
- let str = ""
164
- let p = []
165
- let len = path.shift()
166
- while (path.length > 0) {
167
- const type = path.shift()
168
- let val = null
169
- if (type == 0) {
170
- const type2 = path.shift()
171
- if (type2 == 0) {
172
- val = [type2, path.shift()]
173
- } else {
174
- val = [type2]
175
- }
176
- } else {
177
- val = []
178
- for (let i = 0; i < type; i++) {
179
- val.push(path.shift())
180
- }
181
- }
182
- p.push([type, ...val])
63
+ add_vlinks(val, vlen) {
64
+ this.vlinks_len = this._add(this.vlinks, this.vlinks_len, val, vlen)
183
65
  }
184
- let i = 0
185
- for (let s of p) {
186
- if (s[0] == 0 && s[1] == 0) str += `[${s[2]}]`
187
- else if (s[0] == 0 && s[1] == 1) {
188
- if (str != "") str += "."
189
- } else {
190
- str += `${i == 0 ? "" : "."}${s
191
- .slice(1)
192
- .map(c => String.fromCharCode(Number(c)))
193
- .join("")}`
194
- }
195
- i++
66
+ add_klinks(val, vlen) {
67
+ this.klinks_len = this._add(this.klinks, this.klinks_len, val, vlen)
68
+ }
69
+ add_vflags(val, vlen) {
70
+ this.vflags_len = this._add(this.vflags, this.vflags_len, val, vlen)
71
+ }
72
+ add_kflags(val, vlen) {
73
+ this.kflags_len = this._add(this.kflags, this.kflags_len, val, vlen)
74
+ }
75
+ add_bools(val, vlen) {
76
+ this.bools_len = this._add(this.bools, this.bools_len, val, vlen)
77
+ }
78
+ add_keys(val, vlen) {
79
+ this.keys_len = this._add(this.keys, this.keys_len, val, vlen)
80
+ }
81
+ add_types(val, vlen) {
82
+ this.types_len = this._add(this.types, this.types_len, val, vlen)
83
+ }
84
+ add_nums(val, vlen) {
85
+ this.nums_len = this._add(this.nums, this.nums_len, val, vlen)
86
+ }
87
+ add_dc(val, vlen) {
88
+ this.dc_len = this._add(this.dc, this.dc_len, val, vlen)
89
+ }
90
+ add_kvals(val, vlen) {
91
+ this.kvals_len = this._add(this.kvals, this.kvals_len, val, vlen)
92
+ }
93
+ add_vals(val, vlen) {
94
+ this.vals_len = this._add(this.vals, this.vals_len, val, vlen)
196
95
  }
197
- return str
198
- }
199
96
 
200
- function flattenPath(path) {
201
- let p = [path.length]
202
- for (const v of path) p = p.concat(v)
203
- return p
204
- }
97
+ _add(tar, len, val, vlen) {
98
+ val &= vlen >= 32 ? 0xffffffff : (1 << vlen) - 1
99
+ const used = len & 31
100
+ const free = used === 0 ? 32 : 32 - used
101
+ const idx = len >> 5
102
+
103
+ if (vlen <= free) {
104
+ if (used === 0) tar[idx] = val
105
+ else tar[idx] = (tar[idx] << vlen) | val
106
+ len += vlen
107
+ return len
108
+ }
109
+
110
+ const high = val >>> (vlen - free)
111
+ if (used === 0) tar[idx] = high
112
+ else tar[idx] = (tar[idx] << free) | high
113
+ len += free
205
114
 
206
- function _encode(v, path = []) {
207
- let vals = []
208
- if (typeof v == "number") vals.push([path, encodeVal(v)])
209
- else if (typeof v == "boolean") vals.push([path, encodeVal(v)])
210
- else if (v == null) vals.push([path, encodeVal(v)])
211
- else if (typeof v == "string") vals.push([path, encodeVal(v)])
212
- else if (Array.isArray(v)) {
213
- let i = 0
214
- for (const v2 of v) {
215
- for (const v3 of _encode(v2, [...path, i])) vals.push(v3)
216
- i++
115
+ let rest = vlen - free
116
+ if (rest <= 32) {
117
+ tar[idx + 1] = val & ((1 << rest) - 1)
118
+ len += rest
119
+ return len
217
120
  }
218
- } else if (typeof v == "object") {
219
- for (const k in v) for (let v4 of _encode(v[k], [...path, k])) vals.push(v4)
220
- }
221
- return vals
222
- }
223
121
 
224
- const filterDic = keys => keys.filter(entry => entry.count > 1)
225
-
226
- function countKeys(keys) {
227
- let keys2 = []
228
- for (let v of keys) {
229
- let i = 0
230
- for (let v2 of v) {
231
- const _key = v.slice(0, i + 1)
232
- let exists = false
233
- for (let v3 of keys2) {
234
- if (equals(_key, v3.key)) {
235
- v3.count += 1
236
- exists = true
237
- }
238
- }
239
- if (!exists) keys2.push({ key: _key, count: 1 })
240
- i++
122
+ let writeIdx = idx + 1
123
+ while (rest > 32) {
124
+ tar[writeIdx++] = (val >>> (rest - 32)) & 0xffffffff
125
+ len += 32
126
+ rest -= 32
241
127
  }
242
- }
243
- return keys2
244
- }
245
128
 
246
- function sortKeys(keys) {
247
- return keys.sort((a, b) => {
248
- if (b.count !== a.count) return b.count - a.count
249
- for (let i = 0; i < Math.min(a.key.length, b.key.length); i++) {
250
- const aVal = a.key[i]
251
- const bVal = b.key[i]
252
- if (typeof aVal === "number" && typeof bVal === "string") return -1
253
- if (typeof aVal === "string" && typeof bVal === "number") return 1
254
- if (aVal < bVal) return -1
255
- if (aVal > bVal) return 1
129
+ if (rest > 0) {
130
+ tar[writeIdx] = val & ((1 << rest) - 1)
131
+ len += rest
256
132
  }
133
+ return len
134
+ }
257
135
 
258
- return a.key.length - b.key.length
259
- })
260
- }
136
+ push_vflag(flag) {
137
+ this.add_vflags(flag, 1)
138
+ }
261
139
 
262
- function buildDic(data) {
263
- // --- Step 1. (Optional) Save original input order if needed.
264
- data.forEach((entry, idx) => (entry._origIdx = idx))
265
-
266
- // --- Step 2. Sort the data in "dictionary order."
267
- // Primary: by key array length (shorter arrays come first).
268
- // Secondary: for keys of equal length, by the total character length (ascending)
269
- // so that, for example, ["jane"] (4 chars) comes before ["alice"] (5 chars).
270
- // Tertiary: if still equal, compare element-by-element using natural order.
271
- data.sort((a, b) => {
272
- const keyA = a.key
273
- const keyB = b.key
274
-
275
- // Primary: Compare array lengths.
276
- if (keyA.length !== keyB.length) return keyA.length - keyB.length
277
-
278
- // Secondary: Compare total character lengths (ascending).
279
- const totalA = keyA.reduce((acc, x) => acc + x.toString().length, 0)
280
- const totalB = keyB.reduce((acc, x) => acc + x.toString().length, 0)
281
- if (totalA !== totalB) return totalA - totalB
282
- // Tertiary: Compare element-by-element using natural order.
283
- for (let i = 0; i < keyA.length; i++) {
284
- const elA = keyA[i]
285
- const elB = keyB[i]
286
-
287
- if (typeof elA === typeof elB) {
288
- if (typeof elA === "number") {
289
- if (elA !== elB) return elA - elB
290
- } else if (typeof elA === "string") {
291
- const cmp = elA.localeCompare(elB, undefined, { numeric: true })
292
- if (cmp !== 0) return cmp
293
- } else {
294
- // Fallback: compare string representations.
295
- const cmp = elA
296
- .toString()
297
- .localeCompare(elB.toString(), undefined, { numeric: true })
298
- if (cmp !== 0) return cmp
299
- }
300
- } else {
301
- // If types differ, compare string representations.
302
- const cmp = elA
303
- .toString()
304
- .localeCompare(elB.toString(), undefined, { numeric: true })
305
- if (cmp !== 0) return cmp
306
- }
307
- }
140
+ push_bool(bool) {
141
+ this.add_bools(bool ? 1 : 0, 1)
142
+ }
143
+
144
+ push_kflag(flag) {
145
+ this.add_kflags(flag, 1)
146
+ }
308
147
 
309
- return 0
310
- })
148
+ get_diff(v, prev) {
149
+ let diff = prev === null ? v : v - prev
150
+ let isDiff = false
151
+ if (diff < 0) {
152
+ diff = Math.abs(diff) + 3
153
+ isDiff = diff < 7
154
+ } else isDiff = diff < 4
155
+ const v2 = isDiff ? diff : v
156
+ return (v2 << 1) | (isDiff ? 1 : 0)
157
+ }
311
158
 
312
- // --- Step 3. Build the dictionary.
313
- // Each dictionary entry will be stored as an object with:
314
- // - original: the original key (an array)
315
- // - compressed: the computed compressed representation.
316
- const dict = []
159
+ push_vlink(v) {
160
+ let result = this.get_diff(v, this.prev_link)
161
+ const isDiff = (result & 1) === 1
162
+ const v2 = result >>> 1
163
+ this.prev_link = v
164
+ this.push_vflag(isDiff ? 1 : 0)
165
+ this._push_vlink(v2, isDiff, this.dcount)
166
+ this.rcount++
167
+ }
317
168
 
318
- // Helper: For a given string, look for a previously defined simple key (an array of length 1).
319
- function getPointerIndex(str) {
320
- for (let i = 0; i < dict.length; i++) {
321
- if (dict[i].original.length === 1 && dict[i].original[0] === str) return i
169
+ push_klink(v) {
170
+ let result = this.get_diff(v, this.prev_klink)
171
+ const isDiff = (result & 1) === 1
172
+ const v2 = result >>> 1
173
+ this.prev_klink = v
174
+ this.push_kflag(isDiff ? 1 : 0)
175
+ this._push_klink(v2, isDiff, this.dcount)
176
+ }
177
+
178
+ set_newbits(count) {
179
+ const new_bits = this.fastBits(count + 1)
180
+ if (new_bits > this.prev_bits) {
181
+ const diff = new_bits - this.prev_bits
182
+ for (let i = 0; i < diff; i++) {
183
+ this.add_vlinks(0, this.prev_bits + i)
184
+ }
185
+ this.prev_bits = new_bits
322
186
  }
323
- return -1
187
+ return new_bits
324
188
  }
325
189
 
326
- // Helper: Element-by-element compression.
327
- // For each element in a composite key, if it is a string that already exists as a simple key,
328
- // replace one or more consecutive occurrences with a pointer.
329
- // A single occurrence becomes [dictIndex]; a group becomes [dictIndex, 0].
330
- function compressElementByElement(key) {
331
- const rep = []
332
- let i = 0
333
- while (i < key.length) {
334
- const el = key[i]
335
- if (typeof el === "string") {
336
- const ptrIndex = getPointerIndex(el)
337
- if (ptrIndex !== -1) {
338
- let j = i
339
- while (j < key.length && key[j] === el) {
340
- j++
341
- }
342
- const groupLen = j - i
343
- rep.push(groupLen === 1 ? [ptrIndex] : [ptrIndex, 0])
344
- i = j
345
- continue
346
- }
190
+ set_newbits_k(count) {
191
+ const new_bits = this.fastBits(count + 1)
192
+ if (new_bits > this.prev_kbits) {
193
+ const diff = new_bits - this.prev_kbits
194
+ for (let i = 0; i < diff; i++) {
195
+ this.add_klinks(0, this.prev_kbits + i)
347
196
  }
348
- rep.push(el)
349
- i++
197
+ this.prev_kbits = new_bits
350
198
  }
351
- return rep
199
+ return new_bits
352
200
  }
353
201
 
354
- // Helper: Compute a "cost" for a given representation.
355
- // Each literal (number or string) counts as 1; a pointer array counts as the number of numbers it holds.
356
- function computeCost(rep) {
357
- let cost = 0
358
- for (const token of rep) cost += Array.isArray(token) ? token.length : 1
359
- return cost
202
+ _flush_vlink(v, diff, count) {
203
+ if (diff) {
204
+ this.add_vlinks(v + 1, 3)
205
+ } else {
206
+ const nb = this.set_newbits(count)
207
+ this.add_vlinks(v + 1, nb)
208
+ }
360
209
  }
361
210
 
362
- // Helper: Full segmentation compression.
363
- // Try to segment the entire key as a concatenation of one or more previously defined dictionary entries.
364
- // Uses dynamic programming over the key array.
365
- // Returns an object { cost, seg } where seg is an array of dictionary indices.
366
- function segmentKey(key) {
367
- const n = key.length
368
- const dp = Array(n + 1).fill(null)
369
- dp[n] = { cost: 0, seg: [] }
370
-
371
- for (let i = n - 1; i >= 0; i--) {
372
- let best = null
373
- // Try every dictionary entry.
374
- for (let d = 0; d < dict.length; d++) {
375
- const candidate = dict[d].original
376
- const m = candidate.length
377
- if (i + m <= n) {
378
- let match = true
379
- for (let k = 0; k < m; k++) {
380
- if (key[i + k] !== candidate[k]) {
381
- match = false
382
- break
383
- }
384
- }
385
- if (match && dp[i + m] !== null) {
386
- const candidateCost = 1 + dp[i + m].cost // cost 1 for using this pointer.
387
- if (best === null || candidateCost < best.cost) {
388
- best = { cost: candidateCost, seg: [d].concat(dp[i + m].seg) }
389
- }
390
- }
391
- }
211
+ flush_vlink() {
212
+ if (this.vc_v === null) return
213
+ if (this.vc_count < 4) {
214
+ for (let i = 0; i < this.vc_count; i++)
215
+ this._flush_vlink(
216
+ this.vc_v,
217
+ this.vc_diffs_get(i) === 1,
218
+ this.vc_counts[i],
219
+ )
220
+ } else {
221
+ if (this.vc_diffs_get(0) === 1) {
222
+ this.add_vlinks(0, 3)
223
+ this.short_vlinks(this.vc_count)
224
+ this.add_vlinks(this.vc_v + 1, 3)
225
+ } else {
226
+ const nb = this.set_newbits(this.vc_counts[0])
227
+ this.add_vlinks(0, nb)
228
+ this.short_vlinks(this.vc_count)
229
+ this.add_vlinks(this.vc_v + 1, nb)
392
230
  }
393
- dp[i] = best
394
231
  }
395
- return dp[0]
396
232
  }
397
233
 
398
- // Process each entry (in the sorted, deterministic order).
399
- for (const entry of data) {
400
- const key = entry.key
401
- let compressed
402
- if (key.length === 1) {
403
- // For simple keys, copy as-is.
404
- compressed = key.slice()
234
+ _push_vlink(v, diff, count) {
235
+ if (this.vc_v === null) {
236
+ this.vc_v = v
237
+ this.vc_diffs_set(0, diff ? 1 : 0)
238
+ this.vc_counts[0] = count
239
+ this.vc_count = 1
240
+ } else if (v === this.vc_v) {
241
+ this.vc_diffs_set(this.vc_count, diff ? 1 : 0)
242
+ this.vc_counts[this.vc_count] = count
243
+ this.vc_count++
405
244
  } else {
406
- // Try element-by-element compression.
407
- const repA = compressElementByElement(key)
408
- let bestCost = computeCost(repA)
409
- let bestRep = repA
410
-
411
- // Also try full segmentation over the entire key.
412
- const segRes = segmentKey(key)
413
- if (segRes !== null) {
414
- const repB = [segRes.seg] // Represent segmentation as a pointer.
415
- const costB = segRes.cost
416
- if (costB < bestCost) {
417
- bestCost = costB
418
- bestRep = repB
419
- }
420
- }
245
+ this.flush_vlink()
246
+ this.vc_v = v
247
+ this.vc_diffs_set(0, diff ? 1 : 0)
248
+ this.vc_counts[0] = count
249
+ this.vc_count = 1
250
+ }
251
+ }
421
252
 
422
- // Now try partial segmentation: try segmenting a prefix and then appending the literal remainder.
423
- const n = key.length
424
- for (let i = 1; i < n; i++) {
425
- const prefixSeg = segmentKey(key.slice(0, i))
426
- if (prefixSeg !== null) {
427
- const literalPart = key.slice(i)
428
- const candidateCost = prefixSeg.cost + computeCost(literalPart)
429
- if (candidateCost < bestCost) {
430
- bestCost = candidateCost
431
- // Build candidate representation: pointer for the segmented prefix followed by literal remainder.
432
- bestRep = [prefixSeg.seg].concat(literalPart)
433
- }
434
- }
253
+ flush_klink() {
254
+ if (this.kc_v === null) return
255
+ if (this.kc_count < 4) {
256
+ for (let i = 0; i < this.kc_count; i++)
257
+ this._flush_klink(
258
+ this.kc_v,
259
+ this.kc_diffs_get(i) === 1,
260
+ this.kc_counts[i],
261
+ )
262
+ } else {
263
+ if (this.kc_diffs_get(0) === 1) {
264
+ this.add_klinks(0, 3)
265
+ this.short_klinks(this.kc_count)
266
+ this.add_klinks(this.kc_v + 1, 3)
267
+ } else {
268
+ const nb = this.set_newbits_k(this.kc_counts[0])
269
+ this.add_klinks(0, nb)
270
+ this.short_klinks(this.kc_count)
271
+ this.add_klinks(this.kc_v + 1, nb)
435
272
  }
436
-
437
- compressed = bestRep
438
273
  }
439
- dict.push({ original: key, compressed })
440
274
  }
441
275
 
442
- // --- Step 4. Return the dictionary and key map.
443
- // "dictionary" is an array of compressed keys.
444
- // "keyMap" is the array of original keys (in the same, deterministic order).
445
- return {
446
- dictionary: dict.map(entry => {
447
- return entry.compressed.length === 1 && !is(Array, entry.compressed[0])
448
- ? entry.compressed[0]
449
- : entry.compressed
450
- }),
451
- keyMap: dict.map(entry => entry.original),
276
+ _flush_klink(v, diff, count) {
277
+ if (diff) {
278
+ this.add_klinks(v + 1, 3)
279
+ } else {
280
+ const nb = this.set_newbits_k(count)
281
+ this.add_klinks(v + 1, nb)
282
+ }
452
283
  }
453
- }
454
- const genDic = compose(buildDic, filterDic, sortKeys, countKeys, listKeys)
455
-
456
- function listKeys(v, key = [], keys = []) {
457
- if (Array.isArray(v)) {
458
- let i = 0
459
- for (const v2 of v) {
460
- listKeys(v2, append(i, key), keys)
461
- i++
284
+
285
+ _push_klink(v, diff, count) {
286
+ if (this.kc_v === null) {
287
+ this.kc_v = v
288
+ this.kc_diffs_set(0, diff ? 1 : 0)
289
+ this.kc_counts[0] = count
290
+ this.kc_count = 1
291
+ } else if (v === this.kc_v) {
292
+ this.kc_diffs_set(this.kc_count, diff ? 1 : 0)
293
+ this.kc_counts[this.kc_count] = count
294
+ this.kc_count++
295
+ } else {
296
+ this.flush_klink()
297
+ this.kc_v = v
298
+ this.kc_diffs_set(0, diff ? 1 : 0)
299
+ this.kc_counts[0] = count
300
+ this.kc_count = 1
462
301
  }
463
- } else if (typeof v == "object") {
464
- for (const k in v) listKeys(v[k], append(k, key), keys)
465
- } else {
466
- keys.push(key)
467
302
  }
468
- return keys
469
- }
470
303
 
471
- function isPrefix(path, prefix) {
472
- if (prefix.length > path.length) return false
473
- for (let i = 0; i < prefix.length; i++) {
474
- if (!equals(path[i], prefix[i])) return false
304
+ push_type(v) {
305
+ let count = this.tcount
306
+ if (count > 3) {
307
+ this.add_types(0, 3)
308
+ this.short_types(count)
309
+ this.add_types(v, 3)
310
+ } else for (let i = 0; i < count; i++) this.add_types(v, 3)
311
+ this.tcount = 1
475
312
  }
476
- return true
477
- }
478
- function applyDicToPath(path, sortedDic) {
479
- // Base case: if the path is empty, nothing to replace.
480
- if (path.length === 0) return []
481
- // Iterate over the dictionary entries in descending order.
482
- for (const { entry, index } of sortedDic) {
483
- if (isPrefix(path, entry)) {
484
- // Found a match: remove the matched prefix.
485
- const remainder = path.slice(entry.length)
486
- // Recursively apply dictionary replacement on the remainder.
487
- const replacedRemainder = applyDicToPath(remainder, sortedDic)
488
- // If the remainder is completely replaced (i.e. replacedRemainder is a single dictionary reference array),
489
- // then merge the current dictionary index with that.
490
- if (replacedRemainder.length === 0) {
491
- // No remainder: simply return the dictionary reference.
492
- return [[index]]
493
- }
494
- if (Array.isArray(replacedRemainder[0])) {
495
- // The first component is already a dictionary reference: merge the indices.
496
- return [[index, ...replacedRemainder[0]]]
497
- } else {
498
- // Otherwise, return the dictionary reference for the prefix and then the literal remainder.
499
- return [[index]].concat(replacedRemainder)
500
- }
501
- }
313
+
314
+ push_keylen(v) {
315
+ this.short_keys(v)
502
316
  }
503
- // If no dictionary entry applies, return the original literal path.
504
- return path
505
- }
506
317
 
507
- function applyDic(arr, dic) {
508
- // Build sorted dictionary entries in descending order by length.
509
- const sortedDic = dic
510
- .map((entry, index) => ({ entry, index }))
511
- .sort((a, b) => b.entry.length - a.entry.length)
512
- // For each pair, apply dictionary replacement to the path.
513
- return arr.map(pair => {
514
- const newPath = applyDicToPath(pair[0], sortedDic)
515
- return [newPath, pair[1]]
516
- })
517
- }
318
+ push_int(v) {
319
+ let result = this.get_diff(v, this.prev_num)
320
+ const isDiff = (result & 1) === 1
321
+ const v2 = result >>> 1
518
322
 
519
- function encodePaths(data) {
520
- for (let v of data) {
521
- let path = []
522
- for (let v2 of v[0]) {
523
- if (is(Number, v2)) path.push([0, 0, v2])
524
- else if (is(String, v2)) {
525
- const key = v2.split("").map(c => c.charCodeAt(0))
526
- path.push([key.length, ...(key.length == 0 ? [1] : key)])
527
- } else if (is(Array, v2)) {
528
- if (v2.length === 1) path.push([0, 3, v2[0]])
529
- else path.push([0, 4, v2.length, ...v2])
530
- }
531
- }
532
- v[0] = path
323
+ this.prev_num = v
324
+ this.dint(v2, isDiff)
533
325
  }
534
- return data
535
- }
536
326
 
537
- function mapDic(dic, len) {
538
- let _map = []
539
- while (dic.length > 0) {
540
- let dlen = dic.shift()
541
- let _elms = []
542
- while (dlen > 0) {
543
- let type = dic.shift()
544
- let elms = []
545
- if (type == 7) {
546
- let slen = dic.shift()
547
- elms.push(slen)
548
- for (let i = 0; i < slen; i++) elms.push(dic.shift())
549
- _elms.push(elms)
550
- } else if (type == 3) {
551
- elms = concat(elms, [0, 0, dic.shift()])
552
- _elms.push(elms)
553
- } else if (type == 9) {
554
- for (let v2 of _map[dic.shift()]) _elms.push(v2)
327
+ push_float(neg, v) {
328
+ if (v < 4) this.push_int(neg ? 4 + v : v)
329
+ else this.push_int(neg ? 4 : 0)
330
+ }
331
+
332
+ flush_nums() {
333
+ if (this.nc_diff !== null) {
334
+ if (this.nc_count < 3) {
335
+ for (let i = 0; i < this.nc_count; i++)
336
+ this._dint(this.nc_v, this.nc_diff)
337
+ } else {
338
+ this.add_nums(0, 2)
339
+ this.add_nums(7, 3)
340
+ this.short_nums(this.nc_count)
341
+ if (this.nc_diff) {
342
+ this.add_nums(0, 2)
343
+ this.add_nums(this.nc_v, 3)
344
+ } else if (this.nc_v < 64) {
345
+ const d = this.nc_v < 16 ? 4 : 6
346
+ const flag = this.nc_v < 16 ? 1 : 2
347
+ this.add_nums(flag, 2)
348
+ this.add_nums(this.nc_v, d)
349
+ } else this.leb128_nums(this.nc_v)
555
350
  }
556
- dlen--
557
351
  }
558
- _map.push(_elms)
559
- if (_map.length === len) break
560
352
  }
561
- return _map
562
- }
563
353
 
564
- function encodeDic(dict) {
565
- let enc = []
566
- for (let v of dict) {
567
- let len = 1
568
- let elms = []
569
- if (!is(String, v)) {
570
- len = 0
571
- for (let v2 of v) {
572
- if (is(Array, v2)) {
573
- len += v2.length
574
- for (let v3 of v2) elms = concat(elms, [9, v3])
575
- } else {
576
- len += 1
577
- if (is(String, v2)) {
578
- elms.push(7)
579
- elms.push(v2.length)
580
- elms = concat(
581
- elms,
582
- v2.split("").map(c => c.charCodeAt(0)),
583
- )
584
- } else {
585
- elms = concat(elms, [3, v2])
586
- }
587
- }
588
- }
354
+ dint(v, diff = false) {
355
+ if (this.nc_diff === null) {
356
+ this.nc_diff = diff
357
+ this.nc_v = v
358
+ this.nc_count = 1
359
+ } else if (this.nc_diff === diff && this.nc_v === v) {
360
+ this.nc_count += 1
589
361
  } else {
590
- elms.push(7)
591
- elms.push(v.length)
592
- elms = concat(
593
- elms,
594
- v.split("").map(c => c.charCodeAt(0)),
595
- )
362
+ if (this.nc_count === 1) this._dint(this.nc_v, this.nc_diff)
363
+ else this.flush_nums()
364
+ this.nc_diff = diff
365
+ this.nc_v = v
366
+ this.nc_count = 1
596
367
  }
597
- enc = concat(enc, [len, ...elms])
598
368
  }
599
- return enc
600
- }
601
369
 
602
- function encode(json, nodic = false) {
603
- let dic = null
604
- let dictionary, keyMap
605
- if (nodic !== true) {
606
- ;({ dictionary, keyMap } = genDic(json))
607
- if (dictionary.length > 0) dic = encodeDic(dictionary)
370
+ _dint(v, diff) {
371
+ if (diff) {
372
+ this.add_nums(0, 2)
373
+ this.add_nums(v, 3)
374
+ } else if (v < 64) {
375
+ const d = v < 16 ? 4 : 6
376
+ const flag = v < 16 ? 1 : 2
377
+ this.add_nums(flag, 2)
378
+ this.add_nums(v, d)
379
+ } else this.leb128_nums(v)
608
380
  }
609
- let enc = _encode(json)
610
- if (dic) enc = applyDic(enc, keyMap)
611
-
612
- enc = encodePaths(enc)
613
- enc.sort((a, b) => {
614
- const isUndefined = v => typeof v == "undefined"
615
- const max = Math.max(a[0].length, b[0].length)
616
- if (max > 0) {
617
- for (let i = 0; i < max; i++) {
618
- const exA = !isUndefined(a[0][i])
619
- const exB = !isUndefined(b[0][i])
620
- if (exA && !exB) return 1
621
- if (!exA && exB) return -1
622
- const max2 = Math.max(a[0][i].length, b[0][i].length)
623
- if (max2 > 0) {
624
- for (let i2 = 0; i2 < max2; i2++) {
625
- const vA = a[0][i][i2]
626
- const vB = b[0][i][i2]
627
- const exA = !isUndefined(vA)
628
- const exB = !isUndefined(vB)
629
- if (exA && !exB) return 1
630
- if (!exA && exB) return -1
631
- if (vA > vB) return 1
632
- if (vA < vB) return -1
633
- }
634
- }
635
- }
381
+
382
+ leb128_2_kvals(v) {
383
+ while (v >= 128) {
384
+ this.add_kvals((v & 0x7f) | 0x80, 8)
385
+ v >>>= 7
636
386
  }
637
- return 0
638
- })
639
- const _dic = dic ? [1, 0, 2, dictionary.length, ...dic] : []
640
- return concat(
641
- _dic,
642
- enc.reduce((arr, v) => arr.concat([...flattenPath(v[0]), ...v[1]]), []),
643
- )
644
- }
387
+ this.add_kvals(v, 8)
388
+ }
645
389
 
646
- function _decode(arr) {
647
- let vals = []
648
- let dic = []
649
- while (arr.length > 0) {
650
- let plen = arr.shift()
651
- let keys = []
652
- let val = null
653
- let skip = false
654
- while (plen > 0) {
655
- const plen2 = arr.shift()
656
- if (plen2 == 0) {
657
- const plen3 = arr.shift()
658
- if (plen3 == 1) {
659
- keys.push([plen2, plen3])
660
- } else if (plen3 == 0) {
661
- keys.push([plen2, plen3, arr.shift()])
662
- } else if (plen3 == 2) {
663
- const dict = arr.shift()
664
- dic = mapDic(arr, dict)
665
- skip = true
666
- } else if (plen3 == 3) {
667
- const _keys = dic[arr.shift()]
668
- for (const k of _keys) keys.push(k)
669
- } else if (plen3 == 4) {
670
- let key = []
671
- let plen4 = arr.shift()
672
- for (let i2 = 0; i2 < plen4; i2++) {
673
- const _keys = dic[arr.shift()]
674
- for (const k of _keys) keys.push(k)
675
- }
676
- }
677
- } else if (plen2 != 0) {
678
- const plen3 = plen2
679
- let key = []
680
- for (let i2 = 0; i2 < plen3; i2++) key.push(arr.shift())
681
- keys.push([plen2, ...key])
682
- }
683
- plen--
390
+ leb128_dc(v) {
391
+ this.add_dc(3, 2)
392
+ while (v >= 128) {
393
+ this.add_dc((v & 0x7f) | 0x80, 8)
394
+ v >>>= 7
684
395
  }
685
- if (skip) continue
686
- const type = arr.shift()
687
- val = [type]
688
- if (type == 5 || type == 6) {
689
- val.push(arr.shift())
690
- val.push(arr.shift())
691
- } else if (type == 3 || type == 4) {
692
- val.push(arr.shift())
693
- } else if (type == 7) {
694
- const strlen = arr.shift()
695
- val.push(strlen)
696
- for (let i2 = 0; i2 < strlen; i2++) val.push(arr.shift())
396
+ this.add_dc(v, 8)
397
+ }
398
+
399
+ leb128_keys(v) {
400
+ this.add_keys(3, 2)
401
+ while (v >= 128) {
402
+ this.add_keys((v & 0x7f) | 0x80, 8)
403
+ v >>>= 7
697
404
  }
698
- vals.push([keys, val])
405
+ this.add_keys(v, 8)
699
406
  }
700
- return vals
701
- }
702
407
 
703
- // 0: null, 1: true, 2: false, 3: positive integer, 4: negative integer, 5: positive float, 6: negative float, 7: string, 8: object, 9: ref
704
-
705
- function encodeVal(v) {
706
- let vals = []
707
- if (typeof v == "number" || typeof v == "bigint") {
708
- const int = Number.isInteger(v)
709
- let moved = 0
710
- let num = v
711
- while (num % 1 != 0) {
712
- num *= 10
713
- moved += 1
408
+ leb128_klinks(v) {
409
+ this.add_klinks(3, 2)
410
+ while (v >= 128) {
411
+ this.add_klinks((v & 0x7f) | 0x80, 8)
412
+ v >>>= 7
714
413
  }
715
- let type = 3
716
- if (v >= 0) {
717
- if (moved > 0) type = 5
718
- } else {
719
- if (moved > 0) type = 6
720
- else type = 4
414
+ this.add_klinks(v, 8)
415
+ }
416
+
417
+ leb128_vals(v) {
418
+ this.add_vals(3, 2)
419
+ while (v >= 128) {
420
+ this.add_vals((v & 0x7f) | 0x80, 8)
421
+ v >>>= 7
721
422
  }
722
- vals.push(type)
723
- if (moved > 0) vals.push(moved)
724
- if (v < 0) vals.push(-num)
725
- else vals.push(num)
726
- } else if (typeof v == "boolean") vals.push(v ? 1 : 2)
727
- else if (v == null) vals = [0]
728
- else if (typeof v == "string") {
729
- vals = [7, v.length, ...v.split("").map(c => c.charCodeAt(0))]
730
- } else vals = [8, ...encode(v)]
731
- return vals
732
- }
423
+ this.add_vals(v, 8)
424
+ }
733
425
 
734
- function decodeVal(arr) {
735
- const type = arr[0]
736
- const _val = arr[1]
737
- let val = null
738
- if (type == 0) {
739
- val = null
740
- } else if (type == 1) {
741
- val = true
742
- } else if (type == 2) {
743
- val = false
744
- } else if (type == 3) {
745
- val = arr[1]
746
- } else if (type == 4) {
747
- val = arr[1] * -1
748
- } else if (type == 5) {
749
- val = arr[2]
750
- for (let i = 0; i < arr[1]; i++) {
751
- val /= 10
426
+ leb128_kvals(v) {
427
+ this.add_kvals(3, 2)
428
+ while (v >= 128) {
429
+ this.add_kvals((v & 0x7f) | 0x80, 8)
430
+ v >>>= 7
752
431
  }
753
- } else if (type == 6) {
754
- val = arr[2] * -1
755
- for (let i = 0; i < arr[1]; i++) {
756
- val /= 10
432
+ this.add_kvals(v, 8)
433
+ }
434
+
435
+ leb128_nums(v) {
436
+ this.add_nums(3, 2)
437
+ while (v >= 128) {
438
+ this.add_nums((v & 0x7f) | 0x80, 8)
439
+ v >>>= 7
757
440
  }
758
- } else if (type == 7) {
759
- val = arr
760
- .slice(2)
761
- .map(c => String.fromCharCode(Number(c)))
762
- .join("")
763
- } else if (type == 8) {
764
- val = decode(arr.slice(1))
441
+ this.add_nums(v, 8)
765
442
  }
766
- return val
767
- }
768
443
 
769
- function decode(arr) {
770
- const decoded = _decode(arr)
771
- let json =
772
- decoded[0]?.[0]?.[0]?.[0] == 0 && decoded[0]?.[0]?.[0]?.[1] == 0 ? [] : {}
773
- for (const v of decoded) {
774
- const keys = v[0].map(v2 => {
775
- if (v2[0] == 0) {
776
- if (v2[1] == 1) return ""
777
- return v2[2]
778
- } else {
779
- return v2
780
- .slice(1)
781
- .map(c => String.fromCharCode(Number(c)))
782
- .join("")
783
- }
784
- })
785
- if (keys.length == 0) {
786
- json = decodeVal(v[1])
787
- } else {
788
- let obj = json
789
- let i = 0
790
- for (const k of keys) {
791
- if (typeof k == "number") {
792
- if (typeof keys[i + 1] == "undefined") {
793
- obj[k] = decodeVal(v[1])
794
- } else {
795
- if (typeof obj[k] == "undefined") {
796
- if (typeof keys[i + 1] == "string") {
797
- obj[k] = {}
798
- } else {
799
- obj[k] = []
800
- }
801
- }
444
+ leb128_types(v) {
445
+ this.add_types(3, 2)
446
+ while (v >= 128) {
447
+ this.add_types((v & 0x7f) | 0x80, 8)
448
+ v >>>= 7
449
+ }
450
+ this.add_types(v, 8)
451
+ }
452
+
453
+ leb128_vlinks(v) {
454
+ this.add_vlinks(3, 2)
455
+ while (v >= 128) {
456
+ this.add_vlinks((v & 0x7f) | 0x80, 8)
457
+ v >>>= 7
458
+ }
459
+ this.add_vlinks(v, 8)
460
+ }
461
+
462
+ uint_dc(v) {
463
+ if (v < 64) {
464
+ const d = v < 8 ? 3 : v < 16 ? 4 : 6
465
+ const flag = v < 8 ? 0 : v < 16 ? 1 : 2
466
+ this.add_dc(flag, 2)
467
+ this.add_dc(v, d)
468
+ } else this.leb128_dc(v)
469
+ }
470
+
471
+ short_types(v) {
472
+ if (v < 16) {
473
+ const d = v < 4 ? 2 : this.fastBits(v)
474
+ this.add_types(d - 2, 2)
475
+ this.add_types(v, d)
476
+ } else this.leb128_types(v)
477
+ }
478
+
479
+ short_dc(v) {
480
+ if (v < 16) {
481
+ const d = v < 4 ? 2 : this.fastBits(v)
482
+ this.add_dc(d - 2, 2)
483
+ this.add_dc(v, d)
484
+ } else this.leb128_dc(v)
485
+ }
486
+
487
+ short_vals(v) {
488
+ if (v < 16) {
489
+ const d = v < 4 ? 2 : this.fastBits(v)
490
+ this.add_vals(d - 2, 2)
491
+ this.add_vals(v, d)
492
+ } else this.leb128_vals(v)
493
+ }
494
+
495
+ short_kvals(v) {
496
+ if (v < 16) {
497
+ const d = v < 4 ? 2 : this.fastBits(v)
498
+ this.add_kvals(d - 2, 2)
499
+ this.add_kvals(v, d)
500
+ } else this.leb128_kvals(v)
501
+ }
502
+
503
+ short_keys(v) {
504
+ if (v < 16) {
505
+ const d = v < 4 ? 2 : this.fastBits(v)
506
+ this.add_keys(d - 2, 2)
507
+ this.add_keys(v, d)
508
+ } else this.leb128_keys(v)
509
+ }
510
+
511
+ short_klinks(v) {
512
+ if (v < 16) {
513
+ const d = v < 4 ? 2 : this.fastBits(v)
514
+ this.add_klinks(d - 2, 2)
515
+ this.add_klinks(v, d)
516
+ } else this.leb128_klinks(v)
517
+ }
518
+
519
+ short_vlinks(v) {
520
+ if (v < 16) {
521
+ const d = v < 4 ? 2 : this.fastBits(v)
522
+ this.add_vlinks(d - 2, 2)
523
+ this.add_vlinks(v, d)
524
+ } else this.leb128_vlinks(v)
525
+ }
526
+
527
+ reset() {
528
+ this.strMap.clear()
529
+ this.str_len = 0
530
+ this.prev_bits = 1
531
+ this.prev_kbits = 1
532
+ this.prev_num = 0
533
+ this.nums_count = 0
534
+ this.prev_link = null
535
+ this.prev_klink = null
536
+ this.single = true
537
+ this.len = 0
538
+ this.dlen = 0
539
+ this.jlen = 0
540
+ this.dcount = 0
541
+ this.rcount = 0
542
+ this.tcount = 0
543
+ this.oid = 0
544
+ this.iid = 0
545
+
546
+ this.vc_v = null
547
+
548
+ this.vc_count = null
549
+
550
+ this.kc_v = null
551
+
552
+ this.kc_count = null
553
+
554
+ this.nc_diff = null
555
+ this.nc_v = null
556
+ this.nc_count = null
557
+
558
+ this.vlinks_len = 0
559
+ this.klinks_len = 0
560
+ this.vflags_len = 0
561
+ this.kflags_len = 0
562
+ this.bools_len = 0
563
+ this.keys_len = 0
564
+ this.types_len = 0
565
+ this.nums_len = 0
566
+ this.dc_len = 0
567
+ this.kvals_len = 0
568
+ this.vals_len = 0
569
+ }
570
+
571
+ dump() {
572
+ if (!this.single) {
573
+ this.flush_vlink()
574
+ this.flush_klink()
575
+ this.flush_nums()
576
+ this.add_dc(this.single ? 1 : 0, 1)
577
+ this.short_dc(this.rcount)
578
+ }
579
+
580
+ const totalBits =
581
+ this.dc_len +
582
+ this.vflags_len +
583
+ this.vlinks_len +
584
+ this.kflags_len +
585
+ this.klinks_len +
586
+ this.keys_len +
587
+ this.types_len +
588
+ this.nums_len +
589
+ this.bools_len +
590
+ this.kvals_len +
591
+ this.vals_len
592
+
593
+ const padBits = (8 - (totalBits % 8)) % 8
594
+ const finalBits = totalBits + padBits
595
+ const outLength = finalBits / 8
596
+ const out = new Uint8Array(outLength)
597
+
598
+ let outIndex = 0
599
+ let accumulator = 0
600
+ let accBits = 0
601
+
602
+ const writeBits = (num, numBits) => {
603
+ while (numBits > 0) {
604
+ const free = 8 - accBits
605
+ if (numBits <= free) {
606
+ accumulator = (accumulator << numBits) | (num & ((1 << numBits) - 1))
607
+ accBits += numBits
608
+ numBits = 0
609
+ if (accBits === 8) {
610
+ out[outIndex++] = accumulator
611
+ accumulator = 0
612
+ accBits = 0
802
613
  }
803
614
  } else {
804
- if (typeof obj[k] == "undefined") {
805
- if (typeof keys[i + 1] == "undefined") {
806
- obj[k] = decodeVal(v[1])
807
- } else if (typeof keys[i + 1] == "string") {
808
- obj[k] = {}
809
- } else {
810
- obj[k] = []
811
- }
812
- }
615
+ const shift = numBits - free
616
+ const part = num >>> shift
617
+ accumulator = (accumulator << free) | (part & ((1 << free) - 1))
618
+ out[outIndex++] = accumulator
619
+ num = num & ((1 << shift) - 1)
620
+ numBits -= free
621
+ accumulator = 0
622
+ accBits = 0
813
623
  }
814
- obj = obj[k]
815
- i++
816
624
  }
817
625
  }
818
- }
819
- return json
820
- }
821
626
 
822
- const toIndex = str => {
823
- return (
824
- "1" +
825
- str
826
- .split("")
827
- .map(s => base64Map[s])
828
- .join("")
829
- )
830
- }
831
-
832
- const fromIndex = id => {
833
- let _id = id.toString().split("")
834
- _id.shift()
835
- return splitEvery(2, _id)
836
- .map(s => {
837
- return strMap[s.join("")]
838
- })
839
- .join("")
840
- }
841
-
842
- function toSignal(arr, uint_len = 75) {
843
- const _arr = flatten(
844
- arr.map(n => {
845
- let str = splitEvery(8, n.toString().split(""))
627
+ const writeBuffer = (buffer, bitLen) => {
628
+ let remaining = bitLen
846
629
  let i = 0
847
- str = str.map(s => {
848
- const len = i == str.length - 1 ? s.length : 9
630
+ while (remaining > 0 && i < buffer.length) {
631
+ const bitsThis = Math.min(32, remaining)
632
+ writeBits(buffer[i] >>> 0, bitsThis)
633
+ remaining -= bitsThis
849
634
  i++
850
- return len.toString() + s.join("")
851
- })
852
- return str
853
- }),
854
- )
855
- let _arr2 = []
856
- let one = 0
857
- let i = 0
858
- let start = null
859
- if (!uint_len) uint_len = _arr * 100
860
- for (let v of _arr) {
861
- _arr2.push(v)
862
- if (v.length - 1 == 1) {
863
- if (start == null) start = i
864
- one += v.length - 1
865
- if (one == 9) {
866
- _arr2[start] = `0${one}${_arr2[start][1]}`
867
- for (let i2 = start + 1; i2 <= i; i2++) _arr2[i2] = `${_arr2[i2][1]}`
868
- one = 0
869
- start = null
870
635
  }
871
- } else {
872
- if (one > 2) {
873
- _arr2[start] = `0${one}${_arr2[start][1]}`
874
- for (let i2 = start + 1; i2 < i; i2++) _arr2[i2] = `${_arr2[i2][1]}`
875
- }
876
- one = 0
877
- start = null
878
636
  }
879
- i++
880
- }
881
- if (one > 2) {
882
- _arr2[start] = `0${one}${_arr2[start][1]}`
883
- for (let i2 = start + 1; i2 <= i - 1; i2++) _arr2[i2] = `${_arr2[i2][1]}`
637
+
638
+ writeBuffer(this.dc, this.dc_len)
639
+ writeBuffer(this.vflags, this.vflags_len)
640
+ writeBuffer(this.vlinks, this.vlinks_len)
641
+ writeBuffer(this.kflags, this.kflags_len)
642
+ writeBuffer(this.klinks, this.klinks_len)
643
+ writeBuffer(this.keys, this.keys_len)
644
+ writeBuffer(this.types, this.types_len)
645
+ writeBuffer(this.bools, this.bools_len)
646
+ writeBuffer(this.nums, this.nums_len)
647
+ writeBuffer(this.kvals, this.kvals_len)
648
+ writeBuffer(this.vals, this.vals_len)
649
+
650
+ if (padBits > 0) writeBits(0, padBits)
651
+
652
+ return out
884
653
  }
885
- let _arr3 = []
886
- let chain = null
887
- let cur = 0
888
- let num = ""
889
- for (let v of _arr2) {
890
- if (chain == null && +v[0] == 0) {
891
- chain = +v[1]
892
- cur = 1
893
- num = v
894
- } else if (chain != null) {
895
- num += v
896
- cur++
897
- if (chain == cur) {
898
- _arr3.push(num)
899
- chain = null
900
- num = ""
901
- cur = 0
654
+ }
655
+
656
+ function pushPathStr(u, v2, prev = null) {
657
+ if (u.dcount > 0) u.push_klink(prev === null ? 0 : prev + 1)
658
+ if (u.strMap.has(v2)) {
659
+ u.add_keys(2, 2)
660
+ u.push_keylen(0)
661
+ u.short_kvals(u.strMap.get(v2))
662
+ } else {
663
+ u.strMap.set(v2, u.str_len++)
664
+ const len = v2.length
665
+ let ktype = 3
666
+ let codes = []
667
+ let codes2 = []
668
+ if (len !== 0) {
669
+ let is64 = true
670
+ for (let i = 0; i < len; i++) {
671
+ codes2.push(v2.charCodeAt(i))
672
+ const c = base64[v2[i]]
673
+ if (typeof c === "undefined") is64 = false
674
+ else codes.push(c)
902
675
  }
903
- } else {
904
- _arr3.push(v)
676
+ if (is64) ktype = 2
905
677
  }
678
+ u.add_keys(ktype, 2)
679
+ u.push_keylen(len + 2)
680
+ if (ktype === 3) for (let v of codes2) u.leb128_2_kvals(v)
681
+ else for (let v of codes) u.add_kvals(v, 6)
906
682
  }
907
- if (chain != null) _arr3.push(num)
908
- let arrs2 = []
909
- let len2 = 0
910
- let str2 = ""
911
- for (let v of _arr3) {
912
- if (len2 + v.length > uint_len) {
913
- arrs2.push("1" + str2)
914
- if (+v[0] == 0) {
915
- let len3 = uint_len - len2
916
- if (len3 == 2 || len3 == 3) {
917
- arrs2[arrs2.length - 1] += `1${v[2]}`
918
- let new_len = +v[1] - 1
919
- if (new_len == 2) {
920
- v = `1${v[3]}1${v[4]}`
921
- } else {
922
- v = `0${new_len}${v.slice(3)}`
683
+ u.dcount++
684
+ }
685
+
686
+ function pushPathNum(u, prev = null, keylen) {
687
+ if (u.dcount > 0) u.push_klink(prev === null ? 0 : prev + 1)
688
+ u.add_keys(keylen, 2)
689
+ const id = keylen === 0 ? u.iid++ : u.oid++
690
+ u.dcount++
691
+ }
692
+
693
+ function encode_x(v, u) {
694
+ u.reset()
695
+ if (v === null) {
696
+ u.add_dc(1, 1)
697
+ u.add_dc(0, 7)
698
+ } else if (typeof v !== "object") {
699
+ u.add_dc(1, 1)
700
+ if (v === true) u.add_dc(1, 7)
701
+ else if (v === false) u.add_dc(2, 7)
702
+ else if (v === "") u.add_dc(3, 7)
703
+ else if (typeof v === "number") {
704
+ const moved = v % 1 === v ? 0 : getPrecision(v)
705
+ const type = moved === 0 ? (v < 0 ? 5 : 4) : v < 0 ? 7 : 6
706
+ if (type === 4) {
707
+ u.add_dc(1, 1)
708
+ if (v < 63) u.add_dc(v, 6)
709
+ else {
710
+ u.add_dc(63, 6)
711
+ u.leb128_2_dc(v - 63)
712
+ }
713
+ } else {
714
+ u.add_dc(0, 1)
715
+ u.add_dc(type + 1, 6)
716
+ if (moved > 0) u.uint_dc(moved)
717
+ u.uint_dc((v < 0 ? -1 : 1) * v * Math.pow(10, moved))
718
+ }
719
+ } else if (typeof v === "string") {
720
+ u.add_dc(0, 1)
721
+
722
+ if (v.length === 1) {
723
+ const charCode = v.charCodeAt(0)
724
+ const mapValue = strmap[v]
725
+
726
+ if (typeof mapValue !== "undefined") {
727
+ u.add_dc(mapValue + 9, 6)
728
+ } else {
729
+ u.add_dc(61, 6)
730
+ u.leb128_2_dc(charCode)
731
+ }
732
+ } else {
733
+ let is64 = true
734
+ for (let i = 0; i < v.length; i++) {
735
+ if (typeof base64[v[i]] === "undefined") {
736
+ is64 = false
737
+ break
923
738
  }
924
- } else if (len3 > 3) {
925
- let new_len = +v[1] - 2
926
- let old_len = 2
927
- if (len3 == 4) {
928
- arrs2[arrs2.length - 1] += `1${v[2]}1${v[3]}`
929
- } else {
930
- old_len = len3 - 2
931
- new_len = +v[1] - old_len
932
- arrs2[arrs2.length - 1] += `0${old_len}${v.slice(2, 2 + old_len)}`
739
+ }
740
+
741
+ if (is64) {
742
+ u.add_dc(62, 6)
743
+ u.short_dc(v.length)
744
+ for (let i = 0; i < v.length; i++) {
745
+ u.add_dc(base64[v[i]], 6)
933
746
  }
934
- if (new_len == 1) {
935
- v = `1${v[old_len + 2]}`
936
- } else if (new_len == 2) {
937
- v = `1${v[old_len + 2]}1${v[old_len + 3]}`
938
- } else {
939
- v = `0${new_len}${v.slice(old_len + 2)}`
747
+ } else {
748
+ u.add_dc(63, 6)
749
+ u.short_dc(v.length)
750
+ for (let i = 0; i < v.length; i++) {
751
+ u.leb128_2_dc(v.charCodeAt(i))
940
752
  }
941
753
  }
942
754
  }
943
- len2 = 0
944
- str2 = ""
945
755
  }
946
- len2 += v.length
947
- str2 += v
756
+ } else if (Array.isArray(v) && v.length === 0) {
757
+ u.add_dc(1, 1)
758
+ u.add_dc(4, 7)
759
+ } else if (Object.keys(v).length === 0) {
760
+ u.add_dc(1, 1)
761
+ u.add_dc(5, 7)
762
+ } else {
763
+ u.single = false
764
+ u.push_type(_encode_x(v, u))
948
765
  }
949
- if (str2 != "") arrs2.push("1" + str2)
950
- return arrs2
951
- }
952
-
953
- function fromSignal(arr) {
954
- let _arr = []
955
- let prev = ""
956
- for (let s of arr) {
957
- s = s.slice(1)
958
- let str = s.split("")
959
- while (str.length > 0) {
960
- const len = +str.shift()
961
- if (len == 0) {
962
- const len2 = +str.shift()
963
- for (let i2 = 0; i2 < len2; i2++) {
964
- _arr.push(+str[i2])
965
- }
966
- str = str.slice(len2)
967
- } else if (len == 9) {
968
- prev += str.slice(0, 8).join("")
969
- str = str.slice(8)
766
+ return u.dump()
767
+ }
768
+
769
+ function getPrecision(v) {
770
+ const s = v.toString()
771
+ const dot = s.indexOf(".")
772
+ if (dot === -1) return 0
773
+ const frac = s.slice(dot + 1).replace(/0+$/, "")
774
+ return frac.length
775
+ }
776
+
777
+ function _encode_x(
778
+ v,
779
+ u,
780
+ plen = 0,
781
+ prev = null,
782
+ prev_type = null,
783
+ index = null,
784
+ ) {
785
+ if (typeof v === "number") {
786
+ if (prev !== null) u.push_vlink(prev + 1)
787
+
788
+ const moved = v % 1 === v ? 0 : getPrecision(v)
789
+ const type = moved === 0 ? (v < 0 ? 5 : 4) : 6
790
+
791
+ if (prev_type !== null && prev_type !== 4) u.push_type(prev_type)
792
+ else u.tcount++
793
+ if (moved > 0) {
794
+ u.push_float(v < 0, moved + 1)
795
+ if (moved > 2) u.push_int(moved + 1)
796
+ }
797
+ u.push_int((v < 0 ? -1 : 1) * v * Math.pow(10, moved))
798
+ return type
799
+ } else if (typeof v === "boolean") {
800
+ if (prev !== null) u.push_vlink(prev + 1)
801
+ const type = 3
802
+ if (prev_type !== null && prev_type !== type) u.push_type(prev_type)
803
+ else u.tcount++
804
+ u.push_bool(v)
805
+ return type
806
+ } else if (v === null) {
807
+ if (prev !== null) u.push_vlink(prev + 1)
808
+ if (prev_type !== null && prev_type !== 1) u.push_type(prev_type)
809
+ else u.tcount++
810
+ return 1
811
+ } else if (typeof v === "string") {
812
+ let ktype = 7
813
+ if (prev !== null) u.push_vlink(prev + 1)
814
+ if (u.strMap.has(v)) {
815
+ ktype = 2
816
+ u.push_type(prev_type)
817
+ u.short_vals(0)
818
+ u.short_vals(u.strMap.get(v))
819
+ } else {
820
+ u.strMap.set(v, u.str_len++)
821
+ const len = v.length
822
+ u.short_vals(len)
823
+ let codes = []
824
+ let codes2 = []
825
+ let is64 = true
826
+ if (len === 0) {
827
+ is64 = false
970
828
  } else {
971
- const nums = str.slice(0, len).join("")
972
- str = str.slice(len)
973
- _arr.push(+(prev + nums))
974
- prev = ""
829
+ for (let i = 0; i < len; i++) {
830
+ codes2.push(v.charCodeAt(i))
831
+ const c = base64[v[i]]
832
+ if (typeof c === "undefined") is64 = false
833
+ else codes.push(c)
834
+ }
835
+ if (is64) ktype = 2
975
836
  }
976
- }
977
- }
978
- return _arr
979
- }
980
-
981
- const path = p => toSignal(encodePath(p))
982
- const val = v => toSignal(encodeVal(v))
983
- const query = v => toSignal(encodeQuery(v))
837
+ if (prev_type !== null && prev_type !== ktype) u.push_type(prev_type)
838
+ else u.tcount++
984
839
 
985
- function encodeQuery(v) {
986
- if (!Array.isArray(v)) throw Error("query must be an array")
987
- const op = v[0]
988
- if (isNil(ops[op])) throw Error(`query not supported: ${op}`)
989
- return [ops[op], ...encodeVal(v[1])]
990
- }
991
-
992
- function decodeQuery(v) {
993
- const op = opMap[v[0]]
994
- if (isNil(op)) throw Error("op doens't exist")
995
- return [op, decodeVal(v.slice(1))]
996
- }
997
-
998
- function toUint8(sig) {
999
- let num = BigInt(sig)
1000
- let byteArray = []
1001
- while (num > 0) {
1002
- byteArray.push(Number(num % 256n))
1003
- num /= 256n
840
+ if (is64) for (let v of codes) u.add_vals(v, 6)
841
+ else for (let v of codes2) u.leb128_2_vals(v)
842
+ }
843
+ return ktype
844
+ } else if (Array.isArray(v)) {
845
+ if (v.length === 0) {
846
+ if (prev !== null) u.push_vlink(prev + 1)
847
+ u.push_type(prev_type)
848
+ u.push_float(false, 1)
849
+ return 6
850
+ } else {
851
+ const _prev = u.dcount
852
+ pushPathNum(u, prev, 0)
853
+ let i = 0
854
+ for (const v2 of v) {
855
+ prev_type = _encode_x(v2, u, plen + 1, _prev, prev_type, i)
856
+ i++
857
+ }
858
+ }
859
+ return prev_type
860
+ } else if (typeof v === "object") {
861
+ if (Object.keys(v).length === 0) {
862
+ if (prev !== null) u.push_vlink(prev + 1)
863
+ u.push_type(prev_type)
864
+ u.push_float(true, 1)
865
+ return 6
866
+ } else {
867
+ pushPathNum(u, prev, 1)
868
+ const __prev = u.dcount
869
+ for (const k in v) {
870
+ const _prev = u.dcount
871
+ pushPathStr(u, k, __prev - 1)
872
+ prev_type = _encode_x(v[k], u, plen + 1, _prev, prev_type)
873
+ }
874
+ return prev_type
875
+ }
1004
876
  }
1005
- return new Uint8Array(byteArray.reverse())
1006
- }
1007
- function compress(arr) {
1008
- let sig = toSignal(arr, false)
1009
- return toUint8(sig)
1010
- }
1011
-
1012
- function decompress(arr) {
1013
- const str = fromUint8(arr)
1014
- return fromSignal([str])
1015
877
  }
1016
878
 
1017
- function fromUint8(arr) {
1018
- let num = 0n
1019
- for (let byte of arr) {
1020
- num = num * 256n + BigInt(byte)
1021
- }
1022
- return num.toString()
879
+ function decode_x(v, d) {
880
+ d.decode(v)
881
+ return d.json
1023
882
  }
1024
883
 
1025
- module.exports = {
1026
- encode,
1027
- decode,
1028
- encodePath,
1029
- decodePath,
1030
- encodeVal,
1031
- decodeVal,
1032
- pad,
1033
- _encode,
1034
- flattenPath,
1035
- toSignal,
1036
- fromSignal,
1037
- toIndex,
1038
- fromIndex,
1039
- path,
1040
- val,
1041
- query,
1042
- encodeQuery,
1043
- decodeQuery,
1044
- compress,
1045
- decompress,
1046
- toUint8,
1047
- fromUint8,
1048
- }
884
+ module.exports = { encode_x, decode_x, u8 }