nesoi 3.3.20 → 3.3.22

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 +26 -3
  7. package/lib/elements/entities/bucket/adapters/bucket_adapter.js +32 -2
  8. package/lib/elements/entities/bucket/adapters/memory.nql.js +80 -44
  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 +17 -1
  13. package/lib/elements/entities/bucket/cache/bucket_cache.js +47 -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 +2 -1
  37. package/lib/engine/transaction/trx.js +3 -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
@@ -13,7 +13,10 @@ export declare abstract class ControllerAdapter {
13
13
  protected schema: $Controller;
14
14
  protected daemon?: AnyDaemon;
15
15
  constructor(module: $Module, schema: $Controller);
16
- trx(fn: (trx: AnyTrxNode) => Promise<any>, auth?: AuthRequest<any>): Promise<import("../../../../engine/transaction/trx").TrxStatus<any>>;
16
+ trx(fn: (trx: AnyTrxNode) => Promise<any>, endpoint: {
17
+ name: string;
18
+ idempotent?: boolean;
19
+ }, auth?: AuthRequest<any>): Promise<import("../../../../engine/transaction/trx").TrxStatus<any>>;
17
20
  bind(daemon: AnyDaemon): void;
18
21
  protected abstract makeEndpoint(path: string, schema: $ControllerEndpoint): void;
19
22
  protected abstract makeTopic(schema: $ControllerTopic): void;
@@ -14,14 +14,18 @@ class ControllerAdapter {
14
14
  this.module = module;
15
15
  this.schema = schema;
16
16
  }
17
- async trx(fn, auth) {
17
+ async trx(fn, endpoint, auth) {
18
18
  if (!this.daemon) {
19
19
  throw new Error('Controller not bound to a daemon');
20
20
  }
21
21
  try {
22
- return await this.daemon.trx(this.schema.module)
23
- .auth(auth)
24
- .run(fn);
22
+ const trx = this.daemon.trx(this.schema.module)
23
+ .origin(endpoint.name)
24
+ .auth(auth);
25
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
26
+ if (endpoint.idempotent)
27
+ trx.idempotent;
28
+ return await trx.run(fn);
25
29
  }
26
30
  catch (e) {
27
31
  log_1.Log.error('controller', this.schema.name, 'Unknown error', e);
@@ -36,7 +36,7 @@ class ControllerEndpoint {
36
36
  if (this.schema.target.type === 'machine') {
37
37
  return trx.machine(this.schema.target.short).run(raw);
38
38
  }
39
- }, auth);
39
+ }, this.schema, auth);
40
40
  }
41
41
  }
42
42
  exports.ControllerEndpoint = ControllerEndpoint;
@@ -57,7 +57,7 @@ class ControllerTopic {
57
57
  const response = await this.adapter.trx(async (trx) => {
58
58
  await trx_node_1.TrxNode.checkAuth(trx, this.schema.auth);
59
59
  return trx.topic(this.schema.name).subscribe(fn);
60
- }, auth);
60
+ }, this.schema, auth);
61
61
  if (response.state === 'error') {
62
62
  throw error_1.NesoiError.Controller.SubscribeFailed({ topic: this.schema.alias });
63
63
  }
@@ -67,7 +67,7 @@ class ControllerTopic {
67
67
  const response = await this.adapter.trx(async (trx) => {
68
68
  await trx_node_1.TrxNode.checkAuth(trx, this.schema.auth);
69
69
  return trx.topic(this.schema.name).unsubscribe(id);
70
- });
70
+ }, this.schema);
71
71
  if (response.state === 'error') {
72
72
  throw error_1.NesoiError.Controller.UnsubscribeFailed({ topic: this.schema.alias });
73
73
  }
@@ -14,8 +14,9 @@ export declare class $ControllerEndpoint {
14
14
  msg: Tag;
15
15
  target: Tag;
16
16
  implicit?: Record<string, any> | undefined;
17
+ idempotent: boolean;
17
18
  $t: string;
18
- constructor(name: string, alias: string, auth: $BlockAuth[], tags: string[], msg: Tag, target: Tag, implicit?: Record<string, any> | undefined);
19
+ constructor(name: string, alias: string, auth: $BlockAuth[], tags: string[], msg: Tag, target: Tag, implicit?: Record<string, any> | undefined, idempotent?: boolean);
19
20
  }
20
21
  /**
21
22
  * @category Schemas
@@ -13,8 +13,9 @@ class $ControllerEndpoint {
13
13
  msg;
14
14
  target;
15
15
  implicit;
16
+ idempotent;
16
17
  $t = 'controller.endpoint';
17
- constructor(name, alias, auth, tags, msg, target, implicit) {
18
+ constructor(name, alias, auth, tags, msg, target, implicit, idempotent = false) {
18
19
  this.name = name;
19
20
  this.alias = alias;
20
21
  this.auth = auth;
@@ -22,6 +23,7 @@ class $ControllerEndpoint {
22
23
  this.msg = msg;
23
24
  this.target = target;
24
25
  this.implicit = implicit;
26
+ this.idempotent = idempotent;
25
27
  }
26
28
  }
27
29
  exports.$ControllerEndpoint = $ControllerEndpoint;
@@ -3,8 +3,8 @@ import { NesoiObj, ObjWithOptionalId } from "../../../../engine/data/obj";
3
3
  import { BucketCacheSync } from '../cache/bucket_cache';
4
4
  import { NQL_AnyQuery, NQL_Pagination } from '../query/nql.schema';
5
5
  import { NQLRunner, NQL_Result } from '../query/nql_engine';
6
+ import { NQL_CompiledQuery } from '../query/nql_compiler';
6
7
  import { $Bucket } from "../../..";
7
- import { BucketMetadata } from "../../../../engine/transaction/trx_engine";
8
8
  export type BucketAdapterConfig = {
9
9
  meta: {
10
10
  created_at: string;
@@ -146,8 +146,30 @@ export declare abstract class BucketAdapter<Obj extends NesoiObj, Config extends
146
146
  metadataOnly?: MetadataOnly;
147
147
  }, custom?: {
148
148
  module?: string;
149
- runners?: Record<string, NQLRunner>;
150
- metadata?: BucketMetadata;
149
+ buckets?: Record<string, {
150
+ scope: string;
151
+ nql: NQLRunner;
152
+ }>;
153
+ }): Promise<NQL_Result<MetadataOnly extends true ? {
154
+ id: Obj['id'];
155
+ [x: string]: any;
156
+ } : Obj>>;
157
+ _compileQuery(trx: AnyTrxNode, query: NQL_AnyQuery, custom?: {
158
+ module?: string;
159
+ buckets?: Record<string, {
160
+ scope: string;
161
+ nql: NQLRunner;
162
+ }>;
163
+ }): Promise<NQL_CompiledQuery>;
164
+ _queryCompiled<MetadataOnly extends boolean>(trx: AnyTrxNode, compiled: NQL_CompiledQuery, pagination?: NQL_Pagination, params?: Record<string, any>[], param_templates?: Record<string, string>[], config?: {
165
+ view?: string;
166
+ metadataOnly?: MetadataOnly;
167
+ }, custom?: {
168
+ module?: string;
169
+ buckets?: Record<string, {
170
+ scope: string;
171
+ nql: NQLRunner;
172
+ }>;
151
173
  }): Promise<NQL_Result<MetadataOnly extends true ? {
152
174
  id: Obj['id'];
153
175
  [x: string]: any;
@@ -157,5 +179,6 @@ export declare abstract class BucketAdapter<Obj extends NesoiObj, Config extends
157
179
  * @param {Obj} obj An object of this bucket
158
180
  */
159
181
  getUpdateEpoch(obj: Obj): number;
182
+ private static getCacheCustomBuckets;
160
183
  }
161
184
  export type AnyBucketAdapter = BucketAdapter<any, any>;
@@ -36,12 +36,30 @@ class BucketAdapter {
36
36
  async query(trx, query, pagination, params, param_templates, config,
37
37
  // When running a temporary local memory adapter,
38
38
  // these are required
39
+ custom) {
40
+ const compiled = await this._compileQuery(trx, query, custom);
41
+ return this._queryCompiled(trx, compiled, pagination, params, param_templates, config, custom);
42
+ }
43
+ async _compileQuery(trx, query,
44
+ // When running a temporary local memory adapter,
45
+ // these are required
39
46
  custom) {
40
47
  const module = trx_node_1.TrxNode.getModule(trx);
41
48
  const moduleName = custom?.module || module.name;
42
- const compiled = await nql_compiler_1.NQL_Compiler.build(module.daemon, moduleName, this.schema.name, query, custom?.metadata);
49
+ const customBuckets = {
50
+ ...(custom?.buckets || {}),
51
+ ...BucketAdapter.getCacheCustomBuckets(trx)
52
+ };
53
+ return nql_compiler_1.NQL_Compiler.build(module.daemon, moduleName, this.schema.name, query, customBuckets);
54
+ }
55
+ async _queryCompiled(trx, compiled, pagination, params, param_templates, config, custom) {
56
+ const module = trx_node_1.TrxNode.getModule(trx);
57
+ const customBuckets = {
58
+ ...(custom?.buckets || {}),
59
+ ...BucketAdapter.getCacheCustomBuckets(trx)
60
+ };
43
61
  const view = config?.view ? this.schema.views[config.view] : undefined;
44
- const result = await module.nql.run(trx, compiled, pagination, params, param_templates, view, custom?.runners);
62
+ const result = await module.nql.run(trx, compiled, pagination, params, param_templates, view, customBuckets);
45
63
  if (config?.metadataOnly) {
46
64
  result.data = result.data.map(obj => ({
47
65
  id: obj.id,
@@ -61,5 +79,17 @@ class BucketAdapter {
61
79
  }
62
80
  return objUpdate.epoch;
63
81
  }
82
+ static getCacheCustomBuckets(node) {
83
+ const trx = node.trx;
84
+ const buckets = {};
85
+ for (const tag in trx.cache) {
86
+ const adapter = trx.cache[tag].innerAdapter;
87
+ buckets[tag] = {
88
+ scope: `__cache_${tag}`,
89
+ nql: adapter.nql
90
+ };
91
+ }
92
+ return buckets;
93
+ }
64
94
  }
65
95
  exports.BucketAdapter = BucketAdapter;
@@ -36,8 +36,8 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
36
36
  let fallback = 0;
37
37
  for (let i = 0; i < sort.length; i++) {
38
38
  const s = sort[i];
39
- const a_val = tree_1.Tree.get(a, s.key);
40
- const b_val = tree_1.Tree.get(b, s.key);
39
+ const a_val = s.key_is_deep ? tree_1.Tree.get(a, s.key) : a[s.key];
40
+ const b_val = s.key_is_deep ? tree_1.Tree.get(b, s.key) : b[s.key];
41
41
  if (a_val == null) {
42
42
  if (b_val == null)
43
43
  return 0;
@@ -172,56 +172,42 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
172
172
  };
173
173
  const _rule = (rule, objs, params, param_templates) => {
174
174
  const out = {};
175
- for (const id in objs) {
176
- const obj = objs[id];
177
- let match = false;
178
- const combos = [];
179
- for (const param of params) {
180
- if (param_templates.length) {
181
- for (const template of param_templates) {
182
- combos.push({ params: param, param_template: template });
183
- }
184
- }
185
- else {
186
- combos.push({ params: param, param_template: {} });
175
+ const combos = [];
176
+ for (const param of params) {
177
+ if (param_templates.length) {
178
+ for (const template of param_templates) {
179
+ combos.push({ params: param, param_template: template });
187
180
  }
188
181
  }
189
- for (const combo of combos) {
190
- match = _obj(rule, obj, combo.params, combo.param_template);
191
- if (match)
192
- break;
193
- }
194
- if (rule.not) {
195
- match = !match;
182
+ else {
183
+ combos.push({ params: param, param_template: {} });
196
184
  }
185
+ }
186
+ for (const combo of combos) {
187
+ const match = _index(rule, objs, combo.params, combo.param_template);
197
188
  if (match) {
198
- if (rule.select) {
199
- out[obj.id] = obj[rule.select];
189
+ Object.assign(out, match);
190
+ continue;
191
+ }
192
+ for (const id in objs) {
193
+ const obj = objs[id];
194
+ let match = _obj(rule, obj, combo.params, combo.param_template);
195
+ if (rule.not) {
196
+ match = !match;
200
197
  }
201
- else {
202
- out[obj.id] = obj;
198
+ if (match) {
199
+ if (rule.select) {
200
+ out[obj.id] = obj[rule.select];
201
+ }
202
+ else {
203
+ out[obj.id] = obj;
204
+ }
203
205
  }
204
206
  }
205
207
  }
206
208
  return out;
207
209
  };
208
- const _obj = (rule, obj, params, param_template) => {
209
- const fieldValue = tree_1.Tree.get(obj, rule.fieldpath);
210
- // Value is undefined, only 'present' rule applies
211
- if (fieldValue === undefined) {
212
- if (rule.op === 'present') {
213
- return false;
214
- }
215
- return false;
216
- }
217
- // Fieldpath is a spread, apply rule to each item
218
- if (rule.fieldpath.includes('.#')) {
219
- for (const item of fieldValue) {
220
- if (_obj(rule, item, params, param_template))
221
- return true;
222
- }
223
- return false;
224
- }
210
+ const _value = (rule, params, param_template) => {
225
211
  let queryValue;
226
212
  // Value is a subquery, run union
227
213
  if ('subquery' in rule.value) {
@@ -238,10 +224,14 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
238
224
  }
239
225
  else if ('param' in rule.value) {
240
226
  if (Array.isArray(rule.value.param)) {
241
- queryValue = rule.value.param.map(p => tree_1.Tree.get(params, p));
227
+ queryValue = rule.value.param_is_deep
228
+ ? rule.value.param.map(p => tree_1.Tree.get(params, p))
229
+ : rule.value.param.map(p => params[p]);
242
230
  }
243
231
  else {
244
- queryValue = tree_1.Tree.get(params, rule.value.param);
232
+ queryValue = rule.value.param_is_deep
233
+ ? tree_1.Tree.get(params, rule.value.param)
234
+ : params[rule.value.param];
245
235
  }
246
236
  }
247
237
  else if ('param_with_$' in rule.value) {
@@ -254,6 +244,52 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
254
244
  else if ('static' in rule.value) {
255
245
  queryValue = rule.value.static;
256
246
  }
247
+ return queryValue;
248
+ };
249
+ const _index = (rule, objs, params, param_template) => {
250
+ if (rule.op !== '==')
251
+ return undefined;
252
+ if (rule.fieldpath !== 'id')
253
+ return undefined;
254
+ const queryValue = _value(rule, params, param_template);
255
+ let out = {};
256
+ if (rule.not) {
257
+ out = Object.assign({}, objs);
258
+ delete out[queryValue];
259
+ }
260
+ else {
261
+ const obj = objs[queryValue];
262
+ if (obj) {
263
+ out[obj.id] = obj;
264
+ }
265
+ }
266
+ if (rule.select) {
267
+ for (const id in out) {
268
+ out[id] = out[id][rule.select];
269
+ }
270
+ }
271
+ return out;
272
+ };
273
+ const _obj = (rule, obj, params, param_template) => {
274
+ const fieldValue = rule.fieldpath_is_deep
275
+ ? tree_1.Tree.get(obj, rule.fieldpath)
276
+ : obj[rule.fieldpath];
277
+ // Value is undefined, only 'present' rule applies
278
+ if (fieldValue === undefined) {
279
+ if (rule.op === 'present') {
280
+ return false;
281
+ }
282
+ return false;
283
+ }
284
+ // Fieldpath is a spread, apply rule to each item
285
+ if (rule.fieldpath.includes('.#')) {
286
+ for (const item of fieldValue) {
287
+ if (_obj(rule, item, params, param_template))
288
+ return true;
289
+ }
290
+ return false;
291
+ }
292
+ const queryValue = _value(rule, params, param_template);
257
293
  // Check each operation
258
294
  // (Compatible operations and types have already been validated)
259
295
  if (rule.op === '<') {
@@ -0,0 +1,22 @@
1
+ import { BucketAdapterConfig } from './bucket_adapter';
2
+ import { $Bucket, MemoryBucketAdapter } from "../../..";
3
+ /**
4
+ * @category Adapters
5
+ * @subcategory Entity
6
+ */
7
+ export declare class TestBucketAdapter<B extends $Bucket, Obj extends B['#data']> extends MemoryBucketAdapter<B, Obj> {
8
+ schema: B;
9
+ data: NoInfer<Record<Obj['id'], Obj>>;
10
+ private queryMeta?;
11
+ constructor(schema: B, data?: NoInfer<Record<Obj['id'], Obj>>, config?: BucketAdapterConfig & {
12
+ queryMeta?: {
13
+ scope: string;
14
+ avgTime: number;
15
+ };
16
+ });
17
+ getQueryMeta(): {
18
+ scope: string;
19
+ avgTime: number;
20
+ };
21
+ }
22
+ export type AnyTestBucketAdapter = TestBucketAdapter<any, any>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TestBucketAdapter = void 0;
4
+ const elements_1 = require("../../..");
5
+ /**
6
+ * @category Adapters
7
+ * @subcategory Entity
8
+ */
9
+ class TestBucketAdapter extends elements_1.MemoryBucketAdapter {
10
+ schema;
11
+ data;
12
+ queryMeta;
13
+ constructor(schema, data = {}, config) {
14
+ super(schema, data, config);
15
+ this.schema = schema;
16
+ this.data = data;
17
+ this.queryMeta = config?.queryMeta;
18
+ }
19
+ getQueryMeta() {
20
+ return this.queryMeta || super.getQueryMeta();
21
+ }
22
+ }
23
+ exports.TestBucketAdapter = TestBucketAdapter;
@@ -88,8 +88,8 @@ class Bucket {
88
88
  ? undefined
89
89
  : this.getTenancyQuery(trx);
90
90
  let raw;
91
- // With Tenancy
92
91
  const adapter = await trx_1.Trx.getCache(trx, this) || this.cache || this.adapter;
92
+ // With Tenancy
93
93
  if (tenancy) {
94
94
  const result = await adapter.query(trx, {
95
95
  id,
@@ -127,8 +127,8 @@ class Bucket {
127
127
  ? undefined
128
128
  : this.getTenancyQuery(trx);
129
129
  let raws;
130
- // With Tenancy
131
130
  const adapter = await trx_1.Trx.getCache(trx, this) || this.cache || this.adapter;
131
+ // With Tenancy
132
132
  if (tenancy) {
133
133
  const result = await adapter.query(trx, tenancy, undefined, undefined, undefined, options?.query_view ? { view: options?.query_view } : undefined);
134
134
  raws = result.data;
@@ -2,8 +2,9 @@ import { BucketConfig } from '../bucket.config';
2
2
  import { AnyTrxNode } from "../../../../engine/transaction/trx_node";
3
3
  import { NesoiObj } from "../../../../engine/data/obj";
4
4
  import { NQL_AnyQuery, NQL_Pagination } from '../query/nql.schema';
5
- import { NQL_Result } from '../query/nql_engine';
5
+ import { NQL_Result, NQLRunner } from '../query/nql_engine';
6
6
  import { AnyBucket } from '../bucket';
7
+ import { NQL_CompiledQuery } from '../query/nql_compiler';
7
8
  export type BucketCacheSync<T> = {
8
9
  obj: T;
9
10
  updateEpoch: number;
@@ -42,6 +43,20 @@ export declare class BucketCache<Obj extends NesoiObj> {
42
43
  id: Obj['id'];
43
44
  [x: string]: any;
44
45
  } : Obj>>;
46
+ _compileQuery(trx: AnyTrxNode, query: NQL_AnyQuery, custom?: {
47
+ module?: string;
48
+ buckets?: Record<string, {
49
+ scope: string;
50
+ nql: NQLRunner;
51
+ }>;
52
+ }): Promise<NQL_CompiledQuery>;
53
+ _queryCompiled<MetadataOnly extends boolean>(trx: AnyTrxNode, query: NQL_CompiledQuery, pagination?: NQL_Pagination, params?: Record<string, any>[], param_templates?: Record<string, string>[], config?: {
54
+ view?: string;
55
+ metadataOnly?: MetadataOnly;
56
+ }): Promise<NQL_Result<MetadataOnly extends true ? {
57
+ id: Obj['id'];
58
+ [x: string]: any;
59
+ } : Obj>>;
45
60
  /**
46
61
  * Update inner adapter with data from outer adapter.
47
62
  */
@@ -77,5 +92,6 @@ export declare class BucketCache<Obj extends NesoiObj> {
77
92
  * - reduces transit payload for data that doesn't change much
78
93
  */
79
94
  private syncQuery;
95
+ private static getCacheCustomBuckets;
80
96
  }
81
97
  export type AnyBucketCache = BucketCache<any>;
@@ -2,11 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BucketCache = exports.BucketCacheEntry = void 0;
4
4
  const log_1 = require("../../../../engine/util/log");
5
+ const trx_node_1 = require("../../../../engine/transaction/trx_node");
5
6
  const memory_bucket_adapter_1 = require("../adapters/memory.bucket_adapter");
6
7
  const datetime_1 = require("../../../../engine/data/datetime");
7
8
  const bucket_schema_1 = require("../bucket.schema");
8
9
  const bucket_model_schema_1 = require("../model/bucket_model.schema");
9
10
  const bucket_graph_schema_1 = require("../graph/bucket_graph.schema");
11
+ const dependency_1 = require("../../../../engine/dependency");
12
+ const nql_compiler_1 = require("../query/nql_compiler");
10
13
  /**
11
14
  * @category Elements
12
15
  * @subcategory Entity
@@ -105,26 +108,42 @@ class BucketCache {
105
108
  return out;
106
109
  }
107
110
  async query(trx, query, pagination, params, param_templates, config) {
111
+ const compiled = await this._compileQuery(trx, query);
112
+ return this._queryCompiled(trx, compiled, pagination, params, param_templates, config);
113
+ }
114
+ async _compileQuery(trx, query,
115
+ // When running a temporary local memory adapter,
116
+ // these are required
117
+ custom) {
118
+ const module = trx_node_1.TrxNode.getModule(trx);
119
+ const moduleName = custom?.module || module.name;
120
+ const customBuckets = {
121
+ ...(custom?.buckets || {}),
122
+ ...BucketCache.getCacheCustomBuckets(trx)
123
+ };
124
+ return nql_compiler_1.NQL_Compiler.build(module.daemon, moduleName, this.bucket.schema.name, query, customBuckets);
125
+ }
126
+ async _queryCompiled(trx, query, pagination, params, param_templates, config) {
127
+ const tag = new dependency_1.Tag(this.bucket.schema.module, 'bucket', this.bucket.schema.name);
108
128
  const mode = this.config?.mode?.query;
109
129
  let data;
110
130
  if (mode === 'eager') {
111
131
  log_1.Log.debug('bucket', this.bucket.schema.name, 'CACHE index.eager');
112
- data = await this.innerAdapter.query(trx, query, pagination, params, param_templates, config);
132
+ const result = await this.innerAdapter._queryCompiled(trx, query, pagination, params, param_templates, config, {
133
+ module: this.bucket.schema.module
134
+ });
135
+ data = result.data;
113
136
  }
114
- if (mode === 'incremental') {
115
- const { action, sync } = await this.syncQuery(trx, query, pagination, params);
137
+ else if (mode === 'incremental') {
138
+ const { action, sync } = await this.syncQuery(trx, query /* TODO */, pagination, params);
116
139
  log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE query.incremental, ${action}`);
117
140
  data = sync;
118
141
  }
119
142
  else if (mode === 'all') {
120
143
  const { action, sync } = await this.syncAll(trx);
121
144
  log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE query.all, ${action}`);
122
- const meta = this.innerAdapter.getQueryMeta();
123
- const entries = (await this.innerAdapter.query(trx, query, pagination, params, undefined, undefined, {
124
- module: this.bucket.schema.module,
125
- runners: {
126
- [meta.scope]: this.innerAdapter.nql
127
- }
145
+ const entries = (await this.innerAdapter._queryCompiled(trx, query, pagination, params, undefined, undefined, {
146
+ module: this.bucket.schema.module
128
147
  })).data;
129
148
  data = [];
130
149
  for (const e of entries) {
@@ -132,8 +151,10 @@ class BucketCache {
132
151
  data.push(obj);
133
152
  }
134
153
  }
154
+ // Invalid mode, bypass cache
135
155
  else {
136
- data = (await this.outerAdapter.query(trx, query, pagination, params)).data;
156
+ const result = await this.outerAdapter.query(trx, query /* TODO */, pagination, params);
157
+ data = result.data;
137
158
  }
138
159
  for (const entry of data) {
139
160
  delete entry['__update_epoch'];
@@ -149,6 +170,7 @@ class BucketCache {
149
170
  * Update inner adapter with data from outer adapter.
150
171
  */
151
172
  async sync(trx) {
173
+ log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE sync, trx: ${trx.globalId}`);
152
174
  const objects = await this.outerAdapter.index(trx);
153
175
  const entries = objects.map(obj => new BucketCacheEntry(obj, this.outerAdapter.getUpdateEpoch(obj), this.lastSyncEpoch));
154
176
  await this.innerAdapter.deleteEverything(trx);
@@ -162,6 +184,7 @@ class BucketCache {
162
184
  * - reduces transit payload for data that doesn't change much
163
185
  */
164
186
  async syncOne(trx, id) {
187
+ log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE sync one: ${id}, trx: ${trx.globalId}`);
165
188
  let localObj = await this.innerAdapter.get(trx, id);
166
189
  if (!localObj) {
167
190
  const obj = await this.outerAdapter.get(trx, id);
@@ -253,14 +276,11 @@ class BucketCache {
253
276
  return { action: 'none', sync: [] };
254
277
  }
255
278
  // 2. Read ids from the inner adapter
256
- const meta = this.innerAdapter.getQueryMeta();
279
+ const tag = new dependency_1.Tag(this.bucket.schema.module, 'bucket', this.bucket.schema.name);
257
280
  const innerData = await this.innerAdapter.query(trx, {
258
281
  'id in': outerMetadata.data.map(obj => obj.id)
259
282
  }, undefined, undefined, undefined, undefined, {
260
- module: this.bucket.schema.module,
261
- runners: {
262
- [meta.scope]: this.innerAdapter.nql
263
- }
283
+ module: this.bucket.schema.module
264
284
  });
265
285
  // 3. Filter modified query results
266
286
  const outerEpoch = {};
@@ -298,5 +318,17 @@ class BucketCache {
298
318
  }
299
319
  return { action: 'update', sync: Object.values(queryResults).map(r => new BucketCacheEntry(r.obj, r.updateEpoch, datetime_1.NesoiDatetime.now().epoch)) };
300
320
  }
321
+ static getCacheCustomBuckets(node) {
322
+ const trx = node.trx;
323
+ const buckets = {};
324
+ for (const tag in trx.cache) {
325
+ const adapter = trx.cache[tag].innerAdapter;
326
+ buckets[tag] = {
327
+ scope: `__cache_${tag}`,
328
+ nql: adapter.nql
329
+ };
330
+ }
331
+ return buckets;
332
+ }
301
333
  }
302
334
  exports.BucketCache = BucketCache;