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
@@ -4,7 +4,6 @@
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Tree = void 0;
7
- const error_1 = require("./error");
8
7
  /**
9
8
  * @category Engine
10
9
  * @subcategory Data
@@ -20,112 +19,25 @@ class Tree {
20
19
  *
21
20
  * @deprecated Fieldpath was consolidated into Modelpath and Querypath.
22
21
  */
23
- static get(obj, fieldpath, index = '*') {
24
- index = (!Array.isArray(index)) ? index : [...index];
22
+ static get(obj, fieldpath) {
23
+ if (!fieldpath.includes('.'))
24
+ return obj[fieldpath];
25
25
  const paths = fieldpath.split('.');
26
- const pathIndexCount = paths.filter(p => p === '#').length;
27
- if (Array.isArray(index) && pathIndexCount > index.length) {
28
- throw error_1.NesoiError.Bucket.Fieldpath.InvalidIndexLength({ fieldpath, index });
29
- }
30
26
  let ref = obj;
31
27
  for (let i = 0; i < paths.length; i++) {
32
28
  const path = paths[i];
33
- if (path === '#') {
34
- // 0 index, read the first item from the list
35
- if (index === 0) {
36
- // This is a TypeAsObj, stay on the node
37
- if (typeof ref === 'object' && '__array' in ref) {
38
- //
39
- }
40
- else {
41
- if (typeof ref !== 'object') {
42
- return undefined;
43
- }
44
- if (Array.isArray(ref)) {
45
- ref = ref[0];
46
- }
47
- else {
48
- ref = ref[Object.keys(ref)[0]];
49
- }
50
- }
51
- }
52
- // Null index, return a list of all items
53
- else if (index === '*') {
54
- if (typeof ref !== 'object') {
55
- return undefined;
56
- }
57
- if (!Array.isArray(ref)) {
58
- ref = Object.values(ref);
59
- }
60
- const childPath = paths.slice(i + 1);
61
- if (childPath.length === 0) {
62
- return ref;
63
- }
64
- const out = [];
65
- ref.forEach((v) => {
66
- const deep = this.get(v, childPath.join('.'), '*');
67
- if (deep !== undefined)
68
- out.push(deep);
69
- });
70
- return out.flat(1);
71
- }
72
- // List of indices, advance on it
73
- else {
74
- const idx = index.shift();
75
- if (idx === undefined) {
76
- return undefined;
77
- }
78
- ref = ref[idx];
79
- }
80
- }
81
- else {
82
- ref = ref?.[path];
83
- }
29
+ ref = ref?.[path];
84
30
  if (ref === undefined) {
85
- return ref;
31
+ return undefined;
86
32
  }
87
33
  }
88
34
  // When reading from a TypeAsObj,
89
35
  // advance on unions
90
36
  if (!ref && '__or' in obj) {
91
- return this.get(obj.__or, fieldpath, index);
37
+ return this.get(obj.__or, fieldpath);
92
38
  }
93
39
  return ref;
94
40
  }
95
- static getModelpath(obj, modelpath, index) {
96
- const paths = modelpath.split('.');
97
- let poll = [obj];
98
- while (poll.length) {
99
- const next = [];
100
- for (const item of poll) {
101
- const path = paths[item.i];
102
- // '*'
103
- if (path === '*') {
104
- if (typeof item !== 'object') {
105
- throw new Error(`Can't read *, item is not object (${item})`);
106
- }
107
- next.push(...Object.values(item));
108
- }
109
- else {
110
- const idx_str = path.match(/^\$(\d+)/)?.[1];
111
- let _path = path;
112
- // $0, $1..
113
- if (idx_str !== undefined) {
114
- const idx = parseInt(idx_str);
115
- if (idx >= index.length) {
116
- throw new Error(`Can't read $${idx}, too few indexes (${index.length})`);
117
- }
118
- _path = index[idx];
119
- }
120
- const n = typeof item === 'object' ? item[_path] : undefined;
121
- if (n)
122
- next.push(n);
123
- }
124
- }
125
- poll = next;
126
- }
127
- return poll;
128
- }
129
41
  static set(obj, fieldpath, replacer, __index = []) {
130
42
  const paths = fieldpath.split('.');
131
43
  class Ptr {
@@ -20,7 +20,7 @@ export declare class BucketTrxNode<M extends $Module, $ extends $Bucket> {
20
20
  private bucket?;
21
21
  constructor(trx: TrxNode<any, M, any>, tag: Tag);
22
22
  get no_tenancy(): this;
23
- wrap(action: string, input: Record<string, any>, fn: (trx: AnyTrxNode, element: Bucket<M, $>) => Promise<any>, fmtTrxOut?: (out: any) => any): Promise<any>;
23
+ wrap(action: string, input: Record<string, any>, fn: (trx: AnyTrxNode, element: Bucket<M, $>) => Promise<any>, fmtTrxOut?: (out: any) => any, idempotent?: boolean): Promise<any>;
24
24
  /**
25
25
  * Returns one object by `id`, without pre-formatting,
26
26
  * or `undefined` if the object was not found.
@@ -39,7 +39,7 @@ class BucketTrxNode {
39
39
  /*
40
40
  Wrap
41
41
  */
42
- async wrap(action, input, fn, fmtTrxOut) {
42
+ async wrap(action, input, fn, fmtTrxOut, idempotent = false) {
43
43
  const wrapped = async (parentTrx, bucket) => {
44
44
  const trx = trx_node_1.TrxNode.makeChildNode(parentTrx, bucket.schema.module, 'bucket', bucket.schema.name);
45
45
  trx_node_1.TrxNode.open(trx, action, input);
@@ -54,8 +54,8 @@ class BucketTrxNode {
54
54
  return out;
55
55
  };
56
56
  if (this.external) {
57
- const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag);
58
- return ext.run(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
57
+ const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag, idempotent);
58
+ return ext.run_and_hold(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
59
59
  }
60
60
  else {
61
61
  return wrapped(this.trx, this.bucket);
@@ -72,7 +72,7 @@ class BucketTrxNode {
72
72
  return this.wrap('readOne', { id }, (trx, bucket) => bucket.readOne(trx, id, {
73
73
  silent: true,
74
74
  no_tenancy: !this.enableTenancy
75
- }));
75
+ }), undefined, true);
76
76
  }
77
77
  /**
78
78
  * Returns one object by `id` formated with the specified view,
@@ -84,7 +84,7 @@ class BucketTrxNode {
84
84
  return this.wrap('viewOne', { id }, (trx, bucket) => bucket.viewOne(trx, id, view, {
85
85
  silent: true,
86
86
  no_tenancy: !this.enableTenancy
87
- }));
87
+ }), undefined, true);
88
88
  }
89
89
  /**
90
90
  * Returns one object by `id`, without pre-formatting,
@@ -93,7 +93,7 @@ class BucketTrxNode {
93
93
  async readOneOrFail(id) {
94
94
  return this.wrap('readOneOrFail', { id }, (trx, bucket) => bucket.readOne(trx, id, {
95
95
  no_tenancy: !this.enableTenancy
96
- }));
96
+ }), undefined, true);
97
97
  }
98
98
  /**
99
99
  * Returns one object by `id`, without pre-formatting,
@@ -104,7 +104,7 @@ class BucketTrxNode {
104
104
  async viewOneOrFail(id, view = 'default') {
105
105
  return this.wrap('viewOneOrFail', { id }, (trx, bucket) => bucket.viewOne(trx, id, view, {
106
106
  no_tenancy: !this.enableTenancy
107
- }));
107
+ }), undefined, true);
108
108
  }
109
109
  /*
110
110
  Read/View All
@@ -115,7 +115,7 @@ class BucketTrxNode {
115
115
  async readAll() {
116
116
  return this.wrap('readAll', {}, (trx, bucket) => bucket.readAll(trx, {
117
117
  no_tenancy: !this.enableTenancy
118
- }), objs => ({ length: objs.length }));
118
+ }), objs => ({ length: objs.length }), true);
119
119
  }
120
120
  /**
121
121
  * Returns a list of all objects formated with the specified view.
@@ -125,7 +125,7 @@ class BucketTrxNode {
125
125
  async viewAll(view = 'default') {
126
126
  return this.wrap('viewAll', {}, (trx, bucket) => bucket.viewAll(trx, view, {
127
127
  no_tenancy: !this.enableTenancy
128
- }), objs => ({ length: objs.length }));
128
+ }), objs => ({ length: objs.length }), true);
129
129
  }
130
130
  /*
131
131
  Query
@@ -154,7 +154,7 @@ class BucketTrxNode {
154
154
  silent: true,
155
155
  no_tenancy: !this.enableTenancy,
156
156
  index
157
- }));
157
+ }), undefined, true);
158
158
  }
159
159
  /**
160
160
  * Returns one or more objects referenced by the graph link,
@@ -165,7 +165,7 @@ class BucketTrxNode {
165
165
  silent: true,
166
166
  no_tenancy: !this.enableTenancy,
167
167
  indexes
168
- }));
168
+ }), undefined, true);
169
169
  }
170
170
  /**
171
171
  * Returns one or more objects referenced by the graph link built with a view,
@@ -175,7 +175,7 @@ class BucketTrxNode {
175
175
  return this.wrap('viewLink', { id, link, view }, (trx, bucket) => bucket.viewLink(trx, id, link, view, {
176
176
  silent: true,
177
177
  no_tenancy: !this.enableTenancy
178
- }));
178
+ }), undefined, true);
179
179
  }
180
180
  /**
181
181
  * Returns one or more objects referenced by the graph link,
@@ -184,7 +184,7 @@ class BucketTrxNode {
184
184
  async readLinkOrFail(id, link) {
185
185
  return this.wrap('readLinkOrFail', { id, link }, (trx, bucket) => bucket.readLink(trx, id, link, {
186
186
  no_tenancy: !this.enableTenancy
187
- }));
187
+ }), undefined, true);
188
188
  }
189
189
  /**
190
190
  * Returns one or more objects referenced by the graph link built with a view,
@@ -193,7 +193,7 @@ class BucketTrxNode {
193
193
  async viewLinkOrFail(id, link, view = 'default') {
194
194
  return this.wrap('viewLinkOrFail', { id, link, view }, (trx, bucket) => bucket.viewLink(trx, id, link, view, {
195
195
  no_tenancy: !this.enableTenancy
196
- }));
196
+ }), undefined, true);
197
197
  }
198
198
  /**
199
199
  * Returns `true` if the graph link resolves to at least 1 object.
@@ -201,7 +201,7 @@ class BucketTrxNode {
201
201
  async hasLink(id, link) {
202
202
  return this.wrap('hasLink', { id, link }, (trx, bucket) => bucket.hasLink(trx, id, link, {
203
203
  no_tenancy: !this.enableTenancy
204
- }));
204
+ }), undefined, true);
205
205
  }
206
206
  /*
207
207
  Create
@@ -70,8 +70,8 @@ class BucketQueryTrxNode {
70
70
  return out;
71
71
  };
72
72
  if (this.external) {
73
- const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag);
74
- return ext.run(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
73
+ const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag, true);
74
+ return ext.run_and_hold(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
75
75
  }
76
76
  else {
77
77
  return wrapped(this.trx, this.bucket);
@@ -9,7 +9,9 @@ import { Tag } from "../../dependency";
9
9
  export declare class ExternalTrxNode<M extends $Module, $ extends $Topic> {
10
10
  private trx;
11
11
  private tag;
12
+ private idempotent;
12
13
  private daemon;
13
- constructor(trx: TrxNode<any, M, any>, tag: Tag);
14
+ constructor(trx: TrxNode<any, M, any>, tag: Tag, idempotent?: boolean);
15
+ run_and_hold(element: (trx: AnyTrxNode) => any, fn: (trx: AnyTrxNode, element: any) => Promise<any>): Promise<any>;
14
16
  run(element: (trx: AnyTrxNode) => any, fn: (trx: AnyTrxNode, element: any) => Promise<any>): Promise<any>;
15
17
  }
@@ -10,17 +10,19 @@ const error_1 = require("../../data/error");
10
10
  class ExternalTrxNode {
11
11
  trx;
12
12
  tag;
13
+ idempotent;
13
14
  daemon;
14
- constructor(trx, tag) {
15
+ constructor(trx, tag, idempotent = false) {
15
16
  this.trx = trx;
16
17
  this.tag = tag;
18
+ this.idempotent = idempotent;
17
19
  const _module = trx_node_1.TrxNode.getModule(trx);
18
20
  if (!_module.daemon) {
19
21
  throw error_1.NesoiError.Trx.DaemonNotFound(_module.name);
20
22
  }
21
23
  this.daemon = _module.daemon;
22
24
  }
23
- async run(element, fn) {
25
+ async run_and_hold(element, fn) {
24
26
  const root = this.trx.trx;
25
27
  const module = trx_node_1.TrxNode.getModule(this.trx);
26
28
  const trx = trx_node_1.TrxNode.makeChildNode(this.trx, module.name, 'externals', this.tag.full);
@@ -29,7 +31,14 @@ class ExternalTrxNode {
29
31
  });
30
32
  let out;
31
33
  try {
32
- const res = await this.daemon.trx(this.tag.module)
34
+ const dtrx = await this.daemon.trx(this.tag.module)
35
+ .origin('ext:' + root.id);
36
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
37
+ if (this.idempotent)
38
+ dtrx.idempotent;
39
+ else
40
+ dtrx.idempotent_inherit(trx);
41
+ const res = await dtrx
33
42
  .auth_inherit(trx)
34
43
  .run_and_hold(async (extTrx) => {
35
44
  try {
@@ -46,7 +55,48 @@ class ExternalTrxNode {
46
55
  throw res.status.error;
47
56
  }
48
57
  out = res.status.output;
49
- root.holdNode(res);
58
+ if (!trx.trx.idempotent) {
59
+ root.holdNode(res);
60
+ }
61
+ }
62
+ catch (e) {
63
+ throw trx_node_1.TrxNode.error(trx, e);
64
+ }
65
+ trx_node_1.TrxNode.ok(trx, out);
66
+ return out;
67
+ }
68
+ async run(element, fn) {
69
+ const root = this.trx.trx;
70
+ const module = trx_node_1.TrxNode.getModule(this.trx);
71
+ const trx = trx_node_1.TrxNode.makeChildNode(this.trx, module.name, 'externals', this.tag.full);
72
+ trx_node_1.TrxNode.open(trx, '~', {
73
+ tag: this.tag
74
+ });
75
+ let out;
76
+ try {
77
+ const dtrx = await this.daemon.trx(this.tag.module);
78
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
79
+ if (this.idempotent)
80
+ dtrx.idempotent;
81
+ else
82
+ dtrx.idempotent_inherit(trx);
83
+ const res = await dtrx
84
+ .auth_inherit(trx)
85
+ .run(async (extTrx) => {
86
+ try {
87
+ return await fn(extTrx, element(extTrx));
88
+ }
89
+ catch (e) {
90
+ throw trx_node_1.TrxNode.error(extTrx, e);
91
+ }
92
+ finally {
93
+ trx_node_1.TrxNode.merge(trx, extTrx);
94
+ }
95
+ }, root.id);
96
+ if (res.state === 'error') {
97
+ throw res.error;
98
+ }
99
+ out = res.output;
50
100
  }
51
101
  catch (e) {
52
102
  throw trx_node_1.TrxNode.error(trx, e);
@@ -46,8 +46,9 @@ class JobTrxNode {
46
46
  return out;
47
47
  };
48
48
  if (this.external) {
49
- const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag);
50
- return ext.run(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
49
+ const root = this.trx.trx;
50
+ const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag, root.idempotent);
51
+ return ext.run_and_hold(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
51
52
  }
52
53
  else {
53
54
  return wrapped(this.trx, this.job);
@@ -45,7 +45,7 @@ class MachineTrxNode {
45
45
  };
46
46
  if (this.external) {
47
47
  const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag);
48
- return ext.run(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
48
+ return ext.run_and_hold(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
49
49
  }
50
50
  else {
51
51
  return wrapped(this.trx, this.machine);
@@ -45,7 +45,7 @@ class QueueTrxNode {
45
45
  };
46
46
  if (this.external) {
47
47
  const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag);
48
- return ext.run(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
48
+ return ext.run_and_hold(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
49
49
  }
50
50
  else {
51
51
  return wrapped(this.trx, this.queue);
@@ -45,7 +45,7 @@ class ResourceTrxNode {
45
45
  };
46
46
  if (this.external) {
47
47
  const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag);
48
- return ext.run(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
48
+ return ext.run_and_hold(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
49
49
  }
50
50
  else {
51
51
  return wrapped(this.trx, this.resource);
@@ -45,7 +45,7 @@ class TopicTrxNode {
45
45
  };
46
46
  if (this.external) {
47
47
  const ext = new external_trx_node_1.ExternalTrxNode(this.trx, this.tag);
48
- return ext.run(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
48
+ return ext.run_and_hold(trx => dependency_1.Tag.element(this.tag, trx), wrapped);
49
49
  }
50
50
  else {
51
51
  return wrapped(this.trx, this.resource);
@@ -7,6 +7,7 @@ import { NesoiDatetime } from '../data/datetime';
7
7
  import { NesoiError } from '../data/error';
8
8
  import { AnyBucketCache } from "../../elements/entities/bucket/cache/bucket_cache";
9
9
  import { AnyBucket } from "../../elements/entities/bucket/bucket";
10
+ import { NQLRunner } from "../../elements/entities/bucket/query/nql_engine";
10
11
  type TrxOrigin = TrxEngineOrigin | `trx:${string}`;
11
12
  type TrxState = 'open' | 'hold' | 'ok' | 'error';
12
13
  /**
@@ -34,6 +35,7 @@ export declare class Trx<S extends $Space, M extends $Module, AuthUsers extends
34
35
  private module;
35
36
  id: string;
36
37
  private origin;
38
+ idempotent: boolean;
37
39
  root: TrxNode<S, M, AuthUsers>;
38
40
  nodes: Record<string, TrxNode<S, M, AuthUsers>>;
39
41
  holds: Record<string, TrxNodeHold<any>>;
@@ -42,7 +44,7 @@ export declare class Trx<S extends $Space, M extends $Module, AuthUsers extends
42
44
  ctx: Record<string, any>;
43
45
  cache_config: Record<string, 'eager'>;
44
46
  cache: Record<string, AnyBucketCache>;
45
- constructor(engine: AnyTrxEngine, module: Module<S, M>, origin: TrxOrigin, auth?: {
47
+ constructor(engine: AnyTrxEngine, module: Module<S, M>, origin: TrxOrigin, idempotent?: boolean, auth?: {
46
48
  tokens: AuthRequest<any>;
47
49
  users: AuthUsers;
48
50
  }, id?: string, root?: TrxNode<S, M, AuthUsers>, nodes?: Record<string, TrxNode<S, M, AuthUsers>>);
@@ -56,6 +58,10 @@ export declare class Trx<S extends $Space, M extends $Module, AuthUsers extends
56
58
  * These are configured through the TrxNode.cache method.
57
59
  */
58
60
  static getCache(node: AnyTrxNode, bucket: AnyBucket): Promise<AnyBucketCache | undefined>;
61
+ static getCacheCustomBuckets(node: AnyTrxNode): Record<string, {
62
+ scope: string;
63
+ nql: NQLRunner;
64
+ }>;
59
65
  /**
60
66
  * Context Manipulation
61
67
  *
@@ -70,6 +70,7 @@ class Trx {
70
70
  module;
71
71
  id;
72
72
  origin;
73
+ idempotent;
73
74
  root;
74
75
  nodes;
75
76
  holds = {};
@@ -78,11 +79,12 @@ class Trx {
78
79
  ctx = {};
79
80
  cache_config = {};
80
81
  cache = {};
81
- constructor(engine, module, origin, auth, id, root, nodes) {
82
+ constructor(engine, module, origin, idempotent, auth, id, root, nodes) {
82
83
  this.engine = engine;
83
84
  this.module = module;
84
85
  this.id = id || (Math.random() + 1).toString(36).substring(7);
85
86
  this.origin = origin;
87
+ this.idempotent = idempotent ?? false;
86
88
  this.root = root || new trx_node_1.TrxNode('root', this, undefined, module, auth, false, id);
87
89
  this.nodes = nodes || {};
88
90
  }
@@ -129,6 +131,18 @@ class Trx {
129
131
  }
130
132
  return cache;
131
133
  }
134
+ static getCacheCustomBuckets(node) {
135
+ const trx = node.trx;
136
+ const buckets = {};
137
+ for (const tag in trx.cache) {
138
+ const adapter = trx.cache[tag].innerAdapter;
139
+ buckets[tag] = {
140
+ scope: `__cache_${tag}`,
141
+ nql: adapter.nql
142
+ };
143
+ }
144
+ return buckets;
145
+ }
132
146
  /**
133
147
  * Context Manipulation
134
148
  *
@@ -10,5 +10,10 @@ export type TrxEngineConfig<S extends $Space, M extends $Module, AuthUsers exten
10
10
  * Adapter used to store transactions of this module.
11
11
  */
12
12
  adapter?: (schema: M) => BucketAdapter<TrxData>;
13
- wrap?: <T extends Trx<S, M, AuthUsers>>(trx: T, fn: TrxEngineWrapFn<S, M>, services: Services) => Promise<any>;
13
+ wrap?: {
14
+ begin: <T extends Trx<S, M, AuthUsers>>(trx: T, services: Services) => Promise<void>;
15
+ continue: <T extends Trx<S, M, AuthUsers>>(trx: T, services: Services) => Promise<void>;
16
+ commit: <T extends Trx<S, M, AuthUsers>>(trx: T, services: Services) => Promise<void>;
17
+ rollback: <T extends Trx<S, M, AuthUsers>>(trx: T, services: Services) => Promise<void>;
18
+ }[];
14
19
  };
@@ -20,8 +20,8 @@ export type TrxData = {
20
20
  export type HeldTrxNode<Output> = {
21
21
  id: string;
22
22
  status: TrxStatus<Output>;
23
- commit: () => Promise<AnyTrx>;
24
- rollback: (error: string) => Promise<AnyTrx>;
23
+ commit: () => Promise<any>;
24
+ rollback: (error: string) => Promise<any>;
25
25
  };
26
26
  export type BucketMetadata = ReturnType<AnyBucket['getQueryMeta']> & {
27
27
  tag: Tag;
@@ -45,9 +45,9 @@ export declare class TrxEngine<S extends $Space, M extends $Module, AuthUsers ex
45
45
  private adapter;
46
46
  constructor(origin: TrxEngineOrigin, module: Module<S, M>, authnProviders?: AuthUsers | undefined, config?: TrxEngineConfig<S, M, any, any> | undefined, services?: Record<string, IService>);
47
47
  getModule(): Module<S, M>;
48
- get(id?: string): Promise<Trx<S, M, any>>;
49
- trx(fn: (trx: TrxNode<S, M, any>) => Promise<TrxNodeStatus>, id?: string, tokens?: AuthRequest<keyof AuthUsers>, users?: Partial<AuthUsers>): Promise<TrxStatus<any>>;
50
- trx_hold(fn: (trx: TrxNode<S, M, any>) => Promise<any>, id?: string, authn?: AuthRequest<keyof AuthUsers>, users?: Partial<AuthUsers>): Promise<HeldTrxNode<any>>;
48
+ get(id?: string, origin?: string, idempotent?: boolean): Promise<Trx<S, M, any>>;
49
+ trx(fn: (trx: TrxNode<S, M, any>) => Promise<TrxNodeStatus>, id?: string, tokens?: AuthRequest<keyof AuthUsers>, users?: Partial<AuthUsers>, origin?: string, idempotent?: boolean): Promise<TrxStatus<any>>;
50
+ trx_hold(fn: (trx: TrxNode<S, M, any>) => Promise<any>, id?: string, authn?: AuthRequest<keyof AuthUsers>, users?: Partial<AuthUsers>, origin?: string, idempotent?: boolean): Promise<HeldTrxNode<any>>;
51
51
  getBucketMetadata(tag: Tag): BucketMetadata;
52
52
  getBucketDrive(tag: Tag): DriveAdapter | undefined;
53
53
  authenticate(node: TrxNode<S, M, any>, tokens?: AuthRequest<keyof AuthUsers>, users?: AnyUsers, force?: boolean): Promise<void>;