@graffy/link 0.15.14 → 0.15.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.cjs +189 -58
  2. package/index.mjs +186 -59
  3. package/package.json +3 -2
package/index.cjs CHANGED
@@ -19,63 +19,151 @@ var __spreadValues = (a, b) => {
19
19
  };
20
20
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
21
  var common = require("@graffy/common");
22
+ var debug = require("debug");
23
+ function _interopDefaultLegacy(e) {
24
+ return e && typeof e === "object" && "default" in e ? e : { "default": e };
25
+ }
26
+ var debug__default = /* @__PURE__ */ _interopDefaultLegacy(debug);
22
27
  function linkGraph(rootGraph, defs) {
23
- for (const { path, def } of defs)
24
- linkGraphDef(rootGraph, path, def);
28
+ let version = rootGraph[0].version;
29
+ for (const { path, def } of defs) {
30
+ const braid = def.map(getKeyValues);
31
+ const strands = unbraid(braid);
32
+ const pathReqs = path.filter((key) => key[0] === "$").reduce((acc, key) => {
33
+ acc[key.slice(1)] = true;
34
+ return acc;
35
+ }, {});
36
+ outer:
37
+ for (const { value, vars, reqs } of strands) {
38
+ for (const req in reqs)
39
+ if (!(req in vars))
40
+ continue outer;
41
+ for (const req in pathReqs)
42
+ if (!(req in vars))
43
+ continue outer;
44
+ const realPath = makeRef(path, vars);
45
+ const realRef = makeRef(value, vars);
46
+ const node = { key: realPath.pop(), path: common.encodePath(realRef), version };
47
+ const [range] = common.splitRef(realRef);
48
+ if (range)
49
+ node.prefix = true;
50
+ let target = rootGraph;
51
+ do {
52
+ const key = realPath.shift();
53
+ const nextTarget = target[common.findFirst(target, key)];
54
+ if (!nextTarget || nextTarget.key !== key || nextTarget.end) {
55
+ realPath.unshift(key);
56
+ break;
57
+ }
58
+ target = nextTarget.path ? common.unwrap(rootGraph, nextTarget.path) : nextTarget.children;
59
+ } while (target && realPath.length);
60
+ if (!target)
61
+ return;
62
+ common.merge(target, realPath.length ? common.wrap([node], realPath, version) : [node]);
63
+ }
64
+ }
25
65
  return rootGraph;
26
- function linkGraphDef(graph, path, def, version = 0) {
66
+ function getKeyValues(key) {
67
+ if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
68
+ return lookupValues(rootGraph, key.slice(2).split("."));
69
+ }
70
+ if (Array.isArray(key)) {
71
+ return unbraid(key.map(getKeyValues));
72
+ }
73
+ if (typeof key === "object" && key) {
74
+ const values = unbraid(Object.values(key).map(getKeyValues));
75
+ const keys = Object.keys(key);
76
+ return values.map(({ value, vars, reqs }) => ({
77
+ value: value.reduce((acc, val, i) => {
78
+ acc[keys[i]] = val;
79
+ return acc;
80
+ }, {}),
81
+ vars,
82
+ reqs
83
+ }));
84
+ }
85
+ if (typeof key === "string" && key[0] === "$") {
86
+ return [{ value: key, vars: {}, reqs: { [key.slice(1)]: true } }];
87
+ }
88
+ return [{ value: key, vars: {}, reqs: {} }];
89
+ }
90
+ function lookupValues(graph, path, vars = {}) {
27
91
  const [key, ...rest] = path;
28
- if (rest.length === 0) {
29
- const ref = makeRef(def);
30
- const [range] = common.splitRef(def);
31
- const node2 = { key, path: common.encodePath(ref), version };
32
- if (range)
33
- node2.prefix = true;
34
- common.merge(graph, [node2]);
35
- return;
92
+ if (key[0] === "$") {
93
+ return graph.flatMap((node2) => {
94
+ if (node2.end)
95
+ return [];
96
+ const newVars = __spreadProps(__spreadValues({}, vars), { [key.slice(1)]: node2.key });
97
+ return recurse(node2, rest, newVars);
98
+ });
36
99
  }
37
100
  let node = graph[common.findFirst(graph, key)];
38
- if (!node || node.key !== key || node.end) {
39
- node = { key, version, value: 1 };
40
- common.merge(graph, [node]);
41
- delete node.value;
42
- node.children = [];
43
- }
44
- if (!node.children) {
45
- throw Error("linkGraph.unexpected_leaf " + key);
101
+ if (!node || node.key !== key || node.end)
102
+ return [];
103
+ return recurse(node, rest, vars);
104
+ }
105
+ function recurse(node, path, vars) {
106
+ if (!path.length)
107
+ return [{ value: node.value, vars, reqs: {} }];
108
+ if (node.children)
109
+ return lookupValues(node.children, path, vars);
110
+ if (node.path) {
111
+ const linked = common.unwrap(rootGraph, node.path);
112
+ if (Array.isArray(linked))
113
+ return lookupValues(linked, path, vars);
46
114
  }
47
- linkGraphDef(node.children, rest, def, node.version);
115
+ throw Error("link.no_children " + JSON.stringify(node));
48
116
  }
49
- function makeRef(def) {
50
- function replacePlaceholders(key) {
51
- if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
52
- return common.unwrap(rootGraph, key.slice(2).split("."));
53
- }
54
- if (Array.isArray(key)) {
55
- return key.map(replacePlaceholders);
56
- }
57
- if (typeof key === "object" && key) {
58
- const result = {};
59
- for (const prop in key)
60
- result[prop] = replacePlaceholders(key[prop]);
61
- return result;
62
- }
117
+ }
118
+ function unbraid(braid) {
119
+ const [options, ...rest] = braid;
120
+ if (!rest.length) {
121
+ return options.map((option) => ({
122
+ value: [option.value],
123
+ vars: option.vars,
124
+ reqs: option.reqs
125
+ }));
126
+ }
127
+ const strands = unbraid(rest);
128
+ return options.flatMap((option) => strands.filter((strand) => isCompatible(option.vars, strand.vars)).map((strand) => ({
129
+ value: [option.value, ...strand.value],
130
+ vars: __spreadValues(__spreadValues({}, option.vars), strand.vars),
131
+ reqs: __spreadValues(__spreadValues({}, option.reqs), strand.reqs)
132
+ })));
133
+ }
134
+ function isCompatible(oVars, sVars) {
135
+ for (const name in oVars) {
136
+ if (name in sVars && oVars[name] !== sVars[name])
137
+ return false;
138
+ }
139
+ return true;
140
+ }
141
+ function makeRef(def, vars) {
142
+ function getValue(key) {
143
+ if (typeof key !== "string")
63
144
  return key;
145
+ return key[0] === "$" ? vars[key.slice(1)] : key;
146
+ }
147
+ function replacePlaceholders(key) {
148
+ if (Array.isArray(key)) {
149
+ return key.map(replacePlaceholders);
150
+ }
151
+ if (typeof key === "object" && key) {
152
+ const result = {};
153
+ for (const prop in key)
154
+ result[prop] = replacePlaceholders(key[prop]);
155
+ return result;
64
156
  }
65
- const ref = def.map(replacePlaceholders);
66
- return ref;
157
+ return getValue(key);
67
158
  }
159
+ const ref = def.map(replacePlaceholders);
160
+ return ref;
68
161
  }
69
162
  function prepQueryLinks(rootQuery, defs) {
70
163
  return defs.flatMap(({ path, def }) => prepQueryDef(rootQuery, path, def));
71
164
  function prepQueryDef(query, path, def, vars = {}, version = 0) {
72
165
  var _a;
73
- const [key, ...rest] = path;
74
- if (rest.length === 0) {
75
- const ix = common.findFirst(query, key);
76
- if (((_a = query[ix]) == null ? void 0 : _a.key) !== key)
77
- return [];
78
- const [{ children: subQuery }] = query.splice(ix, 1);
166
+ function addDefQuery(subQuery) {
79
167
  common.add(rootQuery, getDefQuery(def, vars, version));
80
168
  const [range, filter] = common.splitRef(def);
81
169
  if (range && subQuery.length) {
@@ -95,23 +183,54 @@ function prepQueryLinks(rootQuery, defs) {
95
183
  def: def2
96
184
  }));
97
185
  }
186
+ function makePager(pager) {
187
+ Object.defineProperty(pager, "toString", { value: () => key });
188
+ return pager;
189
+ }
190
+ const [key, ...rest] = path;
191
+ if (rest.length === 0) {
192
+ if (key[0] === "$") {
193
+ return query.splice(0).flatMap((node) => {
194
+ vars[key.slice(1)] = makePager(common.decodeArgs(node));
195
+ return addDefQuery(node.children);
196
+ });
197
+ } else {
198
+ const ix = common.findFirst(query, key);
199
+ if (((_a = query[ix]) == null ? void 0 : _a.key) !== key)
200
+ return [];
201
+ const [{ children: subQuery }] = query.splice(ix, 1);
202
+ return addDefQuery(subQuery);
203
+ }
204
+ }
98
205
  let used = [];
99
- if (key[0] !== "$") {
100
- const node = query[common.findFirst(query, key)];
101
- if (!node || node.key !== key || !node.children)
102
- return [];
103
- used = prepQueryDef(node.children, rest, def, vars, node.version);
104
- used = prefixKey(used, node.key);
105
- } else {
206
+ if (key[0] === "$") {
106
207
  for (const node of query) {
107
208
  if (!common.isBranch(node))
108
209
  continue;
109
- let usedHere = prepQueryDef(node.children, rest, def, __spreadProps(__spreadValues({}, vars), {
110
- [key.slice(1)]: node.key
111
- }), node.version);
210
+ let usedHere;
211
+ if (node.prefix) {
212
+ usedHere = node.children.flatMap((subNode) => {
213
+ const pager = makePager(common.decodeArgs(subNode));
214
+ return prefixKey(prepQueryDef(subNode.children, rest, def, __spreadProps(__spreadValues({}, vars), { [key.slice(1)]: [node.key, pager] }), node.version), key);
215
+ });
216
+ } else {
217
+ usedHere = prepQueryDef(node.children, rest, def, __spreadProps(__spreadValues({}, vars), { [key.slice(1)]: node.key }), node.version);
218
+ }
112
219
  usedHere = prefixKey(usedHere, node.key);
113
220
  used = used.concat(usedHere);
114
221
  }
222
+ } else {
223
+ const node = query[common.findFirst(query, key)];
224
+ if (!node || node.key !== key || !node.children)
225
+ return [];
226
+ used = prepQueryDef(node.children, rest, def, vars, node.version);
227
+ used = prefixKey(used, node.key);
228
+ }
229
+ for (let i = 0; i < query.length; i++) {
230
+ if (query[i].children && query[i].children.length === 0) {
231
+ query.splice(i, 1);
232
+ i--;
233
+ }
115
234
  }
116
235
  return used;
117
236
  }
@@ -121,7 +240,7 @@ function getDefQuery(def, vars, version) {
121
240
  return key[0] === "$" ? vars[key.slice(1)] : key;
122
241
  }
123
242
  function getPath(template) {
124
- return template.split(".").map(getValue);
243
+ return template.split(".").flatMap(getValue);
125
244
  }
126
245
  const defQuery = [];
127
246
  function addDefQueries(key) {
@@ -141,14 +260,16 @@ function getDefQuery(def, vars, version) {
141
260
  }
142
261
  function prepareDef(def, vars) {
143
262
  function getValue(key) {
263
+ if (typeof key !== "string")
264
+ return key;
144
265
  return key[0] === "$" ? vars[key.slice(1)] : key;
145
266
  }
146
267
  function replacePlaceholders(key) {
147
268
  if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
148
- return "$$" + key.slice(2).split(".").map(getValue).join(".");
269
+ return "$$" + key.slice(2).split(".").flatMap(getValue).join(".");
149
270
  }
150
271
  if (Array.isArray(key)) {
151
- return key.map(replacePlaceholders);
272
+ return key.flatMap(replacePlaceholders);
152
273
  }
153
274
  if (typeof key === "object" && key) {
154
275
  const result = {};
@@ -158,8 +279,10 @@ function prepareDef(def, vars) {
158
279
  }
159
280
  return getValue(key);
160
281
  }
161
- return def.map(replacePlaceholders);
282
+ const ref = def.flatMap(replacePlaceholders);
283
+ return ref;
162
284
  }
285
+ const log = debug__default["default"]("graffy:link");
163
286
  var index = (defs) => (store) => {
164
287
  const prefix = store.path;
165
288
  const defEntries = Object.entries(defs).map(([prop, def]) => ({
@@ -169,10 +292,18 @@ var index = (defs) => (store) => {
169
292
  store.on("read", async (query, options, next) => {
170
293
  const unwrappedQuery = clone(common.unwrap(query, prefix));
171
294
  const usedDefs = prepQueryLinks(unwrappedQuery, defEntries);
295
+ if (!usedDefs.length)
296
+ return next(query, options);
172
297
  const result = await next(common.wrap(unwrappedQuery, prefix), options);
298
+ const version = result[0].version;
173
299
  const unwrappedResult = common.unwrap(result, prefix);
174
- linkGraph(unwrappedResult, usedDefs);
175
- return result;
300
+ common.add(unwrappedQuery, common.unwrap(query, prefix));
301
+ log("finalizing", prefix, unwrappedQuery);
302
+ const finalizedResult = common.finalize(unwrappedResult, unwrappedQuery, version);
303
+ log("beforeAddingLinks", prefix, finalizedResult);
304
+ linkGraph(finalizedResult, usedDefs);
305
+ log("afterAddingLinks", prefix, finalizedResult);
306
+ return common.wrap(finalizedResult, prefix, version);
176
307
  });
177
308
  };
178
309
  function clone(tree) {
package/index.mjs CHANGED
@@ -17,64 +17,148 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- import { splitRef, encodePath, merge, findFirst, unwrap, add, decodeArgs, isBranch, wrapValue, wrap } from "@graffy/common";
20
+ import { encodePath, splitRef, findFirst, unwrap, merge, wrap, decodeArgs, isBranch, add, wrapValue, finalize } from "@graffy/common";
21
+ import debug from "debug";
21
22
  function linkGraph(rootGraph, defs) {
22
- for (const { path, def } of defs)
23
- linkGraphDef(rootGraph, path, def);
23
+ let version = rootGraph[0].version;
24
+ for (const { path, def } of defs) {
25
+ const braid = def.map(getKeyValues);
26
+ const strands = unbraid(braid);
27
+ const pathReqs = path.filter((key) => key[0] === "$").reduce((acc, key) => {
28
+ acc[key.slice(1)] = true;
29
+ return acc;
30
+ }, {});
31
+ outer:
32
+ for (const { value, vars, reqs } of strands) {
33
+ for (const req in reqs)
34
+ if (!(req in vars))
35
+ continue outer;
36
+ for (const req in pathReqs)
37
+ if (!(req in vars))
38
+ continue outer;
39
+ const realPath = makeRef(path, vars);
40
+ const realRef = makeRef(value, vars);
41
+ const node = { key: realPath.pop(), path: encodePath(realRef), version };
42
+ const [range] = splitRef(realRef);
43
+ if (range)
44
+ node.prefix = true;
45
+ let target = rootGraph;
46
+ do {
47
+ const key = realPath.shift();
48
+ const nextTarget = target[findFirst(target, key)];
49
+ if (!nextTarget || nextTarget.key !== key || nextTarget.end) {
50
+ realPath.unshift(key);
51
+ break;
52
+ }
53
+ target = nextTarget.path ? unwrap(rootGraph, nextTarget.path) : nextTarget.children;
54
+ } while (target && realPath.length);
55
+ if (!target)
56
+ return;
57
+ merge(target, realPath.length ? wrap([node], realPath, version) : [node]);
58
+ }
59
+ }
24
60
  return rootGraph;
25
- function linkGraphDef(graph, path, def, version = 0) {
61
+ function getKeyValues(key) {
62
+ if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
63
+ return lookupValues(rootGraph, key.slice(2).split("."));
64
+ }
65
+ if (Array.isArray(key)) {
66
+ return unbraid(key.map(getKeyValues));
67
+ }
68
+ if (typeof key === "object" && key) {
69
+ const values = unbraid(Object.values(key).map(getKeyValues));
70
+ const keys = Object.keys(key);
71
+ return values.map(({ value, vars, reqs }) => ({
72
+ value: value.reduce((acc, val, i) => {
73
+ acc[keys[i]] = val;
74
+ return acc;
75
+ }, {}),
76
+ vars,
77
+ reqs
78
+ }));
79
+ }
80
+ if (typeof key === "string" && key[0] === "$") {
81
+ return [{ value: key, vars: {}, reqs: { [key.slice(1)]: true } }];
82
+ }
83
+ return [{ value: key, vars: {}, reqs: {} }];
84
+ }
85
+ function lookupValues(graph, path, vars = {}) {
26
86
  const [key, ...rest] = path;
27
- if (rest.length === 0) {
28
- const ref = makeRef(def);
29
- const [range] = splitRef(def);
30
- const node2 = { key, path: encodePath(ref), version };
31
- if (range)
32
- node2.prefix = true;
33
- merge(graph, [node2]);
34
- return;
87
+ if (key[0] === "$") {
88
+ return graph.flatMap((node2) => {
89
+ if (node2.end)
90
+ return [];
91
+ const newVars = __spreadProps(__spreadValues({}, vars), { [key.slice(1)]: node2.key });
92
+ return recurse(node2, rest, newVars);
93
+ });
35
94
  }
36
95
  let node = graph[findFirst(graph, key)];
37
- if (!node || node.key !== key || node.end) {
38
- node = { key, version, value: 1 };
39
- merge(graph, [node]);
40
- delete node.value;
41
- node.children = [];
42
- }
43
- if (!node.children) {
44
- throw Error("linkGraph.unexpected_leaf " + key);
96
+ if (!node || node.key !== key || node.end)
97
+ return [];
98
+ return recurse(node, rest, vars);
99
+ }
100
+ function recurse(node, path, vars) {
101
+ if (!path.length)
102
+ return [{ value: node.value, vars, reqs: {} }];
103
+ if (node.children)
104
+ return lookupValues(node.children, path, vars);
105
+ if (node.path) {
106
+ const linked = unwrap(rootGraph, node.path);
107
+ if (Array.isArray(linked))
108
+ return lookupValues(linked, path, vars);
45
109
  }
46
- linkGraphDef(node.children, rest, def, node.version);
110
+ throw Error("link.no_children " + JSON.stringify(node));
47
111
  }
48
- function makeRef(def) {
49
- function replacePlaceholders(key) {
50
- if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
51
- return unwrap(rootGraph, key.slice(2).split("."));
52
- }
53
- if (Array.isArray(key)) {
54
- return key.map(replacePlaceholders);
55
- }
56
- if (typeof key === "object" && key) {
57
- const result = {};
58
- for (const prop in key)
59
- result[prop] = replacePlaceholders(key[prop]);
60
- return result;
61
- }
112
+ }
113
+ function unbraid(braid) {
114
+ const [options, ...rest] = braid;
115
+ if (!rest.length) {
116
+ return options.map((option) => ({
117
+ value: [option.value],
118
+ vars: option.vars,
119
+ reqs: option.reqs
120
+ }));
121
+ }
122
+ const strands = unbraid(rest);
123
+ return options.flatMap((option) => strands.filter((strand) => isCompatible(option.vars, strand.vars)).map((strand) => ({
124
+ value: [option.value, ...strand.value],
125
+ vars: __spreadValues(__spreadValues({}, option.vars), strand.vars),
126
+ reqs: __spreadValues(__spreadValues({}, option.reqs), strand.reqs)
127
+ })));
128
+ }
129
+ function isCompatible(oVars, sVars) {
130
+ for (const name in oVars) {
131
+ if (name in sVars && oVars[name] !== sVars[name])
132
+ return false;
133
+ }
134
+ return true;
135
+ }
136
+ function makeRef(def, vars) {
137
+ function getValue(key) {
138
+ if (typeof key !== "string")
62
139
  return key;
140
+ return key[0] === "$" ? vars[key.slice(1)] : key;
141
+ }
142
+ function replacePlaceholders(key) {
143
+ if (Array.isArray(key)) {
144
+ return key.map(replacePlaceholders);
63
145
  }
64
- const ref = def.map(replacePlaceholders);
65
- return ref;
146
+ if (typeof key === "object" && key) {
147
+ const result = {};
148
+ for (const prop in key)
149
+ result[prop] = replacePlaceholders(key[prop]);
150
+ return result;
151
+ }
152
+ return getValue(key);
66
153
  }
154
+ const ref = def.map(replacePlaceholders);
155
+ return ref;
67
156
  }
68
157
  function prepQueryLinks(rootQuery, defs) {
69
158
  return defs.flatMap(({ path, def }) => prepQueryDef(rootQuery, path, def));
70
159
  function prepQueryDef(query, path, def, vars = {}, version = 0) {
71
160
  var _a;
72
- const [key, ...rest] = path;
73
- if (rest.length === 0) {
74
- const ix = findFirst(query, key);
75
- if (((_a = query[ix]) == null ? void 0 : _a.key) !== key)
76
- return [];
77
- const [{ children: subQuery }] = query.splice(ix, 1);
161
+ function addDefQuery(subQuery) {
78
162
  add(rootQuery, getDefQuery(def, vars, version));
79
163
  const [range, filter] = splitRef(def);
80
164
  if (range && subQuery.length) {
@@ -94,23 +178,54 @@ function prepQueryLinks(rootQuery, defs) {
94
178
  def: def2
95
179
  }));
96
180
  }
181
+ function makePager(pager) {
182
+ Object.defineProperty(pager, "toString", { value: () => key });
183
+ return pager;
184
+ }
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(decodeArgs(node));
190
+ return addDefQuery(node.children);
191
+ });
192
+ } else {
193
+ const ix = 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
+ }
97
200
  let used = [];
98
- if (key[0] !== "$") {
99
- const node = query[findFirst(query, key)];
100
- if (!node || node.key !== key || !node.children)
101
- return [];
102
- used = prepQueryDef(node.children, rest, def, vars, node.version);
103
- used = prefixKey(used, node.key);
104
- } else {
201
+ if (key[0] === "$") {
105
202
  for (const node of query) {
106
203
  if (!isBranch(node))
107
204
  continue;
108
- let usedHere = prepQueryDef(node.children, rest, def, __spreadProps(__spreadValues({}, vars), {
109
- [key.slice(1)]: node.key
110
- }), node.version);
205
+ let usedHere;
206
+ if (node.prefix) {
207
+ usedHere = node.children.flatMap((subNode) => {
208
+ const pager = makePager(decodeArgs(subNode));
209
+ return prefixKey(prepQueryDef(subNode.children, rest, def, __spreadProps(__spreadValues({}, vars), { [key.slice(1)]: [node.key, pager] }), node.version), key);
210
+ });
211
+ } else {
212
+ usedHere = prepQueryDef(node.children, rest, def, __spreadProps(__spreadValues({}, vars), { [key.slice(1)]: node.key }), node.version);
213
+ }
111
214
  usedHere = prefixKey(usedHere, node.key);
112
215
  used = used.concat(usedHere);
113
216
  }
217
+ } else {
218
+ const node = query[findFirst(query, key)];
219
+ if (!node || node.key !== key || !node.children)
220
+ return [];
221
+ used = prepQueryDef(node.children, rest, def, vars, node.version);
222
+ used = prefixKey(used, node.key);
223
+ }
224
+ for (let i = 0; i < query.length; i++) {
225
+ if (query[i].children && query[i].children.length === 0) {
226
+ query.splice(i, 1);
227
+ i--;
228
+ }
114
229
  }
115
230
  return used;
116
231
  }
@@ -120,7 +235,7 @@ function getDefQuery(def, vars, version) {
120
235
  return key[0] === "$" ? vars[key.slice(1)] : key;
121
236
  }
122
237
  function getPath(template) {
123
- return template.split(".").map(getValue);
238
+ return template.split(".").flatMap(getValue);
124
239
  }
125
240
  const defQuery = [];
126
241
  function addDefQueries(key) {
@@ -140,14 +255,16 @@ function getDefQuery(def, vars, version) {
140
255
  }
141
256
  function prepareDef(def, vars) {
142
257
  function getValue(key) {
258
+ if (typeof key !== "string")
259
+ return key;
143
260
  return key[0] === "$" ? vars[key.slice(1)] : key;
144
261
  }
145
262
  function replacePlaceholders(key) {
146
263
  if (typeof key === "string" && key[0] === "$" && key[1] === "$") {
147
- return "$$" + key.slice(2).split(".").map(getValue).join(".");
264
+ return "$$" + key.slice(2).split(".").flatMap(getValue).join(".");
148
265
  }
149
266
  if (Array.isArray(key)) {
150
- return key.map(replacePlaceholders);
267
+ return key.flatMap(replacePlaceholders);
151
268
  }
152
269
  if (typeof key === "object" && key) {
153
270
  const result = {};
@@ -157,8 +274,10 @@ function prepareDef(def, vars) {
157
274
  }
158
275
  return getValue(key);
159
276
  }
160
- return def.map(replacePlaceholders);
277
+ const ref = def.flatMap(replacePlaceholders);
278
+ return ref;
161
279
  }
280
+ const log = debug("graffy:link");
162
281
  var index = (defs) => (store) => {
163
282
  const prefix = store.path;
164
283
  const defEntries = Object.entries(defs).map(([prop, def]) => ({
@@ -168,10 +287,18 @@ var index = (defs) => (store) => {
168
287
  store.on("read", async (query, options, next) => {
169
288
  const unwrappedQuery = clone(unwrap(query, prefix));
170
289
  const usedDefs = prepQueryLinks(unwrappedQuery, defEntries);
290
+ if (!usedDefs.length)
291
+ return next(query, options);
171
292
  const result = await next(wrap(unwrappedQuery, prefix), options);
293
+ const version = result[0].version;
172
294
  const unwrappedResult = unwrap(result, prefix);
173
- linkGraph(unwrappedResult, usedDefs);
174
- return result;
295
+ add(unwrappedQuery, unwrap(query, prefix));
296
+ log("finalizing", prefix, unwrappedQuery);
297
+ const finalizedResult = finalize(unwrappedResult, unwrappedQuery, version);
298
+ log("beforeAddingLinks", prefix, finalizedResult);
299
+ linkGraph(finalizedResult, usedDefs);
300
+ log("afterAddingLinks", prefix, finalizedResult);
301
+ return wrap(finalizedResult, prefix, version);
175
302
  });
176
303
  };
177
304
  function clone(tree) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
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.14",
5
+ "version": "0.15.15",
6
6
  "main": "./index.cjs",
7
7
  "exports": {
8
8
  "import": "./index.mjs",
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "license": "Apache-2.0",
18
18
  "dependencies": {
19
- "@graffy/common": "0.15.14"
19
+ "@graffy/common": "0.15.15",
20
+ "debug": "^4.3.2"
20
21
  }
21
22
  }