nesoi 3.3.30 → 3.4.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.
Files changed (47) hide show
  1. package/lib/compiler/elements/bucket.element.js +3 -3
  2. package/lib/elements/edge/controller/adapters/controller_adapter.js +1 -3
  3. package/lib/elements/entities/bucket/adapters/memory.nql.js +12 -18
  4. package/lib/elements/entities/bucket/bucket.d.ts +6 -2
  5. package/lib/elements/entities/bucket/bucket.js +4 -4
  6. package/lib/elements/entities/bucket/graph/bucket_graph.js +13 -3
  7. package/lib/elements/entities/bucket/model/bucket_model.convert.js +9 -17
  8. package/lib/elements/entities/bucket/model/bucket_model.d.ts +6 -1
  9. package/lib/elements/entities/bucket/model/bucket_model.js +182 -33
  10. package/lib/elements/entities/bucket/model/bucket_model.schema.d.ts +1 -1
  11. package/lib/elements/entities/bucket/model/bucket_model.schema.js +2 -2
  12. package/lib/elements/entities/bucket/query/nql.schema.d.ts +1 -0
  13. package/lib/elements/entities/bucket/query/nql_compiler.js +5 -4
  14. package/lib/elements/entities/bucket/query/nql_engine.js +0 -2
  15. package/lib/elements/entities/bucket/view/bucket_view.d.ts +5 -4
  16. package/lib/elements/entities/bucket/view/bucket_view.js +300 -188
  17. package/lib/elements/entities/bucket/view/bucket_view.schema.d.ts +5 -3
  18. package/lib/elements/entities/bucket/view/bucket_view.schema.js +3 -1
  19. package/lib/elements/entities/bucket/view/bucket_view_field.builder.d.ts +15 -5
  20. package/lib/elements/entities/bucket/view/bucket_view_field.builder.js +82 -28
  21. package/lib/elements/entities/message/template/message_template_parser.d.ts +5 -1
  22. package/lib/elements/entities/message/template/message_template_parser.js +13 -7
  23. package/lib/engine/daemon.d.ts +1 -11
  24. package/lib/engine/daemon.js +3 -26
  25. package/lib/engine/data/datetime.d.ts +35 -1
  26. package/lib/engine/data/datetime.js +103 -16
  27. package/lib/engine/data/error.d.ts +17 -0
  28. package/lib/engine/data/error.js +16 -0
  29. package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +8 -2
  30. package/lib/engine/transaction/nodes/bucket.trx_node.js +16 -4
  31. package/lib/engine/transaction/nodes/bucket_query.trx_node.js +1 -1
  32. package/lib/engine/transaction/nodes/external.trx_node.d.ts +4 -1
  33. package/lib/engine/transaction/nodes/external.trx_node.js +19 -19
  34. package/lib/engine/transaction/nodes/job.trx_node.d.ts +4 -3
  35. package/lib/engine/transaction/nodes/job.trx_node.js +6 -2
  36. package/lib/engine/transaction/nodes/resource.trx_node.js +2 -1
  37. package/lib/engine/transaction/trx.d.ts +4 -3
  38. package/lib/engine/transaction/trx.js +15 -11
  39. package/lib/engine/transaction/trx_engine.config.d.ts +7 -3
  40. package/lib/engine/transaction/trx_engine.d.ts +7 -3
  41. package/lib/engine/transaction/trx_engine.js +99 -45
  42. package/lib/engine/transaction/trx_node.d.ts +4 -1
  43. package/lib/engine/transaction/trx_node.js +12 -9
  44. package/package.json +1 -1
  45. package/tools/joaquin/bucket.d.ts +6 -2
  46. package/tools/joaquin/bucket.js +4 -4
  47. package/tsconfig.build.tsbuildinfo +1 -1
@@ -26,6 +26,7 @@ class TrxEngine {
26
26
  */
27
27
  innerTrx;
28
28
  adapter;
29
+ log_adapter;
29
30
  constructor(origin, module, authnProviders, config, services = {}) {
30
31
  this.origin = origin;
31
32
  this.module = module;
@@ -35,29 +36,35 @@ class TrxEngine {
35
36
  this.innerTrx = new trx_1.Trx(this, this.module, `trx:${origin}`, true);
36
37
  this.$TrxBucket = new elements_1.$Bucket(this.module.name, '__trx__', `Transaction of Module '${this.module.name}'`, new bucket_model_schema_1.$BucketModel({
37
38
  id: new bucket_model_schema_1.$BucketModelField('id', 'id', 'string', 'ID', true),
39
+ state: new bucket_model_schema_1.$BucketModelField('state', 'state', 'string', 'State', true), // TrxNodeState
38
40
  origin: new bucket_model_schema_1.$BucketModelField('origin', 'origin', 'string', 'Origin', true),
39
41
  module: new bucket_model_schema_1.$BucketModelField('module', 'module', 'string', 'Module', true),
40
42
  start: new bucket_model_schema_1.$BucketModelField('start', 'start', 'datetime', 'Start', true),
41
- end: new bucket_model_schema_1.$BucketModelField('end', 'end', 'datetime', 'End', false),
43
+ end: new bucket_model_schema_1.$BucketModelField('end', 'end', 'datetime', 'End', false)
42
44
  }), new bucket_graph_schema_1.$BucketGraph(), {});
43
- this.adapter = config?.adapter?.(module.schema) || new memory_bucket_adapter_1.MemoryBucketAdapter(this.$TrxBucket, {});
45
+ this.adapter = config?.adapter?.(this.$TrxBucket) || new memory_bucket_adapter_1.MemoryBucketAdapter(this.$TrxBucket, {});
46
+ if (config?.log_adapter) {
47
+ this.log_adapter = config?.log_adapter?.(this.$TrxBucket);
48
+ }
44
49
  }
45
50
  getModule() {
46
51
  return this.module;
47
52
  }
48
- async get(id, origin, idempotent = false) {
53
+ async get(id, origin, req_idempotent = false) {
49
54
  const _origin = origin ?? this.origin;
50
55
  let trx;
51
56
  // New transaction
52
57
  if (!id) {
53
- trx = new trx_1.Trx(this, this.module, _origin, idempotent);
54
- log_1.Log.info('module', this.module.name, `Begin${idempotent ? '*' : ''} ${(0, log_1.scopeTag)('trx', trx.id + trx.root.id)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
58
+ trx = new trx_1.Trx(this, this.module, _origin, req_idempotent);
59
+ log_1.Log.debug('module', this.module.name, `Begin${req_idempotent ? '*' : ''} ${(0, log_1.scopeTag)('trx', trx.root.globalId)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
55
60
  for (const wrap of this.config?.wrap || []) {
61
+ // The wrappers decide how to begin a db transaction, based on the trx idempotent flag.
56
62
  await wrap.begin(trx, this.services);
57
63
  }
58
- if (!idempotent) {
64
+ if (!req_idempotent) {
59
65
  await this.adapter.create(this.innerTrx.root, {
60
66
  id: trx.id,
67
+ state: 'open',
61
68
  origin: trx.origin,
62
69
  start: trx.start,
63
70
  end: trx.end,
@@ -69,49 +76,78 @@ class TrxEngine {
69
76
  // Chain/Continue transaction
70
77
  else {
71
78
  const trxData = await this.adapter.get(this.innerTrx.root, id);
79
+ // If trxData exists, the transaction to which it refers is non-idempotent,
80
+ // since idempotent transactions are not stored.
81
+ //
72
82
  // If a transaction is being continued it cannot become idempotent,
73
83
  // since the data it needs is inside the transaction.
74
- // > Started as NOT idempotent on this module, is NEVER idempotent
75
- // This only affects services which need this info for deciding whether
76
- // to commit/rollback a transaction. The trx engine still uses the requested
77
- // idempotent value to decide whether to run or not a commit/rollback,
78
- // because otherwise it would commit/rollback partially idempotent transactions
79
- // before they're actually finished.
80
- if (trxData)
81
- idempotent = false;
84
+ //
85
+ // If the transaction started as non-idempotent and is continued as idempotent,
86
+ // the code below will transform it into non-idempotent, however
87
+ // the engine.ok and engine.error still treat it as idempotent, to avoid commit/rollback
88
+ // of the original transaction.
89
+ //
82
90
  // Differently, a transaction with specific id which doesn't exist can
83
91
  // be either an ongoing idempotent transaction from this module or an
84
92
  // external transaction starting at a different module.
85
- // On either case, it's allowed to become idempotent.
86
- // > Not stored, can become idempotent.
87
- // if (!trxData) idempotent = idempotent;
93
+ // On either case, it's allowed to be idempotent or not.
94
+ const idempotent = trxData ? false : req_idempotent;
88
95
  trx = new trx_1.Trx(this, this.module, _origin, idempotent, undefined, id);
89
- // (Continue*)
90
- if (idempotent) {
91
- log_1.Log.info('module', this.module.name, `Continue* ${(0, log_1.scopeTag)('trx', id)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
92
- for (const wrap of this.config?.wrap || []) {
93
- await wrap.continue(trx, this.services);
96
+ // (Begin/Continue*)
97
+ // The request is for an idempotent transaction.
98
+ if (req_idempotent) {
99
+ // A non-idempotent transaction with the same id exists on this module.
100
+ // so it's being continued as an idempotent transaction.
101
+ if (trxData) {
102
+ log_1.Log.debug('module', this.module.name, `Continue* ${(0, log_1.scopeTag)('trx', trx.root.globalId)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
103
+ if (trxData.state !== 'hold') {
104
+ throw new Error(`Attempt to continue transaction ${trxData.id}, currently at '${trxData.state}', failed. Should be at 'hold'. This might mean there are parallel attempts to continue a transaction, which must be handled with a queue.`);
105
+ }
106
+ for (const wrap of this.config?.wrap || []) {
107
+ // The wrappers decide how to continue a db transaction, based on the trx idempotent flag.
108
+ await wrap.continue(trx, this.services);
109
+ }
110
+ }
111
+ // No transaction with the same id exists on this module.
112
+ // so it's starting as an idempotent transaction.
113
+ else {
114
+ log_1.Log.debug('module', this.module.name, `Begin* ${(0, log_1.scopeTag)('trx', trx.root.globalId)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
115
+ for (const wrap of this.config?.wrap || []) {
116
+ // The wrappers decide how to begin a db transaction, based on the trx idempotent flag.
117
+ await wrap.begin(trx, this.services);
118
+ }
94
119
  }
95
120
  return trx;
96
121
  }
97
122
  // (Continue)
123
+ // A non-idempotent transaction with the same id exists on this module,
124
+ // so it's being continued.
98
125
  if (trxData) {
126
+ log_1.Log.debug('module', this.module.name, `Continue ${(0, log_1.scopeTag)('trx', trx.root.globalId)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
127
+ if (trxData.state !== 'hold') {
128
+ throw new Error(`Attempt to continue transaction ${trxData.id}, currently at '${trxData.state}', failed. Should be at 'hold'. This might mean there are parallel attempts to continue a transaction, which must be handled with a queue.`);
129
+ }
99
130
  // Update transaction with data read from adapter
100
131
  trx.start = trxData.start;
101
132
  trx.end = trxData.end;
102
- log_1.Log.info('module', this.module.name, `Continue ${(0, log_1.scopeTag)('trx', trx.id + trx.root.id)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
103
133
  for (const wrap of this.config?.wrap || []) {
134
+ // The wrappers decide how to continue a db transaction, based on the trx idempotent flag.
104
135
  await wrap.continue(trx, this.services);
105
136
  }
106
137
  }
107
138
  // (Chain)
139
+ // No transaction with the same id exists on this module,
140
+ // so it's starting as a "chained" transaction - a new one with
141
+ // the same ID as the one from some module.
108
142
  else {
109
- log_1.Log.info('module', this.module.name, `Chain ${(0, log_1.scopeTag)('trx', id + trx.root.id)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
143
+ log_1.Log.debug('module', this.module.name, `Chain${trx.idempotent ? '*' : ''} ${(0, log_1.scopeTag)('trx', trx.root.globalId)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
110
144
  for (const wrap of this.config?.wrap || []) {
145
+ // The wrappers decide how to begin a db transaction, based on the trx idempotent flag.
111
146
  await wrap.begin(trx, this.services);
112
147
  }
113
148
  await this.adapter.create(this.innerTrx.root, {
114
149
  id: trx.id,
150
+ state: 'open',
115
151
  origin: _origin,
116
152
  start: trx.start,
117
153
  end: trx.end,
@@ -126,29 +162,29 @@ class TrxEngine {
126
162
  try {
127
163
  await this.authenticate(trx.root, tokens, users);
128
164
  const output = await fn(trx.root);
129
- await this.commit(trx, output, idempotent);
165
+ await this.ok(trx, output, idempotent);
130
166
  }
131
167
  catch (e) {
132
- await this.rollback(trx, e, idempotent);
168
+ await this.error(trx, e, idempotent);
133
169
  }
134
170
  return trx.status();
135
171
  }
136
- async trx_hold(fn, id, authn, users, origin, idempotent = false) {
137
- const trx = await this.get(id, origin, idempotent);
172
+ async trx_hold(fn, id, authn, users, origin) {
173
+ const trx = await this.get(id, origin, false);
138
174
  let output = {};
139
175
  try {
140
176
  await this.authenticate(trx.root, authn, users);
141
177
  output = await fn(trx.root);
142
- await this.hold(trx, output, idempotent);
178
+ await this.hold(trx, output);
143
179
  }
144
180
  catch (e) {
145
- await this.rollback(trx, e, idempotent);
181
+ await this.error(trx, e, false);
146
182
  }
147
183
  return {
148
184
  id: trx.id,
149
185
  status: trx.status(),
150
- commit: () => this.commit(trx, output, idempotent),
151
- rollback: (error) => this.rollback(trx, error, idempotent)
186
+ commit: () => this.ok(trx, output, false),
187
+ rollback: (error) => this.error(trx, error, false)
152
188
  };
153
189
  }
154
190
  /* Metadata sharing between modules */
@@ -188,13 +224,12 @@ class TrxEngine {
188
224
  trx_node_1.TrxNode.addAuthn(node, _tokens, _users);
189
225
  }
190
226
  //
191
- async hold(trx, output, idempotent) {
192
- log_1.Log.debug('module', this.module.name, `Hold ${(0, log_1.scopeTag)('trx', trx.id)} @ ${(0, log_1.anyScopeTag)(this.origin)}`);
227
+ async hold(trx, output) {
228
+ log_1.Log.debug('module', this.module.name, `Hold ${(0, log_1.scopeTag)('trx', trx.root.globalId)}`);
193
229
  trx_node_1.TrxNode.hold(trx.root, output);
194
- if (idempotent)
195
- return trx;
196
230
  await this.adapter.put(this.innerTrx.root, {
197
231
  id: trx.id,
232
+ state: 'hold',
198
233
  origin: this.origin,
199
234
  start: trx.start,
200
235
  end: trx.end,
@@ -202,40 +237,59 @@ class TrxEngine {
202
237
  });
203
238
  return trx;
204
239
  }
205
- async commit(trx, output, idempotent) {
240
+ async ok(trx, output, idempotent) {
241
+ log_1.Log.debug('module', this.module.name, `Ok${idempotent ? '*' : ''} ${(0, log_1.scopeTag)('trx', trx.root.globalId)}`);
206
242
  trx_node_1.TrxNode.ok(trx.root, output);
207
243
  trx.end = datetime_1.NesoiDatetime.now();
244
+ const held_children = Object.keys(trx.holds).length;
245
+ if (held_children) {
246
+ log_1.Log.debug('module', this.module.name, `Commit Holds ${(0, log_1.scopeTag)('trx', trx.root.globalId)} (${held_children})`);
247
+ await trx_1.Trx.commitHolds(trx);
248
+ }
208
249
  if (idempotent)
209
250
  return trx;
210
- await trx_1.Trx.onCommit(trx);
211
- log_1.Log.info('module', this.module.name, `Commit ${(0, log_1.scopeTag)('trx', trx.id)} @ ${(0, log_1.anyScopeTag)(this.origin)} (held: ${Object.keys(trx.holds).length})`);
212
- await this.adapter.put(this.innerTrx.root, {
251
+ return this.commit(trx);
252
+ }
253
+ async commit(trx) {
254
+ log_1.Log.debug('module', this.module.name, `Commit ${(0, log_1.scopeTag)('trx', trx.root.globalId)}`);
255
+ await this.log_adapter?.put(this.innerTrx.root, {
213
256
  id: trx.id,
257
+ state: 'ok',
214
258
  origin: this.origin,
215
259
  start: trx.start,
216
260
  end: trx.end,
217
261
  module: this.module.name,
218
262
  });
263
+ await this.adapter.delete(this.innerTrx.root, trx.id);
219
264
  for (const wrap of this.config?.wrap || []) {
220
265
  await wrap.commit(trx, this.services);
221
266
  }
222
267
  return trx;
223
268
  }
224
- async rollback(trx, error, idempotent) {
225
- log_1.Log.error('module', this.module.name, `[${error.status}] ${error.toString()}`, error.stack);
269
+ async error(trx, error, idempotent) {
270
+ log_1.Log.error('module', this.module.name, `[${error.status}]${idempotent ? '*' : ''} ${error.toString()}`, error.stack);
226
271
  trx_node_1.TrxNode.error(trx.root, error);
227
272
  trx.end = datetime_1.NesoiDatetime.now();
273
+ const held_children = Object.keys(trx.holds).length;
274
+ if (held_children) {
275
+ log_1.Log.debug('module', this.module.name, `Rollback Holds ${(0, log_1.scopeTag)('trx', trx.root.globalId)} (${held_children})`);
276
+ await trx_1.Trx.rollbackHolds(trx);
277
+ }
228
278
  if (idempotent)
229
279
  return trx;
230
- await trx_1.Trx.onRollback(trx);
231
- log_1.Log.warn('module', this.module.name, `Rollback ${(0, log_1.scopeTag)('trx', trx.id)} @ ${(0, log_1.anyScopeTag)(this.origin)} (held: ${Object.keys(trx.holds).length})`);
232
- await this.adapter.put(this.innerTrx.root, {
280
+ return this.rollback(trx);
281
+ }
282
+ async rollback(trx) {
283
+ log_1.Log.warn('module', this.module.name, `Rollback ${(0, log_1.scopeTag)('trx', trx.root.globalId)} (held: ${Object.keys(trx.holds).length})`);
284
+ await this.log_adapter?.put(this.innerTrx.root, {
233
285
  id: trx.id,
286
+ state: 'error',
234
287
  origin: this.origin,
235
288
  start: trx.start,
236
289
  end: trx.end,
237
290
  module: this.module.name,
238
291
  });
292
+ await this.adapter.delete(this.innerTrx.root, trx.id);
239
293
  for (const wrap of this.config?.wrap || []) {
240
294
  await wrap.rollback(trx, this.services);
241
295
  }
@@ -27,6 +27,9 @@ export type TrxNodeStatus = {
27
27
  cached_buckets: number;
28
28
  nodes: TrxNodeStatus[];
29
29
  app: number;
30
+ ext?: {
31
+ idempotent: boolean;
32
+ };
30
33
  };
31
34
  /**
32
35
  * @category Engine
@@ -53,7 +56,7 @@ export declare class TrxNode<Space extends $Space, M extends $Module, AuthUsers
53
56
  constructor(scope: 'root' | `${string}::${TrxNodeBlock}:${string}` | `${string}::virtual`, trx: AnyTrx, parent: AnyTrxNode | undefined, module: AnyModule, auth?: {
54
57
  tokens: AuthRequest<any>;
55
58
  users: AuthUsers;
56
- } | undefined, external?: boolean | undefined, id?: string);
59
+ } | undefined, external?: boolean | undefined);
57
60
  static open(node: AnyTrxNode, action: string, input: Record<string, any>): void;
58
61
  static hold(node: AnyTrxNode, output?: Record<string, any>): void;
59
62
  static ok(node: AnyTrxNode, output?: Record<string, any>): void;
@@ -44,19 +44,16 @@ class TrxNode {
44
44
  hold: undefined,
45
45
  end: undefined
46
46
  };
47
- constructor(scope, trx, parent, module, auth, external, id) {
47
+ constructor(scope, trx, parent, module, auth, external) {
48
48
  this.scope = scope;
49
49
  this.trx = trx;
50
50
  this.parent = parent;
51
51
  this.module = module;
52
52
  this.auth = auth;
53
53
  this.external = external;
54
- if (parent) {
55
- this.id = id || (Math.random() + 1).toString(36).substring(7);
56
- }
57
- else {
58
- this.id = '#' + (Math.random() + 1).toString(36).substring(7);
59
- }
54
+ this.id = parent
55
+ ? (Math.random() + 1).toString(36).substring(7)
56
+ : '#';
60
57
  this.globalId = `${this.trx.id}.${this.id}`;
61
58
  }
62
59
  static open(node, action, input) {
@@ -201,7 +198,7 @@ class TrxNode {
201
198
  // Status
202
199
  status() {
203
200
  return {
204
- id: this.id,
201
+ id: this.globalId,
205
202
  scope: this.scope,
206
203
  state: this.state,
207
204
  action: this.action,
@@ -210,7 +207,10 @@ class TrxNode {
210
207
  error: this.error,
211
208
  cached_buckets: Object.keys(this._cache).length,
212
209
  nodes: this.children.map(child => child.status()),
213
- app: this.time.end ? (this.time.end.epoch - this.time.start.epoch) : -1
210
+ app: this.time.end ? (this.time.end.epoch - this.time.start.epoch) : -1,
211
+ ext: this.action === '~' ? {
212
+ idempotent: this.input?.idempotent
213
+ } : undefined
214
214
  };
215
215
  }
216
216
  //
@@ -219,6 +219,9 @@ class TrxNode {
219
219
  to.children.push(child);
220
220
  to.trx.addNode(child);
221
221
  }
222
+ to.input = {
223
+ idempotent: from.trx.idempotent
224
+ };
222
225
  }
223
226
  static makeChildNode(node, module, block, name) {
224
227
  const child = new TrxNode(`${module}::${block}:${name}`, node.trx, node, node.module, node.auth);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nesoi",
3
- "version": "3.3.30",
3
+ "version": "3.4.1",
4
4
  "description": "Declarative framework for data-driven applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,11 +18,15 @@ export declare function expectBucket(def: (builder: AnyBucketBuilder) => any, in
18
18
  builder: AnyBucketBuilder;
19
19
  data: Record<string, any>;
20
20
  })[]): {
21
- toBuildOne(raw: Record<string, any>, view: string): {
21
+ toBuildOne(raw: Record<string, any>, view: string, flags?: {
22
+ serialize: boolean;
23
+ }): {
22
24
  as(parsed: Record<string, any> | Record<string, any>[]): Promise<void>;
23
25
  butFail(error: (...args: any[]) => NesoiError.BaseError): Promise<void>;
24
26
  };
25
- toBuildMany(raws: Record<string, any>[], view: string): {
27
+ toBuildMany(raws: Record<string, any>[], view: string, flags?: {
28
+ serialize: boolean;
29
+ }): {
26
30
  as(parsed: Record<string, any> | Record<string, any>[]): Promise<void>;
27
31
  butFail(error: (...args: any[]) => NesoiError.BaseError): Promise<void>;
28
32
  };
@@ -37,12 +37,12 @@ function expectBucket(def, inject = []) {
37
37
  });
38
38
  let promise;
39
39
  const step1 = {
40
- toBuildOne(raw, view) {
41
- promise = () => app.daemon().then(daemon => daemon.trx('test').run(trx => trx.bucket('test').buildOne(raw, view)));
40
+ toBuildOne(raw, view, flags) {
41
+ promise = () => app.daemon().then(daemon => daemon.trx('test').run(trx => trx.bucket('test').buildOne(raw, view, flags)));
42
42
  return step2;
43
43
  },
44
- toBuildMany(raws, view) {
45
- promise = () => app.daemon().then(daemon => daemon.trx('test').run(trx => trx.bucket('test').buildMany(raws, view)));
44
+ toBuildMany(raws, view, flags) {
45
+ promise = () => app.daemon().then(daemon => daemon.trx('test').run(trx => trx.bucket('test').buildMany(raws, view, flags)));
46
46
  return step2;
47
47
  }
48
48
  };