nesoi 3.4.0 → 3.4.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.
Files changed (33) hide show
  1. package/lib/compiler/elements/bucket.element.js +3 -3
  2. package/lib/compiler/typescript/bridge/extract.js +1 -1
  3. package/lib/compiler/typescript/bridge/organize.js +3 -3
  4. package/lib/elements/entities/bucket/adapters/memory.nql.js +12 -18
  5. package/lib/elements/entities/bucket/bucket.d.ts +6 -2
  6. package/lib/elements/entities/bucket/bucket.js +4 -4
  7. package/lib/elements/entities/bucket/graph/bucket_graph.js +13 -3
  8. package/lib/elements/entities/bucket/model/bucket_model.convert.js +9 -17
  9. package/lib/elements/entities/bucket/model/bucket_model.d.ts +6 -1
  10. package/lib/elements/entities/bucket/model/bucket_model.js +182 -33
  11. package/lib/elements/entities/bucket/model/bucket_model.schema.d.ts +1 -1
  12. package/lib/elements/entities/bucket/model/bucket_model.schema.js +2 -2
  13. package/lib/elements/entities/bucket/query/nql.schema.d.ts +1 -0
  14. package/lib/elements/entities/bucket/query/nql_compiler.js +5 -4
  15. package/lib/elements/entities/bucket/query/nql_engine.js +0 -2
  16. package/lib/elements/entities/bucket/view/bucket_view.d.ts +5 -4
  17. package/lib/elements/entities/bucket/view/bucket_view.js +300 -188
  18. package/lib/elements/entities/bucket/view/bucket_view.schema.d.ts +5 -3
  19. package/lib/elements/entities/bucket/view/bucket_view.schema.js +3 -1
  20. package/lib/elements/entities/bucket/view/bucket_view_field.builder.d.ts +16 -5
  21. package/lib/elements/entities/bucket/view/bucket_view_field.builder.js +86 -24
  22. package/lib/engine/data/error.d.ts +12 -0
  23. package/lib/engine/data/error.js +12 -0
  24. package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +6 -2
  25. package/lib/engine/transaction/nodes/bucket.trx_node.js +4 -4
  26. package/lib/engine/transaction/nodes/external.trx_node.d.ts +4 -1
  27. package/lib/engine/transaction/nodes/external.trx_node.js +5 -2
  28. package/lib/engine/transaction/nodes/job.trx_node.js +0 -1
  29. package/lib/engine/transaction/trx_engine.js +8 -10
  30. package/package.json +1 -1
  31. package/tools/joaquin/bucket.d.ts +6 -2
  32. package/tools/joaquin/bucket.js +4 -4
  33. package/tsconfig.build.tsbuildinfo +1 -1
@@ -10,6 +10,7 @@ const error_1 = require("../../../../engine/data/error");
10
10
  const tree_1 = require("../../../../engine/data/tree");
11
11
  const daemon_1 = require("../../../../engine/daemon");
12
12
  const dependency_1 = require("../../../../engine/dependency");
13
+ const bucket_model_1 = require("../model/bucket_model");
13
14
  class ViewValue {
14
15
  value = undefined;
15
16
  constructor() { }
@@ -25,22 +26,24 @@ class BucketView {
25
26
  this.bucket = bucket;
26
27
  this.schema = schema;
27
28
  }
28
- async parse(trx, raw, flags) {
29
+ async parse(trx, root, flags) {
29
30
  const module = trx_node_1.TrxNode.getModule(trx);
30
31
  const tag = new dependency_1.Tag(this.bucket.module.name, 'bucket', this.bucket.schema.name);
31
32
  const meta = await daemon_1.Daemon.getBucketMetadata(module.daemon, tag);
32
33
  const parsed = {};
33
- if ('__raw' in this.schema.fields) {
34
- Object.assign(parsed, raw);
34
+ if ('__root' in this.schema.fields || '__parent' in this.schema.fields || '__value' in this.schema.fields) {
35
+ Object.assign(parsed, root);
35
36
  }
36
37
  let layer = Object.values(this.schema.fields).map(field => ({
37
38
  bucket: meta,
38
39
  field,
39
40
  data: [{
40
- raw,
41
- value: raw,
41
+ root,
42
+ parent: root,
42
43
  index: [],
43
- target: parsed
44
+ value: root,
45
+ target: parsed,
46
+ key: field.name
44
47
  }]
45
48
  }));
46
49
  while (layer.length) {
@@ -48,37 +51,39 @@ class BucketView {
48
51
  }
49
52
  parsed['$v'] = this.schema.name;
50
53
  return {
51
- id: raw.id,
54
+ id: root.id,
52
55
  ...parsed
53
56
  };
54
57
  }
55
- async parseMany(trx, raws, flags) {
58
+ async parseMany(trx, roots, flags) {
56
59
  const module = trx_node_1.TrxNode.getModule(trx);
57
60
  const tag = new dependency_1.Tag(this.bucket.module.name, 'bucket', this.bucket.schema.name);
58
61
  const meta = await daemon_1.Daemon.getBucketMetadata(module.daemon, tag);
59
62
  const parseds = [];
60
- for (const raw of raws) {
63
+ for (const root of roots) {
61
64
  const parsed = {};
62
- if ('__raw' in this.schema.fields) {
63
- Object.assign(parsed, raw);
65
+ if ('__root' in this.schema.fields || '__parent' in this.schema.fields || '__value' in this.schema.fields) {
66
+ Object.assign(parsed, root);
64
67
  }
65
68
  parseds.push(parsed);
66
69
  }
67
70
  let layer = Object.values(this.schema.fields).map(field => ({
68
71
  bucket: meta,
69
72
  field,
70
- data: raws.map((raw, i) => ({
71
- raw,
72
- value: raw,
73
+ data: roots.map((root, i) => ({
74
+ root,
75
+ parent: root,
73
76
  index: [],
74
- target: parseds[i]
77
+ value: root,
78
+ target: parseds[i],
79
+ key: field.name
75
80
  }))
76
81
  }));
77
82
  while (layer.length) {
78
83
  layer = await this.parseLayer(trx, layer, flags);
79
84
  }
80
- for (let i = 0; i < raws.length; i++) {
81
- parseds[i].id = raws[i].id;
85
+ for (let i = 0; i < roots.length; i++) {
86
+ parseds[i].id = roots[i].id;
82
87
  parseds[i]['$v'] = this.schema.name;
83
88
  }
84
89
  return parseds;
@@ -115,9 +120,9 @@ class BucketView {
115
120
  continue;
116
121
  if (!node.field.children)
117
122
  continue;
118
- if ('__raw' in node.field.children) {
123
+ if ('__root' in node.field.children || '__parent' in this.schema.fields || '__value' in node.field.children) {
119
124
  for (const d of node.data) {
120
- d.target[node.field.name] = d.value;
125
+ d.target[d.key] = d.value;
121
126
  }
122
127
  }
123
128
  next.push(...Object.values(node.field.children).map(field => ({
@@ -126,152 +131,230 @@ class BucketView {
126
131
  data: node.data
127
132
  })));
128
133
  }
129
- // Chains
130
- for (const node of layer) {
131
- if (!node.field.chain)
132
- continue;
133
- next.push({
134
- bucket: node.bucket,
135
- field: node.field.chain,
136
- data: node.data.map(d => ({
137
- index: d.index,
138
- target: d.target,
139
- raw: d.raw,
140
- value: d.target[node.field.name]
141
- }))
142
- });
143
- }
144
134
  return next;
145
135
  }
136
+ toDict(as_dict, data, final = false) {
137
+ const dict = {};
138
+ const next_data = [];
139
+ let poll = data.map(d => ({
140
+ i: 0,
141
+ index: d.index,
142
+ value: d.value,
143
+ target: dict
144
+ }));
145
+ while (poll.length) {
146
+ const next = [];
147
+ for (const entry of poll) {
148
+ const isLeaf = entry.i === as_dict.length - 1;
149
+ const key = entry.index.at(as_dict[entry.i]);
150
+ if (!key) {
151
+ throw new Error(`Invalid view dict argument ${as_dict}`); // TODO: NesoiError
152
+ }
153
+ if (isLeaf) {
154
+ if (final) {
155
+ entry.target[key] = entry.value;
156
+ }
157
+ else {
158
+ entry.target[key] = {};
159
+ next_data.push({
160
+ target: entry.target[key],
161
+ value: entry.value,
162
+ index: entry.index
163
+ });
164
+ }
165
+ }
166
+ else {
167
+ entry.target[key] = {};
168
+ next.push({
169
+ i: entry.i + 1,
170
+ index: entry.index,
171
+ value: entry.value,
172
+ target: entry.target[key]
173
+ });
174
+ }
175
+ }
176
+ poll = next;
177
+ }
178
+ return {
179
+ value: dict,
180
+ next: next_data
181
+ };
182
+ }
146
183
  /**
147
184
  * [model]
148
185
  * Read one property from
149
186
  */
150
187
  parseModelProp(node, flags) {
151
- const initAs = (!node.field.children) ? 'value' : 'obj';
152
- const rawChild = '__raw' in (node.field.children || {});
153
- const nextData = this.doParseModelProp(node, initAs, rawChild, flags);
154
- if (!node.field.children)
155
- return [];
188
+ const nextData = this.doParseModelProp(node, flags);
156
189
  const next = [];
157
- // subview
158
- for (const key in node.field.children) {
159
- if (key === '__raw')
160
- continue;
190
+ // Add children (subview) to queue
191
+ if (node.field.children) {
192
+ for (const key in node.field.children) {
193
+ if (key === '__root')
194
+ continue;
195
+ if (key === '__parent')
196
+ continue;
197
+ if (key === '__value')
198
+ continue;
199
+ next.push({
200
+ bucket: node.bucket,
201
+ field: node.field.children[key],
202
+ data: nextData.map(d => ({
203
+ ...d,
204
+ key: d.key ?? node.field.children[key].name
205
+ }))
206
+ });
207
+ }
208
+ }
209
+ // Chains
210
+ if (node.field.chain) {
161
211
  next.push({
162
212
  bucket: node.bucket,
163
- field: node.field.children[key],
164
- data: nextData
213
+ field: node.field.chain,
214
+ data: nextData.map(d => ({
215
+ root: d.root,
216
+ parent: d.parent,
217
+ index: d.index,
218
+ value: d.value,
219
+ target: d.target,
220
+ key: d.key
221
+ }))
165
222
  });
166
223
  }
167
224
  return next;
168
225
  }
169
- doParseModelProp(node, initAs, rawChild, flags) {
170
- const modelpath = node.field.meta.model.path;
171
- const isValueModel = modelpath === '.';
172
- const name = node.field.name;
173
- let poll = node.data.map(d => ({
174
- ...d,
175
- value: isValueModel ? d.value : d.raw,
176
- key: name
177
- }));
178
- if (isValueModel) {
179
- for (const data of poll) {
226
+ doParseModelProp(node, flags) {
227
+ const model = new bucket_model_1.BucketModel(node.bucket.schema);
228
+ let modelpath = node.field.meta.model.path;
229
+ if (node.field.prop)
230
+ modelpath += '.' + node.field.prop;
231
+ const hasSubview = node.field.children;
232
+ const hasChain = node.field.chain;
233
+ const hasRootSubviewField = '__root' in (node.field.children || {});
234
+ const hasParentSubviewField = '__parent' in (node.field.children || {});
235
+ const hasValueSubviewField = '__value' in (node.field.children || {});
236
+ const nextData = [];
237
+ for (const data of node.data) {
238
+ // Modelpath refers to the whole value
239
+ if (modelpath === '__root') {
240
+ data.target[data.key] = data.root;
241
+ continue;
242
+ }
243
+ if (modelpath === '__parent') {
244
+ data.target[data.key] = data.parent;
245
+ continue;
246
+ }
247
+ if (modelpath === '__value') {
180
248
  data.target[data.key] = data.value;
249
+ continue;
181
250
  }
182
- }
183
- else {
184
- const paths = modelpath.split('.');
185
- for (const path of paths) {
186
- // *
187
- if (path === '*') {
188
- // Expand each value of the poll (assumed to be a dict or list)
189
- poll = poll.map(item => {
190
- if (typeof item.value !== 'object') {
191
- throw new Error(`Failed to parse ${paths}, intermediate value ${item.value} is not a list or object`);
192
- }
193
- if (Array.isArray(item.value)) {
194
- item.target[item.key] = initAs === 'value'
195
- ? [...item.value]
196
- : item.value.map(() => ({}));
197
- return item.value.map((v, i) => ({
198
- index: [...item.index, i],
199
- raw: item.raw,
200
- value: v,
201
- target: item.target[item.key],
202
- key: i
203
- }));
204
- }
251
+ let node_modelpath = modelpath;
252
+ if (data.index.length) {
253
+ for (let i = 0; i < data.index.length; i++) {
254
+ node_modelpath = node_modelpath.replace(new RegExp('\\$' + i, 'g'), data.index[i].toString());
255
+ }
256
+ }
257
+ // Copy modelpath value from object
258
+ const value = model.copy(data.parent, 'save', () => !!flags?.serialize, node_modelpath);
259
+ const many = modelpath.split('.').includes('*');
260
+ // Modelpath contains '*', so it returns N results
261
+ if (many) {
262
+ const next = value.map(v => {
263
+ const index = [...data.index, ...v.index];
264
+ if (hasRootSubviewField || hasParentSubviewField || hasValueSubviewField) {
265
+ // Value is not an object, start subview as empty object
266
+ if (typeof v.value !== 'object' || Array.isArray(v.value))
267
+ return { value: v.value, target: {}, index: index };
268
+ // Value is an object, start subview with root/value
205
269
  else {
206
- item.target[item.key] = initAs === 'value'
207
- ? { ...item.value }
208
- : Object.fromEntries(Object.entries(item.value).map(([k]) => [k, {}]));
209
- return Object.entries(item.value).map(([k, v]) => ({
210
- index: [...item.index, k],
211
- raw: item.raw,
212
- value: v,
213
- target: item.target[item.key],
214
- key: k
215
- }));
270
+ const val = Object.assign({}, hasRootSubviewField ? data.root : {}, hasParentSubviewField ? data.parent : {}, hasValueSubviewField ? v.value : {});
271
+ return { value: v.value, target: val, index: index };
216
272
  }
217
- }).flat(1);
218
- continue;
273
+ }
274
+ else if (hasSubview)
275
+ return { value: v.value, target: {}, index: index };
276
+ else
277
+ return { value: v.value, target: v.value, index: index };
278
+ });
279
+ if (node.field.as_dict) {
280
+ const dict = this.toDict(node.field.as_dict, next, !node.field.children);
281
+ data.target[data.key] = dict.value;
282
+ // Add to be processed by subview
283
+ nextData.push(...dict.next.map((v, i) => ({
284
+ root: data.root,
285
+ parent: data.parent,
286
+ index: v.index,
287
+ value: v.value,
288
+ target: v.target
289
+ })));
219
290
  }
220
- // $1, $2.. or string|number
221
291
  else {
222
- // Walk each node
223
- const next = [];
224
- for (const item of poll) {
225
- // $0, $1.. -> string
226
- const idx = path.match(/^\$(\d+)/)?.[1];
227
- let _path = path;
228
- if (idx !== undefined) {
229
- // Replace by index key
230
- _path = item.index[parseInt(idx)];
231
- }
232
- const n = typeof item.value === 'object'
233
- ? item.value[_path]
234
- : undefined;
235
- item.target[item.key] = initAs === 'value'
236
- ? n
237
- : {};
238
- if (n !== undefined) {
239
- next.push({
240
- index: item.index,
241
- raw: item.raw,
242
- value: n,
243
- target: item.target,
244
- key: item.key
245
- });
246
- }
292
+ if (hasChain) {
293
+ data.target[data.key] = [];
294
+ nextData.push(...next.map((v, i) => ({
295
+ root: data.root,
296
+ parent: data.parent,
297
+ index: v.index,
298
+ value: v.value,
299
+ target: data.target[data.key],
300
+ key: i.toString()
301
+ })));
302
+ }
303
+ else {
304
+ data.target[data.key] = next.map(v => v.target);
305
+ // Add to be processed by subview
306
+ nextData.push(...next.map((v, i) => ({
307
+ root: data.root,
308
+ parent: data.parent,
309
+ index: v.index,
310
+ value: v.value,
311
+ target: v.target
312
+ })));
247
313
  }
248
- poll = next;
249
314
  }
250
315
  }
251
- }
252
- // For each leaf, if it's an object (not an array),
253
- // pre-fill with it's value.
254
- // This means that ...$.raw() only works on modelpaths that
255
- // result in an object. Otherwise, it's ignored.
256
- if (rawChild) {
257
- for (const data of poll) {
258
- if (typeof data.value === 'object' && !Array.isArray(data.value)) {
259
- data.target[data.key] = data.value;
316
+ // Modelpath does not contain '*', so it returns 1 result
317
+ else {
318
+ const v = value[0];
319
+ const index = [...data.index, ...(v?.index ?? [])];
320
+ let target = v?.value;
321
+ if (hasRootSubviewField || hasParentSubviewField || hasValueSubviewField) {
322
+ // Value is not an object, start subview as empty object
323
+ if (typeof v.value !== 'object' || Array.isArray(v.value))
324
+ target = {};
325
+ // Value is an object, start subview with root/value
326
+ else {
327
+ target = Object.assign({}, hasRootSubviewField ? data.root : {}, hasParentSubviewField ? data.parent : {}, hasValueSubviewField ? v.value : {});
328
+ }
329
+ }
330
+ else if (hasSubview)
331
+ target = {};
332
+ if (target) {
333
+ if (hasChain) {
334
+ nextData.push({
335
+ root: data.root,
336
+ parent: data.parent,
337
+ index: index,
338
+ value: v.value,
339
+ target: data.target,
340
+ key: data.key
341
+ });
342
+ }
343
+ else {
344
+ data.target[data.key] = target;
345
+ // Add to be processed by subview
346
+ nextData.push({
347
+ root: data.root,
348
+ parent: target,
349
+ index: index,
350
+ value: v.value,
351
+ target
352
+ });
353
+ }
260
354
  }
261
355
  }
262
356
  }
263
- // Apply prop
264
- for (const data of poll) {
265
- if (node.field.prop) {
266
- data.target[data.key] = data.target[data.key][node.field.prop];
267
- }
268
- }
269
- return poll.map(p => ({
270
- index: p.index,
271
- raw: p.raw,
272
- value: p.value,
273
- target: p.target[p.key]
274
- }));
357
+ return nextData;
275
358
  }
276
359
  /**
277
360
  * [computed]
@@ -279,7 +362,7 @@ class BucketView {
279
362
  async parseComputedProp(trx, node) {
280
363
  const meta = node.field.meta.computed;
281
364
  for (const entry of node.data) {
282
- entry.target[node.field.name] = await promise_1.default.solve(meta.fn({ trx, raw: entry.raw, value: entry.value, bucket: node.bucket.schema }));
365
+ entry.target[entry.key] = await promise_1.default.solve(meta.fn({ trx, root: entry.root, parent: entry.parent, value: entry.value, bucket: node.bucket.schema }));
283
366
  }
284
367
  }
285
368
  /**
@@ -292,69 +375,77 @@ class BucketView {
292
375
  // Step 1: Read many links from bucket
293
376
  // External
294
377
  if (node.bucket.tag.module !== module.name) {
295
- linksObjs = await trx.bucket(node.bucket.tag.short).readManyLinks(node.data.map(entry => entry.raw.id), //ids -> objs -> params
296
- meta.path, [] // param templates temporarily disabled
297
- );
378
+ linksObjs = await trx.bucket(node.bucket.tag.short).readManyLinks(node.data.map(entry => entry.parent.id), //ids -> objs -> params
379
+ meta.path, node.data.map(entry => entry.index));
298
380
  }
299
381
  // Internal
300
382
  else {
301
383
  const bucket = module.buckets[node.bucket.tag.name];
302
- linksObjs = await bucket.graph.readManyLinks(trx, node.data.map(entry => entry.raw), {
384
+ linksObjs = await bucket.graph.readManyLinks(trx, node.data.map(entry => entry.parent), {
303
385
  name: meta.link,
304
- indexes: [] // param templates temporarily disabled
386
+ indexes: node.data.map(entry => entry.index)
305
387
  }, { silent: true });
306
388
  }
307
389
  // Step 2: Initialize target values
308
390
  const link = node.bucket.schema.graph.links[meta.link];
309
391
  for (let i = 0; i < linksObjs.length; i++) {
392
+ const target = node.data[i].target;
393
+ const key = node.data[i].key;
310
394
  if (meta.view) {
311
395
  if (link.many) {
312
- node.data[i].target[node.field.name] = [];
396
+ target[key] = [];
313
397
  }
314
398
  else {
315
- node.data[i].target[node.field.name] = linksObjs[i] ? {} : undefined;
399
+ target[key] = linksObjs[i] ? {} : undefined;
316
400
  }
317
401
  }
318
402
  else if (node.field.prop) {
319
403
  if (link.many) {
320
- node.data[i].target[node.field.name] = linksObjs[i].map((link) => link[node.field.prop]);
404
+ target[key] = linksObjs[i].map((link) => link[node.field.prop]);
321
405
  }
322
406
  else {
323
- node.data[i].target[node.field.name] = linksObjs[i]?.[node.field.prop];
407
+ target[key] = linksObjs[i]?.[node.field.prop];
324
408
  }
325
409
  }
326
410
  else {
327
- node.data[i].target[node.field.name] = linksObjs[i];
411
+ target[key] = linksObjs[i];
328
412
  }
329
413
  }
414
+ const schema = node.bucket.schema;
415
+ const otherBucketDep = schema.graph.links[meta.link].bucket;
416
+ const daemon = module.daemon;
417
+ const otherBucket = await daemon_1.Daemon.getBucketMetadata(daemon, otherBucketDep);
330
418
  // Step 3: Build view
331
419
  let next = [];
332
420
  let nextData = linksObjs;
333
421
  if (meta.view) {
334
- const schema = node.bucket.schema;
335
- const otherBucketDep = schema.graph.links[meta.link].bucket;
336
- const module = trx_node_1.TrxNode.getModule(trx);
337
- const daemon = module.daemon;
338
- const otherBucket = await daemon_1.Daemon.getBucketMetadata(daemon, otherBucketDep);
339
422
  const view = otherBucket.schema.views[meta.view];
340
- const { __raw, ...v } = view.fields;
423
+ const includeRoot = '__root' in view.fields;
424
+ const includeParent = '__parent' in view.fields;
425
+ const includeValue = '__value' in view.fields;
426
+ const v = { ...view.fields };
427
+ delete v['__root'];
428
+ delete v['__parent'];
429
+ delete v['__value'];
341
430
  const link = node.bucket.schema.graph.links[meta.link];
342
431
  if (link.many) {
343
432
  const _links = linksObjs;
344
433
  for (let i = 0; i < _links.length; i++) {
345
- const target = node.data[i].target[node.field.name];
434
+ const key = node.data[i].key;
435
+ const target = node.data[i].target[key];
346
436
  for (let j = 0; j < _links[i].length; j++) {
347
437
  if (node.field.prop) {
348
438
  target.push(_links[i][j][node.field.prop]);
349
439
  }
350
440
  else {
351
- target.push(__raw ? { ..._links[i][j] } : {});
441
+ const init = Object.assign({ $v: meta.view }, (includeRoot || includeParent || includeValue) ? _links[i][j] : {});
442
+ target.push(init);
352
443
  target[j].$v = meta.view;
353
444
  }
354
445
  }
355
446
  }
356
447
  if (!node.field.prop) {
357
- nextData = _links.map((ll, i) => ll.map((l, j) => ({ value: l, target: node.data[i].target[node.field.name][j] }))).flat(1);
448
+ nextData = _links.map((ll, i) => ll.map((l, j) => ({ value: l, target: node.data[i].target[node.data[i].key][j] }))).flat(1);
358
449
  }
359
450
  else {
360
451
  nextData = [];
@@ -366,35 +457,38 @@ class BucketView {
366
457
  for (let i = 0; i < _links.length; i++) {
367
458
  if (!_links[i])
368
459
  continue;
460
+ const key = node.data[i].key;
369
461
  if (node.field.prop) {
370
- node.data[i].target[node.field.name] = _links[i][node.field.prop];
462
+ node.data[i].target[key] = _links[i][node.field.prop];
371
463
  }
372
464
  else {
373
- const target = node.data[i].target[node.field.name];
374
- if (__raw) {
465
+ const target = node.data[i].target[key];
466
+ if (includeRoot || includeParent || includeValue) {
375
467
  Object.assign(target, _links[i]);
376
468
  }
377
469
  target.$v = meta.view;
378
470
  nextData.push({
379
- value: _links[i], target: node.data[i].target[node.field.name]
471
+ value: _links[i], target: node.data[i].target[key]
380
472
  });
381
473
  }
382
474
  }
383
475
  }
384
476
  // (still step 3) Add link bucket view fields to queue
385
477
  next = [];
386
- const bucket = await daemon_1.Daemon.getBucketMetadata(module.daemon, otherBucketDep);
478
+ // const bucket = await Daemon.getBucketMetadata(module.daemon!, otherBucketDep);
387
479
  // Next data is empty if meta.prop is defined, since there's no need to go deeper
388
480
  if (nextData.length) {
389
481
  for (const field of Object.values(v)) {
390
482
  next.push({
391
- bucket,
483
+ bucket: otherBucket,
392
484
  field,
393
485
  data: nextData.map($ => ({
394
- raw: $.value,
486
+ root: $.value,
487
+ parent: $.value,
395
488
  value: $.value,
396
489
  index: [],
397
- target: $.target
490
+ target: $.target,
491
+ key: field.name
398
492
  }))
399
493
  });
400
494
  }
@@ -406,45 +500,63 @@ class BucketView {
406
500
  const subview_data = [];
407
501
  for (let i = 0; i < linksObjs.length; i++) {
408
502
  const objs = linksObjs[i];
503
+ if (!objs)
504
+ continue;
505
+ const key = node.data[i].key;
409
506
  let target;
410
507
  if (link.many) {
411
508
  target = [];
412
- for (const tobj of node.data[i].target[node.field.name]) {
413
- if ('__raw' in node.field.children) {
414
- target.push({ ...tobj });
415
- }
416
- else {
417
- target.push({ id: tobj.id });
418
- }
509
+ for (const tobj of node.data[i].target[key]) {
510
+ const init = Object.assign({ id: tobj.id }, '__root' in node.field.children ? node.data[i].root : {}, '__parent' in node.field.children ? node.data[i].root : {}, '__value' in node.field.children ? tobj : {});
511
+ target.push(init);
419
512
  }
420
- subview_data.push(...objs.map((obj, i) => ({
421
- obj: { ...obj },
422
- target: target[i]
513
+ subview_data.push(...objs.map((obj, j) => ({
514
+ root: node.data[i].root,
515
+ parent: node.data[i].parent,
516
+ value: { ...obj },
517
+ target: target[j]
423
518
  })));
424
519
  }
425
520
  else {
426
521
  target = { id: objs.id };
427
- if ('__raw' in node.field.children) {
428
- Object.assign(target, node.data[i].target[node.field.name]);
522
+ if ('__root' in node.field.children) {
523
+ Object.assign(target, node.data[i].root);
429
524
  }
430
- subview_data.push({ obj: { ...objs }, target });
525
+ if ('__parent' in node.field.children) {
526
+ Object.assign(target, node.data[i].parent);
527
+ }
528
+ if ('__value' in node.field.children) {
529
+ Object.assign(target, node.data[i].target[key]);
530
+ }
531
+ subview_data.push({
532
+ root: node.data[i].root,
533
+ parent: node.data[i].parent,
534
+ value: { ...objs },
535
+ target
536
+ });
431
537
  }
432
- node.data[i].target[node.field.name] = target;
538
+ node.data[i].target[key] = target;
433
539
  }
434
540
  const module = trx_node_1.TrxNode.getModule(trx);
435
541
  const subview_bucket = daemon_1.Daemon.getBucketMetadata(module.daemon, link.bucket);
436
542
  // Add subview data to queue
437
543
  for (const key in node.field.children) {
438
- if (key === '__raw')
544
+ if (key === '__root')
545
+ continue;
546
+ if (key === '__parent')
547
+ continue;
548
+ if (key === '__value')
439
549
  continue;
440
550
  next.push({
441
551
  bucket: subview_bucket,
442
552
  field: node.field.children[key],
443
553
  data: subview_data.map(data => ({
444
- raw: data.obj,
445
- value: data.obj,
554
+ root: data.root,
555
+ parent: data.value,
446
556
  index: [],
447
- target: data.target
557
+ value: data.value,
558
+ target: data.target,
559
+ key: node.field.children[key].name
448
560
  }))
449
561
  });
450
562
  }
@@ -462,16 +574,16 @@ class BucketView {
462
574
  }
463
575
  const meta = node.field.meta.drive;
464
576
  for (const entry of node.data) {
465
- const value = tree_1.Tree.get(entry.raw, meta.path);
577
+ const value = tree_1.Tree.get(entry.root, meta.path);
466
578
  if (Array.isArray(value)) {
467
579
  const public_urls = [];
468
580
  for (const obj of value) {
469
581
  public_urls.push(await drive.public(obj));
470
582
  }
471
- entry.target[node.field.name] = public_urls;
583
+ entry.target[entry.key] = public_urls;
472
584
  }
473
585
  else {
474
- entry.target[node.field.name] = await drive.public(value);
586
+ entry.target[entry.key] = await drive.public(value);
475
587
  }
476
588
  }
477
589
  }