nesoi 3.3.19 → 3.3.21

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 (44) hide show
  1. package/lib/elements/edge/controller/adapters/controller_adapter.d.ts +4 -1
  2. package/lib/elements/edge/controller/adapters/controller_adapter.js +8 -4
  3. package/lib/elements/edge/controller/controller.js +3 -3
  4. package/lib/elements/edge/controller/controller.schema.d.ts +2 -1
  5. package/lib/elements/edge/controller/controller.schema.js +3 -1
  6. package/lib/elements/entities/bucket/adapters/bucket_adapter.d.ts +25 -3
  7. package/lib/elements/entities/bucket/adapters/bucket_adapter.js +21 -2
  8. package/lib/elements/entities/bucket/adapters/memory.nql.js +86 -50
  9. package/lib/elements/entities/bucket/adapters/test.bucket_adapter.d.ts +22 -0
  10. package/lib/elements/entities/bucket/adapters/test.bucket_adapter.js +23 -0
  11. package/lib/elements/entities/bucket/bucket.js +2 -2
  12. package/lib/elements/entities/bucket/cache/bucket_cache.d.ts +16 -1
  13. package/lib/elements/entities/bucket/cache/bucket_cache.js +36 -15
  14. package/lib/elements/entities/bucket/graph/bucket_graph.js +28 -18
  15. package/lib/elements/entities/bucket/query/nql.schema.d.ts +3 -0
  16. package/lib/elements/entities/bucket/query/nql_compiler.d.ts +10 -4
  17. package/lib/elements/entities/bucket/query/nql_compiler.js +42 -35
  18. package/lib/elements/entities/bucket/query/nql_engine.d.ts +4 -1
  19. package/lib/elements/entities/bucket/query/nql_engine.js +3 -5
  20. package/lib/elements/entities/message/template/message_template_field.builder.d.ts +2 -0
  21. package/lib/elements/entities/message/template/message_template_field.builder.js +5 -0
  22. package/lib/engine/daemon.d.ts +19 -0
  23. package/lib/engine/daemon.js +40 -2
  24. package/lib/engine/data/tree.d.ts +1 -2
  25. package/lib/engine/data/tree.js +6 -94
  26. package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +1 -1
  27. package/lib/engine/transaction/nodes/bucket.trx_node.js +15 -15
  28. package/lib/engine/transaction/nodes/bucket_query.trx_node.js +2 -2
  29. package/lib/engine/transaction/nodes/external.trx_node.d.ts +3 -1
  30. package/lib/engine/transaction/nodes/external.trx_node.js +54 -4
  31. package/lib/engine/transaction/nodes/job.trx_node.js +3 -2
  32. package/lib/engine/transaction/nodes/machine.trx_node.js +1 -1
  33. package/lib/engine/transaction/nodes/queue.trx_node.js +1 -1
  34. package/lib/engine/transaction/nodes/resource.trx_node.js +1 -1
  35. package/lib/engine/transaction/nodes/topic.trx_node.js +1 -1
  36. package/lib/engine/transaction/trx.d.ts +7 -1
  37. package/lib/engine/transaction/trx.js +15 -1
  38. package/lib/engine/transaction/trx_engine.config.d.ts +6 -1
  39. package/lib/engine/transaction/trx_engine.d.ts +5 -5
  40. package/lib/engine/transaction/trx_engine.js +59 -36
  41. package/lib/engine/transaction/trx_node.d.ts +1 -1
  42. package/lib/engine/transaction/trx_node.js +1 -1
  43. package/package.json +1 -1
  44. package/tsconfig.build.tsbuildinfo +1 -1
@@ -62,7 +62,7 @@ class BucketGraph {
62
62
  ...schema.query,
63
63
  '#and __tenancy__': tenancy
64
64
  };
65
- const adapter = await trx_1.Trx.getCache(trx, this.bucket) || otherBucket.cache || otherBucket.adapter;
65
+ const adapter = await trx_1.Trx.getCache(trx, otherBucket) || otherBucket.cache || otherBucket.adapter;
66
66
  links = await adapter.query(trx, query, page, params, param_templates ? [param_templates] : undefined);
67
67
  }
68
68
  // Empty response
@@ -113,8 +113,8 @@ class BucketGraph {
113
113
  const tempData = {};
114
114
  for (const obj of allLinks)
115
115
  tempData[obj.id] = obj;
116
- const otherBucket = await daemon_1.Daemon.getBucketMetadata(module.daemon, schema.bucket);
117
- tempAdapter = new memory_bucket_adapter_1.MemoryBucketAdapter(otherBucket.schema, tempData);
116
+ const otherMeta = await daemon_1.Daemon.getBucketMetadata(module.daemon, schema.bucket);
117
+ tempAdapter = new memory_bucket_adapter_1.MemoryBucketAdapter(otherMeta.schema, tempData);
118
118
  }
119
119
  // Internal
120
120
  else {
@@ -128,10 +128,10 @@ class BucketGraph {
128
128
  '#and __tenancy__': tenancy
129
129
  };
130
130
  if (otherBucket.adapter instanceof memory_bucket_adapter_1.MemoryBucketAdapter) {
131
- tempAdapter = await trx_1.Trx.getCache(trx, this.bucket) || otherBucket.cache || otherBucket.adapter;
131
+ tempAdapter = await trx_1.Trx.getCache(trx, otherBucket) || otherBucket.cache || otherBucket.adapter;
132
132
  }
133
133
  else {
134
- const adapter = await trx_1.Trx.getCache(trx, this.bucket) || otherBucket.cache || otherBucket.adapter;
134
+ const adapter = await trx_1.Trx.getCache(trx, otherBucket) || otherBucket.cache || otherBucket.adapter;
135
135
  const allLinks = await adapter.query(trx, query, undefined, params, param_templates);
136
136
  const tempData = {};
137
137
  for (const obj of allLinks.data)
@@ -141,25 +141,35 @@ class BucketGraph {
141
141
  }
142
142
  // 2nd Query
143
143
  const links = [];
144
+ const compiled = await tempAdapter._compileQuery(trx, schema.query, {
145
+ module: schema.bucket.module,
146
+ buckets: {
147
+ [schema.bucket.short]: {
148
+ scope: '__graph__',
149
+ nql: (tempAdapter instanceof bucket_cache_1.BucketCache) ? undefined : tempAdapter.nql
150
+ }
151
+ },
152
+ });
144
153
  for (const obj of objs) {
145
- const result = tempAdapter instanceof bucket_cache_1.BucketCache
146
- ? await tempAdapter.query(trx, schema.query, {
154
+ let result;
155
+ if (tempAdapter instanceof bucket_cache_1.BucketCache) {
156
+ result = await tempAdapter._queryCompiled(trx, compiled, {
147
157
  perPage: schema.many ? undefined : 1,
148
- }, [{ ...obj }], undefined)
149
- : await tempAdapter.query(trx, schema.query, {
158
+ }, [{ ...obj }], undefined);
159
+ }
160
+ else {
161
+ result = await tempAdapter._queryCompiled(trx, compiled, {
150
162
  perPage: schema.many ? undefined : 1,
151
163
  }, [{ ...obj }], undefined, undefined, {
152
164
  module: schema.bucket.module,
153
- runners: {
154
- [tempAdapter.getQueryMeta().scope]: tempAdapter.nql
165
+ buckets: {
166
+ [schema.bucket.short]: {
167
+ scope: '__graph__',
168
+ nql: tempAdapter.nql
169
+ }
155
170
  },
156
- metadata: {
157
- ...tempAdapter.getQueryMeta(),
158
- schema: tempAdapter.schema,
159
- tag: schema.bucket,
160
- meta: tempAdapter.config.meta
161
- }
162
171
  });
172
+ }
163
173
  if (schema.many) {
164
174
  links.push(result.data);
165
175
  }
@@ -239,7 +249,7 @@ class BucketGraph {
239
249
  ...schema.query,
240
250
  '#and__tenancy__': tenancy
241
251
  };
242
- const adapter = await trx_1.Trx.getCache(trx, this.bucket) || otherBucket.cache || otherBucket.adapter;
252
+ const adapter = await trx_1.Trx.getCache(trx, otherBucket) || otherBucket.cache || otherBucket.adapter;
243
253
  links = await adapter.query(trx, query, page, params);
244
254
  }
245
255
  return !!links.data.length;
@@ -13,6 +13,7 @@ export type NQL_Union = {
13
13
  inters: NQL_Intersection[];
14
14
  sort?: {
15
15
  key: string;
16
+ key_is_deep: boolean;
16
17
  dir: ('asc' | 'desc');
17
18
  }[];
18
19
  _debug_id?: number;
@@ -25,6 +26,7 @@ export type NQL_Intersection = {
25
26
  export type NQL_Rule = {
26
27
  meta: NQL_QueryMeta;
27
28
  fieldpath: string;
29
+ fieldpath_is_deep: boolean;
28
30
  op: NQL_Operation;
29
31
  case_i: boolean;
30
32
  not: boolean;
@@ -32,6 +34,7 @@ export type NQL_Rule = {
32
34
  static: any | any[];
33
35
  } | {
34
36
  param: string | string[];
37
+ param_is_deep: boolean;
35
38
  } | {
36
39
  param_with_$: string;
37
40
  } | {
@@ -1,6 +1,6 @@
1
1
  import { NQL_AnyQuery, NQL_Union, NQL_Part, NQL_Node } from './nql.schema';
2
2
  import { AnyDaemon } from "../../../../engine/daemon";
3
- import { BucketMetadata } from "../../../../engine/transaction/trx_engine";
3
+ import { NQLRunner } from './nql_engine';
4
4
  /**
5
5
  * @category NQL
6
6
  * */
@@ -9,11 +9,14 @@ export declare class NQL_RuleTree {
9
9
  private module;
10
10
  private bucketName;
11
11
  private query;
12
- private customMetadata?;
12
+ private customBuckets;
13
13
  private debug;
14
14
  private static OpByType;
15
15
  root: NQL_Union;
16
- constructor(daemon: AnyDaemon, module: string, bucketName: string, query: NQL_AnyQuery, customMetadata?: BucketMetadata | undefined, debug?: boolean);
16
+ constructor(daemon: AnyDaemon, module: string, bucketName: string, query: NQL_AnyQuery, customBuckets?: Record<string, {
17
+ scope: string;
18
+ nql: NQLRunner;
19
+ }>, debug?: boolean);
17
20
  parse(): Promise<void>;
18
21
  private parseUnion;
19
22
  private parseSort;
@@ -39,7 +42,10 @@ export declare class NQL_RuleTree {
39
42
  * @category NQL
40
43
  * */
41
44
  export declare class NQL_Compiler {
42
- static build(daemon: AnyDaemon, module: string, bucketName: string, query: NQL_AnyQuery, customMetadata?: BucketMetadata): Promise<NQL_CompiledQuery>;
45
+ static build(daemon: AnyDaemon, module: string, bucketName: string, query: NQL_AnyQuery, customBuckets?: Record<string, {
46
+ scope: string;
47
+ nql: NQLRunner;
48
+ }>): Promise<NQL_CompiledQuery>;
43
49
  static buildTree(tree: NQL_RuleTree): Promise<NQL_CompiledQuery>;
44
50
  }
45
51
  /**
@@ -13,7 +13,7 @@ class NQL_RuleTree {
13
13
  module;
14
14
  bucketName;
15
15
  query;
16
- customMetadata;
16
+ customBuckets;
17
17
  debug;
18
18
  static OpByType = {
19
19
  'boolean': ['==', 'in', 'present'],
@@ -34,18 +34,19 @@ class NQL_RuleTree {
34
34
  'unknown': ['==', 'contains', 'contains_any', 'in', 'present']
35
35
  };
36
36
  root;
37
- constructor(daemon, module, bucketName, query, customMetadata, debug = false) {
37
+ constructor(daemon, module, bucketName, query, customBuckets = {}, debug = false) {
38
38
  this.daemon = daemon;
39
39
  this.module = module;
40
40
  this.bucketName = bucketName;
41
41
  this.query = query;
42
- this.customMetadata = customMetadata;
42
+ this.customBuckets = customBuckets;
43
43
  this.debug = debug;
44
44
  }
45
45
  async parse() {
46
46
  const tag = dependency_1.Tag.fromNameOrShort(this.module, 'bucket', this.bucketName);
47
- const bucket = this.customMetadata || await daemon_1.Daemon.getBucketMetadata(this.daemon, tag);
48
- this.root = await this.parseUnion(bucket, this.query);
47
+ const meta = await daemon_1.Daemon.getBucketMetadata(this.daemon, tag);
48
+ meta.scope = this.customBuckets[tag.short]?.scope || meta.scope;
49
+ this.root = await this.parseUnion(meta, this.query);
49
50
  if (this.debug) {
50
51
  console.log(this.describe());
51
52
  }
@@ -56,10 +57,10 @@ class NQL_RuleTree {
56
57
  }
57
58
  }
58
59
  // Parse NQL
59
- async parseUnion(bucket, query, select) {
60
+ async parseUnion(meta, query, select) {
60
61
  const union = {
61
62
  meta: {
62
- ...bucket,
63
+ ...meta,
63
64
  avgTime: 0
64
65
  },
65
66
  inters: [
@@ -68,16 +69,17 @@ class NQL_RuleTree {
68
69
  };
69
70
  for (const key in query) {
70
71
  const value = query[key];
71
- const parsedKey = await this.parseKey(bucket, key);
72
+ const parsedKey = await this.parseKey(meta, key);
72
73
  // Fieldpath term -> Condition
73
74
  if (parsedKey.type === 'fieldpath') {
74
- const parsed = await this.parseValue(value, parsedKey, bucket, select);
75
+ const parsed = await this.parseValue(value, parsedKey, meta, select);
75
76
  const rule = ('subquery' in parsed)
76
77
  ? parsed.subquery.union
77
78
  : {
78
- meta: { ...bucket },
79
+ meta: { ...meta },
79
80
  select,
80
81
  fieldpath: parsedKey.fieldpath,
82
+ fieldpath_is_deep: parsedKey.fieldpath.includes('.'),
81
83
  value: parsed,
82
84
  op: parsedKey.op,
83
85
  case_i: parsedKey.case_i,
@@ -102,15 +104,15 @@ class NQL_RuleTree {
102
104
  throw new Error('Graph Link not supported yet');
103
105
  }
104
106
  else if (parsedKey.type === 'and') {
105
- const subInter = await this.parseUnion(bucket, value, select);
107
+ const subInter = await this.parseUnion(meta, value, select);
106
108
  union.inters[0].rules.push(subInter);
107
109
  }
108
110
  else if (parsedKey.type === 'or') {
109
- const subInter = await this.parseUnion(bucket, value, select);
111
+ const subInter = await this.parseUnion(meta, value, select);
110
112
  union.inters.push({ meta: {}, rules: [subInter] });
111
113
  }
112
114
  else if (parsedKey.type === 'sort') {
113
- union.sort = await this.parseSort(bucket, value);
115
+ union.sort = await this.parseSort(meta, value);
114
116
  }
115
117
  }
116
118
  if (!union.inters[0]?.rules.length) {
@@ -118,7 +120,7 @@ class NQL_RuleTree {
118
120
  }
119
121
  return union;
120
122
  }
121
- parseSort(bucket, value) {
123
+ parseSort(meta, value) {
122
124
  if (!Array.isArray(value))
123
125
  value = [value];
124
126
  if (value.some(v => typeof v !== 'string')) {
@@ -138,11 +140,11 @@ class NQL_RuleTree {
138
140
  else {
139
141
  throw new Error(`Invalid query sort direction '${key}', string must end with '@asc' or '@desc'`);
140
142
  }
141
- const is_metadata_field = Object.values(bucket.meta).includes(key);
143
+ const is_metadata_field = Object.values(meta.meta).includes(key);
142
144
  if (!is_metadata_field) {
143
- const fields = bucket_model_schema_1.$BucketModel.getField(bucket.schema.model, key);
145
+ const fields = bucket_model_schema_1.$BucketModel.getField(meta.schema.model, key);
144
146
  if (!fields.length) {
145
- throw new Error(`Field '${key}' not found on bucket '${bucket.schema.name}'`);
147
+ throw new Error(`Field '${key}' not found on bucket '${meta.schema.name}'`);
146
148
  }
147
149
  for (const field of fields) {
148
150
  if (![
@@ -154,12 +156,13 @@ class NQL_RuleTree {
154
156
  }
155
157
  sort.push({
156
158
  key,
159
+ key_is_deep: key.includes('.'),
157
160
  dir: vdir
158
161
  });
159
162
  }
160
163
  return sort;
161
164
  }
162
- async parseKey(bucket, key) {
165
+ async parseKey(meta, key) {
163
166
  if (key === '#sort') {
164
167
  return { type: 'sort' };
165
168
  }
@@ -171,9 +174,9 @@ class NQL_RuleTree {
171
174
  }
172
175
  else if (key.startsWith('*')) {
173
176
  const linkName = key.slice(1);
174
- const link = bucket.schema.graph.links[linkName];
177
+ const link = meta.schema.graph.links[linkName];
175
178
  if (!link) {
176
- throw new Error(`Graph Link '${linkName}' doesn't exist on the bucket ${bucket}`);
179
+ throw new Error(`Graph Link '${linkName}' doesn't exist on the bucket ${meta}`);
177
180
  }
178
181
  const linkBucket = await daemon_1.Daemon.getBucketMetadata(this.daemon, link.bucket);
179
182
  return { type: 'graphlink', link: link.name, linkBucket: linkBucket.schema };
@@ -184,13 +187,13 @@ class NQL_RuleTree {
184
187
  throw new Error(`Invalid term '${key}'`);
185
188
  }
186
189
  const [_, or, fieldpath, not, case_i, op] = term;
187
- if (Object.values(bucket.meta).includes(fieldpath)) {
190
+ if (Object.values(meta.meta).includes(fieldpath)) {
188
191
  const _op = this.parseOp([{ type: 'datetime', name: fieldpath }], op);
189
192
  return { type: 'fieldpath', or: !!or, fieldpath, not: !!not, case_i: !!case_i, op: _op };
190
193
  }
191
- const fields = bucket_model_schema_1.$BucketModel.getField(bucket.schema.model, fieldpath);
194
+ const fields = bucket_model_schema_1.$BucketModel.getField(meta.schema.model, fieldpath);
192
195
  if (!fields.length) {
193
- throw new Error(`Field '${fieldpath}' not found on bucket '${bucket.schema.name}'`);
196
+ throw new Error(`Field '${fieldpath}' not found on bucket '${meta.schema.name}'`);
194
197
  }
195
198
  const _op = this.parseOp(fields, op);
196
199
  return { type: 'fieldpath', or: !!or, fieldpath, not: !!not, case_i: !!case_i, op: _op };
@@ -253,7 +256,7 @@ class NQL_RuleTree {
253
256
  throw new Error(`Cannot mix static and parameter values inside array value [${value}]`);
254
257
  }
255
258
  if (params.length > 0) {
256
- return { param: params };
259
+ return { param: params, param_is_deep: params.some(p => p.includes('.')) };
257
260
  }
258
261
  else {
259
262
  return { static: statyc };
@@ -262,7 +265,7 @@ class NQL_RuleTree {
262
265
  else {
263
266
  // Parameter
264
267
  if ('.' in value) {
265
- return { param: value['.'] };
268
+ return { param: value['.'], param_is_deep: value['.'].includes('.') };
266
269
  }
267
270
  // Path Parameter
268
271
  else if ('$' in value) {
@@ -292,24 +295,28 @@ class NQL_RuleTree {
292
295
  }
293
296
  const [_, or, refBucket, fieldpath] = refField;
294
297
  const tag = dependency_1.Tag.fromNameOrShort(this.module, 'bucket', refBucket);
295
- const bucket = await daemon_1.Daemon.getBucketMetadata(this.daemon, tag);
296
- if (!bucket) {
297
- throw new Error(`Bucket '${bucket}' not found on module`);
298
+ const subMeta = await daemon_1.Daemon.getBucketMetadata(this.daemon, tag);
299
+ if (!subMeta) {
300
+ throw new Error(`Bucket '${subMeta}' not found on module`);
298
301
  }
299
- const field = bucket_model_schema_1.$BucketModel.getField(bucket.schema.model, fieldpath);
302
+ subMeta.scope = this.customBuckets[tag.short]?.scope || subMeta.scope;
303
+ const field = bucket_model_schema_1.$BucketModel.getField(subMeta.schema.model, fieldpath);
300
304
  if (!field) {
301
- throw new Error(`Field '${fieldpath}' not found on bucket '${bucket.schema.name}'`);
305
+ throw new Error(`Field '${fieldpath}' not found on bucket '${subMeta.schema.name}'`);
302
306
  }
303
- const refInter = await this.parseUnion(bucket, value[key], fieldpath);
307
+ // The union belongs to the sub scope.
308
+ const refInter = await this.parseUnion(subMeta, value[key], fieldpath);
304
309
  const rule = {
310
+ // This rule belongs to the parent scope.
305
311
  meta: { ...meta },
306
312
  select,
307
313
  fieldpath: parsedKey.fieldpath,
314
+ fieldpath_is_deep: parsedKey.fieldpath.includes('.'),
308
315
  case_i: parsedKey.case_i,
309
316
  not: parsedKey.not,
310
317
  op: parsedKey.op,
311
318
  value: {
312
- subquery: { union: refInter, bucket: bucket.schema, select: fieldpath }
319
+ subquery: { union: refInter, bucket: subMeta.schema, select: fieldpath }
313
320
  }
314
321
  };
315
322
  if (!or) {
@@ -512,8 +519,8 @@ exports.NQL_RuleTree = NQL_RuleTree;
512
519
  * @category NQL
513
520
  * */
514
521
  class NQL_Compiler {
515
- static async build(daemon, module, bucketName, query, customMetadata) {
516
- const tree = new NQL_RuleTree(daemon, module, bucketName, query, customMetadata);
522
+ static async build(daemon, module, bucketName, query, customBuckets = {}) {
523
+ const tree = new NQL_RuleTree(daemon, module, bucketName, query, customBuckets);
517
524
  return this.buildTree(tree);
518
525
  }
519
526
  static async buildTree(tree) {
@@ -659,7 +666,7 @@ class NQL_Compiler {
659
666
  // Close part (&1)
660
667
  if (rule.part) {
661
668
  // Rebuild Union on original tree as Condition
662
- buildNode.value = { param: `%__${rule.part}__%` };
669
+ buildNode.value = { param: `%__${rule.part}__%`, param_is_deep: false };
663
670
  if (rule.part == partStack.at(-1).i) {
664
671
  // debugLog.push('⊙ [part] ' + rule.part);
665
672
  orderedParts.push(parts[rule.part]);
@@ -24,7 +24,10 @@ export declare class NQL_Engine {
24
24
  private module;
25
25
  private runners;
26
26
  constructor(module: AnyModule);
27
- run(trx: AnyTrxNode, query: NQL_CompiledQuery, pagination?: NQL_Pagination, params?: Record<string, any>[], param_templates?: Record<string, string>[], view?: $BucketView, customRunners?: Record<string, NQLRunner>): Promise<NQL_Result>;
27
+ run(trx: AnyTrxNode, query: NQL_CompiledQuery, pagination?: NQL_Pagination, params?: Record<string, any>[], param_templates?: Record<string, string>[], view?: $BucketView, customBuckets?: Record<string, {
28
+ scope: string;
29
+ nql: NQLRunner;
30
+ }>): Promise<NQL_Result>;
28
31
  linkExternal(bucket: AnyBucket): void;
29
32
  }
30
33
  export {};
@@ -23,7 +23,7 @@ class NQL_Engine {
23
23
  }
24
24
  }
25
25
  }
26
- async run(trx, query, pagination, params = [{}], param_templates = [], view, customRunners) {
26
+ async run(trx, query, pagination, params = [{}], param_templates = [], view, customBuckets) {
27
27
  if (!params.length)
28
28
  params = [{}];
29
29
  if (!param_templates.length)
@@ -35,10 +35,8 @@ class NQL_Engine {
35
35
  const part_i = query.execOrder[i];
36
36
  const part = query.parts[part_i];
37
37
  // Run part
38
- const runners = customRunners
39
- ? { ...this.runners, ...customRunners }
40
- : this.runners;
41
- const _runner = runners[part.union.meta.scope];
38
+ const _runner = Object.values(customBuckets || {}).find(b => b.scope === part.union.meta.scope)?.nql
39
+ || this.runners[part.union.meta.scope];
42
40
  const out = await _runner.run(trx, part, params, param_templates, pagination, view);
43
41
  result = out;
44
42
  // Part failed, return
@@ -70,6 +70,7 @@ export declare class MessageTemplateFieldBuilder<Module extends $Module, Message
70
70
  private _required;
71
71
  private _defaultValue?;
72
72
  private _nullable;
73
+ private _rawName?;
73
74
  private _rules;
74
75
  constructor(type: $MessageTemplateFieldType, meta: Omit<$MessageTemplateFieldMeta, 'enum' | 'msg' | 'id'> & {
75
76
  enum?: {
@@ -97,6 +98,7 @@ export declare class MessageTemplateFieldBuilder<Module extends $Module, Message
97
98
  ], InputSuffix>;
98
99
  get nullable(): MessageTemplateFieldBuilder<Module, Message, Input | null, Output | null, Children, Optional, InputSuffix>;
99
100
  rule(rule: MessageTemplateRuleDef<Output, Message['#raw']>): this;
101
+ rawName(name: string): this;
100
102
  static build(builder: AnyMessageTemplateFieldBuilder, name: string, tree: ModuleTree, module: $Module, basePathRaw: string, basePathParsed: string): $MessageTemplateField;
101
103
  static buildMany(fields: MessageTemplateFieldBuilders, tree: ModuleTree, module: $Module, basePathRaw?: string, basePathParsed?: string, name?: string, key?: string): $MessageTemplateFields;
102
104
  }
@@ -138,6 +138,7 @@ class MessageTemplateFieldBuilder {
138
138
  _required = true;
139
139
  _defaultValue = undefined;
140
140
  _nullable = false;
141
+ _rawName;
141
142
  _rules = [];
142
143
  constructor(type, meta, alias, children) {
143
144
  this.type = type;
@@ -166,6 +167,10 @@ class MessageTemplateFieldBuilder {
166
167
  this._rules.push(rule);
167
168
  return this;
168
169
  }
170
+ rawName(name) {
171
+ this._rawName = name;
172
+ return this;
173
+ }
169
174
  // Build
170
175
  static build(builder, name, tree, module, basePathRaw, basePathParsed) {
171
176
  const pathRaw = basePathRaw + (builder.type === 'id' ? `${name}_id` : name);
@@ -123,10 +123,29 @@ export declare class DaemonTrx<S extends $Space, M extends $Module, AuthUsers ex
123
123
  * authenticate this transaction prior to running.
124
124
  */
125
125
  private tokens?;
126
+ /**
127
+ *
128
+ */
129
+ private _origin?;
130
+ /**
131
+ * An idempotent transaction doesn't generate a commit/rollback.
132
+ */
133
+ private _idempotent;
126
134
  /**
127
135
  * @param trxEngine The transaction engine where to run the transaction.
128
136
  */
129
137
  constructor(trxEngine: AnyTrxEngine);
138
+ origin(origin: string): this;
139
+ /**
140
+ * Flags this transaction as idempotent.
141
+ * This means its not stored, neither commited/rolled back.
142
+ * This should generally be used for readonly transactions.
143
+ */
144
+ get idempotent(): this;
145
+ /**
146
+ * Inherit authentication from another transaction node.
147
+ */
148
+ idempotent_inherit(trx: AnyTrxNode): this;
130
149
  /**
131
150
  * Inherit authentication from another transaction node.
132
151
  */
@@ -176,12 +176,40 @@ class DaemonTrx {
176
176
  * authenticate this transaction prior to running.
177
177
  */
178
178
  tokens;
179
+ /**
180
+ *
181
+ */
182
+ _origin;
183
+ /**
184
+ * An idempotent transaction doesn't generate a commit/rollback.
185
+ */
186
+ _idempotent = false;
179
187
  /**
180
188
  * @param trxEngine The transaction engine where to run the transaction.
181
189
  */
182
190
  constructor(trxEngine) {
183
191
  this.trxEngine = trxEngine;
184
192
  }
193
+ origin(origin) {
194
+ this._origin = origin;
195
+ return this;
196
+ }
197
+ /**
198
+ * Flags this transaction as idempotent.
199
+ * This means its not stored, neither commited/rolled back.
200
+ * This should generally be used for readonly transactions.
201
+ */
202
+ get idempotent() {
203
+ this._idempotent = true;
204
+ return this;
205
+ }
206
+ /**
207
+ * Inherit authentication from another transaction node.
208
+ */
209
+ idempotent_inherit(trx) {
210
+ this._idempotent = trx.trx.idempotent;
211
+ return this;
212
+ }
185
213
  /**
186
214
  * Inherit authentication from another transaction node.
187
215
  */
@@ -211,7 +239,7 @@ class DaemonTrx {
211
239
  ...this.tokens
212
240
  };
213
241
  const users = inheritedAuth?.users;
214
- return this.trxEngine.trx(fn, id, tokens, users);
242
+ return this.trxEngine.trx(fn, id, tokens, users, this._origin, this._idempotent);
215
243
  }
216
244
  /**
217
245
  * Run a method inside the transaction, and hold it until
@@ -220,13 +248,23 @@ class DaemonTrx {
220
248
  * @param fn A function to execute inside the transaction
221
249
  * @returns A `TrxStatus` containing metadata about the transaction and the function response
222
250
  */
223
- run_and_hold(fn, id) {
251
+ async run_and_hold(fn, id) {
224
252
  const inheritedAuth = this._inherit.auth;
225
253
  const tokens = {
226
254
  ...inheritedAuth?.tokens,
227
255
  ...this.tokens
228
256
  };
229
257
  const users = inheritedAuth?.users;
258
+ // Idempotent transactions are not commited/rolled back, so they don't need to be held.
259
+ if (this._idempotent) {
260
+ const status = await this.trxEngine.trx(fn, id, tokens, users, this._origin, this._idempotent);
261
+ return {
262
+ id: status.id,
263
+ status,
264
+ commit: () => Promise.resolve(),
265
+ rollback: () => Promise.resolve(),
266
+ };
267
+ }
230
268
  return this.trxEngine.trx_hold(fn, id, tokens, users);
231
269
  }
232
270
  }
@@ -13,7 +13,6 @@ export declare class Tree {
13
13
  *
14
14
  * @deprecated Fieldpath was consolidated into Modelpath and Querypath.
15
15
  */
16
- static get(obj: Record<string, any>, fieldpath: string, index?: '*' | 0 | (number | string)[]): any;
17
- static getModelpath(obj: Record<string, any>, modelpath: string, index: (string | number)[]): any[];
16
+ static get(obj: Record<string, any>, fieldpath: string): any;
18
17
  static set(obj: Record<string, any>, fieldpath: string, replacer: (v: any, i: (number | string)[]) => any, __index?: (number | string)[]): void;
19
18
  }