@graffy/link 0.15.25-alpha.4 → 0.15.25-alpha.5
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/package.json +3 -8
- package/index.cjs +0 -325
package/package.json
CHANGED
|
@@ -2,13 +2,8 @@
|
|
|
2
2
|
"name": "@graffy/link",
|
|
3
3
|
"description": "Graffy module for constructing links using an intuitive, declarative notation.",
|
|
4
4
|
"author": "aravind (https://github.com/aravindet)",
|
|
5
|
-
"version": "0.15.25-alpha.
|
|
6
|
-
"main": "./index.
|
|
7
|
-
"exports": {
|
|
8
|
-
"import": "./index.mjs",
|
|
9
|
-
"require": "./index.cjs"
|
|
10
|
-
},
|
|
11
|
-
"module": "./index.mjs",
|
|
5
|
+
"version": "0.15.25-alpha.5",
|
|
6
|
+
"main": "./index.mjs",
|
|
12
7
|
"types": "./types/index.d.ts",
|
|
13
8
|
"repository": {
|
|
14
9
|
"type": "git",
|
|
@@ -16,7 +11,7 @@
|
|
|
16
11
|
},
|
|
17
12
|
"license": "Apache-2.0",
|
|
18
13
|
"dependencies": {
|
|
19
|
-
"@graffy/common": "0.15.25-alpha.
|
|
14
|
+
"@graffy/common": "0.15.25-alpha.5",
|
|
20
15
|
"debug": "^4.3.3"
|
|
21
16
|
}
|
|
22
17
|
}
|
package/index.cjs
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
const common = require("@graffy/common");
|
|
3
|
-
const debug = require("debug");
|
|
4
|
-
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
|
|
5
|
-
const debug__default = /* @__PURE__ */ _interopDefaultLegacy(debug);
|
|
6
|
-
function linkGraph(rootGraph, defs) {
|
|
7
|
-
let version = rootGraph[0].version;
|
|
8
|
-
for (const { path, def } of defs) {
|
|
9
|
-
const braid = def.map(getChoices);
|
|
10
|
-
const strands = unbraid(braid);
|
|
11
|
-
for (const { value, vars } of strands) {
|
|
12
|
-
const realPath = makeRef(path, vars);
|
|
13
|
-
const realRef = makeRef(value, vars);
|
|
14
|
-
const node = { key: realPath.pop(), path: common.encodePath(realRef), version };
|
|
15
|
-
const [range] = common.splitRef(realRef);
|
|
16
|
-
if (range)
|
|
17
|
-
node.prefix = true;
|
|
18
|
-
let target = rootGraph;
|
|
19
|
-
do {
|
|
20
|
-
const key = realPath.shift();
|
|
21
|
-
const nextTarget = target[common.findFirst(target, key)];
|
|
22
|
-
if (!nextTarget || nextTarget.key !== key || nextTarget.end) {
|
|
23
|
-
realPath.unshift(key);
|
|
24
|
-
break;
|
|
25
|
-
}
|
|
26
|
-
target = nextTarget.path ? common.unwrap(rootGraph, nextTarget.path) : nextTarget.children;
|
|
27
|
-
} while (target && realPath.length);
|
|
28
|
-
if (!target)
|
|
29
|
-
return;
|
|
30
|
-
common.merge(target, realPath.length ? common.wrap([node], realPath, version) : [node]);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return rootGraph;
|
|
34
|
-
function getChoices(key) {
|
|
35
|
-
if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
|
|
36
|
-
return lookupValues(rootGraph, key.slice(2).split("."));
|
|
37
|
-
}
|
|
38
|
-
if (Array.isArray(key)) {
|
|
39
|
-
if (!key.length)
|
|
40
|
-
return [{ value: [], vars: {} }];
|
|
41
|
-
return unbraid(key.map(getChoices));
|
|
42
|
-
}
|
|
43
|
-
if (typeof key === "object" && key) {
|
|
44
|
-
const [range = {}, filter = {}] = common.splitArgs(key);
|
|
45
|
-
const entries = Object.entries(filter).flat();
|
|
46
|
-
if (!entries.length)
|
|
47
|
-
return [{ value: {}, vars: {} }];
|
|
48
|
-
const strands = unbraid(entries.map(getChoices));
|
|
49
|
-
return strands.map(({ value, vars }) => ({
|
|
50
|
-
value: {
|
|
51
|
-
...range,
|
|
52
|
-
...Object.fromEntries(
|
|
53
|
-
value.reduce((acc, item, i) => {
|
|
54
|
-
if (i % 2) {
|
|
55
|
-
acc[acc.length - 1].push(item);
|
|
56
|
-
} else {
|
|
57
|
-
acc.push([item]);
|
|
58
|
-
}
|
|
59
|
-
return acc;
|
|
60
|
-
}, [])
|
|
61
|
-
)
|
|
62
|
-
},
|
|
63
|
-
vars
|
|
64
|
-
}));
|
|
65
|
-
}
|
|
66
|
-
return [{ value: key, vars: {} }];
|
|
67
|
-
}
|
|
68
|
-
function lookupValues(graph, path, vars = {}) {
|
|
69
|
-
const [key, ...rest] = path;
|
|
70
|
-
if (key[0] === "$") {
|
|
71
|
-
return graph.flatMap((node2) => {
|
|
72
|
-
if (node2.end)
|
|
73
|
-
return [];
|
|
74
|
-
const newVars = { ...vars, [key.slice(1)]: node2.key };
|
|
75
|
-
return recurse(node2, rest, newVars);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
let node = graph[common.findFirst(graph, key)];
|
|
79
|
-
if (!node || node.key !== key || node.end)
|
|
80
|
-
return [];
|
|
81
|
-
return recurse(node, rest, vars);
|
|
82
|
-
}
|
|
83
|
-
function recurse(node, path, vars) {
|
|
84
|
-
if (!path.length)
|
|
85
|
-
return [{ value: node.value, vars }];
|
|
86
|
-
if (node.children)
|
|
87
|
-
return lookupValues(node.children, path, vars);
|
|
88
|
-
if (node.path) {
|
|
89
|
-
const linked = common.unwrap(rootGraph, node.path);
|
|
90
|
-
if (Array.isArray(linked))
|
|
91
|
-
return lookupValues(linked, path, vars);
|
|
92
|
-
}
|
|
93
|
-
throw Error("link.no_children " + JSON.stringify(node));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
function unbraid(braid) {
|
|
97
|
-
if (!braid.length)
|
|
98
|
-
return [];
|
|
99
|
-
const [options, ...rest] = braid;
|
|
100
|
-
if (!rest.length) {
|
|
101
|
-
return options.map((option) => ({
|
|
102
|
-
value: [option.value],
|
|
103
|
-
vars: option.vars
|
|
104
|
-
}));
|
|
105
|
-
}
|
|
106
|
-
const strands = unbraid(rest);
|
|
107
|
-
return options.flatMap(
|
|
108
|
-
(option) => strands.filter((strand) => isCompatible(option.vars, strand.vars)).map((strand) => ({
|
|
109
|
-
value: [option.value, ...strand.value],
|
|
110
|
-
vars: { ...option.vars, ...strand.vars }
|
|
111
|
-
}))
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
function isCompatible(oVars, sVars) {
|
|
115
|
-
for (const name in oVars) {
|
|
116
|
-
if (name in sVars && oVars[name] !== sVars[name])
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
function makeRef(def, vars) {
|
|
122
|
-
function getValue(key) {
|
|
123
|
-
if (typeof key !== "string")
|
|
124
|
-
return key;
|
|
125
|
-
return key[0] === "$" && key.slice(1) in vars ? vars[key.slice(1)] : key;
|
|
126
|
-
}
|
|
127
|
-
function replacePlaceholders(key) {
|
|
128
|
-
if (Array.isArray(key)) {
|
|
129
|
-
return key.map(replacePlaceholders);
|
|
130
|
-
}
|
|
131
|
-
if (typeof key === "object" && key) {
|
|
132
|
-
const result = {};
|
|
133
|
-
for (const prop in key) {
|
|
134
|
-
result[replacePlaceholders(prop)] = replacePlaceholders(key[prop]);
|
|
135
|
-
}
|
|
136
|
-
return result;
|
|
137
|
-
}
|
|
138
|
-
return getValue(key);
|
|
139
|
-
}
|
|
140
|
-
const ref = def.map(replacePlaceholders);
|
|
141
|
-
return ref;
|
|
142
|
-
}
|
|
143
|
-
function prepQueryLinks(rootQuery, defs) {
|
|
144
|
-
return defs.flatMap(({ path, def }) => prepQueryDef(rootQuery, path, def));
|
|
145
|
-
function prepQueryDef(query, path, def, vars = {}, version = 0) {
|
|
146
|
-
var _a;
|
|
147
|
-
function addDefQuery(subQuery) {
|
|
148
|
-
common.add(rootQuery, getDefQuery(def, vars, version));
|
|
149
|
-
const [range, filter] = common.splitRef(def);
|
|
150
|
-
if (range && subQuery.length) {
|
|
151
|
-
return subQuery.map((node) => {
|
|
152
|
-
if (!node.prefix && !node.end) {
|
|
153
|
-
throw Error(
|
|
154
|
-
"link.range_expected: " + path.concat(node.key).join(".")
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
return {
|
|
158
|
-
path: path.concat(node.key),
|
|
159
|
-
def: prepareDef(
|
|
160
|
-
def.slice(0, -1).concat({
|
|
161
|
-
...filter,
|
|
162
|
-
...node.prefix ? common.decodeArgs(node) : {},
|
|
163
|
-
...range
|
|
164
|
-
}),
|
|
165
|
-
vars
|
|
166
|
-
)
|
|
167
|
-
};
|
|
168
|
-
});
|
|
169
|
-
} else {
|
|
170
|
-
return [{ path, def: prepareDef(def, vars) }];
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
function prefixKey(defs2, key2) {
|
|
174
|
-
return defs2.map(({ path: path2, def: def2 }) => ({
|
|
175
|
-
path: [key2, ...path2],
|
|
176
|
-
def: def2
|
|
177
|
-
}));
|
|
178
|
-
}
|
|
179
|
-
function makePager(pager) {
|
|
180
|
-
Object.defineProperty(pager, "toString", { value: () => key });
|
|
181
|
-
return pager;
|
|
182
|
-
}
|
|
183
|
-
if (!Array.isArray(query) || !query.length)
|
|
184
|
-
return [];
|
|
185
|
-
const [key, ...rest] = path;
|
|
186
|
-
if (rest.length === 0) {
|
|
187
|
-
if (key[0] === "$") {
|
|
188
|
-
return query.splice(0).flatMap((node) => {
|
|
189
|
-
vars[key.slice(1)] = makePager(common.decodeArgs(node));
|
|
190
|
-
return addDefQuery(node.children);
|
|
191
|
-
});
|
|
192
|
-
} else {
|
|
193
|
-
const ix = common.findFirst(query, key);
|
|
194
|
-
if (((_a = query[ix]) == null ? void 0 : _a.key) !== key)
|
|
195
|
-
return [];
|
|
196
|
-
const [{ children: subQuery }] = query.splice(ix, 1);
|
|
197
|
-
return addDefQuery(subQuery);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
let used = [];
|
|
201
|
-
if (key[0] === "$") {
|
|
202
|
-
for (const node of query) {
|
|
203
|
-
if (!common.isBranch(node))
|
|
204
|
-
continue;
|
|
205
|
-
let usedHere;
|
|
206
|
-
if (node.prefix) {
|
|
207
|
-
usedHere = node.children.flatMap((subNode) => {
|
|
208
|
-
const pager = makePager(common.decodeArgs(subNode));
|
|
209
|
-
return prefixKey(
|
|
210
|
-
prepQueryDef(
|
|
211
|
-
subNode.children,
|
|
212
|
-
rest,
|
|
213
|
-
def,
|
|
214
|
-
{ ...vars, [key.slice(1)]: [node.key, pager] },
|
|
215
|
-
node.version
|
|
216
|
-
),
|
|
217
|
-
key
|
|
218
|
-
);
|
|
219
|
-
});
|
|
220
|
-
} else {
|
|
221
|
-
usedHere = prepQueryDef(
|
|
222
|
-
node.children,
|
|
223
|
-
rest,
|
|
224
|
-
def,
|
|
225
|
-
{ ...vars, [key.slice(1)]: node.key },
|
|
226
|
-
node.version
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
usedHere = prefixKey(usedHere, node.key);
|
|
230
|
-
used = used.concat(usedHere);
|
|
231
|
-
}
|
|
232
|
-
} else {
|
|
233
|
-
const node = query[common.findFirst(query, key)];
|
|
234
|
-
if (!node || node.key !== key || !node.children)
|
|
235
|
-
return [];
|
|
236
|
-
used = prepQueryDef(node.children, rest, def, vars, node.version);
|
|
237
|
-
used = prefixKey(used, node.key);
|
|
238
|
-
}
|
|
239
|
-
for (let i = 0; i < query.length; i++) {
|
|
240
|
-
if (query[i].children && query[i].children.length === 0) {
|
|
241
|
-
query.splice(i, 1);
|
|
242
|
-
i--;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
return used;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
function getDefQuery(def, vars, version) {
|
|
249
|
-
function getValue(key) {
|
|
250
|
-
return key[0] === "$" ? vars[key.slice(1)] : key;
|
|
251
|
-
}
|
|
252
|
-
function getPath(template) {
|
|
253
|
-
return template.split(".").flatMap(getValue);
|
|
254
|
-
}
|
|
255
|
-
const defQuery = [];
|
|
256
|
-
function addDefQueries(key) {
|
|
257
|
-
if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
|
|
258
|
-
common.add(defQuery, common.wrapValue(1, getPath(key.slice(2)), version));
|
|
259
|
-
}
|
|
260
|
-
if (Array.isArray(key)) {
|
|
261
|
-
key.map(addDefQueries);
|
|
262
|
-
}
|
|
263
|
-
if (typeof key === "object" && key) {
|
|
264
|
-
for (const prop in key) {
|
|
265
|
-
addDefQueries(prop);
|
|
266
|
-
addDefQueries(key[prop]);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
def.map(addDefQueries);
|
|
271
|
-
return defQuery;
|
|
272
|
-
}
|
|
273
|
-
function prepareDef(def, vars) {
|
|
274
|
-
function getValue(key) {
|
|
275
|
-
if (typeof key !== "string")
|
|
276
|
-
return key;
|
|
277
|
-
return key[0] === "$" && key.slice(1) in vars ? vars[key.slice(1)] : key;
|
|
278
|
-
}
|
|
279
|
-
function replacePlaceholders(key) {
|
|
280
|
-
if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
|
|
281
|
-
return "$$" + key.slice(2).split(".").flatMap(getValue).join(".");
|
|
282
|
-
}
|
|
283
|
-
if (Array.isArray(key)) {
|
|
284
|
-
return key.map(replacePlaceholders);
|
|
285
|
-
}
|
|
286
|
-
if (typeof key === "object" && key) {
|
|
287
|
-
const result = {};
|
|
288
|
-
for (const prop in key) {
|
|
289
|
-
result[replacePlaceholders(prop)] = replacePlaceholders(key[prop]);
|
|
290
|
-
}
|
|
291
|
-
return result;
|
|
292
|
-
}
|
|
293
|
-
return getValue(key);
|
|
294
|
-
}
|
|
295
|
-
const ref = def.map(replacePlaceholders);
|
|
296
|
-
return ref;
|
|
297
|
-
}
|
|
298
|
-
const log = debug__default.default("graffy:link");
|
|
299
|
-
const index = (defs) => (store) => {
|
|
300
|
-
const prefix = store.path;
|
|
301
|
-
const defEntries = Object.entries(defs).map(([prop, def]) => ({
|
|
302
|
-
path: prop.split("."),
|
|
303
|
-
def
|
|
304
|
-
}));
|
|
305
|
-
store.on("read", async (query, options, next) => {
|
|
306
|
-
const unwrappedQuery = clone(common.unwrap(query, prefix));
|
|
307
|
-
const usedDefs = prepQueryLinks(unwrappedQuery, defEntries);
|
|
308
|
-
if (!usedDefs.length)
|
|
309
|
-
return next(query, options);
|
|
310
|
-
const result = await next(common.wrap(unwrappedQuery, prefix), options);
|
|
311
|
-
const version = result[0].version;
|
|
312
|
-
const unwrappedResult = common.unwrap(result, prefix);
|
|
313
|
-
common.add(unwrappedQuery, common.unwrap(query, prefix));
|
|
314
|
-
log("finalizing", prefix, unwrappedQuery);
|
|
315
|
-
const finalizedResult = common.finalize(unwrappedResult, unwrappedQuery, version);
|
|
316
|
-
log("beforeAddingLinks", prefix, finalizedResult);
|
|
317
|
-
linkGraph(finalizedResult, usedDefs);
|
|
318
|
-
log("afterAddingLinks", prefix, finalizedResult);
|
|
319
|
-
return common.wrap(finalizedResult, prefix, version);
|
|
320
|
-
});
|
|
321
|
-
};
|
|
322
|
-
function clone(tree) {
|
|
323
|
-
return JSON.parse(JSON.stringify(tree));
|
|
324
|
-
}
|
|
325
|
-
module.exports = index;
|