@graffy/common 0.19.1-alpha.1 → 0.19.1
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.cjs +1673 -0
- package/index.mjs +1673 -0
- package/package.json +8 -14
- package/types/coding/args.d.ts +5 -0
- package/types/coding/base64.d.ts +2 -0
- package/types/coding/decodeTree.d.ts +2 -0
- package/types/coding/encodeTree.d.ts +2 -0
- package/{coding/index.js → types/coding/index.d.ts} +4 -4
- package/types/coding/number.d.ts +2 -0
- package/types/coding/pack.d.ts +2 -0
- package/types/coding/path.d.ts +3 -0
- package/types/coding/string.d.ts +2 -0
- package/types/coding/struct.d.ts +11 -0
- package/types/node/find.d.ts +2 -0
- package/{node/index.js → types/node/index.d.ts} +0 -1
- package/types/node/types.d.ts +6 -0
- package/types/object.d.ts +4 -0
- package/{ops → types/ops}/finalize.d.ts +1 -1
- package/{ops → types/ops}/getKnown.d.ts +4 -1
- package/types/ops/merge.d.ts +3 -0
- package/types/ops/path.d.ts +6 -0
- package/types/ops/sieve.d.ts +3 -0
- package/{ops → types/ops}/slice.d.ts +6 -2
- package/types/ops/step.d.ts +6 -0
- package/types/stream/makeWatcher.d.ts +16 -0
- package/types/util.d.ts +15 -0
- package/coding/alphabet.js +0 -5
- package/coding/args.d.ts +0 -5
- package/coding/args.js +0 -93
- package/coding/base64.d.ts +0 -2
- package/coding/base64.js +0 -41
- package/coding/decodeTree.d.ts +0 -2
- package/coding/decodeTree.js +0 -197
- package/coding/decorate.js +0 -211
- package/coding/encodeTree.d.ts +0 -2
- package/coding/encodeTree.js +0 -248
- package/coding/id.js +0 -4
- package/coding/index.d.ts +0 -8
- package/coding/number.d.ts +0 -2
- package/coding/number.js +0 -39
- package/coding/pack.d.ts +0 -2
- package/coding/pack.js +0 -71
- package/coding/path.d.ts +0 -3
- package/coding/path.js +0 -41
- package/coding/string.d.ts +0 -2
- package/coding/string.js +0 -8
- package/coding/struct.d.ts +0 -11
- package/coding/struct.js +0 -163
- package/index.d.ts +0 -6
- package/node/find.d.ts +0 -2
- package/node/find.js +0 -14
- package/node/index.d.ts +0 -2
- package/node/types.d.ts +0 -6
- package/node/types.js +0 -18
- package/object.d.ts +0 -4
- package/object.js +0 -86
- package/ops/add.js +0 -64
- package/ops/finalize.js +0 -19
- package/ops/getKnown.js +0 -24
- package/ops/index.d.ts +0 -9
- package/ops/merge.d.ts +0 -3
- package/ops/merge.js +0 -112
- package/ops/path.d.ts +0 -6
- package/ops/path.js +0 -91
- package/ops/setVersion.js +0 -29
- package/ops/sieve.d.ts +0 -3
- package/ops/sieve.js +0 -193
- package/ops/slice.js +0 -153
- package/ops/step.d.ts +0 -6
- package/ops/step.js +0 -61
- package/stream/index.d.ts +0 -2
- package/stream/makeWatcher.d.ts +0 -10
- package/stream/makeWatcher.js +0 -19
- package/stream/mergeStreams.js +0 -20
- package/util.d.ts +0 -15
- package/util.js +0 -106
- package/{coding → types/coding}/alphabet.d.ts +0 -0
- package/{coding → types/coding}/decorate.d.ts +0 -0
- package/{coding → types/coding}/id.d.ts +0 -0
- package/{index.js → types/index.d.ts} +0 -0
- package/{ops → types/ops}/add.d.ts +0 -0
- package/{ops/index.js → types/ops/index.d.ts} +1 -1
- /package/{ops → types/ops}/setVersion.d.ts +0 -0
- /package/{stream/index.js → types/stream/index.d.ts} +0 -0
- /package/{stream → types/stream}/mergeStreams.d.ts +0 -0
package/coding/decorate.js
DELETED
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import { findFirst, isRange } from "../node/index.js";
|
|
2
|
-
import { getNodeValue, IS_VAL, unwrap } from "../ops/index.js";
|
|
3
|
-
import { cmp, isDef, isEmpty, isMinKey, isPlainObject, MIN_KEY, } from "../util.js";
|
|
4
|
-
import { decode as decodeArgs, encode as encodeArgs, splitArgs, } from "./args.js";
|
|
5
|
-
import { decodeGraph } from "./decodeTree.js";
|
|
6
|
-
import { decode as decodePath, encode as encodePath, splitRef, } from "./path.js";
|
|
7
|
-
const REF = Symbol();
|
|
8
|
-
const PRE = Symbol();
|
|
9
|
-
export default function decorate(rootGraph, rootQuery) {
|
|
10
|
-
// console.log('Decorating', rootGraph, rootQuery);
|
|
11
|
-
function construct(plumGraph, query) {
|
|
12
|
-
if (plumGraph === null)
|
|
13
|
-
return null;
|
|
14
|
-
if (!isDef(plumGraph))
|
|
15
|
-
plumGraph = [];
|
|
16
|
-
if (query.$key)
|
|
17
|
-
query = [query];
|
|
18
|
-
// console.log('Constructing', plumGraph, query);
|
|
19
|
-
let graph;
|
|
20
|
-
if (query.$ref) {
|
|
21
|
-
const { $ref, ...props } = query;
|
|
22
|
-
const [range, filter] = splitRef($ref);
|
|
23
|
-
const path = encodePath($ref);
|
|
24
|
-
const targetPlumGraph = unwrap(rootGraph, path);
|
|
25
|
-
if (targetPlumGraph) {
|
|
26
|
-
if (range)
|
|
27
|
-
targetPlumGraph[PRE] = filter;
|
|
28
|
-
graph = construct(targetPlumGraph, range ? { $key: range, ...props } : props);
|
|
29
|
-
Object.defineProperty(graph, '$ref', { value: $ref });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
else if (Array.isArray(query)) {
|
|
33
|
-
let pageKey;
|
|
34
|
-
graph = query.flatMap((item, i) => {
|
|
35
|
-
if (!item?.$key) {
|
|
36
|
-
// This is an integer-indexed array.
|
|
37
|
-
return construct(descend(plumGraph, i), item);
|
|
38
|
-
}
|
|
39
|
-
const { $key, $chi, ...props } = item;
|
|
40
|
-
const subQuery = $chi || (isEmpty(props) ? 1 : props);
|
|
41
|
-
if (!(isPlainObject($key) && splitArgs($key)[0])) {
|
|
42
|
-
// This is a non-string argument without pagination
|
|
43
|
-
return construct(descend(plumGraph, $key), subQuery);
|
|
44
|
-
}
|
|
45
|
-
// This is a pagination query.
|
|
46
|
-
if (pageKey) {
|
|
47
|
-
throw Error(`decorate.multi_range_query:${JSON.stringify({ $key, pageKey })}`);
|
|
48
|
-
}
|
|
49
|
-
pageKey = $key;
|
|
50
|
-
const children = slice(plumGraph, $key);
|
|
51
|
-
return children
|
|
52
|
-
.filter((node) => !isRange(node))
|
|
53
|
-
.map((node) => {
|
|
54
|
-
const $key = decodeArgs(node);
|
|
55
|
-
const subResult = construct(getValue(node), subQuery);
|
|
56
|
-
if (typeof subResult === 'object' && subResult) {
|
|
57
|
-
subResult.$key =
|
|
58
|
-
children[PRE] && !isMinKey(children[PRE])
|
|
59
|
-
? { ...children[PRE], $cursor: $key }
|
|
60
|
-
: $key;
|
|
61
|
-
}
|
|
62
|
-
return subResult;
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
// .filter(Boolean);
|
|
66
|
-
if (pageKey)
|
|
67
|
-
addPageMeta(graph, pageKey);
|
|
68
|
-
}
|
|
69
|
-
else if (typeof query === 'object') {
|
|
70
|
-
graph = {};
|
|
71
|
-
for (const prop in query) {
|
|
72
|
-
graph[prop] = construct(descend(plumGraph, prop), query[prop]);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
else if (query) {
|
|
76
|
-
if (Array.isArray(plumGraph) && !plumGraph.length) {
|
|
77
|
-
graph = undefined;
|
|
78
|
-
}
|
|
79
|
-
else if (typeof plumGraph !== 'object' || !plumGraph) {
|
|
80
|
-
graph = plumGraph;
|
|
81
|
-
}
|
|
82
|
-
else if (plumGraph[IS_VAL]) {
|
|
83
|
-
graph = Array.isArray(plumGraph)
|
|
84
|
-
? plumGraph.slice(0)
|
|
85
|
-
: { ...plumGraph };
|
|
86
|
-
graph.$val = true;
|
|
87
|
-
}
|
|
88
|
-
else if (Array.isArray(plumGraph)) {
|
|
89
|
-
graph = deValNull(decodeGraph(plumGraph));
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
throw Error('decorate.unexpected_graph');
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (plumGraph[REF]) {
|
|
96
|
-
Object.defineProperty(graph, '$ref', {
|
|
97
|
-
value: decodePath(plumGraph[REF]),
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
return graph;
|
|
101
|
-
}
|
|
102
|
-
function descend(children, $key) {
|
|
103
|
-
const key = ArrayBuffer.isView($key) ? $key : encodeArgs($key).key;
|
|
104
|
-
if (!Array.isArray(children))
|
|
105
|
-
return null;
|
|
106
|
-
const ix = findFirst(children, key);
|
|
107
|
-
const node = children[ix];
|
|
108
|
-
if (!node)
|
|
109
|
-
return;
|
|
110
|
-
if (isRange(node) && node.end >= key)
|
|
111
|
-
return null;
|
|
112
|
-
if (cmp(node.key, key) !== 0)
|
|
113
|
-
return;
|
|
114
|
-
const result = getValue(node);
|
|
115
|
-
if (node.prefix)
|
|
116
|
-
result[PRE] = $key;
|
|
117
|
-
return result;
|
|
118
|
-
}
|
|
119
|
-
function getValue(node) {
|
|
120
|
-
let result;
|
|
121
|
-
if (node.path) {
|
|
122
|
-
result = unwrap(rootGraph, node.path);
|
|
123
|
-
if (typeof result === 'object' && result)
|
|
124
|
-
result[REF] = node.path;
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
result = getNodeValue(node);
|
|
128
|
-
}
|
|
129
|
-
return result;
|
|
130
|
-
}
|
|
131
|
-
function slice(children, $key) {
|
|
132
|
-
const [range, filter] = splitArgs($key);
|
|
133
|
-
if (isDef(filter)) {
|
|
134
|
-
children = descend(children, filter);
|
|
135
|
-
}
|
|
136
|
-
else if (isMinKey(children[0].key) && children[0].prefix) {
|
|
137
|
-
children = descend(children, MIN_KEY);
|
|
138
|
-
}
|
|
139
|
-
const { key, end, limit = Number.POSITIVE_INFINITY } = encodeArgs(range);
|
|
140
|
-
const ix = findFirst(children, key);
|
|
141
|
-
let i = ix;
|
|
142
|
-
let result;
|
|
143
|
-
if (cmp(key, end) < 0) {
|
|
144
|
-
for (let n = 0; i < children.length && n < limit; i++) {
|
|
145
|
-
if (!isRange(children[i]))
|
|
146
|
-
n++;
|
|
147
|
-
}
|
|
148
|
-
// console.log('slicing fwd', children, ix, i);
|
|
149
|
-
result = children.slice(ix, i);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
for (let n = 0; i >= 0 && n < limit; i--) {
|
|
153
|
-
if (!isRange(children[i]))
|
|
154
|
-
n++;
|
|
155
|
-
}
|
|
156
|
-
// console.log('slicing bkd', children, i + 1, ix + 1);
|
|
157
|
-
result = children.slice(i + 1, ix + 1);
|
|
158
|
-
}
|
|
159
|
-
if (children[REF])
|
|
160
|
-
result[REF] = children[REF];
|
|
161
|
-
if (children[PRE])
|
|
162
|
-
result[PRE] = children[PRE];
|
|
163
|
-
return result;
|
|
164
|
-
}
|
|
165
|
-
const result = construct(rootGraph, rootQuery);
|
|
166
|
-
// console.log('Decorate', result, rootGraph, rootQuery);
|
|
167
|
-
return result;
|
|
168
|
-
}
|
|
169
|
-
// Replace $val: null produced by
|
|
170
|
-
function deValNull(graph) {
|
|
171
|
-
if (typeof graph !== 'object' || !graph)
|
|
172
|
-
return graph;
|
|
173
|
-
if ('$val' in graph && graph.$val !== true)
|
|
174
|
-
return graph.$val;
|
|
175
|
-
// Important: update graph in-place to avoid losing non-enumerable props.
|
|
176
|
-
for (const prop in graph)
|
|
177
|
-
graph[prop] = deValNull(graph[prop]);
|
|
178
|
-
return graph;
|
|
179
|
-
}
|
|
180
|
-
function addPageMeta(graph, args) {
|
|
181
|
-
if (args.$all) {
|
|
182
|
-
Object.assign(graph, { $page: args, $prev: null, $next: null });
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
const [{ $first, $last, ...bounds }, filter] = splitArgs(args);
|
|
186
|
-
const count = $first || $last;
|
|
187
|
-
/** @type {any} */
|
|
188
|
-
const $page = { ...filter, ...bounds, $all: true };
|
|
189
|
-
if (graph.length === count) {
|
|
190
|
-
// This result was limited by the count; update the "outer" bound.
|
|
191
|
-
if ($first) {
|
|
192
|
-
const boundKey = graph[graph.length - 1].$key;
|
|
193
|
-
$page.$until = isDef(boundKey?.$cursor) ? boundKey.$cursor : boundKey;
|
|
194
|
-
delete $page.$before;
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
const boundKey = graph[0].$key;
|
|
198
|
-
$page.$since = isDef(boundKey?.$cursor) ? boundKey.$cursor : boundKey;
|
|
199
|
-
delete $page.$after;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// biome-ignore format: ternary chain
|
|
203
|
-
const $prev = isDef($page.$after) ? { ...filter, $last: count, $until: $page.$after } :
|
|
204
|
-
isDef($page.$since) ? { ...filter, $last: count, $before: $page.$since } :
|
|
205
|
-
null;
|
|
206
|
-
// biome-ignore format: ternary chain
|
|
207
|
-
const $next = isDef($page.$before) ? { ...filter, $first: count, $since: $page.$before } :
|
|
208
|
-
isDef($page.$until) ? { ...filter, $first: count, $after: $page.$until } :
|
|
209
|
-
null;
|
|
210
|
-
Object.assign(graph, { $page, $next, $prev });
|
|
211
|
-
}
|
package/coding/encodeTree.d.ts
DELETED
package/coding/encodeTree.js
DELETED
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import isEqual from 'lodash/isEqual.js';
|
|
2
|
-
import { add, merge, setVersion, wrap } from "../ops/index.js";
|
|
3
|
-
import { clone, cmp, isDef, isEmpty, isPlainObject, MAX_KEY, MIN_KEY, } from "../util.js";
|
|
4
|
-
import { encode as encodeArgs, splitArgs } from "./args.js";
|
|
5
|
-
import { encode as encodePath, splitRef } from "./path.js";
|
|
6
|
-
const ROOT_KEY = Symbol();
|
|
7
|
-
/**
|
|
8
|
-
@param {any} value
|
|
9
|
-
@param {{version?: number, isGraph?: boolean}} options
|
|
10
|
-
*/
|
|
11
|
-
function encode(value, { version, isGraph } = {}) {
|
|
12
|
-
const links = [];
|
|
13
|
-
function pushLink($ref, $ver, props, $val, $chi) {
|
|
14
|
-
const [range, _] = splitRef($ref);
|
|
15
|
-
const node = !isEmpty(props)
|
|
16
|
-
? makeNode(range ? [{ $key: range, ...props }] : props, undefined, $ver)
|
|
17
|
-
: isDef($chi)
|
|
18
|
-
? makeNode(range ? [{ $key: range, $chi }] : $chi, undefined, $ver)
|
|
19
|
-
: null;
|
|
20
|
-
// biome-ignore format: ternary chain
|
|
21
|
-
const children = node ? node.children :
|
|
22
|
-
isDef($val) ? $val :
|
|
23
|
-
isGraph ? undefined : 1;
|
|
24
|
-
if (children) {
|
|
25
|
-
links.push(wrap(children, encodePath($ref), $ver, !!range)[0]);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const combine = isGraph ? merge : add;
|
|
29
|
-
function makeNode(object, key, ver, parentPuts = []) {
|
|
30
|
-
if (!isDef(object))
|
|
31
|
-
return;
|
|
32
|
-
const { $key, $ver, $ref, $val, $chi, $put, ...props } = object || {};
|
|
33
|
-
// Turn any non-enumerable properties of object into enumerable,
|
|
34
|
-
// so they're included in ...object below.
|
|
35
|
-
if (typeof object === 'object' && object && !Array.isArray(object)) {
|
|
36
|
-
object = {
|
|
37
|
-
...Object.fromEntries(Object.entries({
|
|
38
|
-
$key,
|
|
39
|
-
$ver,
|
|
40
|
-
$ref,
|
|
41
|
-
$val,
|
|
42
|
-
$chi,
|
|
43
|
-
$put,
|
|
44
|
-
}).filter(([_, val]) => isDef(val))),
|
|
45
|
-
...props,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
// An empty object is considered equivalent to undefined.
|
|
49
|
-
if (typeof object === 'object' && object && isEmpty(object))
|
|
50
|
-
return;
|
|
51
|
-
if (isDef($ver))
|
|
52
|
-
ver = $ver;
|
|
53
|
-
if (isPlainObject($key)) {
|
|
54
|
-
const [page, filter] = splitArgs($key);
|
|
55
|
-
if (page) {
|
|
56
|
-
/*
|
|
57
|
-
CONSTRUCT PREFIX NODES
|
|
58
|
-
When we encounter a range key in a graph, it means one of these:
|
|
59
|
-
1. an empty range, e.g. { $key: { $after: 'foo' } }
|
|
60
|
-
2. a range reference, e.g.
|
|
61
|
-
{ $key: { x: 1, $all: true }, $ref: ['foo', { $all: true }] }
|
|
62
|
-
3. as a shortcut to avoid repetition in query results e.g.
|
|
63
|
-
{ $key: { x: 1, $all: true }, $chi: [
|
|
64
|
-
{ $key: 'a', $val: 'A' },
|
|
65
|
-
{ $key: 'b', $val: 'B' } ] }
|
|
66
|
-
is equivalent to:
|
|
67
|
-
[ { $key: { x: 1, $before: 'a' } },
|
|
68
|
-
{ $key: { x: 1, $cursor: 'a' }, $val: 'A' },
|
|
69
|
-
{ $key: { x: 1, $after: 'a', $before: 'b' } },
|
|
70
|
-
{ $key: { x: 1, $cursor: 'b' }, $val: 'B' } ]
|
|
71
|
-
|
|
72
|
-
Cases 2. and 3. are handled below: Basically we strip out the "page"
|
|
73
|
-
part from the key (leaving only the filter), construct a node with that,
|
|
74
|
-
then add the "prefix" flag to the node.
|
|
75
|
-
|
|
76
|
-
The page part is passed as $put for constructing children (when it's a
|
|
77
|
-
graph with children)
|
|
78
|
-
*/
|
|
79
|
-
const foundPuts = parentPuts
|
|
80
|
-
.filter(([_, putFilter]) => isEqual(filter, putFilter))
|
|
81
|
-
.map(([range]) => range);
|
|
82
|
-
if (isGraph &&
|
|
83
|
-
!isDef(page.$cursor) &&
|
|
84
|
-
($ref || $val || $chi || $put || !isEmpty(props))) {
|
|
85
|
-
object.$key = filter || {};
|
|
86
|
-
object.$put = foundPuts;
|
|
87
|
-
const node = makeNode(object, key, ver);
|
|
88
|
-
if (!filter)
|
|
89
|
-
node.key = MIN_KEY;
|
|
90
|
-
node.prefix = true;
|
|
91
|
-
return node;
|
|
92
|
-
}
|
|
93
|
-
if ((!isDef(key) || Number.isInteger(key)) &&
|
|
94
|
-
(filter || isDef(page.$cursor))) {
|
|
95
|
-
object.$key = isDef(page.$cursor) ? page.$cursor : page;
|
|
96
|
-
const wrapper = { $key: filter || {}, $chi: [object] };
|
|
97
|
-
if (isGraph)
|
|
98
|
-
wrapper.$put = foundPuts;
|
|
99
|
-
const node = makeNode(wrapper, key, ver);
|
|
100
|
-
if (!filter)
|
|
101
|
-
node.key = MIN_KEY;
|
|
102
|
-
node.prefix = true;
|
|
103
|
-
return node;
|
|
104
|
-
}
|
|
105
|
-
// console.log('No prefix made', { key, $key, object });
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
let putRange = [];
|
|
109
|
-
const prefixPuts = [];
|
|
110
|
-
// If this is a plain array (without keyed objects), we should "put" the
|
|
111
|
-
// entire positive integer range to give it atomic write behavior.
|
|
112
|
-
if (Array.isArray(object) &&
|
|
113
|
-
!isDef($put) &&
|
|
114
|
-
!isDef($val) &&
|
|
115
|
-
!object.some((it) => isDef(it?.$key))) {
|
|
116
|
-
putRange = [encodeArgs({ $since: 0, $until: Number.POSITIVE_INFINITY })];
|
|
117
|
-
}
|
|
118
|
-
function classifyPut(put) {
|
|
119
|
-
const [range, filter] = splitArgs(put);
|
|
120
|
-
if (filter) {
|
|
121
|
-
prefixPuts.push([range, filter]);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
putRange.push(encodeArgs(put));
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if ($put === true) {
|
|
128
|
-
putRange = [{ key: MIN_KEY, end: MAX_KEY }];
|
|
129
|
-
}
|
|
130
|
-
else if (Array.isArray($put)) {
|
|
131
|
-
$put.forEach(classifyPut);
|
|
132
|
-
}
|
|
133
|
-
else if (isDef($put)) {
|
|
134
|
-
classifyPut($put);
|
|
135
|
-
}
|
|
136
|
-
if (isDef($key) && (Number.isInteger(key) || !isDef(key)))
|
|
137
|
-
key = $key;
|
|
138
|
-
const node = key === ROOT_KEY || !isDef(key) ? {} : encodeArgs(key);
|
|
139
|
-
// console.log('Set version', node.key, ver);
|
|
140
|
-
node.version = ver;
|
|
141
|
-
// console.log('Constructed', { node, $key, key });
|
|
142
|
-
if (object === null) {
|
|
143
|
-
node.end = node.key;
|
|
144
|
-
}
|
|
145
|
-
else if (isDef($key) && isDef(key) && key !== $key) {
|
|
146
|
-
// An array has been omitted because there is only one child.
|
|
147
|
-
node.children = [makeNode(object, undefined, ver, prefixPuts)].filter(Boolean);
|
|
148
|
-
// We don't want to add a $put at this level.
|
|
149
|
-
return node;
|
|
150
|
-
}
|
|
151
|
-
else if ($ref) {
|
|
152
|
-
pushLink($ref, node.version, props, $val, $chi);
|
|
153
|
-
if (!isGraph)
|
|
154
|
-
return; // Drop query aliases from encoded format
|
|
155
|
-
node.path = encodePath($ref);
|
|
156
|
-
}
|
|
157
|
-
else if ($val === true) {
|
|
158
|
-
node.value = Array.isArray(object) ? clone(object) : props;
|
|
159
|
-
}
|
|
160
|
-
else if (isDef($val)) {
|
|
161
|
-
node.value = $val;
|
|
162
|
-
}
|
|
163
|
-
else if (typeof object !== 'object') {
|
|
164
|
-
node.value = isGraph || typeof object === 'number' ? object : 1;
|
|
165
|
-
}
|
|
166
|
-
else if (isDef($chi)) {
|
|
167
|
-
const children = $chi
|
|
168
|
-
.map((obj) => makeNode(obj, undefined, ver, prefixPuts))
|
|
169
|
-
.filter(Boolean)
|
|
170
|
-
.sort((a, b) => cmp(a.key, b.key));
|
|
171
|
-
if (children.length) {
|
|
172
|
-
node.children = children;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
else if (Array.isArray(object)) {
|
|
176
|
-
const children = object
|
|
177
|
-
.map((obj, i) => makeNode(obj, i, ver, prefixPuts))
|
|
178
|
-
.filter(Boolean)
|
|
179
|
-
.reduce((acc, it) => {
|
|
180
|
-
combine(acc, [it]);
|
|
181
|
-
return acc;
|
|
182
|
-
}, []);
|
|
183
|
-
if (children.length) {
|
|
184
|
-
node.children = children;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
const children = Object.keys(props)
|
|
189
|
-
.sort()
|
|
190
|
-
.map((key) => makeNode(object[key], key, ver))
|
|
191
|
-
.filter(Boolean);
|
|
192
|
-
if (children.length) {
|
|
193
|
-
node.children = children;
|
|
194
|
-
}
|
|
195
|
-
else if (putRange.length) {
|
|
196
|
-
// Do nothing; this is to avoid falling into the later branches
|
|
197
|
-
}
|
|
198
|
-
else if (isGraph) {
|
|
199
|
-
// Some inconsistency here.
|
|
200
|
-
// { foo: {} } === undefined (we know nothing)
|
|
201
|
-
// but { $key: 'foo' }] === { foo: null } (we know foo doesn't exist)
|
|
202
|
-
// This is because when using the $key notation, we can't use null.
|
|
203
|
-
if (!(isDef($key) || isDef($put)))
|
|
204
|
-
return;
|
|
205
|
-
if (node.key && !node.end)
|
|
206
|
-
node.end = node.key;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
if (!isDef($key))
|
|
210
|
-
return;
|
|
211
|
-
node.value = 1;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
if (isGraph && putRange.length && !isDef(node.path) && !isDef(node.value)) {
|
|
215
|
-
const putRangeClone = putRange.map(({ key, end }) => ({
|
|
216
|
-
key,
|
|
217
|
-
end,
|
|
218
|
-
version: 0,
|
|
219
|
-
}));
|
|
220
|
-
node.children = merge(putRangeClone, node.children || []);
|
|
221
|
-
}
|
|
222
|
-
if (
|
|
223
|
-
// (key === ROOT_KEY || isDef(node.key)) &&
|
|
224
|
-
node.children?.length ||
|
|
225
|
-
isDef(node.end) ||
|
|
226
|
-
isDef(node.value) ||
|
|
227
|
-
isDef(node.path)) {
|
|
228
|
-
return node;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
if (value?.$key)
|
|
232
|
-
value = [value];
|
|
233
|
-
const result = makeNode(value, ROOT_KEY, version)?.children || [];
|
|
234
|
-
while (links.length) {
|
|
235
|
-
combine(result, [links.pop()]);
|
|
236
|
-
}
|
|
237
|
-
// console.log('Encoded', isGraph, value);
|
|
238
|
-
// console.log('Result', result);
|
|
239
|
-
return result;
|
|
240
|
-
}
|
|
241
|
-
export function encodeGraph(obj, version = Date.now()) {
|
|
242
|
-
const encoded = encode(obj, { version, isGraph: true });
|
|
243
|
-
const versioned = setVersion(encoded, version, true);
|
|
244
|
-
return versioned;
|
|
245
|
-
}
|
|
246
|
-
export function encodeQuery(obj, version = 0) {
|
|
247
|
-
return encode(obj, { version, isGraph: false });
|
|
248
|
-
}
|
package/coding/id.js
DELETED
package/coding/index.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { decode as decodeArgs, encode as encodeArgs, splitArgs, } from './args.js';
|
|
2
|
-
export * from './decodeTree.js';
|
|
3
|
-
export { default as decorate } from './decorate.js';
|
|
4
|
-
export * from './encodeTree.js';
|
|
5
|
-
export { default as makeId } from './id.js';
|
|
6
|
-
export * from './pack.js';
|
|
7
|
-
export { decode as decodePath, encode as encodePath, splitRef, } from './path.js';
|
|
8
|
-
export { decode as decodeValue, encode as encodeValue } from './struct.js';
|
package/coding/number.d.ts
DELETED
package/coding/number.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Order-preserving encoding of 64-bit floating point numbers.
|
|
3
|
-
*/
|
|
4
|
-
function TwosComplement(view) {
|
|
5
|
-
const lo = -view.getUint32(4) >>> 0;
|
|
6
|
-
const carry = lo ? 0 : -1;
|
|
7
|
-
const hi = (~view.getUint32(0) + carry) >>> 0;
|
|
8
|
-
view.setUint32(0, hi);
|
|
9
|
-
view.setUint32(4, lo);
|
|
10
|
-
}
|
|
11
|
-
export function encode(number) {
|
|
12
|
-
const buffer = new ArrayBuffer(8);
|
|
13
|
-
const view = new DataView(buffer);
|
|
14
|
-
view.setFloat64(0, number);
|
|
15
|
-
/* if first bit is set */
|
|
16
|
-
if (number < 0) {
|
|
17
|
-
TwosComplement(view);
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
/* non-negative number, just set the leading bit. */
|
|
21
|
-
view.setUint8(0, view.getUint8(0) | 0x80);
|
|
22
|
-
}
|
|
23
|
-
return new Uint8Array(buffer);
|
|
24
|
-
}
|
|
25
|
-
export function decode(u8Arr) {
|
|
26
|
-
const copy = new Uint8Array(8);
|
|
27
|
-
copy.set(u8Arr, 0);
|
|
28
|
-
const { buffer, byteOffset, byteLength } = copy;
|
|
29
|
-
const view = new DataView(buffer, byteOffset, byteLength);
|
|
30
|
-
const high = view.getUint8(0);
|
|
31
|
-
if (high & 0x80) {
|
|
32
|
-
// originally a non-negative number. Just set the sign bit back to 0.
|
|
33
|
-
view.setUint8(0, high & 0x7f);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
TwosComplement(view);
|
|
37
|
-
}
|
|
38
|
-
return view.getFloat64(0);
|
|
39
|
-
}
|
package/coding/pack.d.ts
DELETED
package/coding/pack.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { decode, encode } from "./base64.js";
|
|
2
|
-
import { decodeValue, encodeValue } from "./index.js";
|
|
3
|
-
import { STR } from "./struct.js";
|
|
4
|
-
const props = [
|
|
5
|
-
'end',
|
|
6
|
-
'version',
|
|
7
|
-
'limit',
|
|
8
|
-
'value',
|
|
9
|
-
'path',
|
|
10
|
-
'prefix',
|
|
11
|
-
'children',
|
|
12
|
-
];
|
|
13
|
-
function serializeKey(key) {
|
|
14
|
-
if (key[0] === STR) {
|
|
15
|
-
const last = key[key.length - 1];
|
|
16
|
-
if (last !== 0 && last !== 0xff) {
|
|
17
|
-
return decodeValue(key);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return `\0${encode(key)}`;
|
|
21
|
-
}
|
|
22
|
-
function deserializeKey(key) {
|
|
23
|
-
if (key[0] === '\0')
|
|
24
|
-
return decode(key.slice(1));
|
|
25
|
-
return encodeValue(key);
|
|
26
|
-
}
|
|
27
|
-
export function pack(children, parentVersion) {
|
|
28
|
-
if (!Array.isArray(children))
|
|
29
|
-
return children;
|
|
30
|
-
const array = children.map((node) => props.reduce((array, prop, i) => {
|
|
31
|
-
if (!(prop in node))
|
|
32
|
-
return array;
|
|
33
|
-
let value = node[prop];
|
|
34
|
-
if (prop === 'version' && value === parentVersion)
|
|
35
|
-
return array;
|
|
36
|
-
if (prop === 'children')
|
|
37
|
-
value = pack(value, node.version);
|
|
38
|
-
if (prop === 'end')
|
|
39
|
-
value = serializeKey(value);
|
|
40
|
-
if (prop === 'path')
|
|
41
|
-
value = value.map(serializeKey);
|
|
42
|
-
array[1] |= 1 << i;
|
|
43
|
-
array.push(value);
|
|
44
|
-
return array;
|
|
45
|
-
}, [serializeKey(node.key), 0]));
|
|
46
|
-
return array;
|
|
47
|
-
}
|
|
48
|
-
export function unpack(children, parentVersion) {
|
|
49
|
-
if (!Array.isArray(children))
|
|
50
|
-
return children;
|
|
51
|
-
const node = children.map(([key, type, ...values]) => props.reduce((node, prop, i) => {
|
|
52
|
-
if (!(type & (1 << i)))
|
|
53
|
-
return node;
|
|
54
|
-
let value = values.shift();
|
|
55
|
-
if (prop === 'children')
|
|
56
|
-
value = unpack(value, node.version);
|
|
57
|
-
if (prop === 'end')
|
|
58
|
-
value = deserializeKey(value);
|
|
59
|
-
if (prop === 'path')
|
|
60
|
-
value = value.map(deserializeKey);
|
|
61
|
-
node[prop] = value;
|
|
62
|
-
return node;
|
|
63
|
-
}, { key: deserializeKey(key), version: parentVersion }));
|
|
64
|
-
return node;
|
|
65
|
-
}
|
|
66
|
-
// export function serialize(payload) {
|
|
67
|
-
// return JSON.stringify(pack(payload));
|
|
68
|
-
// }
|
|
69
|
-
// export function deserialize(str) {
|
|
70
|
-
// return unpack(JSON.parse(str));
|
|
71
|
-
// }
|
package/coding/path.d.ts
DELETED
package/coding/path.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { isPlainObject, MIN_KEY } from "../util.js";
|
|
2
|
-
import { decode as decodeArgs, encode as encodeArgs, splitArgs, } from "./args.js";
|
|
3
|
-
const PATH_SEPARATOR = '.';
|
|
4
|
-
export function encode(path) {
|
|
5
|
-
if (typeof path === 'string') {
|
|
6
|
-
if (!path.length || path === PATH_SEPARATOR)
|
|
7
|
-
return [];
|
|
8
|
-
path = path.split(PATH_SEPARATOR);
|
|
9
|
-
}
|
|
10
|
-
if (!Array.isArray(path)) {
|
|
11
|
-
throw Error(`encodePath.invalid:${JSON.stringify(path)}`);
|
|
12
|
-
}
|
|
13
|
-
function encodeSegment(seg) {
|
|
14
|
-
if (ArrayBuffer.isView(seg))
|
|
15
|
-
return seg;
|
|
16
|
-
const node = encodeArgs(seg);
|
|
17
|
-
if (node.end)
|
|
18
|
-
return node;
|
|
19
|
-
return node.key;
|
|
20
|
-
}
|
|
21
|
-
if (isPlainObject(path[path.length - 1])) {
|
|
22
|
-
const [page, filter] = splitArgs(path[path.length - 1]);
|
|
23
|
-
if (page)
|
|
24
|
-
path = path.slice(0, -1).concat([filter || MIN_KEY]);
|
|
25
|
-
}
|
|
26
|
-
return path.map(encodeSegment);
|
|
27
|
-
}
|
|
28
|
-
export function decode(path) {
|
|
29
|
-
if (!Array.isArray(path)) {
|
|
30
|
-
throw Error(`decodePath.invalid:${JSON.stringify(path)}`);
|
|
31
|
-
}
|
|
32
|
-
return path.map((key) => decodeArgs({ key }));
|
|
33
|
-
}
|
|
34
|
-
export function splitRef($ref) {
|
|
35
|
-
if (!Array.isArray($ref))
|
|
36
|
-
return [];
|
|
37
|
-
const tail = $ref[$ref.length - 1];
|
|
38
|
-
if (!isPlainObject(tail))
|
|
39
|
-
return [];
|
|
40
|
-
return splitArgs(tail);
|
|
41
|
-
}
|
package/coding/string.d.ts
DELETED
package/coding/string.js
DELETED
package/coding/struct.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare const END = 0;
|
|
2
|
-
export declare const NULL = 1;
|
|
3
|
-
export declare const FALSE = 2;
|
|
4
|
-
export declare const TRUE = 3;
|
|
5
|
-
export declare const NUM = 4;
|
|
6
|
-
export declare const STR = 5;
|
|
7
|
-
export declare const ARR = 6;
|
|
8
|
-
export declare const OBJ = 7;
|
|
9
|
-
export declare const EOK = 127;
|
|
10
|
-
export declare function encode(value: any): Uint8Array<any>;
|
|
11
|
-
export declare function decode(buffer: any): any;
|