@graffy/common 0.15.25 → 0.16.0-alpha.2

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/index.mjs CHANGED
@@ -1,12 +1,6 @@
1
1
  import mergeIterators from "merge-async-iterators";
2
2
  import { makeStream } from "@graffy/stream";
3
3
  import isEqual from "lodash/isEqual.js";
4
- function encode$7(query) {
5
- return encodeURIComponent(JSON.stringify(query));
6
- }
7
- function decode$7(fields) {
8
- return JSON.parse(decodeURIComponent(fields));
9
- }
10
4
  const textEncoder = new TextEncoder();
11
5
  const textDecoder = new TextDecoder("utf-8");
12
6
  function encode$6(string) {
@@ -28,7 +22,9 @@ function encode$5(number) {
28
22
  return new Uint8Array(buffer);
29
23
  }
30
24
  function decode$5(u8Arr) {
31
- const { buffer, byteOffset, byteLength } = u8Arr;
25
+ const copy = new Uint8Array(8);
26
+ copy.set(u8Arr, 0);
27
+ const { buffer, byteOffset, byteLength } = copy;
32
28
  const view = new DataView(buffer, byteOffset, byteLength);
33
29
  const high = view.getUint8(0);
34
30
  if (high & 128) {
@@ -39,41 +35,92 @@ function decode$5(u8Arr) {
39
35
  }
40
36
  return view.getFloat64(0);
41
37
  }
42
- const alpha = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
43
- function getByte(view, offset) {
44
- return offset < view.byteLength ? view.getUint8(offset) : 0;
38
+ const MIN_KEY = new Uint8Array();
39
+ const MAX_KEY = new Uint8Array([255]);
40
+ function isMinKey(key) {
41
+ return key.length === 0;
45
42
  }
46
- function getChar(string, offset) {
47
- return offset < string.length ? alpha.indexOf(string[offset]) : 0;
43
+ function isMaxKey(key) {
44
+ return key.length === 1 && key[0] === 255;
48
45
  }
49
- function encode$4(u8Arr) {
50
- const { buffer, byteOffset, byteLength } = u8Arr;
51
- const view = new DataView(buffer, byteOffset, byteLength);
52
- let str = "";
53
- for (let i = 0; i < view.byteLength; i += 3) {
54
- let value = (getByte(view, i) << 16) + (getByte(view, i + 1) << 8) + getByte(view, i + 2);
55
- let gstr = "";
56
- for (let j = 0; j < 4; j++) {
57
- gstr = alpha[value & 63] + gstr;
58
- value = value >> 6 | 0;
59
- }
60
- str += gstr;
46
+ function err(message, { cause = null, ...args } = {}) {
47
+ const e = new Error(message + (args ? " " + JSON.stringify(args) : ""));
48
+ e.cause = cause;
49
+ throw e;
50
+ }
51
+ function errIf(message, condition, args) {
52
+ if (condition)
53
+ err(message, args);
54
+ }
55
+ function isEmpty(object) {
56
+ for (const _ in object)
57
+ return false;
58
+ return true;
59
+ }
60
+ function isDef(value) {
61
+ return typeof value !== "undefined";
62
+ }
63
+ function isPlainObject(arg) {
64
+ return typeof arg === "object" && arg && !Array.isArray(arg) && !ArrayBuffer.isView(arg);
65
+ }
66
+ function cmp(a, b) {
67
+ const l = a.length < b.length ? a.length : b.length;
68
+ for (let i = 0; i < l; i++) {
69
+ if (a[i] < b[i])
70
+ return -1;
71
+ if (a[i] > b[i])
72
+ return 1;
61
73
  }
62
- return str.substr(0, Math.ceil(view.byteLength * 4 / 3));
74
+ if (a.length < b.length)
75
+ return -1;
76
+ if (a.length > b.length)
77
+ return 1;
78
+ return 0;
63
79
  }
64
- function decode$4(string, start = 0) {
65
- const buffer = new ArrayBuffer(Math.floor((string.length - start) * 3 / 4));
66
- const view = new DataView(buffer);
67
- for (let i = start; i < string.length; i += 4) {
68
- let value = (getChar(string, i) << 18) + (getChar(string, i + 1) << 12) + (getChar(string, i + 2) << 6) + getChar(string, i + 3);
69
- for (let j = i * 3 / 4 + 2; j >= i * 3 / 4; j--) {
70
- if (j < view.byteLength)
71
- view.setUint8(j, value & 255);
72
- value = value >> 8 | 0;
80
+ function find(items, compare2, first = 0, last = items.length) {
81
+ let currentFirst = first;
82
+ let currentLast = last;
83
+ while (currentFirst < currentLast) {
84
+ const ix = (currentFirst + currentLast) / 2 | 0;
85
+ const d = compare2(items[ix]);
86
+ if (d < 0) {
87
+ currentFirst = ix + 1;
88
+ } else if (d > 0) {
89
+ currentLast = ix;
90
+ } else {
91
+ return ix;
73
92
  }
74
93
  }
75
- return new Uint8Array(buffer);
94
+ return currentFirst;
76
95
  }
96
+ const stringifyDescriptor = {
97
+ value: function() {
98
+ var _a;
99
+ if ((this == null ? void 0 : this.length) === 0)
100
+ return "\xB7";
101
+ let str = "";
102
+ let bull = false;
103
+ (_a = this == null ? void 0 : this.forEach) == null ? void 0 : _a.call(this, (value, i) => {
104
+ if (value >= 32 && value <= 126) {
105
+ str += String.fromCharCode(value);
106
+ bull = true;
107
+ } else {
108
+ str += (bull ? "\xB7" : "") + ("0" + value.toString(16)).slice(-2) + (i < this.length - 1 ? "\xB7" : "");
109
+ bull = false;
110
+ }
111
+ });
112
+ return str;
113
+ }
114
+ };
115
+ function addStringify(buffer) {
116
+ Object.defineProperties(buffer, {
117
+ toString: stringifyDescriptor,
118
+ [Symbol.for("nodejs.util.inspect.custom")]: stringifyDescriptor
119
+ });
120
+ return buffer;
121
+ }
122
+ addStringify(MIN_KEY);
123
+ addStringify(MAX_KEY);
77
124
  const END = 0;
78
125
  const NULL = 1;
79
126
  const FALSE = 2;
@@ -82,12 +129,9 @@ const NUM = 4;
82
129
  const STR = 5;
83
130
  const ARR = 6;
84
131
  const OBJ = 7;
132
+ const EOK = 127;
85
133
  function encodeArray(array) {
86
- return [
87
- ARR,
88
- ...array.flatMap((value) => encodeParts(value)),
89
- END
90
- ];
134
+ return [ARR, ...array.flatMap((value) => encodeParts(value)), END];
91
135
  }
92
136
  function encodeObject(object) {
93
137
  const keys = Object.keys(object).sort();
@@ -119,10 +163,21 @@ function encodeParts(value) {
119
163
  return encodeObject(value);
120
164
  return [NULL];
121
165
  }
122
- function encode$3(value) {
166
+ function encode$4(value) {
123
167
  const parts = encodeParts(value);
124
168
  while (parts[parts.length - 1] === END)
125
169
  parts.pop();
170
+ const lastPart = parts[parts.length - 1];
171
+ if (typeof lastPart !== "number") {
172
+ let end = lastPart.length - 1;
173
+ while (end >= 0 && !lastPart[end])
174
+ end--;
175
+ if (lastPart[end] !== 255) {
176
+ parts[parts.length - 1] = lastPart.slice(0, end + 1);
177
+ } else {
178
+ parts.push(EOK);
179
+ }
180
+ }
126
181
  const length = parts.reduce(
127
182
  (sum, part) => sum + (typeof part === "number" ? 1 : part.length),
128
183
  0
@@ -138,12 +193,12 @@ function encode$3(value) {
138
193
  i += part.length;
139
194
  }
140
195
  }
141
- return encode$4(buffer);
196
+ addStringify(buffer);
197
+ return buffer;
142
198
  }
143
199
  const nextKey = /* @__PURE__ */ new WeakMap();
144
- function decode$3(key) {
200
+ function decode$4(buffer) {
145
201
  let i = 0;
146
- const buffer = decode$4(key, 0);
147
202
  const stack = [[]];
148
203
  function readString() {
149
204
  let start = i;
@@ -177,6 +232,8 @@ function decode$3(key) {
177
232
  const type = buffer[i];
178
233
  const start = ++i;
179
234
  switch (type) {
235
+ case EOK:
236
+ return stack[0][0];
180
237
  case END:
181
238
  popToken();
182
239
  break;
@@ -209,87 +266,67 @@ function decode$3(key) {
209
266
  return stack[0][0];
210
267
  }
211
268
  function keyStep(key) {
212
- if (key === "")
269
+ if (isMinKey(key))
213
270
  return { key, step: 1 };
214
- if (key === "\uFFFF")
271
+ if (isMaxKey(key))
215
272
  return { key, step: -1 };
216
273
  const l = key.length - 1;
217
- switch (key.charCodeAt(l)) {
274
+ let newKey;
275
+ let step;
276
+ switch (key[l]) {
218
277
  case 0:
219
- return { key: key.substr(0, l), step: 1 };
220
- case 65535:
221
- return {
222
- key: key.substr(0, l - 1) + String.fromCharCode(key.charCodeAt(l - 1) + 1),
223
- step: -1
224
- };
278
+ newKey = key.slice(0, l);
279
+ step = 1;
280
+ break;
281
+ case 255:
282
+ newKey = key.slice(0, l);
283
+ newKey[l - 1]++;
284
+ step = -1;
285
+ break;
225
286
  default:
226
- return { key, step: 0 };
287
+ newKey = key;
288
+ step = 0;
227
289
  }
290
+ return { key: addStringify(newKey), step };
228
291
  }
229
292
  function keyBefore(key) {
230
- if (key === "" || key === "\uFFFF" || key === "\0" || key === "\0\uFFFF") {
293
+ if (isMinKey(key) || isMaxKey(key))
231
294
  return key;
232
- }
233
295
  const l = key.length - 1;
234
- return key.charCodeAt(l) === 0 ? key.substr(0, l) : key.substr(0, l) + String.fromCharCode(key.charCodeAt(l) - 1) + "\uFFFF";
296
+ let newKey;
297
+ if (key[l] === 0) {
298
+ newKey = key.slice(0, l);
299
+ } else {
300
+ newKey = new Uint8Array(l + 2);
301
+ newKey.set(key, 0);
302
+ newKey[l]--;
303
+ newKey[l + 1] = 255;
304
+ }
305
+ addStringify(newKey);
306
+ return newKey;
235
307
  }
236
308
  function keyAfter(key) {
237
- if (key === "\uFFFF" || key === "\0" || key === "\0\uFFFF") {
309
+ if (isMaxKey(key))
238
310
  return key;
239
- }
240
311
  const l = key.length - 1;
241
- return key.charCodeAt(l) === 65535 ? key.substr(0, l - 1) + String.fromCharCode(key.charCodeAt(l - 1) + 1) : key + "\0";
242
- }
243
- function err(message, { cause, ...args } = {}) {
244
- const e = new Error(message + (args ? " " + JSON.stringify(args) : ""));
245
- e.cause = cause;
246
- throw e;
247
- }
248
- function errIf(message, condition, args) {
249
- if (condition)
250
- err(message, args);
251
- }
252
- function isEmpty(object) {
253
- for (const _ in object)
254
- return false;
255
- return true;
256
- }
257
- function isDef(value) {
258
- return typeof value !== "undefined";
259
- }
260
- function isPlainObject(arg) {
261
- return typeof arg === "object" && arg && !Array.isArray(arg);
262
- }
263
- function isEncodedKey(str) {
264
- return str[0] === "\0";
265
- }
266
- function find(items, compare2, first = 0, last = items.length) {
267
- let currentFirst = first;
268
- let currentLast = last;
269
- while (currentFirst < currentLast) {
270
- const ix = (currentFirst + currentLast) / 2 | 0;
271
- const d = compare2(items[ix]);
272
- if (d < 0) {
273
- currentFirst = ix + 1;
274
- } else if (d > 0) {
275
- currentLast = ix;
276
- } else {
277
- return ix;
278
- }
279
- }
280
- return currentFirst;
281
- }
282
- function maybeEncode(value) {
283
- return typeof value === "string" ? value : "\0" + encode$3(value);
284
- }
285
- function maybeDecode(string) {
286
- if (isEncodedKey(string)) {
287
- const { key, step } = keyStep(string.slice(1));
288
- const value = key === "" || key === "\uFFFF" ? key : decode$3(key);
289
- return { key: value, step };
312
+ let newKey;
313
+ if (key[l] === 255) {
314
+ newKey = key.slice(0, l);
315
+ newKey[l - 1]++;
290
316
  } else {
291
- return keyStep(string);
317
+ newKey = new Uint8Array(l + 2);
318
+ newKey.set(key, 0);
319
+ newKey[l + 1] = 0;
292
320
  }
321
+ addStringify(newKey);
322
+ return newKey;
323
+ }
324
+ function decodeBound(bound) {
325
+ const { key, step } = keyStep(bound);
326
+ if (isMinKey(key) || isMaxKey(key))
327
+ return { step };
328
+ const value = decode$4(key);
329
+ return { key: value, step };
293
330
  }
294
331
  const pageProps = {
295
332
  $all: 1,
@@ -311,13 +348,13 @@ function splitArgs(arg) {
311
348
  isEmpty(filter) ? void 0 : filter
312
349
  ];
313
350
  }
314
- function encode$2(arg) {
351
+ function encode$3(arg) {
315
352
  if (!isPlainObject(arg))
316
- return { key: maybeEncode(arg) };
353
+ return { key: encode$4(arg) };
317
354
  const [page, filter] = splitArgs(arg);
318
355
  errIf("page_and_filter", page && filter, arg);
319
356
  if (!page)
320
- return { key: maybeEncode(filter || {}) };
357
+ return { key: encode$4(filter || {}) };
321
358
  const { $cursor, ...range } = page;
322
359
  const { $first, $all, $last, $after, $before, $since, $until } = range;
323
360
  const hasRange = !isEmpty(range);
@@ -327,17 +364,17 @@ function encode$2(arg) {
327
364
  errIf("after_and_since", isDef($after) && isDef($since), arg);
328
365
  errIf("before_and_until", isDef($before) && isDef($until), arg);
329
366
  errIf("cursor_and_range_arg", isDef($cursor) && hasRange, arg);
330
- let [key, end] = hasRange ? ["", "\uFFFF"] : [];
367
+ let [key, end] = hasRange ? [MIN_KEY, MAX_KEY] : [];
331
368
  if (isDef($cursor))
332
- key = maybeEncode($cursor);
369
+ key = encode$4($cursor);
333
370
  if (isDef($after))
334
- key = keyAfter(maybeEncode($after));
371
+ key = keyAfter(encode$4($after));
335
372
  if (isDef($before))
336
- end = keyBefore(maybeEncode($before));
373
+ end = keyBefore(encode$4($before));
337
374
  if (isDef($since))
338
- key = maybeEncode($since);
375
+ key = encode$4($since);
339
376
  if (isDef($until))
340
- end = maybeEncode($until);
377
+ end = encode$4($until);
341
378
  if (isDef($last))
342
379
  [key, end] = [end, key];
343
380
  const node = { key };
@@ -347,35 +384,34 @@ function encode$2(arg) {
347
384
  node.limit = $first || $last;
348
385
  return node;
349
386
  }
350
- function decode$2(node) {
387
+ function decode$3(node) {
351
388
  if (typeof node === "string")
352
- return node;
389
+ throw Error("why?");
353
390
  const { key, end, limit } = node;
354
- if (!isEncodedKey(key) && (!isDef(end) || end === key))
355
- return key;
356
391
  errIf("no_key", !isDef(key));
357
392
  errIf("limit_without_end", isDef(limit) && !isDef(end));
358
- const kParts = maybeDecode(key);
359
- if (!isDef(end))
393
+ const kParts = decodeBound(key);
394
+ if (!isDef(end) || cmp(key, end) === 0)
360
395
  return kParts.key;
361
- const eParts = maybeDecode(end);
362
- const [lower, upper] = key < end ? [kParts, eParts] : [eParts, kParts];
396
+ const eParts = decodeBound(end);
397
+ const reverse = cmp(key, end) > 0;
398
+ const [lower, upper] = reverse ? [eParts, kParts] : [kParts, eParts];
363
399
  const args = {};
364
400
  if (limit) {
365
- args[key < end ? "$first" : "$last"] = limit;
366
- } else if (lower.key === "" && upper.key === "\uFFFF") {
401
+ args[reverse ? "$last" : "$first"] = limit;
402
+ } else if (isMinKey(key) && isMaxKey(end) || isMinKey(end) && isMaxKey(key)) {
367
403
  args.$all = true;
368
404
  }
369
- if (lower.key !== "") {
405
+ if (lower.key && !isMinKey(lower.key)) {
370
406
  args[lower.step === 1 ? "$after" : "$since"] = lower.key;
371
407
  }
372
- if (upper.key !== "\uFFFF") {
408
+ if (upper.key && !isMaxKey(upper.key)) {
373
409
  args[upper.step === -1 ? "$before" : "$until"] = upper.key;
374
410
  }
375
411
  return args;
376
412
  }
377
413
  const PATH_SEPARATOR = ".";
378
- function encode$1(path) {
414
+ function encode$2(path) {
379
415
  if (typeof path === "string") {
380
416
  if (!path.length || path === PATH_SEPARATOR)
381
417
  return [];
@@ -385,25 +421,25 @@ function encode$1(path) {
385
421
  throw Error("encodePath.invalid:" + JSON.stringify(path));
386
422
  }
387
423
  function encodeSegment(seg) {
388
- if (typeof seg === "string")
424
+ if (ArrayBuffer.isView(seg))
389
425
  return seg;
390
- const { key, end } = encode$2(seg);
391
- if (end)
392
- throw "encodePath.unexpected_range_key";
393
- return key;
426
+ const node = encode$3(seg);
427
+ if (node.end)
428
+ return node;
429
+ return node.key;
394
430
  }
395
- if (!isPlainObject(path[path.length - 1]))
396
- return path.map(encodeSegment);
397
- const [page, filter = {}] = splitArgs(path[path.length - 1]);
398
- if (!page)
399
- return path.map(encodeSegment);
400
- return path.slice(0, -1).concat([filter]).map(encodeSegment);
431
+ if (isPlainObject(path[path.length - 1])) {
432
+ const [page, filter] = splitArgs(path[path.length - 1]);
433
+ if (page)
434
+ path = path.slice(0, -1).concat([filter || MIN_KEY]);
435
+ }
436
+ return path.map(encodeSegment);
401
437
  }
402
- function decode$1(path) {
438
+ function decode$2(path) {
403
439
  if (!Array.isArray(path)) {
404
440
  throw Error("decodePath.invalid:" + JSON.stringify(path));
405
441
  }
406
- return path.map((key) => decode$2({ key }));
442
+ return path.map((key) => decode$3({ key }));
407
443
  }
408
444
  function splitRef($ref) {
409
445
  if (!Array.isArray($ref))
@@ -423,16 +459,17 @@ let customAlphabet = (alphabet, defaultSize = 21) => {
423
459
  return id2;
424
460
  };
425
461
  };
462
+ const alpha = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
426
463
  const id = customAlphabet(alpha, 20);
427
464
  function findFirst(children, target, first, last) {
428
465
  return find(
429
466
  children,
430
467
  ({ key, end }) => {
431
- if (key === target || end && key < target && end >= target)
468
+ const keyCmp = cmp(key, target);
469
+ const endCmp = end && cmp(end, target);
470
+ if (end && keyCmp < 0 && endCmp >= 0)
432
471
  return 0;
433
- if (key < target)
434
- return -1;
435
- return 1;
472
+ return keyCmp;
436
473
  },
437
474
  first,
438
475
  last
@@ -440,7 +477,7 @@ function findFirst(children, target, first, last) {
440
477
  }
441
478
  function findLast(children, end, first, last) {
442
479
  const ix = findFirst(children, end, first, last);
443
- return children[ix] && children[ix].key <= end ? ix + 1 : ix;
480
+ return children[ix] && cmp(children[ix].key, end) <= 0 ? ix + 1 : ix;
444
481
  }
445
482
  function isRange(node) {
446
483
  return node && typeof node.end !== "undefined";
@@ -454,9 +491,6 @@ function isPrefix(node) {
454
491
  function isLink(node) {
455
492
  return node && typeof node.path !== "undefined";
456
493
  }
457
- function isEncoded(node) {
458
- return node && node.key[0] === "\0";
459
- }
460
494
  function isOlder(node, version) {
461
495
  return typeof node.version !== "undefined" && node.version < version;
462
496
  }
@@ -467,12 +501,12 @@ function add(base, diff) {
467
501
  let changed = false;
468
502
  let index = 0;
469
503
  for (const node of diff) {
470
- const cmp = compare(node);
504
+ const cmp2 = compare(node);
471
505
  const nodeIsBranch = isBranch(node);
472
- index = find(base, cmp, index);
506
+ index = find(base, cmp2, index);
473
507
  const item = base[index];
474
508
  const itemIsBranch = isBranch(item);
475
- if (!item || cmp(item)) {
509
+ if (!item || cmp2(item)) {
476
510
  base.splice(index, 0, clone(node));
477
511
  changed = true;
478
512
  continue;
@@ -497,7 +531,7 @@ function add(base, diff) {
497
531
  }
498
532
  function compare(node) {
499
533
  return (item) => {
500
- const v = compareValue(item.key, node.key) || compareValue(item.end, node.end) || compareValue(item.limit, node.limit);
534
+ const v = cmp(item.key, node.key) || compareValue(!!item.end, !!node.end) || item.end && cmp(item.end, node.end) || compareValue(item.limit, node.limit);
501
535
  return v;
502
536
  };
503
537
  }
@@ -541,9 +575,9 @@ function mergeRanges$1(base, node) {
541
575
  if (node.version < base.version)
542
576
  [node, base] = [base, node];
543
577
  return [
544
- base.key < node.key && { ...base, end: keyBefore(node.key) },
578
+ cmp(base.key, node.key) < 0 && { ...base, end: keyBefore(node.key) },
545
579
  node,
546
- base.end > node.end && { ...base, key: keyAfter(node.end) }
580
+ cmp(base.end, node.end) > 0 && { ...base, key: keyAfter(node.end) }
547
581
  ].filter(Boolean);
548
582
  }
549
583
  function insertNode$1(current, change, start = 0) {
@@ -552,7 +586,7 @@ function insertNode$1(current, change, start = 0) {
552
586
  const key = change.key;
553
587
  const index = findFirst(current, key, start);
554
588
  const node = current[index];
555
- if (node && node.key <= key) {
589
+ if (node && cmp(node.key, key) <= 0) {
556
590
  return isRange(node) ? insertNodeIntoRange$1(current, index, change) : updateNode$1(current, index, change);
557
591
  } else {
558
592
  current.splice(index, 0, change);
@@ -566,9 +600,9 @@ function insertNodeIntoRange$1(current, index, change) {
566
600
  if (!newChange)
567
601
  return;
568
602
  const insertions = [
569
- range.key < key && { ...range, end: keyBefore(key) },
603
+ cmp(range.key, key) < 0 && { ...range, end: keyBefore(key) },
570
604
  newChange,
571
- range.end > key && { ...range, key: keyAfter(key) }
605
+ cmp(range.end, key) > 0 && { ...range, key: keyAfter(key) }
572
606
  ].filter(Boolean);
573
607
  current.splice(index, 1, ...insertions);
574
608
  return index + insertions.length - 1;
@@ -592,7 +626,7 @@ function updateNode$1(current, index, change) {
592
626
  function getNewer(node, base) {
593
627
  const { version } = base;
594
628
  if (isBranch(node)) {
595
- const children = [{ key: "", end: "\uFFFF", version }];
629
+ const children = [{ key: MIN_KEY, end: MAX_KEY, version }];
596
630
  merge(children, node.children);
597
631
  return children.length === 1 ? null : { ...node, children };
598
632
  } else {
@@ -600,8 +634,13 @@ function getNewer(node, base) {
600
634
  }
601
635
  }
602
636
  const IS_VAL = Symbol("IS_VAL");
637
+ function makeNode(seg, props2) {
638
+ if (ArrayBuffer.isView(seg))
639
+ return { key: seg, ...props2 };
640
+ return { ...seg, ...props2 };
641
+ }
603
642
  function wrapValue(value, path, version = 0) {
604
- const node = { ...encode$2(path[path.length - 1]), value, version };
643
+ const node = makeNode(path[path.length - 1], { value, version });
605
644
  return wrap([node], path.slice(0, -1), version);
606
645
  }
607
646
  function wrap(children, path, version = 0, prefix = false) {
@@ -611,16 +650,16 @@ function wrap(children, path, version = 0, prefix = false) {
611
650
  return children;
612
651
  let i = path.length - 1;
613
652
  if (!Array.isArray(children)) {
614
- children = [{ ...encode$2(path[i--]), value: children, version }];
653
+ children = [makeNode(path[i--], { value: children, version })];
615
654
  } else {
616
655
  if (!children.length)
617
656
  return;
618
- children = [{ ...encode$2(path[i--]), version, children }];
657
+ children = [makeNode(path[i--], { children, version })];
619
658
  }
620
659
  if (prefix)
621
660
  children[0].prefix = true;
622
661
  while (i >= 0)
623
- children = [{ ...encode$2(path[i--]), version, children }];
662
+ children = [makeNode(path[i--], { children, version })];
624
663
  return children;
625
664
  }
626
665
  function unwrap(tree, path) {
@@ -629,12 +668,14 @@ function unwrap(tree, path) {
629
668
  let children = tree;
630
669
  let node = { children };
631
670
  for (let i = 0; i < path.length; i++) {
632
- const { key } = encode$2(path[i]);
671
+ const key = path[i];
672
+ if (!ArrayBuffer.isView(key))
673
+ throw Error("unwrap.ranges_unsupported");
633
674
  children = node.children;
634
675
  if (!children)
635
676
  return null;
636
677
  node = children[findFirst(children, key)];
637
- if (!node || node.key > key)
678
+ if (!node || cmp(node.key, key) > 0)
638
679
  return void 0;
639
680
  if (isRange(node))
640
681
  return null;
@@ -661,7 +702,7 @@ function remove(children, path) {
661
702
  const key = path[0];
662
703
  const ix = findFirst(children, key);
663
704
  const node = children[ix];
664
- if (!node || node.key > key || isRange(node))
705
+ if (!node || cmp(node.key, key) > 0 || isRange(node))
665
706
  return children;
666
707
  if (path.length === 1) {
667
708
  return children.slice(0, ix).concat(children.slice(ix + 1));
@@ -716,12 +757,12 @@ function slice(graph, query, root) {
716
757
  function sliceNode(graph, query, result) {
717
758
  const { key, version } = query;
718
759
  const { root } = result;
719
- if (!graph || graph.key > key || isOlder(graph, version)) {
760
+ if (!graph || cmp(graph.key, key) > 0 || isOlder(graph, version)) {
720
761
  result.addUnknown(query);
721
762
  } else if (isRange(graph)) {
722
763
  if (isBranch(query)) {
723
764
  const { known } = slice(
724
- [{ key: "", end: "\uFFFF", version: graph.version }],
765
+ [{ key: MIN_KEY, end: MAX_KEY, version: graph.version }],
725
766
  query.children
726
767
  );
727
768
  result.addKnown({ key, version: graph.version, children: known });
@@ -752,7 +793,7 @@ function sliceNode(graph, query, result) {
752
793
  result.addKnown(graph);
753
794
  } else if (isBranch(query)) {
754
795
  const { known } = slice(
755
- [{ key: "", end: "\uFFFF", version: graph.version }],
796
+ [{ key: MIN_KEY, end: MAX_KEY, version: graph.version }],
756
797
  query.children
757
798
  );
758
799
  result.addKnown({ key, version: graph.version, children: known });
@@ -762,8 +803,8 @@ function sliceNode(graph, query, result) {
762
803
  }
763
804
  function sliceRange(graph, query, result) {
764
805
  let { key, end, limit = Infinity, version } = query;
765
- const step = key < end ? 1 : -1;
766
- if (graph[0].key === "" && graph[0].prefix && graph[0].children) {
806
+ const step = cmp(key, end) < 0 ? 1 : -1;
807
+ if (isMinKey(graph[0].key) && graph[0].prefix && graph[0].children) {
767
808
  const { known, unknown } = slice(graph[0].children, [query], result.root);
768
809
  if (known)
769
810
  result.addKnown({ ...graph[0], children: known });
@@ -771,10 +812,10 @@ function sliceRange(graph, query, result) {
771
812
  result.addUnknown({ ...query[0], children: unknown });
772
813
  return;
773
814
  }
774
- if (key < end) {
775
- for (let i = findFirst(graph, key); key <= end && limit > 0; i++) {
815
+ if (cmp(key, end) < 0) {
816
+ for (let i = findFirst(graph, key); cmp(key, end) <= 0 && limit > 0; i++) {
776
817
  const node = graph[i];
777
- if (!node || key < node.key || isOlder(node, version))
818
+ if (!node || cmp(key, node.key) < 0 || isOlder(node, version))
778
819
  break;
779
820
  if (isRange(node)) {
780
821
  result.addKnown(getOverlap(node, key, end));
@@ -785,9 +826,9 @@ function sliceRange(graph, query, result) {
785
826
  key = keyAfter(node.end || node.key);
786
827
  }
787
828
  } else {
788
- for (let i = findLast(graph, key) - 1; key >= end && limit > 0; i--) {
829
+ for (let i = findLast(graph, key) - 1; cmp(key, end) >= 0 && limit > 0; i--) {
789
830
  const node = graph[i];
790
- if (!node || key > (node.end || node.key) || isOlder(node, version))
831
+ if (!node || cmp(key, node.end || node.key) > 0 || isOlder(node, version))
791
832
  break;
792
833
  if (isRange(node)) {
793
834
  result.addKnown(getOverlap(node, end, key));
@@ -798,18 +839,18 @@ function sliceRange(graph, query, result) {
798
839
  key = keyBefore(node.key);
799
840
  }
800
841
  }
801
- if (limit && (step < 0 ? key > end : key < end)) {
842
+ if (limit && (step < 0 ? cmp(key, end) > 0 : cmp(key, end) < 0)) {
802
843
  const unknown = { ...query, key, end, limit };
803
844
  result.addUnknown(unknown);
804
845
  }
805
846
  }
806
847
  function getOverlap(node, key, end) {
807
- if (node.key >= key && node.end <= end)
848
+ if (cmp(node.key, key) >= 0 && cmp(node.end, end) <= 0)
808
849
  return node;
809
850
  return {
810
851
  ...node,
811
- key: node.key > key ? node.key : key,
812
- end: node.end < end ? node.end : end
852
+ key: cmp(node.key, key) > 0 ? node.key : key,
853
+ end: cmp(node.end, end) < 0 ? node.end : end
813
854
  };
814
855
  }
815
856
  function sieve(current, changes, result = []) {
@@ -823,7 +864,7 @@ function insertRange(current, change, result, start = 0) {
823
864
  const { key, end } = change;
824
865
  const keyIx = findFirst(current, key, start);
825
866
  const endIx = findLast(current, end, keyIx);
826
- if (keyIx === endIx && !(current[keyIx] && current[keyIx].key <= key && current[keyIx].end >= end)) {
867
+ if (keyIx === endIx && !(current[keyIx] && cmp(current[keyIx].key, key) <= 0 && cmp(current[keyIx].end, end) >= 0)) {
827
868
  return keyIx;
828
869
  }
829
870
  const appliedChange = [];
@@ -831,7 +872,7 @@ function insertRange(current, change, result, start = 0) {
831
872
  for (let i = keyIx; i < endIx; i++) {
832
873
  const node = current[i];
833
874
  if (isRange(node) && node.version >= 0) {
834
- if (node.key > currentKey) {
875
+ if (cmp(node.key, currentKey) > 0) {
835
876
  appliedChange.push({
836
877
  key: currentKey,
837
878
  end: keyBefore(node.key),
@@ -849,11 +890,11 @@ function insertRange(current, change, result, start = 0) {
849
890
  currentKey = keyAfter(node.key);
850
891
  }
851
892
  }
852
- if (currentKey >= change.end) {
893
+ if (cmp(currentKey, change.end) >= 0) {
853
894
  break;
854
895
  }
855
896
  }
856
- if (currentKey <= change.end) {
897
+ if (cmp(currentKey, change.end) <= 0) {
857
898
  appliedChange.push({
858
899
  key: currentKey,
859
900
  end: change.end,
@@ -878,16 +919,16 @@ function mergeRanges(base, node) {
878
919
  if (node.version < base.version)
879
920
  [node, base] = [base, node];
880
921
  return [
881
- base.key < node.key && { ...base, end: keyBefore(node.key) },
922
+ cmp(base.key, node.key) < 0 && { ...base, end: keyBefore(node.key) },
882
923
  node,
883
- base.end > node.end && { ...base, key: keyAfter(node.end) }
924
+ cmp(base.end, node.end) > 0 && { ...base, key: keyAfter(node.end) }
884
925
  ].filter(Boolean);
885
926
  }
886
927
  function insertNode(current, change, result, start = 0) {
887
928
  const key = change.key;
888
929
  const index = findFirst(current, key, start);
889
930
  const node = current[index];
890
- if (node && node.key <= key) {
931
+ if (node && cmp(node.key, key) <= 0) {
891
932
  return isRange(node) ? insertNodeIntoRange(current, index, change, result) : updateNode(current, index, change, result);
892
933
  } else {
893
934
  return index;
@@ -902,9 +943,9 @@ function insertNodeIntoRange(current, index, change, result) {
902
943
  return;
903
944
  result.push(newChange);
904
945
  const insertions = [
905
- range.key < key && { ...range, end: keyBefore(key) },
946
+ cmp(range.key, key) < 0 && { ...range, end: keyBefore(key) },
906
947
  newNode,
907
- range.end > key && { ...range, key: keyAfter(key) }
948
+ cmp(range.end, key) > 0 && { ...range, key: keyAfter(key) }
908
949
  ].filter(Boolean);
909
950
  current.splice(index, 1, ...insertions);
910
951
  return index + insertions.length - 1;
@@ -948,7 +989,7 @@ function isPathEqual(first, second) {
948
989
  }
949
990
  function getNewerNode(node, base) {
950
991
  if (isBranch(node)) {
951
- const emptyNode = { key: "", end: "\uFFFF", version: base.version };
992
+ const emptyNode = { key: MIN_KEY, end: MAX_KEY, version: base.version };
952
993
  const children = [emptyNode];
953
994
  sieve(children, node.children);
954
995
  return children.length === 1 && children[0] === emptyNode ? null : { ...node, children };
@@ -979,7 +1020,7 @@ function getKnown(graph, version = 0) {
979
1020
  for (const { key, end, children } of graph) {
980
1021
  const node = { key, version };
981
1022
  if (end) {
982
- if (end !== key)
1023
+ if (cmp(end, key) !== 0)
983
1024
  node.end = end;
984
1025
  node.value = 1;
985
1026
  }
@@ -993,14 +1034,14 @@ function getKnown(graph, version = 0) {
993
1034
  return query;
994
1035
  }
995
1036
  function finalize(graph, query, version = Date.now()) {
996
- let result = [{ key: "", end: "\uFFFF", version: 0 }];
1037
+ let result = [{ key: MIN_KEY, end: MAX_KEY, version: 0 }];
997
1038
  merge(result, graph);
998
1039
  if (query)
999
1040
  result = slice(result, query).known || [];
1000
1041
  result = setVersion(result, version);
1001
1042
  return result;
1002
1043
  }
1003
- function decode(nodes = [], { isGraph } = {}) {
1044
+ function decode$1(nodes = [], { isGraph } = {}) {
1004
1045
  function decodeChildren(nodes2) {
1005
1046
  let result = [];
1006
1047
  let allStrs = true;
@@ -1019,16 +1060,17 @@ function decode(nodes = [], { isGraph } = {}) {
1019
1060
  function addPutRange({ key, end }) {
1020
1061
  if (lastNode) {
1021
1062
  if (lastNode.end) {
1022
- if (key === keyAfter(lastNode.end)) {
1063
+ if (cmp(key, keyAfter(lastNode.end)) === 0) {
1023
1064
  lastNode.end = end || key;
1024
- return end && end !== key;
1065
+ return end && cmp(end, key) !== 0;
1025
1066
  }
1026
1067
  } else {
1027
- if (key === keyAfter(lastNode.key))
1068
+ if (cmp(key, keyAfter(lastNode.key)) === 0) {
1028
1069
  key = lastNode.key;
1070
+ }
1029
1071
  }
1030
1072
  }
1031
- if (end && key !== end) {
1073
+ if (end && cmp(key, end) !== 0) {
1032
1074
  lastNode = { key, end };
1033
1075
  putRanges.push(lastNode);
1034
1076
  return true;
@@ -1050,7 +1092,7 @@ function decode(nodes = [], { isGraph } = {}) {
1050
1092
  else
1051
1093
  pushResult(decodeLeafNode(node));
1052
1094
  }
1053
- if (allNums || allStrs) {
1095
+ if (allStrs || allNums && putRanges.length === 1 && cmp(putRanges[0].key, 0) === 0 && cmp(putRanges[0].end, Infinity) === 0) {
1054
1096
  result = result.reduce(
1055
1097
  (collection, item) => {
1056
1098
  if (Array.isArray(item)) {
@@ -1071,18 +1113,18 @@ function decode(nodes = [], { isGraph } = {}) {
1071
1113
  );
1072
1114
  }
1073
1115
  if (isGraph && putRanges.length) {
1074
- if (putRanges[0].key === "" && putRanges[0].end === "\uFFFF") {
1116
+ if (isMinKey(putRanges[0].key) && isMaxKey(putRanges[0].end)) {
1075
1117
  Object.defineProperty(result, "$put", { value: true });
1076
1118
  } else {
1077
1119
  Object.defineProperty(result, "$put", {
1078
- value: putRanges.map((rNode) => decode$2(rNode))
1120
+ value: putRanges.map((rNode) => decode$3(rNode))
1079
1121
  });
1080
1122
  }
1081
1123
  }
1082
1124
  return result;
1083
1125
  }
1084
1126
  function decodePrefixNode(node) {
1085
- let args = decode$2(node);
1127
+ let args = decode$3(node);
1086
1128
  if (args === "")
1087
1129
  args = {};
1088
1130
  if (typeof args === "string") {
@@ -1090,7 +1132,7 @@ function decode(nodes = [], { isGraph } = {}) {
1090
1132
  }
1091
1133
  if (isLink(node)) {
1092
1134
  args.$all = true;
1093
- const $ref = decode$1(node.path);
1135
+ const $ref = decode$2(node.path);
1094
1136
  const lastKey = $ref[$ref.length - 1];
1095
1137
  if (typeof lastKey === "string") {
1096
1138
  throw Error("decode.unencoded_prefix_ref: " + node.path);
@@ -1117,30 +1159,31 @@ function decode(nodes = [], { isGraph } = {}) {
1117
1159
  }
1118
1160
  function decodeBranchNode(node) {
1119
1161
  const child = decodeChildren(node.children);
1120
- child.$key = decode$2(node);
1162
+ child.$key = decode$3(node);
1121
1163
  return child;
1122
1164
  }
1123
1165
  function decodeLeafNode(node) {
1124
1166
  const child = isGraph ? { $val: node.value } : {};
1125
- child.$key = decode$2(node);
1167
+ child.$key = decode$3(node);
1126
1168
  return child;
1127
1169
  }
1128
1170
  function decodeRangeNode(node) {
1129
- if (node.key === node.end)
1130
- return { $key: decode$2({ key: node.key }) };
1171
+ if (cmp(node.key, node.end) === 0) {
1172
+ return { $key: decode$3({ key: node.key }) };
1173
+ }
1131
1174
  }
1132
1175
  function decodeLinkNode(node) {
1133
- const linkObject = { $key: decode$2(node) };
1134
- Object.defineProperty(linkObject, "$ref", { value: decode$1(node.path) });
1176
+ const linkObject = { $key: decode$3(node) };
1177
+ Object.defineProperty(linkObject, "$ref", { value: decode$2(node.path) });
1135
1178
  return linkObject;
1136
1179
  }
1137
1180
  return decodeChildren(nodes);
1138
1181
  }
1139
1182
  function decodeGraph(graph) {
1140
- return decode(graph, { isGraph: true });
1183
+ return decode$1(graph, { isGraph: true });
1141
1184
  }
1142
1185
  function decodeQuery(query) {
1143
- return decode(query, { isGraph: false });
1186
+ return decode$1(query, { isGraph: false });
1144
1187
  }
1145
1188
  const REF = Symbol();
1146
1189
  const PRE = Symbol();
@@ -1154,25 +1197,27 @@ function decorate(rootGraph, rootQuery) {
1154
1197
  query = [query];
1155
1198
  let graph;
1156
1199
  if (query.$ref) {
1157
- const { $ref, ...props } = query;
1200
+ const { $ref, ...props2 } = query;
1158
1201
  const [range, filter] = splitRef($ref);
1159
- const path = encode$1($ref);
1202
+ const path = encode$2($ref);
1160
1203
  const targetPlumGraph = unwrap(rootGraph, path);
1161
- if (range)
1162
- targetPlumGraph[PRE] = filter;
1163
- graph = construct(
1164
- targetPlumGraph,
1165
- range ? { $key: range, ...props } : props
1166
- );
1167
- Object.defineProperty(graph, "$ref", { value: $ref });
1204
+ if (targetPlumGraph) {
1205
+ if (range)
1206
+ targetPlumGraph[PRE] = filter;
1207
+ graph = construct(
1208
+ targetPlumGraph,
1209
+ range ? { $key: range, ...props2 } : props2
1210
+ );
1211
+ Object.defineProperty(graph, "$ref", { value: $ref });
1212
+ }
1168
1213
  } else if (Array.isArray(query)) {
1169
1214
  let pageKey;
1170
1215
  graph = query.flatMap((item, i) => {
1171
1216
  if (!(item == null ? void 0 : item.$key)) {
1172
1217
  return construct(descend(plumGraph, i), item);
1173
1218
  }
1174
- const { $key, $chi, ...props } = item;
1175
- const subQuery = $chi || (isEmpty(props) ? 1 : props);
1219
+ const { $key, $chi, ...props2 } = item;
1220
+ const subQuery = $chi || (isEmpty(props2) ? 1 : props2);
1176
1221
  if (!isPlainObject($key) || !splitArgs($key)[0]) {
1177
1222
  return construct(descend(plumGraph, $key), subQuery);
1178
1223
  }
@@ -1184,10 +1229,10 @@ function decorate(rootGraph, rootQuery) {
1184
1229
  pageKey = $key;
1185
1230
  const children = slice2(plumGraph, $key);
1186
1231
  return children.filter((node) => !isRange(node)).map((node) => {
1187
- const $key2 = decode$2(node);
1232
+ const $key2 = decode$3(node);
1188
1233
  const subResult = construct(getValue(node), subQuery);
1189
1234
  if (typeof subResult === "object") {
1190
- subResult.$key = children[PRE] ? { ...children[PRE], $cursor: $key2 } : $key2;
1235
+ subResult.$key = children[PRE] && !isMinKey(children[PRE]) ? { ...children[PRE], $cursor: $key2 } : $key2;
1191
1236
  }
1192
1237
  return subResult;
1193
1238
  });
@@ -1215,13 +1260,13 @@ function decorate(rootGraph, rootQuery) {
1215
1260
  }
1216
1261
  if (plumGraph[REF]) {
1217
1262
  Object.defineProperty(graph, "$ref", {
1218
- value: decode$1(plumGraph[REF])
1263
+ value: decode$2(plumGraph[REF])
1219
1264
  });
1220
1265
  }
1221
1266
  return graph;
1222
1267
  }
1223
1268
  function descend(children, $key) {
1224
- const { key } = encode$2($key);
1269
+ const key = ArrayBuffer.isView($key) ? $key : encode$3($key).key;
1225
1270
  if (!Array.isArray(children))
1226
1271
  return null;
1227
1272
  const ix = findFirst(children, key);
@@ -1230,7 +1275,7 @@ function decorate(rootGraph, rootQuery) {
1230
1275
  return;
1231
1276
  if (isRange(node) && node.end >= key)
1232
1277
  return null;
1233
- if (node.key !== key)
1278
+ if (cmp(node.key, key) !== 0)
1234
1279
  return;
1235
1280
  const result2 = getValue(node);
1236
1281
  if (node.prefix)
@@ -1252,14 +1297,14 @@ function decorate(rootGraph, rootQuery) {
1252
1297
  const [range, filter] = splitArgs($key);
1253
1298
  if (isDef(filter)) {
1254
1299
  children = descend(children, filter);
1255
- } else if (children[0].key === "" && children[0].prefix) {
1256
- children = descend(children, "");
1300
+ } else if (isMinKey(children[0].key) && children[0].prefix) {
1301
+ children = descend(children, MIN_KEY);
1257
1302
  }
1258
- const { key, end, limit = Infinity } = encode$2(range);
1303
+ const { key, end, limit = Infinity } = encode$3(range);
1259
1304
  const ix = findFirst(children, key);
1260
1305
  let i = ix;
1261
1306
  let result2;
1262
- if (key < end) {
1307
+ if (cmp(key, end) < 0) {
1263
1308
  for (let n = 0; i < children.length && n < limit; i++) {
1264
1309
  if (!isRange(children[i]))
1265
1310
  n++;
@@ -1304,52 +1349,152 @@ function addPageMeta(graph, args) {
1304
1349
  let $next = isDef($page.$before) ? { ...filter, $first: count, $since: $page.$before } : isDef($page.$until) ? { ...filter, $first: count, $after: $page.$until } : null;
1305
1350
  Object.assign(graph, { $page, $next, $prev });
1306
1351
  }
1307
- function serialize(obj) {
1308
- return JSON.stringify(obj).replace(/\uffff/g, "\\uffff");
1352
+ function getByte(view, offset) {
1353
+ return offset < view.byteLength ? view.getUint8(offset) : 0;
1354
+ }
1355
+ function getChar(string, offset) {
1356
+ return offset < string.length ? alpha.indexOf(string[offset]) : 0;
1357
+ }
1358
+ function encode$1(u8Arr) {
1359
+ const { buffer, byteOffset, byteLength } = u8Arr;
1360
+ const view = new DataView(buffer, byteOffset, byteLength);
1361
+ let str = "";
1362
+ for (let i = 0; i < view.byteLength; i += 3) {
1363
+ let value = (getByte(view, i) << 16) + (getByte(view, i + 1) << 8) + getByte(view, i + 2);
1364
+ let gstr = "";
1365
+ for (let j = 0; j < 4; j++) {
1366
+ gstr = alpha[value & 63] + gstr;
1367
+ value = value >> 6 | 0;
1368
+ }
1369
+ str += gstr;
1370
+ }
1371
+ return str.substring(0, Math.ceil(view.byteLength * 4 / 3));
1372
+ }
1373
+ function decode(string, start = 0) {
1374
+ const buffer = new ArrayBuffer(Math.floor((string.length - start) * 3 / 4));
1375
+ const view = new DataView(buffer);
1376
+ for (let i = start; i < string.length; i += 4) {
1377
+ let value = (getChar(string, i) << 18) + (getChar(string, i + 1) << 12) + (getChar(string, i + 2) << 6) + getChar(string, i + 3);
1378
+ for (let j = i * 3 / 4 + 2; j >= i * 3 / 4; j--) {
1379
+ if (j < view.byteLength)
1380
+ view.setUint8(j, value & 255);
1381
+ value = value >> 8 | 0;
1382
+ }
1383
+ }
1384
+ return addStringify(new Uint8Array(buffer));
1385
+ }
1386
+ const props = [
1387
+ "end",
1388
+ "version",
1389
+ "limit",
1390
+ "value",
1391
+ "path",
1392
+ "prefix",
1393
+ "children"
1394
+ ];
1395
+ function serializeKey(key) {
1396
+ if (key[0] === STR)
1397
+ return decode$4(key);
1398
+ return "\0" + encode$1(key);
1399
+ }
1400
+ function deserializeKey(key) {
1401
+ if (key[0] === "\0")
1402
+ return decode(key.slice(1));
1403
+ return encode$4(key);
1404
+ }
1405
+ function serializeNodes(children, parentVersion) {
1406
+ const array = children.map(
1407
+ (node) => props.reduce(
1408
+ (array2, prop, i) => {
1409
+ if (!(prop in node))
1410
+ return array2;
1411
+ let value = node[prop];
1412
+ if (prop === "version" && value === parentVersion)
1413
+ return array2;
1414
+ if (prop === "children")
1415
+ value = serializeNodes(value, node.version);
1416
+ if (prop === "end")
1417
+ value = serializeKey(value);
1418
+ if (prop === "path")
1419
+ value = value.map(serializeKey);
1420
+ array2[1] |= 1 << i;
1421
+ array2.push(value);
1422
+ return array2;
1423
+ },
1424
+ [serializeKey(node.key), 0]
1425
+ )
1426
+ );
1427
+ return array;
1428
+ }
1429
+ function deserializeNodes(children, parentVersion) {
1430
+ const node = children.map(
1431
+ ([key, type, ...values]) => props.reduce(
1432
+ (node2, prop, i) => {
1433
+ if (!(type & 1 << i))
1434
+ return node2;
1435
+ let value = values.shift();
1436
+ if (prop === "children")
1437
+ value = deserializeNodes(value, node2.version);
1438
+ if (prop === "end")
1439
+ value = deserializeKey(value);
1440
+ if (prop === "path")
1441
+ value = value.map(deserializeKey);
1442
+ node2[prop] = value;
1443
+ return node2;
1444
+ },
1445
+ { key: deserializeKey(key), version: parentVersion }
1446
+ )
1447
+ );
1448
+ return node;
1449
+ }
1450
+ function serialize(payload) {
1451
+ return JSON.stringify(serializeNodes(payload));
1309
1452
  }
1310
1453
  function deserialize(str) {
1311
- return JSON.parse(str);
1454
+ return deserializeNodes(JSON.parse(str));
1312
1455
  }
1313
1456
  const ROOT_KEY = Symbol();
1314
1457
  function encode(value, { version, isGraph } = {}) {
1315
1458
  var _a;
1316
1459
  const links = [];
1317
- function pushLink($ref, $ver, props, $val, $chi) {
1460
+ function pushLink($ref, $ver, props2, $val, $chi) {
1318
1461
  const [range, _] = splitRef($ref);
1319
- let children = !isEmpty(props) ? makeNode(
1320
- range ? [{ $key: range, ...props }] : props,
1462
+ let children = !isEmpty(props2) ? makeNode2(
1463
+ range ? [{ $key: range, ...props2 }] : props2,
1321
1464
  void 0,
1322
1465
  $ver
1323
- ).children : isDef($chi) ? makeNode(
1466
+ ).children : isDef($chi) ? makeNode2(
1324
1467
  range ? [{ $key: range, $chi }] : $chi,
1325
1468
  void 0,
1326
1469
  $ver
1327
1470
  ).children : isDef($val) ? $val : isGraph ? void 0 : 1;
1328
1471
  if (children) {
1329
- links.push(wrap(children, encode$1($ref), $ver, !!range)[0]);
1472
+ links.push(wrap(children, encode$2($ref), $ver, !!range)[0]);
1330
1473
  }
1331
1474
  }
1332
1475
  const combine = isGraph ? merge : add;
1333
- function makeNode(object, key, ver) {
1476
+ function makeNode2(object, key, ver) {
1334
1477
  var _a2;
1335
1478
  if (!isDef(object))
1336
1479
  return;
1337
1480
  if (typeof object === "object" && object && isEmpty(object))
1338
1481
  return;
1339
- const { $key, $ver, $ref, $val, $chi, $put, ...props } = object || {};
1482
+ const { $key, $ver, $ref, $val, $chi, $put, ...props2 } = object || {};
1340
1483
  if (isDef($ver))
1341
1484
  ver = $ver;
1342
1485
  if (isPlainObject($key)) {
1343
1486
  const [page, filter] = splitArgs($key);
1344
- if (isGraph && page && !isDef(page.$cursor) && ($ref || $val || $chi || $put || !isEmpty(props))) {
1345
- const node2 = makeNode({ ...object, $key: filter || "" }, key, ver);
1487
+ if (isGraph && page && !isDef(page.$cursor) && ($ref || $val || $chi || $put || !isEmpty(props2))) {
1488
+ const node2 = makeNode2({ ...object, $key: filter || {} }, key, ver);
1489
+ if (!filter)
1490
+ node2.key = MIN_KEY;
1346
1491
  node2.prefix = true;
1347
1492
  return node2;
1348
1493
  }
1349
1494
  if ((!isDef(key) || Number.isInteger(key)) && page && (filter || isDef(page.$cursor))) {
1350
- const node2 = makeNode(
1495
+ const node2 = makeNode2(
1351
1496
  {
1352
- $key: filter || "",
1497
+ $key: filter || {},
1353
1498
  $chi: [
1354
1499
  { ...object, $key: isDef(page.$cursor) ? page.$cursor : page }
1355
1500
  ]
@@ -1357,37 +1502,39 @@ function encode(value, { version, isGraph } = {}) {
1357
1502
  key,
1358
1503
  ver
1359
1504
  );
1505
+ if (!filter)
1506
+ node2.key = MIN_KEY;
1360
1507
  node2.prefix = true;
1361
1508
  return node2;
1362
1509
  }
1363
1510
  }
1364
1511
  if (isDef($key) && (Number.isInteger(key) || !isDef(key)))
1365
1512
  key = $key;
1366
- const node = key === ROOT_KEY || !isDef(key) ? {} : encode$2(key);
1513
+ const node = key === ROOT_KEY || !isDef(key) ? {} : encode$3(key);
1367
1514
  node.version = ver;
1368
1515
  if (object === null) {
1369
1516
  node.end = node.key;
1370
1517
  } else if (isDef($key) && isDef(key) && key !== $key) {
1371
- node.children = [makeNode(object, void 0, ver)].filter(Boolean);
1518
+ node.children = [makeNode2(object, void 0, ver)].filter(Boolean);
1372
1519
  return node;
1373
1520
  } else if ($ref) {
1374
- pushLink($ref, node.version, props, $val, $chi);
1521
+ pushLink($ref, node.version, props2, $val, $chi);
1375
1522
  if (!isGraph)
1376
1523
  return;
1377
- node.path = encode$1($ref);
1524
+ node.path = encode$2($ref);
1378
1525
  } else if ($val === true) {
1379
- node.value = props;
1526
+ node.value = props2;
1380
1527
  } else if (isDef($val)) {
1381
1528
  node.value = $val;
1382
1529
  } else if (typeof object !== "object") {
1383
1530
  node.value = isGraph || typeof object === "number" ? object : 1;
1384
1531
  } else if (isDef($chi)) {
1385
- const children = $chi.map((obj) => makeNode(obj, void 0, ver)).filter(Boolean).sort((a, b) => a.key <= b.key ? -1 : 1);
1532
+ const children = $chi.map((obj) => makeNode2(obj, void 0, ver)).filter(Boolean).sort((a, b) => cmp(a.key, b.key));
1386
1533
  if (children.length) {
1387
1534
  node.children = children;
1388
1535
  }
1389
1536
  } else if (Array.isArray(object)) {
1390
- const children = object.map((obj, i) => makeNode(obj, i, ver)).filter(Boolean).reduce((acc, it) => {
1537
+ const children = object.map((obj, i) => makeNode2(obj, i, ver)).filter(Boolean).reduce((acc, it) => {
1391
1538
  combine(acc, [it]);
1392
1539
  return acc;
1393
1540
  }, []);
@@ -1395,7 +1542,7 @@ function encode(value, { version, isGraph } = {}) {
1395
1542
  node.children = children;
1396
1543
  }
1397
1544
  } else {
1398
- const children = Object.keys(props).sort().map((key2) => makeNode(object[key2], key2, ver)).filter(Boolean);
1545
+ const children = Object.keys(props2).sort().map((key2) => makeNode2(object[key2], key2, ver)).filter(Boolean);
1399
1546
  if (children.length) {
1400
1547
  node.children = children;
1401
1548
  } else if (isGraph) {
@@ -1411,14 +1558,14 @@ function encode(value, { version, isGraph } = {}) {
1411
1558
  }
1412
1559
  let putQuery;
1413
1560
  if (Array.isArray(object) && !object.some((it) => isDef(it == null ? void 0 : it.$key))) {
1414
- putQuery = [encode$2({ $since: 0, $until: Infinity })];
1561
+ putQuery = [encode$3({ $since: 0, $until: Infinity })];
1415
1562
  }
1416
1563
  if ($put === true) {
1417
1564
  putQuery = null;
1418
1565
  } else if (Array.isArray($put)) {
1419
- putQuery = $put.map((arg) => encode$2(arg));
1566
+ putQuery = $put.map((arg) => encode$3(arg));
1420
1567
  } else if (isDef($put)) {
1421
- putQuery = [encode$2($put)];
1568
+ putQuery = [encode$3($put)];
1422
1569
  }
1423
1570
  if (isGraph && isDef(putQuery)) {
1424
1571
  node.children = finalize(node.children || [], putQuery, node.version);
@@ -1429,7 +1576,7 @@ function encode(value, { version, isGraph } = {}) {
1429
1576
  }
1430
1577
  if (value == null ? void 0 : value.$key)
1431
1578
  value = [value];
1432
- let result = ((_a = makeNode(value, ROOT_KEY, version)) == null ? void 0 : _a.children) || [];
1579
+ let result = ((_a = makeNode2(value, ROOT_KEY, version)) == null ? void 0 : _a.children) || [];
1433
1580
  while (links.length) {
1434
1581
  combine(result, [links.pop()]);
1435
1582
  }
@@ -1548,22 +1695,24 @@ function unwrapObject(object, path) {
1548
1695
  }
1549
1696
  export {
1550
1697
  IS_VAL,
1698
+ MAX_KEY,
1699
+ MIN_KEY,
1551
1700
  add,
1701
+ addStringify,
1552
1702
  cloneObject,
1553
- decode$2 as decodeArgs,
1703
+ cmp,
1704
+ decode$3 as decodeArgs,
1554
1705
  decodeGraph,
1555
- decode$1 as decodePath,
1706
+ decode$2 as decodePath,
1556
1707
  decodeQuery,
1557
- decode$7 as decodeUrl,
1558
- decode$3 as decodeValue,
1708
+ decode$4 as decodeValue,
1559
1709
  decorate,
1560
1710
  deserialize,
1561
- encode$2 as encodeArgs,
1711
+ encode$3 as encodeArgs,
1562
1712
  encodeGraph,
1563
- encode$1 as encodePath,
1713
+ encode$2 as encodePath,
1564
1714
  encodeQuery,
1565
- encode$7 as encodeUrl,
1566
- encode$3 as encodeValue,
1715
+ encode$4 as encodeValue,
1567
1716
  err,
1568
1717
  errIf,
1569
1718
  finalize,
@@ -1575,9 +1724,9 @@ export {
1575
1724
  isBranch,
1576
1725
  isDef,
1577
1726
  isEmpty,
1578
- isEncoded,
1579
- isEncodedKey,
1580
1727
  isLink,
1728
+ isMaxKey,
1729
+ isMinKey,
1581
1730
  isNewer,
1582
1731
  isOlder,
1583
1732
  isPlainObject,