nesoi 3.2.2 → 3.2.4
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.
- package/lib/compiler/elements/constants.element.js +1 -1
- package/lib/compiler/error.d.ts +1 -0
- package/lib/compiler/error.js +3 -0
- package/lib/compiler/stages/4_build_schemas_stage.js +14 -0
- package/lib/compiler/treeshake.js +3 -1
- package/lib/elements/edge/externals/externals.builder.d.ts +2 -0
- package/lib/elements/edge/externals/externals.builder.js +6 -1
- package/lib/elements/edge/externals/externals.schema.d.ts +2 -1
- package/lib/elements/edge/externals/externals.schema.js +3 -1
- package/lib/elements/entities/bucket/bucket.d.ts +2 -1
- package/lib/elements/entities/bucket/bucket.js +12 -14
- package/lib/elements/entities/bucket/cache/bucket_cache.d.ts +14 -10
- package/lib/elements/entities/bucket/cache/bucket_cache.js +92 -58
- package/lib/elements/entities/bucket/graph/bucket_graph.js +13 -6
- package/lib/elements/entities/bucket/model/bucket_model.schema.js +2 -2
- package/lib/elements/entities/bucket/model/bucket_model_field.builder.d.ts +3 -4
- package/lib/elements/entities/bucket/query/nql_compiler.js +7 -1
- package/lib/elements/entities/constants/constants.schema.d.ts +2 -4
- package/lib/engine/apps/inline.app.js +1 -0
- package/lib/engine/module.d.ts +2 -2
- package/lib/engine/module.js +9 -2
- package/lib/engine/transaction/nodes/bucket_query.trx_node.d.ts +1 -1
- package/lib/engine/transaction/nodes/bucket_query.trx_node.js +1 -1
- package/lib/engine/transaction/trx_node.d.ts +1 -2
- package/package.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/lib/compiler/error.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare class CompilerError extends Error {
|
|
|
6
6
|
static UnmetModuleDependency(from: string, name: string): CompilerError;
|
|
7
7
|
static UnmetDependency(from: string, name: string): CompilerError;
|
|
8
8
|
static CircularDependency(): CompilerError;
|
|
9
|
+
static ExternalEnumNotFound(name: string): CompilerError;
|
|
9
10
|
}
|
|
10
11
|
export declare class HelperError extends Error {
|
|
11
12
|
constructor(message: string);
|
package/lib/compiler/error.js
CHANGED
|
@@ -23,6 +23,9 @@ class CompilerError extends Error {
|
|
|
23
23
|
static CircularDependency() {
|
|
24
24
|
return new CompilerError('Circular dependency found while building.');
|
|
25
25
|
}
|
|
26
|
+
static ExternalEnumNotFound(name) {
|
|
27
|
+
return new CompilerError(`External enum '${name}' not found`);
|
|
28
|
+
}
|
|
26
29
|
}
|
|
27
30
|
exports.CompilerError = CompilerError;
|
|
28
31
|
class HelperError extends Error {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BuildSchemasStage = void 0;
|
|
4
4
|
const log_1 = require("../../engine/util/log");
|
|
5
|
+
const error_1 = require("../error");
|
|
5
6
|
/**
|
|
6
7
|
* [Compiler Stage #4]
|
|
7
8
|
* Build the node schemas, following the graph resolved on previous steps.
|
|
@@ -41,6 +42,19 @@ class BuildSchemasStage {
|
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
44
|
await module.buildNode(node, this.compiler.tree);
|
|
45
|
+
// Inject external enums on the module schema
|
|
46
|
+
if (node.type === 'externals') {
|
|
47
|
+
const schema = node.schema;
|
|
48
|
+
for (const e in schema.enums) {
|
|
49
|
+
const enumDep = schema.enums[e];
|
|
50
|
+
const enumModule = this.compiler.modules[enumDep.module].module;
|
|
51
|
+
const constants = enumModule.schema.constants;
|
|
52
|
+
if (!constants.enums[enumDep.name]) {
|
|
53
|
+
throw error_1.CompilerError.ExternalEnumNotFound(e);
|
|
54
|
+
}
|
|
55
|
+
module.schema.constants.enums[enumDep.refName] = constants.enums[enumDep.name];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
44
58
|
});
|
|
45
59
|
const t = new Date().getTime();
|
|
46
60
|
log_1.Log.debug('compiler', 'stage.build_schemas', `[t: ${(t - t0) / 1000} ms]`);
|
|
@@ -21,11 +21,13 @@ class Treeshake {
|
|
|
21
21
|
const buckets = b.buckets;
|
|
22
22
|
const messages = b.messages;
|
|
23
23
|
const jobs = b.jobs;
|
|
24
|
+
const enums = b.enums;
|
|
24
25
|
log_1.Log.trace('compiler', 'treeshake', `${' '.repeat(depth)} └ Treeshaking node ${(0, log_1.scopeTag)($b, node.name)}`);
|
|
25
26
|
node.dependencies = [
|
|
26
27
|
...Object.values(buckets),
|
|
27
28
|
...Object.values(messages),
|
|
28
|
-
...Object.values(jobs)
|
|
29
|
+
...Object.values(jobs),
|
|
30
|
+
...Object.values(enums).map(dep => new dependency_1.$Dependency(node.module, 'constants', `${dep.module}::*`))
|
|
29
31
|
];
|
|
30
32
|
node.dependencies = this.cleanNodeDependencies(node);
|
|
31
33
|
}
|
|
@@ -20,11 +20,13 @@ export declare class ExternalsBuilder<Space extends $Space, ModuleName extends k
|
|
|
20
20
|
private messages;
|
|
21
21
|
private jobs;
|
|
22
22
|
private machines;
|
|
23
|
+
private enums;
|
|
23
24
|
constructor(module: string);
|
|
24
25
|
bucket<M extends keyof Space['modules'], B extends ExternalBucketRefName<Space, ModuleName>>(ref: B): this;
|
|
25
26
|
message<M extends Exclude<keyof Space['modules'], ModuleName>, B extends keyof Space['modules'][M]['messages']>(ref: `${M & string}::${B & string}`): this;
|
|
26
27
|
job<M extends Exclude<keyof Space['modules'], ModuleName>, B extends keyof Space['modules'][M]['jobs']>(ref: `${M & string}::${B & string}`): this;
|
|
27
28
|
machine<M extends Exclude<keyof Space['modules'], ModuleName>, B extends keyof Space['modules'][M]['machines']>(ref: `${M & string}::${B & string}`): this;
|
|
29
|
+
enum<M extends Exclude<keyof Space['modules'], ModuleName>, B extends keyof Space['modules'][M]['constants']['enums']>(ref: `${M & string}::${B & string}`): this;
|
|
28
30
|
static merge(to: AnyExternalsBuilder, from: AnyExternalsBuilder): void;
|
|
29
31
|
static build(node: ExternalsBuilderNode): $Externals;
|
|
30
32
|
}
|
|
@@ -16,6 +16,7 @@ class ExternalsBuilder {
|
|
|
16
16
|
this.messages = {};
|
|
17
17
|
this.jobs = {};
|
|
18
18
|
this.machines = {};
|
|
19
|
+
this.enums = {};
|
|
19
20
|
}
|
|
20
21
|
bucket(ref) {
|
|
21
22
|
this.buckets[ref] = new dependency_1.$Dependency(this.module, 'bucket', ref);
|
|
@@ -33,13 +34,17 @@ class ExternalsBuilder {
|
|
|
33
34
|
this.machines[ref] = new dependency_1.$Dependency(this.module, 'machine', ref);
|
|
34
35
|
return this;
|
|
35
36
|
}
|
|
37
|
+
enum(ref) {
|
|
38
|
+
this.enums[ref] = new dependency_1.$Dependency(this.module, 'enum', ref);
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
36
41
|
static merge(to, from) {
|
|
37
42
|
Object.assign(to.buckets, from.buckets);
|
|
38
43
|
Object.assign(to.jobs, from.jobs);
|
|
39
44
|
}
|
|
40
45
|
// Build
|
|
41
46
|
static build(node) {
|
|
42
|
-
node.schema = new externals_schema_1.$Externals(node.module, node.builder.buckets, node.builder.messages, node.builder.jobs, node.builder.machines);
|
|
47
|
+
node.schema = new externals_schema_1.$Externals(node.module, node.builder.buckets, node.builder.messages, node.builder.jobs, node.builder.machines, node.builder.enums);
|
|
43
48
|
return node.schema;
|
|
44
49
|
}
|
|
45
50
|
}
|
|
@@ -9,8 +9,9 @@ export declare class $Externals {
|
|
|
9
9
|
messages: Record<string, $Dependency>;
|
|
10
10
|
jobs: Record<string, $Dependency>;
|
|
11
11
|
machines: Record<string, $Dependency>;
|
|
12
|
+
enums: Record<string, $Dependency>;
|
|
12
13
|
$t: "externals";
|
|
13
14
|
module: string;
|
|
14
|
-
constructor(name: string, buckets?: Record<string, $Dependency>, messages?: Record<string, $Dependency>, jobs?: Record<string, $Dependency>, machines?: Record<string, $Dependency>);
|
|
15
|
+
constructor(name: string, buckets?: Record<string, $Dependency>, messages?: Record<string, $Dependency>, jobs?: Record<string, $Dependency>, machines?: Record<string, $Dependency>, enums?: Record<string, $Dependency>);
|
|
15
16
|
static merge(to: $Externals, from: $Externals): void;
|
|
16
17
|
}
|
|
@@ -6,12 +6,13 @@ exports.$Externals = void 0;
|
|
|
6
6
|
* @subcategory Edge
|
|
7
7
|
*/
|
|
8
8
|
class $Externals {
|
|
9
|
-
constructor(name, buckets = {}, messages = {}, jobs = {}, machines = {}) {
|
|
9
|
+
constructor(name, buckets = {}, messages = {}, jobs = {}, machines = {}, enums = {}) {
|
|
10
10
|
this.name = name;
|
|
11
11
|
this.buckets = buckets;
|
|
12
12
|
this.messages = messages;
|
|
13
13
|
this.jobs = jobs;
|
|
14
14
|
this.machines = machines;
|
|
15
|
+
this.enums = enums;
|
|
15
16
|
this.$t = 'externals';
|
|
16
17
|
this.module = this.name;
|
|
17
18
|
}
|
|
@@ -20,6 +21,7 @@ class $Externals {
|
|
|
20
21
|
Object.assign(to.messages, from.messages);
|
|
21
22
|
Object.assign(to.jobs, from.jobs);
|
|
22
23
|
Object.assign(to.machines, from.machines);
|
|
24
|
+
Object.assign(to.enums, from.enums);
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
exports.$Externals = $Externals;
|
|
@@ -4,6 +4,7 @@ import { $Module, ViewName, ViewObj } from "../../../schema";
|
|
|
4
4
|
import { $Bucket } from './bucket.schema';
|
|
5
5
|
import { BucketAdapter } from './adapters/bucket_adapter';
|
|
6
6
|
import { BucketConfig } from './bucket.config';
|
|
7
|
+
import { AnyBucketCache } from './cache/bucket_cache';
|
|
7
8
|
import { BucketGraph } from './graph/bucket_graph';
|
|
8
9
|
import { NQL_AnyQuery, NQL_Pagination } from './query/nql.schema';
|
|
9
10
|
import { CreateObj, PatchObj, PutObj } from './bucket.types';
|
|
@@ -32,7 +33,7 @@ export declare class Bucket<M extends $Module, $ extends $Bucket> {
|
|
|
32
33
|
private config?;
|
|
33
34
|
services: Record<string, IService>;
|
|
34
35
|
adapter: BucketAdapter<$['#data']>;
|
|
35
|
-
|
|
36
|
+
cache?: AnyBucketCache;
|
|
36
37
|
graph: BucketGraph<M, $>;
|
|
37
38
|
private views;
|
|
38
39
|
drive?: DriveAdapter;
|
|
@@ -45,7 +45,7 @@ class Bucket {
|
|
|
45
45
|
this.views = views;
|
|
46
46
|
// Cache
|
|
47
47
|
if (this.config?.cache) {
|
|
48
|
-
this.cache = new bucket_cache_1.BucketCache(this
|
|
48
|
+
this.cache = new bucket_cache_1.BucketCache(this, this.config.cache);
|
|
49
49
|
}
|
|
50
50
|
// Drive
|
|
51
51
|
if (this.config?.drive) {
|
|
@@ -79,8 +79,9 @@ class Bucket {
|
|
|
79
79
|
: this.getTenancyQuery(trx);
|
|
80
80
|
let raw;
|
|
81
81
|
// With Tenancy
|
|
82
|
+
const adapter = this.cache || this.adapter;
|
|
82
83
|
if (tenancy) {
|
|
83
|
-
const result = await
|
|
84
|
+
const result = await adapter.query(trx, {
|
|
84
85
|
id,
|
|
85
86
|
'#and': tenancy
|
|
86
87
|
}, { perPage: 1 }, undefined, options?.query_view ? { view: options?.query_view } : undefined);
|
|
@@ -88,9 +89,7 @@ class Bucket {
|
|
|
88
89
|
}
|
|
89
90
|
// Without Tenancy
|
|
90
91
|
else {
|
|
91
|
-
raw =
|
|
92
|
-
? await this.cache.get(trx, id)
|
|
93
|
-
: await this.adapter.get(trx, id);
|
|
92
|
+
raw = await adapter.get(trx, id);
|
|
94
93
|
}
|
|
95
94
|
// Empty result
|
|
96
95
|
if (!raw) {
|
|
@@ -119,15 +118,14 @@ class Bucket {
|
|
|
119
118
|
: this.getTenancyQuery(trx);
|
|
120
119
|
let raws;
|
|
121
120
|
// With Tenancy
|
|
121
|
+
const adapter = this.cache || this.adapter;
|
|
122
122
|
if (tenancy) {
|
|
123
|
-
const result = await
|
|
123
|
+
const result = await adapter.query(trx, tenancy, undefined, options?.query_view ? [{ view: options?.query_view }] : undefined);
|
|
124
124
|
raws = result.data;
|
|
125
125
|
}
|
|
126
126
|
// Without Tenancy
|
|
127
127
|
else {
|
|
128
|
-
raws = this.
|
|
129
|
-
? await this.cache.index(trx)
|
|
130
|
-
: await this.adapter.index(trx);
|
|
128
|
+
raws = await this.adapter.index(trx);
|
|
131
129
|
}
|
|
132
130
|
// Encryption
|
|
133
131
|
if (this.schema.model.hasEncryptedField) {
|
|
@@ -426,9 +424,10 @@ class Bucket {
|
|
|
426
424
|
// Read old object, if safe, to check if it exists
|
|
427
425
|
let oldObj;
|
|
428
426
|
if (!options?.unsafe) {
|
|
427
|
+
const adapter = this.cache || this.adapter;
|
|
429
428
|
// With Tenancy
|
|
430
429
|
if (tenancy) {
|
|
431
|
-
const result = await
|
|
430
|
+
const result = await adapter.query(trx, {
|
|
432
431
|
id: obj.id,
|
|
433
432
|
'#and': tenancy
|
|
434
433
|
}, { perPage: 1 }, undefined, {
|
|
@@ -438,9 +437,7 @@ class Bucket {
|
|
|
438
437
|
}
|
|
439
438
|
// Without Tenancy
|
|
440
439
|
else {
|
|
441
|
-
oldObj =
|
|
442
|
-
? await this.cache.get(trx, obj['id'])
|
|
443
|
-
: await this.adapter.get(trx, obj['id']);
|
|
440
|
+
oldObj = await adapter.get(trx, obj['id']);
|
|
444
441
|
}
|
|
445
442
|
// Empty response
|
|
446
443
|
if (!oldObj) {
|
|
@@ -716,7 +713,8 @@ class Bucket {
|
|
|
716
713
|
'#and': tenancy
|
|
717
714
|
};
|
|
718
715
|
// Query
|
|
719
|
-
const
|
|
716
|
+
const adapter = this.cache || this.adapter;
|
|
717
|
+
const result = await adapter.query(trx, query, pagination, options?.params);
|
|
720
718
|
if (!result.data.length)
|
|
721
719
|
return result;
|
|
722
720
|
// Encryption
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { BucketConfig } from '../bucket.config';
|
|
2
2
|
import { AnyTrxNode } from "../../../../engine/transaction/trx_node";
|
|
3
3
|
import { NesoiObj } from "../../../../engine/data/obj";
|
|
4
|
-
import { AnyBucketAdapter } from '../adapters/bucket_adapter';
|
|
5
|
-
import { $BucketView } from '../view/bucket_view.schema';
|
|
6
4
|
import { NQL_AnyQuery, NQL_Pagination } from '../query/nql.schema';
|
|
7
5
|
import { NQL_Result } from '../query/nql_engine';
|
|
6
|
+
import { AnyBucket } from '../bucket';
|
|
8
7
|
export type BucketCacheSync<T> = {
|
|
9
8
|
obj: T;
|
|
10
9
|
updateEpoch: number;
|
|
@@ -14,28 +13,33 @@ export type BucketCacheSync<T> = {
|
|
|
14
13
|
* @subcategory Entity
|
|
15
14
|
* */
|
|
16
15
|
export declare class BucketCacheEntry<Obj extends NesoiObj> {
|
|
16
|
+
__update_epoch: number;
|
|
17
|
+
__sync_epoch: number;
|
|
17
18
|
id: Obj['id'];
|
|
18
|
-
obj: Obj;
|
|
19
|
-
updateEpoch: number;
|
|
20
|
-
syncEpoch: number;
|
|
21
|
-
constructor(id: Obj['id'], obj: Obj, updateEpoch: number, syncEpoch: number);
|
|
19
|
+
constructor(obj: Obj, __update_epoch: number, __sync_epoch: number);
|
|
22
20
|
}
|
|
23
21
|
/**
|
|
24
22
|
* @category Elements
|
|
25
23
|
* @subcategory Entity
|
|
26
24
|
* */
|
|
27
25
|
export declare class BucketCache<Obj extends NesoiObj> {
|
|
28
|
-
private
|
|
29
|
-
private outerAdapter;
|
|
26
|
+
private bucket;
|
|
30
27
|
private config;
|
|
31
28
|
private lastUpdateEpoch?;
|
|
32
29
|
private lastSyncEpoch?;
|
|
33
30
|
private lastHash?;
|
|
34
31
|
private innerAdapter;
|
|
35
|
-
|
|
32
|
+
private outerAdapter;
|
|
33
|
+
constructor(bucket: AnyBucket, config: NonNullable<BucketConfig<any, any, any>['cache']>);
|
|
36
34
|
get(trx: AnyTrxNode, id: NesoiObj['id']): Promise<any>;
|
|
37
35
|
index(trx: AnyTrxNode): Promise<any[]>;
|
|
38
|
-
query(trx: AnyTrxNode,
|
|
36
|
+
query<MetadataOnly extends boolean>(trx: AnyTrxNode, query: NQL_AnyQuery, pagination?: NQL_Pagination, params?: Record<string, any>[], config?: {
|
|
37
|
+
view?: string;
|
|
38
|
+
metadataOnly?: MetadataOnly;
|
|
39
|
+
}): Promise<NQL_Result<MetadataOnly extends true ? {
|
|
40
|
+
id: Obj['id'];
|
|
41
|
+
[x: string]: any;
|
|
42
|
+
} : Obj>>;
|
|
39
43
|
private syncOne;
|
|
40
44
|
private syncOneAndPast;
|
|
41
45
|
private syncAll;
|
|
@@ -4,16 +4,18 @@ exports.BucketCache = exports.BucketCacheEntry = void 0;
|
|
|
4
4
|
const log_1 = require("../../../../engine/util/log");
|
|
5
5
|
const memory_bucket_adapter_1 = require("../adapters/memory.bucket_adapter");
|
|
6
6
|
const datetime_1 = require("../../../../engine/data/datetime");
|
|
7
|
+
const bucket_schema_1 = require("../bucket.schema");
|
|
8
|
+
const bucket_model_schema_1 = require("../model/bucket_model.schema");
|
|
9
|
+
const bucket_graph_schema_1 = require("../graph/bucket_graph.schema");
|
|
7
10
|
/**
|
|
8
11
|
* @category Elements
|
|
9
12
|
* @subcategory Entity
|
|
10
13
|
* */
|
|
11
14
|
class BucketCacheEntry {
|
|
12
|
-
constructor(
|
|
13
|
-
this.
|
|
14
|
-
this.
|
|
15
|
-
this
|
|
16
|
-
this.syncEpoch = syncEpoch;
|
|
15
|
+
constructor(obj, __update_epoch, __sync_epoch) {
|
|
16
|
+
this.__update_epoch = __update_epoch;
|
|
17
|
+
this.__sync_epoch = __sync_epoch;
|
|
18
|
+
Object.assign(this, obj);
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
exports.BucketCacheEntry = BucketCacheEntry;
|
|
@@ -22,28 +24,43 @@ exports.BucketCacheEntry = BucketCacheEntry;
|
|
|
22
24
|
* @subcategory Entity
|
|
23
25
|
* */
|
|
24
26
|
class BucketCache {
|
|
25
|
-
constructor(
|
|
26
|
-
this.
|
|
27
|
-
this.outerAdapter = outerAdapter;
|
|
27
|
+
constructor(bucket, config) {
|
|
28
|
+
this.bucket = bucket;
|
|
28
29
|
this.config = config;
|
|
29
|
-
|
|
30
|
+
const innerSchema = new bucket_schema_1.$Bucket(bucket.schema.module, bucket.schema.name, '[cache] ' + bucket.schema.alias, new bucket_model_schema_1.$BucketModel({
|
|
31
|
+
...bucket.schema.model.fields,
|
|
32
|
+
__update_epoch: new bucket_model_schema_1.$BucketModelField('__update_epoch', '__update_epoch', 'int', '__update_epoch', true),
|
|
33
|
+
__sync_epoch: new bucket_model_schema_1.$BucketModelField('__sync_epoch', '__sync_epoch', 'int', '__sync_epoch', true),
|
|
34
|
+
}), new bucket_graph_schema_1.$BucketGraph(), {});
|
|
35
|
+
this.innerAdapter = this.config?.adapter || new memory_bucket_adapter_1.MemoryBucketAdapter(innerSchema, {});
|
|
36
|
+
this.outerAdapter = bucket.adapter;
|
|
30
37
|
}
|
|
31
38
|
async get(trx, id) {
|
|
32
39
|
const mode = this.config?.mode?.get;
|
|
33
40
|
if (mode === 'one') {
|
|
34
41
|
const { action, sync } = await this.syncOne(trx, id);
|
|
35
|
-
log_1.Log.debug('bucket', this.
|
|
36
|
-
|
|
42
|
+
log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE get.one, ${action}`);
|
|
43
|
+
if (!sync)
|
|
44
|
+
return undefined;
|
|
45
|
+
const { __update_epoch, __sync_epoch, ...obj } = sync;
|
|
46
|
+
return obj;
|
|
37
47
|
}
|
|
38
48
|
if (mode === 'past') {
|
|
39
49
|
const { action, sync } = await this.syncOneAndPast(trx, id);
|
|
40
|
-
log_1.Log.debug('bucket', this.
|
|
41
|
-
|
|
50
|
+
log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE get.past, ${action}`);
|
|
51
|
+
if (!sync)
|
|
52
|
+
return undefined;
|
|
53
|
+
const { __update_epoch, __sync_epoch, ...obj } = sync;
|
|
54
|
+
return obj;
|
|
42
55
|
}
|
|
43
56
|
if (mode === 'all') {
|
|
44
57
|
const { action, sync } = await this.syncAll(trx);
|
|
45
|
-
log_1.Log.debug('bucket', this.
|
|
46
|
-
|
|
58
|
+
log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE get.all, ${action}`);
|
|
59
|
+
const one = sync.find(s => s.id === id);
|
|
60
|
+
if (!one)
|
|
61
|
+
return undefined;
|
|
62
|
+
const { __update_epoch, __sync_epoch, ...obj } = one;
|
|
63
|
+
return one;
|
|
47
64
|
}
|
|
48
65
|
return this.outerAdapter.get(trx, id);
|
|
49
66
|
}
|
|
@@ -51,50 +68,69 @@ class BucketCache {
|
|
|
51
68
|
const mode = this.config?.mode?.index;
|
|
52
69
|
if (mode === 'all') {
|
|
53
70
|
const { action, sync } = await this.syncAll(trx);
|
|
54
|
-
log_1.Log.debug('bucket', this.
|
|
55
|
-
|
|
71
|
+
log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE index.all, ${action}`);
|
|
72
|
+
const data = [];
|
|
73
|
+
for (const e of sync) {
|
|
74
|
+
const { __update_epoch, __sync_epoch, ...obj } = e;
|
|
75
|
+
data.push(obj);
|
|
76
|
+
}
|
|
77
|
+
return data;
|
|
56
78
|
}
|
|
57
79
|
return this.outerAdapter.index(trx);
|
|
58
80
|
}
|
|
59
|
-
async query(trx,
|
|
81
|
+
async query(trx, query, pagination, params, config) {
|
|
60
82
|
const mode = this.config?.mode?.query;
|
|
83
|
+
let data;
|
|
61
84
|
if (mode === 'incremental') {
|
|
62
|
-
const { action, sync } = await this.syncQuery(trx,
|
|
63
|
-
log_1.Log.debug('bucket', this.
|
|
64
|
-
|
|
85
|
+
const { action, sync } = await this.syncQuery(trx, query, pagination, params);
|
|
86
|
+
log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE query.incremental, ${action}`);
|
|
87
|
+
data = sync;
|
|
65
88
|
}
|
|
66
|
-
if (mode === 'all') {
|
|
89
|
+
else if (mode === 'all') {
|
|
67
90
|
const { action, sync } = await this.syncAll(trx);
|
|
68
|
-
log_1.Log.debug('bucket', this.
|
|
69
|
-
|
|
91
|
+
log_1.Log.debug('bucket', this.bucket.schema.name, `CACHE query.all, ${action}`);
|
|
92
|
+
const entries = (await this.innerAdapter.query(trx, query, pagination, params, undefined, this.innerAdapter.nql)).data;
|
|
93
|
+
data = [];
|
|
94
|
+
for (const e of entries) {
|
|
95
|
+
const { __update_epoch, __sync_epoch, ...obj } = e;
|
|
96
|
+
data.push(obj);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
data = (await this.outerAdapter.query(trx, query, pagination, params)).data;
|
|
101
|
+
}
|
|
102
|
+
for (const entry of data) {
|
|
103
|
+
delete entry['__update_epoch'];
|
|
104
|
+
delete entry['__sync_epoch'];
|
|
70
105
|
}
|
|
71
|
-
|
|
106
|
+
if (config?.view) {
|
|
107
|
+
data = await this.bucket.buildMany(trx, data, config.view);
|
|
108
|
+
}
|
|
109
|
+
return { data };
|
|
72
110
|
}
|
|
73
111
|
/* Cache modes */
|
|
74
112
|
async syncOne(trx, id) {
|
|
75
|
-
|
|
113
|
+
let localObj = await this.innerAdapter.get(trx, id);
|
|
76
114
|
if (!localObj) {
|
|
77
115
|
const obj = await this.outerAdapter.get(trx, id);
|
|
78
116
|
if (obj) {
|
|
79
|
-
const entry = new BucketCacheEntry(obj
|
|
117
|
+
const entry = new BucketCacheEntry(obj, this.outerAdapter.getUpdateEpoch(obj), this.lastSyncEpoch);
|
|
80
118
|
await this.innerAdapter.create(trx, entry);
|
|
81
119
|
return { action: 'update', sync: entry };
|
|
82
120
|
}
|
|
83
|
-
return { action: '
|
|
121
|
+
return { action: 'none' };
|
|
84
122
|
}
|
|
85
|
-
const sync = await this.outerAdapter.syncOne(trx, id, localObj.
|
|
123
|
+
const sync = await this.outerAdapter.syncOne(trx, id, localObj.__update_epoch);
|
|
86
124
|
if (sync === null) {
|
|
87
|
-
return { action: '
|
|
125
|
+
return { action: 'none', sync: localObj };
|
|
88
126
|
}
|
|
89
127
|
if (sync === 'deleted') {
|
|
90
128
|
await this.innerAdapter.delete(trx, id);
|
|
91
129
|
return { action: 'delete' };
|
|
92
130
|
}
|
|
93
|
-
localObj
|
|
94
|
-
localObj.updateEpoch = sync.updateEpoch;
|
|
95
|
-
localObj.syncEpoch = datetime_1.NesoiDatetime.now().epoch;
|
|
131
|
+
localObj = new BucketCacheEntry(sync.obj, sync.updateEpoch, datetime_1.NesoiDatetime.now().epoch);
|
|
96
132
|
await this.innerAdapter.put(trx, localObj);
|
|
97
|
-
return { action: 'update', sync };
|
|
133
|
+
return { action: 'update', sync: localObj };
|
|
98
134
|
}
|
|
99
135
|
async syncOneAndPast(trx, id) {
|
|
100
136
|
const localObj = await this.innerAdapter.get(trx, id);
|
|
@@ -102,54 +138,52 @@ class BucketCache {
|
|
|
102
138
|
const obj = await this.outerAdapter.get(trx, id);
|
|
103
139
|
if (obj) {
|
|
104
140
|
await this.innerAdapter.create(trx, obj);
|
|
105
|
-
return { action: 'update', sync:
|
|
106
|
-
obj,
|
|
107
|
-
updateEpoch: this.outerAdapter.getUpdateEpoch(obj)
|
|
108
|
-
} };
|
|
141
|
+
return { action: 'update', sync: new BucketCacheEntry(obj, this.outerAdapter.getUpdateEpoch(obj), datetime_1.NesoiDatetime.now().epoch) };
|
|
109
142
|
}
|
|
110
|
-
return { action: '
|
|
143
|
+
return { action: 'none' };
|
|
111
144
|
}
|
|
112
|
-
const sync = await this.outerAdapter.syncOneAndPast(trx, id, localObj.
|
|
145
|
+
const sync = await this.outerAdapter.syncOneAndPast(trx, id, localObj.__update_epoch);
|
|
113
146
|
if (sync === null) {
|
|
114
|
-
return { action: '
|
|
147
|
+
return { action: 'none', sync: localObj };
|
|
115
148
|
}
|
|
116
149
|
if (sync === 'deleted') {
|
|
117
150
|
await this.innerAdapter.delete(trx, id);
|
|
118
151
|
return { action: 'delete' };
|
|
119
152
|
}
|
|
120
|
-
|
|
121
|
-
|
|
153
|
+
const entries = sync.map(s => new BucketCacheEntry(s.obj, s.updateEpoch, datetime_1.NesoiDatetime.now().epoch));
|
|
154
|
+
await this.innerAdapter.putMany(trx, entries);
|
|
155
|
+
return { action: 'update', sync: entries.find(e => e.id === id) };
|
|
122
156
|
}
|
|
123
157
|
async syncAll(trx) {
|
|
124
158
|
const sync = await this.outerAdapter.syncAll(trx, this.lastHash, this.lastUpdateEpoch);
|
|
125
159
|
if (sync === null) {
|
|
126
160
|
const all = await this.innerAdapter.index(trx);
|
|
127
|
-
return { action: '
|
|
161
|
+
return { action: 'none', sync: all };
|
|
128
162
|
}
|
|
129
163
|
this.lastUpdateEpoch = sync.updateEpoch;
|
|
130
164
|
this.lastHash = sync.hash;
|
|
131
165
|
this.lastSyncEpoch = datetime_1.NesoiDatetime.now().epoch;
|
|
132
|
-
const entries = sync.sync.map(s => new BucketCacheEntry(s.obj
|
|
166
|
+
const entries = sync.sync.map(s => new BucketCacheEntry(s.obj, s.updateEpoch, this.lastSyncEpoch));
|
|
133
167
|
if (sync.reset) {
|
|
134
168
|
await this.innerAdapter.deleteEverything(trx);
|
|
135
169
|
await this.innerAdapter.putMany(trx, entries);
|
|
136
|
-
return { action: 'reset', sync:
|
|
170
|
+
return { action: 'reset', sync: entries };
|
|
137
171
|
}
|
|
138
172
|
await this.innerAdapter.putMany(trx, entries);
|
|
139
|
-
return { action: 'update', sync:
|
|
173
|
+
return { action: 'update', sync: entries };
|
|
140
174
|
}
|
|
141
|
-
async syncQuery(trx,
|
|
175
|
+
async syncQuery(trx, query, pagination, params) {
|
|
142
176
|
// 1. Query id and epoch from outer adapter
|
|
143
|
-
const outerMetadata = await this.outerAdapter.query(trx, query, pagination,
|
|
177
|
+
const outerMetadata = await this.outerAdapter.query(trx, query, pagination, params, {
|
|
144
178
|
metadataOnly: true
|
|
145
179
|
});
|
|
146
180
|
if (!outerMetadata.data.length) {
|
|
147
|
-
return { action: '
|
|
181
|
+
return { action: 'none', sync: [] };
|
|
148
182
|
}
|
|
149
183
|
// 2. Read ids from the inner adapter
|
|
150
184
|
const innerData = await this.innerAdapter.query(trx, {
|
|
151
185
|
'id in': outerMetadata.data.map(obj => obj.id)
|
|
152
|
-
});
|
|
186
|
+
}, undefined, undefined, undefined, this.innerAdapter.nql);
|
|
153
187
|
// 3. Filter modified query results
|
|
154
188
|
const outerEpoch = {};
|
|
155
189
|
for (const i in outerMetadata.data) {
|
|
@@ -159,18 +193,18 @@ class BucketCache {
|
|
|
159
193
|
const queryResults = {};
|
|
160
194
|
const modifiedIds = [];
|
|
161
195
|
for (const i in innerData.data) {
|
|
162
|
-
const
|
|
163
|
-
const epoch = outerEpoch[
|
|
164
|
-
if (!epoch || epoch >
|
|
165
|
-
modifiedIds.push(
|
|
196
|
+
const entry = innerData.data[i];
|
|
197
|
+
const epoch = outerEpoch[entry.id];
|
|
198
|
+
if (!epoch || epoch > entry.__update_epoch) {
|
|
199
|
+
modifiedIds.push(entry.id);
|
|
166
200
|
}
|
|
167
201
|
else {
|
|
168
|
-
queryResults[
|
|
202
|
+
queryResults[entry.id] = entry;
|
|
169
203
|
}
|
|
170
204
|
}
|
|
171
205
|
// 4. Nothing changed, return current data
|
|
172
206
|
if (!modifiedIds.length) {
|
|
173
|
-
return { action: '
|
|
207
|
+
return { action: 'none', sync: innerData.data };
|
|
174
208
|
}
|
|
175
209
|
// 5. Query modified objects to outer adapter and merge them on results
|
|
176
210
|
const outerData = await this.outerAdapter.query(trx, {
|
|
@@ -184,7 +218,7 @@ class BucketCache {
|
|
|
184
218
|
updateEpoch
|
|
185
219
|
};
|
|
186
220
|
}
|
|
187
|
-
return { action: 'update', sync: Object.values(queryResults) };
|
|
221
|
+
return { action: 'update', sync: Object.values(queryResults).map(r => new BucketCacheEntry(r.obj, r.updateEpoch, datetime_1.NesoiDatetime.now().epoch)) };
|
|
188
222
|
}
|
|
189
223
|
}
|
|
190
224
|
exports.BucketCache = BucketCache;
|
|
@@ -5,6 +5,7 @@ const trx_node_1 = require("../../../../engine/transaction/trx_node");
|
|
|
5
5
|
const log_1 = require("../../../../engine/util/log");
|
|
6
6
|
const error_1 = require("../../../../engine/data/error");
|
|
7
7
|
const memory_bucket_adapter_1 = require("../adapters/memory.bucket_adapter");
|
|
8
|
+
const bucket_cache_1 = require("../cache/bucket_cache");
|
|
8
9
|
/**
|
|
9
10
|
* @category Elements
|
|
10
11
|
* @subcategory Entity
|
|
@@ -31,7 +32,8 @@ class BucketGraph {
|
|
|
31
32
|
: this.bucket.getTenancyQuery(trx);
|
|
32
33
|
// Query
|
|
33
34
|
const otherBucket = trx_node_1.TrxNode.getModule(trx).buckets[schema.bucket.refName];
|
|
34
|
-
const
|
|
35
|
+
const adapter = otherBucket.cache || otherBucket.adapter;
|
|
36
|
+
const links = await adapter.query(trx, {
|
|
35
37
|
...schema.query,
|
|
36
38
|
'#and': tenancy
|
|
37
39
|
}, {
|
|
@@ -77,10 +79,11 @@ class BucketGraph {
|
|
|
77
79
|
// let tempData: Record<string, any> = {};
|
|
78
80
|
let tempAdapter;
|
|
79
81
|
if (otherBucket.adapter instanceof memory_bucket_adapter_1.MemoryBucketAdapter) {
|
|
80
|
-
tempAdapter = otherBucket.adapter;
|
|
82
|
+
tempAdapter = otherBucket.cache || otherBucket.adapter;
|
|
81
83
|
}
|
|
82
84
|
else {
|
|
83
|
-
const
|
|
85
|
+
const adapter = otherBucket.cache || otherBucket.adapter;
|
|
86
|
+
const allLinks = await adapter.query(trx, {
|
|
84
87
|
...schema.query,
|
|
85
88
|
'#and': tenancy
|
|
86
89
|
}, undefined, objs.map(obj => ({ ...obj })));
|
|
@@ -91,9 +94,13 @@ class BucketGraph {
|
|
|
91
94
|
}
|
|
92
95
|
const links = [];
|
|
93
96
|
for (const obj of objs) {
|
|
94
|
-
const result =
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
const result = tempAdapter instanceof bucket_cache_1.BucketCache
|
|
98
|
+
? await tempAdapter.query(trx, schema.query, {
|
|
99
|
+
perPage: schema.many ? undefined : 1,
|
|
100
|
+
}, [{ ...obj }], undefined)
|
|
101
|
+
: await tempAdapter.query(trx, schema.query, {
|
|
102
|
+
perPage: schema.many ? undefined : 1,
|
|
103
|
+
}, [{ ...obj }], undefined, tempAdapter.nql);
|
|
97
104
|
if (schema.many) {
|
|
98
105
|
links.push(result.data);
|
|
99
106
|
}
|
|
@@ -146,7 +146,7 @@ class $BucketModel {
|
|
|
146
146
|
path: i.toString(),
|
|
147
147
|
obj: val,
|
|
148
148
|
copy: entry.copy[entry.path],
|
|
149
|
-
field: entry.field.children['
|
|
149
|
+
field: entry.field.children['#']
|
|
150
150
|
})));
|
|
151
151
|
}
|
|
152
152
|
else if (entry.field.type === 'dict') {
|
|
@@ -157,7 +157,7 @@ class $BucketModel {
|
|
|
157
157
|
path,
|
|
158
158
|
obj: val,
|
|
159
159
|
copy: entry.copy[entry.path],
|
|
160
|
-
field: entry.field.children['
|
|
160
|
+
field: entry.field.children['#']
|
|
161
161
|
})));
|
|
162
162
|
}
|
|
163
163
|
else if (entry.field.type === 'obj') {
|