nesoi 3.0.12 → 3.0.14
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/apps/monolyth/stages/2_build_typescript_stage.js +5 -2
- package/lib/compiler/apps/monolyth/stages/3_copy_types_stage.js +2 -2
- package/lib/compiler/apps/monolyth/stages/4_dump_modules_stage.js +2 -2
- package/lib/compiler/apps/monolyth/stages/7_dump_package_json_stage.js +4 -1
- package/lib/compiler/compiler.d.ts +2 -0
- package/lib/compiler/compiler.js +10 -38
- package/lib/compiler/elements/cached.element.d.ts +11 -0
- package/lib/compiler/elements/cached.element.js +18 -0
- package/lib/compiler/elements/element.d.ts +3 -1
- package/lib/compiler/elements/element.js +3 -1
- package/lib/compiler/elements/externals.element.d.ts +1 -1
- package/lib/compiler/elements/externals.element.js +2 -35
- package/lib/compiler/module.d.ts +3 -2
- package/lib/compiler/module.js +9 -2
- package/lib/compiler/progressive.d.ts +71 -0
- package/lib/compiler/progressive.js +164 -0
- package/lib/compiler/stages/1_scan_stage.js +5 -2
- package/lib/compiler/stages/2_treeshake_stage.js +7 -1
- package/lib/compiler/stages/3_extract_ts_stage.js +9 -0
- package/lib/compiler/stages/4_build_schemas_stage.js +10 -1
- package/lib/compiler/stages/5_inject_ts_stage.js +3 -0
- package/lib/compiler/stages/6_build_elements_stage.js +3 -0
- package/lib/compiler/stages/7_dump_stage.d.ts +4 -1
- package/lib/compiler/stages/7_dump_stage.js +108 -44
- package/lib/compiler/stages/8_diagnose_stage.js +3 -0
- package/lib/compiler/treeshake.d.ts +5 -2
- package/lib/compiler/treeshake.js +41 -8
- package/lib/compiler/typescript/bridge/inject.js +2 -0
- package/lib/compiler/typescript/transformers/app_inject.transformer.js +1 -1
- package/lib/elements/blocks/resource/resource.js +1 -1
- package/lib/elements/entities/bucket/bucket.d.ts +3 -1
- package/lib/elements/entities/bucket/bucket.js +18 -6
- package/lib/engine/apps/app.config.d.ts +11 -9
- package/lib/engine/apps/app.config.js +1 -2
- package/lib/engine/apps/app.js +2 -2
- package/lib/engine/data/trash.d.ts +13 -10
- package/lib/engine/data/trash.js +33 -0
- package/lib/engine/dependency.d.ts +6 -0
- package/lib/engine/dependency.js +1 -0
- package/lib/engine/module.d.ts +4 -2
- package/lib/engine/module.js +8 -3
- package/lib/engine/space.d.ts +1 -1
- package/lib/engine/space.js +14 -5
- package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +5 -1
- package/lib/engine/transaction/nodes/bucket.trx_node.js +9 -2
- package/lib/engine/transaction/nodes/bucket_query.trx_node.d.ts +3 -3
- package/lib/engine/transaction/nodes/bucket_query.trx_node.js +2 -2
- package/lib/engine/transaction/trx_engine.d.ts +1 -1
- package/lib/engine/transaction/trx_node.d.ts +1 -1
- package/lib/engine/transaction/trx_node.js +3 -1
- package/lib/engine/tree.d.ts +8 -1
- package/lib/engine/tree.js +45 -25
- package/lib/engine/util/hash.d.ts +2 -1
- package/lib/engine/util/hash.js +10 -1
- package/package.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -15,14 +15,23 @@ class BuildSchemasStage {
|
|
|
15
15
|
}
|
|
16
16
|
async run() {
|
|
17
17
|
log_1.Log.info('compiler', 'stage.build_schemas', 'Building schemas...');
|
|
18
|
+
const t0 = new Date().getTime();
|
|
18
19
|
await this.compiler.tree.traverse('Building schemas ', async (node) => {
|
|
20
|
+
const module = this.compiler.modules[node.module].module;
|
|
21
|
+
if (node.progressive) {
|
|
22
|
+
await module.inject({
|
|
23
|
+
[node.progressive.schema.$t + 's']: [node.progressive.schema]
|
|
24
|
+
});
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
19
27
|
// Inline nodes are built by their root builder
|
|
20
28
|
if (node.isInline) {
|
|
21
29
|
return;
|
|
22
30
|
}
|
|
23
|
-
const module = this.compiler.modules[node.module].module;
|
|
24
31
|
await module.buildNode(node, this.compiler.tree);
|
|
25
32
|
});
|
|
33
|
+
const t = new Date().getTime();
|
|
34
|
+
log_1.Log.debug('compiler', 'stage.build_schemas', `[t: ${(t - t0) / 1000} ms]`);
|
|
26
35
|
}
|
|
27
36
|
}
|
|
28
37
|
exports.BuildSchemasStage = BuildSchemasStage;
|
|
@@ -16,9 +16,12 @@ class InjectTSStage {
|
|
|
16
16
|
}
|
|
17
17
|
run() {
|
|
18
18
|
log_1.Log.info('compiler', 'stage.inject_ts', 'Injecting TypeScript code to schemas...');
|
|
19
|
+
const t0 = new Date().getTime();
|
|
19
20
|
const { tree } = this.compiler;
|
|
20
21
|
const nodes = tree.allNodes();
|
|
21
22
|
inject_1.TSBridgeInject.inject(this.compiler, nodes);
|
|
23
|
+
const t = new Date().getTime();
|
|
24
|
+
log_1.Log.debug('compiler', 'stage.inject_ts', `[t: ${(t - t0) / 1000} ms]`);
|
|
22
25
|
log_1.Log.trace('compiler', 'stage.inject_ts', 'Finished injecting TS code');
|
|
23
26
|
}
|
|
24
27
|
}
|
|
@@ -16,10 +16,13 @@ class BuildElementsStage {
|
|
|
16
16
|
}
|
|
17
17
|
async run() {
|
|
18
18
|
log_1.Log.info('compiler', 'stage.build_elements', 'Building Elements...');
|
|
19
|
+
const t0 = new Date().getTime();
|
|
19
20
|
await this.compiler.tree.traverse('Building elements ', async (node) => {
|
|
20
21
|
const module = this.compiler.modules[node.module];
|
|
21
22
|
await module.buildElementNode(node);
|
|
22
23
|
});
|
|
24
|
+
const t = new Date().getTime();
|
|
25
|
+
log_1.Log.debug('compiler', 'stage.build_elements', `[t: ${(t - t0) / 1000} ms]`);
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
exports.BuildElementsStage = BuildElementsStage;
|
|
@@ -8,10 +8,13 @@ import { Compiler } from '../compiler';
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class DumpStage {
|
|
10
10
|
compiler: Compiler;
|
|
11
|
+
private cache;
|
|
12
|
+
private hash;
|
|
11
13
|
constructor(compiler: Compiler);
|
|
12
|
-
run(): void
|
|
14
|
+
run(): Promise<void>;
|
|
13
15
|
private dumpSpace;
|
|
14
16
|
private dumpModule;
|
|
15
17
|
private dumpModuleSchemas;
|
|
16
18
|
private dumpModuleType;
|
|
19
|
+
private makeModuleType;
|
|
17
20
|
}
|
|
@@ -45,6 +45,7 @@ const dependency_1 = require("../../engine/dependency");
|
|
|
45
45
|
const bucket_element_1 = require("../elements/bucket.element");
|
|
46
46
|
const dump_helpers_1 = require("../helpers/dump_helpers");
|
|
47
47
|
const space_1 = require("../../engine/space");
|
|
48
|
+
const progressive_1 = require("../progressive");
|
|
48
49
|
/**
|
|
49
50
|
* [Compiler Stage #7]
|
|
50
51
|
* Dump the element schemas and types to the .nesoi folder.
|
|
@@ -56,12 +57,27 @@ class DumpStage {
|
|
|
56
57
|
constructor(compiler) {
|
|
57
58
|
this.compiler = compiler;
|
|
58
59
|
}
|
|
59
|
-
run() {
|
|
60
|
+
async run() {
|
|
60
61
|
log_1.Log.info('compiler', 'stage.dump', 'Dumping Schemas and Types...');
|
|
61
|
-
const
|
|
62
|
+
const t0 = new Date().getTime();
|
|
63
|
+
this.cache = await progressive_1.ProgressiveBuild.cache(this.compiler);
|
|
64
|
+
this.hash = await progressive_1.ProgressiveBuild.hash(this.compiler);
|
|
65
|
+
let spaceType;
|
|
66
|
+
if (this.hash.$ !== this.cache.hash.$) {
|
|
67
|
+
spaceType = this.dumpSpace();
|
|
68
|
+
this.cache.types.space = spaceType;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
spaceType = this.cache.types.space;
|
|
72
|
+
}
|
|
62
73
|
Object.values(this.compiler.modules).forEach(module => {
|
|
63
|
-
this.
|
|
74
|
+
if (this.hash.modules[module.lowName]?.$ !== this.cache.hash.modules[module.lowName]?.$) {
|
|
75
|
+
this.dumpModule(module, spaceType);
|
|
76
|
+
}
|
|
64
77
|
});
|
|
78
|
+
await progressive_1.ProgressiveBuild.save(this.compiler.space, this.cache, this.hash);
|
|
79
|
+
const t = new Date().getTime();
|
|
80
|
+
log_1.Log.debug('compiler', 'stage.dump', `[t: ${(t - t0) / 1000} ms]`);
|
|
65
81
|
}
|
|
66
82
|
/* Space */
|
|
67
83
|
dumpSpace() {
|
|
@@ -74,7 +90,7 @@ class DumpStage {
|
|
|
74
90
|
Object.entries(_authn).forEach(([name, model]) => {
|
|
75
91
|
type.authnUsers[name] = bucket_element_1.BucketElement.buildModelTypeFromSchema(model);
|
|
76
92
|
});
|
|
77
|
-
// Module
|
|
93
|
+
// Module imports
|
|
78
94
|
let dump = '';
|
|
79
95
|
dump += `import { $Space } from '${this.compiler.config?.nesoiPath ?? 'nesoi'}/lib/schema';\n`;
|
|
80
96
|
Object.values(this.compiler.modules).forEach(module => {
|
|
@@ -105,12 +121,18 @@ class DumpStage {
|
|
|
105
121
|
dumpModuleSchemas(module, dumpDir) {
|
|
106
122
|
const nesoiPath = this.compiler.config?.nesoiPath ?? 'nesoi';
|
|
107
123
|
module.elements.forEach((element) => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
124
|
+
if (element.schema.$t === 'constants'
|
|
125
|
+
|| element.schema.$t === 'externals'
|
|
126
|
+
|| (this.hash.modules[element.schema.module].nodes[element.tag]
|
|
127
|
+
!== this.cache.hash.modules[element.schema.module]?.nodes[element.tag])) {
|
|
128
|
+
const filename = path_1.default.basename(element.filepath());
|
|
129
|
+
const elPath = path_1.default.resolve(dumpDir, filename);
|
|
130
|
+
fs.writeFileSync(elPath, element.dumpFileSchema(nesoiPath));
|
|
131
|
+
}
|
|
111
132
|
});
|
|
112
133
|
}
|
|
113
134
|
dumpModuleType(module, spaceType, dumpDir) {
|
|
135
|
+
var _a, _b;
|
|
114
136
|
const nesoiPath = this.compiler.config?.nesoiPath ?? 'nesoi';
|
|
115
137
|
const moduleFile = [];
|
|
116
138
|
moduleFile.push(`import { $Module, $Constants, $Bucket, $Message, $Job, $Resource, $Machine, $Controller, $Queue } from '${nesoiPath}/lib/elements';`);
|
|
@@ -118,6 +140,71 @@ class DumpStage {
|
|
|
118
140
|
moduleFile.push(`import { NesoiDatetime } from '${nesoiPath}/lib/engine/data/datetime';`);
|
|
119
141
|
moduleFile.push(`import { NesoiDecimal } from '${nesoiPath}/lib/engine/data/decimal';`);
|
|
120
142
|
moduleFile.push(`import { NesoiFile } from '${nesoiPath}/lib/engine/data/file';`);
|
|
143
|
+
// Get external modules
|
|
144
|
+
const moduleDependencies = new Set();
|
|
145
|
+
// Pre-populate from cache
|
|
146
|
+
if (this.cache) {
|
|
147
|
+
this.cache.modules[module.lowName]?.dependencies.modules.forEach(module => {
|
|
148
|
+
if (module in this.compiler.modules) {
|
|
149
|
+
moduleDependencies.add(module);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Extract from updated elements
|
|
154
|
+
const externalElement = module.elements
|
|
155
|
+
.find(el => el.$t === 'externals');
|
|
156
|
+
if (externalElement) {
|
|
157
|
+
for (const module of externalElement.getModuleDependencies()) {
|
|
158
|
+
moduleDependencies.add(module);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Dump external imports
|
|
162
|
+
moduleFile.push(...Array.from(moduleDependencies)
|
|
163
|
+
.map(module => `import ${name_helpers_1.NameHelpers.nameLowToHigh(module)}Module from './${module}.module'`));
|
|
164
|
+
(_a = this.cache.modules)[_b = module.lowName] ?? (_a[_b] = {
|
|
165
|
+
dependencies: {
|
|
166
|
+
modules: []
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
this.cache.modules[module.lowName].dependencies.modules = Array.from(moduleDependencies);
|
|
170
|
+
// Build module type (with all elements)
|
|
171
|
+
const type = this.makeModuleType(module);
|
|
172
|
+
this.cache.types.modules[module.lowName] = type;
|
|
173
|
+
// Dump module type
|
|
174
|
+
moduleFile.push('');
|
|
175
|
+
moduleFile.push('/**');
|
|
176
|
+
moduleFile.push(` * ${module.typeName}`);
|
|
177
|
+
moduleFile.push(' */');
|
|
178
|
+
moduleFile.push('');
|
|
179
|
+
let moduleDump = `export default interface ${module.typeName} extends $Module `;
|
|
180
|
+
moduleDump += dump_helpers_1.DumpHelpers.dumpType({
|
|
181
|
+
// Constants should be unknown by default, since enum types
|
|
182
|
+
// are validated across modules. The default type causes
|
|
183
|
+
// the enum alias to be keyof ... & Record<string, ...>, which
|
|
184
|
+
// invalidated the type assertion
|
|
185
|
+
constants: 'Omit<$Constants, \'values\'|\'enums\'> & { values: {}, enums: {} }',
|
|
186
|
+
...type
|
|
187
|
+
});
|
|
188
|
+
moduleFile.push(moduleDump);
|
|
189
|
+
moduleFile.push('');
|
|
190
|
+
moduleFile.push('/* */');
|
|
191
|
+
moduleFile.push('');
|
|
192
|
+
// Dump authentication users
|
|
193
|
+
moduleFile.push(`type AuthnUsers = ${dump_helpers_1.DumpHelpers.dumpType(spaceType.authnUsers)}`);
|
|
194
|
+
// Dump other elements
|
|
195
|
+
module.elements
|
|
196
|
+
.filter(el => el.$t !== 'externals')
|
|
197
|
+
.forEach((element) => {
|
|
198
|
+
const type = element.dumpTypeSchema(this.cache);
|
|
199
|
+
this.cache.types.elements[element.tag] = type;
|
|
200
|
+
moduleFile.push(this.cache.types.elements[element.tag]);
|
|
201
|
+
});
|
|
202
|
+
// Write to file
|
|
203
|
+
const moduleFilename = `../${module.lowName}.module`;
|
|
204
|
+
const moduleFilepath = path_1.default.resolve(dumpDir, moduleFilename + '.ts');
|
|
205
|
+
fs.writeFileSync(moduleFilepath, moduleFile.join('\n'));
|
|
206
|
+
}
|
|
207
|
+
makeModuleType(module) {
|
|
121
208
|
// Build module type (with all blocks)
|
|
122
209
|
const type = {
|
|
123
210
|
name: `'${module.lowName}'`,
|
|
@@ -131,6 +218,19 @@ class DumpStage {
|
|
|
131
218
|
queues: {},
|
|
132
219
|
controllers: {},
|
|
133
220
|
};
|
|
221
|
+
// Merge types that currently exist and are found on cache
|
|
222
|
+
const typeCache = this.cache.types.modules[module.lowName];
|
|
223
|
+
if (typeCache) {
|
|
224
|
+
type.externals = typeCache.externals || 'any';
|
|
225
|
+
type.constants = typeCache.constants || 'any';
|
|
226
|
+
for (const eltype of ['buckets', 'messages', 'jobs', 'resources', 'machines', 'queues', 'controllers']) {
|
|
227
|
+
for (const name in typeCache[eltype] || {}) {
|
|
228
|
+
if (name in module.module.schema[eltype]) {
|
|
229
|
+
type[eltype][name] = typeCache[eltype][name];
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
134
234
|
const externals = module.elements.find(el => el.$t === 'externals');
|
|
135
235
|
// Inject external node types on module
|
|
136
236
|
if (externals) {
|
|
@@ -171,43 +271,7 @@ class DumpStage {
|
|
|
171
271
|
.filter(el => el.$t === 'message')
|
|
172
272
|
.map(el => el.typeName));
|
|
173
273
|
type['#authn'] = 'AuthnUsers';
|
|
174
|
-
|
|
175
|
-
module.elements
|
|
176
|
-
.filter(el => el.$t === 'externals')
|
|
177
|
-
.forEach((element) => {
|
|
178
|
-
moduleFile.push(element.dumpTypeSchema());
|
|
179
|
-
});
|
|
180
|
-
// Dump module type
|
|
181
|
-
moduleFile.push('');
|
|
182
|
-
moduleFile.push('/**');
|
|
183
|
-
moduleFile.push(` * ${module.typeName}`);
|
|
184
|
-
moduleFile.push(' */');
|
|
185
|
-
moduleFile.push('');
|
|
186
|
-
let moduleDump = `export default interface ${module.typeName} extends $Module `;
|
|
187
|
-
moduleDump += dump_helpers_1.DumpHelpers.dumpType({
|
|
188
|
-
// Constants should be unknown by default, since enum types
|
|
189
|
-
// are validated across modules. The default type causes
|
|
190
|
-
// the enum alias to be keyof ... & Record<string, ...>, which
|
|
191
|
-
// invalidated the type assertion
|
|
192
|
-
constants: 'Omit<$Constants, \'values\'|\'enums\'> & { values: {}, enums: {} }',
|
|
193
|
-
...type
|
|
194
|
-
});
|
|
195
|
-
moduleFile.push(moduleDump);
|
|
196
|
-
moduleFile.push('');
|
|
197
|
-
moduleFile.push('/* */');
|
|
198
|
-
moduleFile.push('');
|
|
199
|
-
// Dump authentication users
|
|
200
|
-
moduleFile.push(`type AuthnUsers = ${dump_helpers_1.DumpHelpers.dumpType(spaceType.authnUsers)}`);
|
|
201
|
-
// Dump other elements
|
|
202
|
-
module.elements
|
|
203
|
-
.filter(el => el.$t !== 'externals')
|
|
204
|
-
.forEach((element) => {
|
|
205
|
-
moduleFile.push(element.dumpTypeSchema());
|
|
206
|
-
});
|
|
207
|
-
// Write to file
|
|
208
|
-
const moduleFilename = `../${module.lowName}.module`;
|
|
209
|
-
const moduleFilepath = path_1.default.resolve(dumpDir, moduleFilename + '.ts');
|
|
210
|
-
fs.writeFileSync(moduleFilepath, moduleFile.join('\n'));
|
|
274
|
+
return type;
|
|
211
275
|
}
|
|
212
276
|
}
|
|
213
277
|
exports.DumpStage = DumpStage;
|
|
@@ -21,6 +21,7 @@ class DiagnoseStage {
|
|
|
21
21
|
}
|
|
22
22
|
async run() {
|
|
23
23
|
log_1.Log.info('compiler', 'stage.diagnose', 'Diagnosing space files with TypeScript...');
|
|
24
|
+
const t0 = new Date().getTime();
|
|
24
25
|
const { tsCompiler, tree } = this.compiler;
|
|
25
26
|
// Recreate TS program, to load new version of types
|
|
26
27
|
tsCompiler.createProgram();
|
|
@@ -41,6 +42,8 @@ class DiagnoseStage {
|
|
|
41
42
|
filepaths.forEach(filepath => {
|
|
42
43
|
tsCompiler.check(filepath);
|
|
43
44
|
});
|
|
45
|
+
const t = new Date().getTime();
|
|
46
|
+
log_1.Log.debug('compiler', 'stage.diagnose', `[t: ${(t - t0) / 1000} ms]`);
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
exports.DiagnoseStage = DiagnoseStage;
|
|
@@ -2,6 +2,7 @@ import { $Dependency, BuilderNode } from "../engine/dependency";
|
|
|
2
2
|
import { BucketGraphBuilder } from "../elements/entities/bucket/graph/bucket_graph.builder";
|
|
3
3
|
import { AnyModule } from "../engine/module";
|
|
4
4
|
import { $BucketModelFields } from "../elements/entities/bucket/model/bucket_model.schema";
|
|
5
|
+
import { ProgressiveBuildCache } from './progressive';
|
|
5
6
|
export type TreeshakeConfig = {
|
|
6
7
|
exclude?: string[];
|
|
7
8
|
};
|
|
@@ -28,14 +29,16 @@ export declare class Treeshake {
|
|
|
28
29
|
inlines: BuilderNode[];
|
|
29
30
|
};
|
|
30
31
|
static controller(node: BuilderNode): void;
|
|
31
|
-
static queue(node: BuilderNode):
|
|
32
|
+
static queue(node: BuilderNode): {
|
|
33
|
+
inlines: BuilderNode[];
|
|
34
|
+
};
|
|
32
35
|
/**
|
|
33
36
|
* Scans the module directory, imports the builders and lists
|
|
34
37
|
* all nodes found.
|
|
35
38
|
*
|
|
36
39
|
* @returns A list of all `BuilderNodes` found on the module folder
|
|
37
40
|
*/
|
|
38
|
-
static module(module: AnyModule, config?: TreeshakeConfig): Promise<BuilderNode[]>;
|
|
41
|
+
static module(module: AnyModule, cache: ProgressiveBuildCache, config?: TreeshakeConfig): Promise<BuilderNode[]>;
|
|
39
42
|
/**
|
|
40
43
|
* Shakes a file to find all the builders declared on that file, and returns
|
|
41
44
|
* them as BuilderNodes:
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.Treeshake = void 0;
|
|
4
7
|
const dependency_1 = require("../engine/dependency");
|
|
@@ -8,6 +11,8 @@ const log_1 = require("../engine/util/log");
|
|
|
8
11
|
const string_1 = require("../engine/util/string");
|
|
9
12
|
const error_1 = require("../engine/data/error");
|
|
10
13
|
const constants_builder_1 = require("../elements/entities/constants/constants.builder");
|
|
14
|
+
const progressive_1 = require("./progressive");
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
11
16
|
class Treeshake {
|
|
12
17
|
/* Externals */
|
|
13
18
|
static externals(node, depth = 1) {
|
|
@@ -191,8 +196,15 @@ class Treeshake {
|
|
|
191
196
|
node.dependencies = [];
|
|
192
197
|
}
|
|
193
198
|
static queue(node) {
|
|
194
|
-
const
|
|
195
|
-
node.
|
|
199
|
+
const builder = node.builder;
|
|
200
|
+
log_1.Log.trace('compiler', 'treeshake', `└ Treeshaking node ${(0, log_1.scopeTag)(builder.$b, node.name)}`);
|
|
201
|
+
const inlineTreeshake = Treeshake.blockInlineNodes(node);
|
|
202
|
+
node.dependencies = [
|
|
203
|
+
...Treeshake.blockIO(node),
|
|
204
|
+
...inlineTreeshake.dependencies
|
|
205
|
+
];
|
|
206
|
+
node.dependencies = this.cleanNodeDependencies(node);
|
|
207
|
+
return { inlines: inlineTreeshake.inlines };
|
|
196
208
|
}
|
|
197
209
|
/* Module */
|
|
198
210
|
/**
|
|
@@ -201,7 +213,7 @@ class Treeshake {
|
|
|
201
213
|
*
|
|
202
214
|
* @returns A list of all `BuilderNodes` found on the module folder
|
|
203
215
|
*/
|
|
204
|
-
static async module(module, config) {
|
|
216
|
+
static async module(module, cache, config) {
|
|
205
217
|
log_1.Log.debug('compiler', 'treeshake', `Treeshaking ${(0, log_1.scopeTag)('module', module.name)}`);
|
|
206
218
|
const nodes = [];
|
|
207
219
|
const merge = (node) => {
|
|
@@ -230,7 +242,7 @@ class Treeshake {
|
|
|
230
242
|
if (module.boot && 'dirpath' in module.boot) {
|
|
231
243
|
const files = module.scanFiles(module.boot.dirpath, config?.exclude);
|
|
232
244
|
for (const file of files) {
|
|
233
|
-
const fileNodes = await Treeshake.file(module.name, file);
|
|
245
|
+
const fileNodes = await Treeshake.file(module.name, file, cache);
|
|
234
246
|
fileNodes.forEach(merge);
|
|
235
247
|
}
|
|
236
248
|
}
|
|
@@ -254,7 +266,13 @@ class Treeshake {
|
|
|
254
266
|
* - Inline builders
|
|
255
267
|
* - Nested inline builders
|
|
256
268
|
*/
|
|
257
|
-
static async file(module, filepath) {
|
|
269
|
+
static async file(module, filepath, cache) {
|
|
270
|
+
if (cache && filepath in cache.files) {
|
|
271
|
+
const nodes = await progressive_1.ProgressiveBuild.treeshake(cache, filepath);
|
|
272
|
+
if (nodes) {
|
|
273
|
+
return nodes;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
258
276
|
log_1.Log.debug('compiler', 'treeshake', ` └ Treeshaking file ${(0, string_1.colored)(filepath, 'blue')}`);
|
|
259
277
|
// Require is used here to avoid cache - which allows watch mode
|
|
260
278
|
delete require.cache[filepath];
|
|
@@ -272,6 +290,10 @@ class Treeshake {
|
|
|
272
290
|
nodes.push(...Treeshake.builder(module, builder, filepath));
|
|
273
291
|
}
|
|
274
292
|
log_1.Log.debug('compiler', 'treeshake', ` - Nodes: ${(0, string_1.colored)(nodes.map(node => node.tag).join(', '), 'purple')}`);
|
|
293
|
+
cache.files[filepath] = {
|
|
294
|
+
type: nodes.map(node => node.type),
|
|
295
|
+
elements: nodes.map(node => path_1.default.join(cache.nesoidir, module, `${node.type}__${node.name}.ts`)).flat(1)
|
|
296
|
+
};
|
|
275
297
|
return nodes;
|
|
276
298
|
}
|
|
277
299
|
/**
|
|
@@ -341,7 +363,14 @@ class Treeshake {
|
|
|
341
363
|
Treeshake.controller(node);
|
|
342
364
|
}
|
|
343
365
|
else if (builder.$b === 'queue') {
|
|
344
|
-
Treeshake.queue(node);
|
|
366
|
+
const { inlines } = Treeshake.queue(node);
|
|
367
|
+
inlines.forEach(inline => {
|
|
368
|
+
nodes.push({
|
|
369
|
+
...inline,
|
|
370
|
+
module,
|
|
371
|
+
filepath
|
|
372
|
+
});
|
|
373
|
+
});
|
|
345
374
|
}
|
|
346
375
|
else {
|
|
347
376
|
throw error_1.NesoiError.Module.UnknownBuilderType({}, filepath, '', builder.$b);
|
|
@@ -382,9 +411,13 @@ class Treeshake {
|
|
|
382
411
|
}))
|
|
383
412
|
.sort((a, b) => a.tag.localeCompare(b.tag))
|
|
384
413
|
.forEach(({ node, tag }) => {
|
|
385
|
-
log_1.Log.
|
|
414
|
+
log_1.Log.debug('compiler', 'treeshake', `${' '.repeat(depth)} └ ${tag} ` + (0, string_1.colored)(`@ ${node.filepath}`, 'purple'));
|
|
415
|
+
if (node.progressive) {
|
|
416
|
+
log_1.Log.debug('compiler', 'treeshake', `${' '.repeat(depth + 1)}` + (0, string_1.colored)('[cache]', 'green'));
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
386
419
|
if (node.dependencies.length) {
|
|
387
|
-
log_1.Log.
|
|
420
|
+
log_1.Log.debug('compiler', 'treeshake', (0, string_1.colored)(`${' '.repeat(depth)} (depends on: ${node.dependencies.map(dep => dep.tag).join(', ')})`, 'purple'));
|
|
388
421
|
}
|
|
389
422
|
if ('_inlineNodes' in node.builder) {
|
|
390
423
|
const inlineNodes = node.builder['_inlineNodes'];
|
|
@@ -7,6 +7,8 @@ class TSBridgeInject {
|
|
|
7
7
|
static inject(compiler, nodes) {
|
|
8
8
|
const { tsCompiler } = compiler;
|
|
9
9
|
nodes.forEach(node => {
|
|
10
|
+
if (node.progressive)
|
|
11
|
+
return;
|
|
10
12
|
log_1.Log.debug('compiler', 'bridge.inject', `Injecting TS code on ${node.tag}`);
|
|
11
13
|
const schema = node.schema;
|
|
12
14
|
if (schema.$t === 'bucket') {
|
|
@@ -60,7 +60,7 @@ function makeAppInjectTransformer(modules) {
|
|
|
60
60
|
monolyth = true;
|
|
61
61
|
return deep.node;
|
|
62
62
|
}, context);
|
|
63
|
-
// Transform .modules() into .
|
|
63
|
+
// Transform .modules() into .inject()
|
|
64
64
|
if (monolyth
|
|
65
65
|
&& ts.isCallExpression(cNode)
|
|
66
66
|
&& ts.isPropertyAccessExpression(cNode.expression)
|
|
@@ -11,6 +11,7 @@ import { NQL_Result } from './query/nql_engine';
|
|
|
11
11
|
import { $BucketModelFields } from './model/bucket_model.schema';
|
|
12
12
|
import { DriveAdapter } from '../drive/drive_adapter';
|
|
13
13
|
import { IService } from "../../../engine/apps/service";
|
|
14
|
+
import { AnyModule } from "../../../engine/module";
|
|
14
15
|
/**
|
|
15
16
|
* **This should only be used inside a `#composition` of a bucket `create`** to refer to the parent id, which doesn't exist yet.
|
|
16
17
|
*
|
|
@@ -26,6 +27,7 @@ export declare const $id: string | number;
|
|
|
26
27
|
* @subcategory Entity
|
|
27
28
|
* */
|
|
28
29
|
export declare class Bucket<M extends $Module, $ extends $Bucket> {
|
|
30
|
+
module: AnyModule;
|
|
29
31
|
schema: $;
|
|
30
32
|
private config?;
|
|
31
33
|
services: Record<string, IService>;
|
|
@@ -34,7 +36,7 @@ export declare class Bucket<M extends $Module, $ extends $Bucket> {
|
|
|
34
36
|
graph: BucketGraph<M, $>;
|
|
35
37
|
private views;
|
|
36
38
|
drive?: DriveAdapter;
|
|
37
|
-
constructor(schema: $, config?: BucketConfig<any, any, any> | undefined, services?: Record<string, IService>);
|
|
39
|
+
constructor(module: AnyModule, schema: $, config?: BucketConfig<any, any, any> | undefined, services?: Record<string, IService>);
|
|
38
40
|
getQueryMeta(): {
|
|
39
41
|
bucket: $;
|
|
40
42
|
scope: string;
|
|
@@ -12,6 +12,7 @@ const datetime_1 = require("../../../engine/data/datetime");
|
|
|
12
12
|
const tree_1 = require("../../../engine/data/tree");
|
|
13
13
|
const crypto_1 = require("../../../engine/util/crypto");
|
|
14
14
|
const bucket_model_schema_1 = require("./model/bucket_model.schema");
|
|
15
|
+
const trash_1 = require("../../../engine/data/trash");
|
|
15
16
|
/**
|
|
16
17
|
* **This should only be used inside a `#composition` of a bucket `create`** to refer to the parent id, which doesn't exist yet.
|
|
17
18
|
*
|
|
@@ -27,7 +28,8 @@ exports.$id = Symbol('FUTURE ID OF CREATE');
|
|
|
27
28
|
* @subcategory Entity
|
|
28
29
|
* */
|
|
29
30
|
class Bucket {
|
|
30
|
-
constructor(schema, config, services = {}) {
|
|
31
|
+
constructor(module, schema, config, services = {}) {
|
|
32
|
+
this.module = module;
|
|
31
33
|
this.schema = schema;
|
|
32
34
|
this.config = config;
|
|
33
35
|
this.services = services;
|
|
@@ -506,18 +508,19 @@ class Bucket {
|
|
|
506
508
|
throw error_1.NesoiError.Bucket.InvalidId({ bucket: this.schema.alias, id });
|
|
507
509
|
}
|
|
508
510
|
// Read object, if safe, to check if it exists
|
|
509
|
-
|
|
511
|
+
let result;
|
|
512
|
+
if (this.module.trash || !options?.unsafe) {
|
|
510
513
|
// Tenancy
|
|
511
514
|
const tenancy = (options?.no_tenancy)
|
|
512
515
|
? undefined
|
|
513
516
|
: this.getTenancyQuery(trx);
|
|
514
517
|
// Check if object exists
|
|
515
|
-
|
|
518
|
+
result = await this.adapter.query(trx, {
|
|
516
519
|
id, '#and': tenancy
|
|
517
520
|
}, { perPage: 1 }, undefined, {
|
|
518
521
|
metadataOnly: true
|
|
519
522
|
});
|
|
520
|
-
if (!result.data.length) {
|
|
523
|
+
if (!result.data.length && !options?.unsafe) {
|
|
521
524
|
throw error_1.NesoiError.Bucket.ObjNotFound({ bucket: this.schema.alias, id });
|
|
522
525
|
}
|
|
523
526
|
}
|
|
@@ -542,6 +545,10 @@ class Bucket {
|
|
|
542
545
|
}
|
|
543
546
|
}
|
|
544
547
|
// Delete the object itself
|
|
548
|
+
if (this.module.trash) {
|
|
549
|
+
const obj = result.data[0];
|
|
550
|
+
await trash_1.Trash.add(trx, this.module, this.schema.name, obj);
|
|
551
|
+
}
|
|
545
552
|
await this.adapter.delete(trx, id);
|
|
546
553
|
// Composition (with self key)
|
|
547
554
|
for (const link of Object.values(this.schema.graph.links)) {
|
|
@@ -574,13 +581,14 @@ class Bucket {
|
|
|
574
581
|
async deleteMany(trx, ids, options) {
|
|
575
582
|
log_1.Log.debug('bucket', this.schema.name, `Delete Many ids=${ids}`);
|
|
576
583
|
// Filter ids, if safe, to check if it exists
|
|
577
|
-
|
|
584
|
+
let result;
|
|
585
|
+
if (this.module.trash || !options?.unsafe) {
|
|
578
586
|
// Tenancy
|
|
579
587
|
const tenancy = (options?.no_tenancy)
|
|
580
588
|
? undefined
|
|
581
589
|
: this.getTenancyQuery(trx);
|
|
582
590
|
// Filter ids
|
|
583
|
-
|
|
591
|
+
result = await this.adapter.query(trx, {
|
|
584
592
|
'id in': ids,
|
|
585
593
|
'#and': tenancy
|
|
586
594
|
}, undefined, undefined, {
|
|
@@ -606,6 +614,10 @@ class Bucket {
|
|
|
606
614
|
}
|
|
607
615
|
}
|
|
608
616
|
}
|
|
617
|
+
if (this.module.trash) {
|
|
618
|
+
const objs = result.data;
|
|
619
|
+
await trash_1.Trash.addMany(trx, this.module, this.schema.name, objs);
|
|
620
|
+
}
|
|
609
621
|
await this.adapter.deleteMany(trx, ids);
|
|
610
622
|
// Composition (with self key)
|
|
611
623
|
for (const link of Object.values(this.schema.graph.links)) {
|
|
@@ -8,10 +8,11 @@ import { App } from './app';
|
|
|
8
8
|
import { IService } from './service';
|
|
9
9
|
import { CLIConfig } from '../cli/cli';
|
|
10
10
|
import { BucketAdapter } from "../../elements/entities/bucket/adapters/bucket_adapter";
|
|
11
|
-
import {
|
|
11
|
+
import { $TrashBucket } from '../data/trash';
|
|
12
12
|
import { $Bucket } from "../../elements";
|
|
13
13
|
import { Overlay } from '../util/type';
|
|
14
14
|
import { TrxStatus } from '../transaction/trx';
|
|
15
|
+
import { NesoiObj } from '../data/obj';
|
|
15
16
|
export type AppConfig<S extends $Space, Modules extends ModuleName<S>> = {
|
|
16
17
|
i18n?: AppI18nConfig;
|
|
17
18
|
authn?: AppAuthnConfig<S>;
|
|
@@ -20,6 +21,7 @@ export type AppConfig<S extends $Space, Modules extends ModuleName<S>> = {
|
|
|
20
21
|
cli?: CLIConfig<any>;
|
|
21
22
|
compiler?: CompilerConfig;
|
|
22
23
|
trxEngine?: AppTrxEngineConfig<S, Modules, any>;
|
|
24
|
+
trash?: AppTrashConfig<S, Modules, any>;
|
|
23
25
|
};
|
|
24
26
|
export type AnyAppConfig = AppConfig<any, any>;
|
|
25
27
|
export type AppI18nConfig = {
|
|
@@ -33,11 +35,11 @@ export type AppBucketConfig<S extends $Space, Modules extends ModuleName<S>, Ser
|
|
|
33
35
|
[K in keyof S['modules'][M]['buckets']]: BucketConfig<S['modules'][M], S['modules'][M]['buckets'][K], Services>;
|
|
34
36
|
}>;
|
|
35
37
|
}>;
|
|
36
|
-
export type AppTrashConfig = {
|
|
37
|
-
|
|
38
|
-
'#data'
|
|
39
|
-
}
|
|
40
|
-
}
|
|
38
|
+
export type AppTrashConfig<S extends $Space, Modules extends ModuleName<S>, Services extends Record<string, IService>> = Partial<{
|
|
39
|
+
[M in (Modules & keyof S['modules'])]: {
|
|
40
|
+
adapter?: (schema: typeof $TrashBucket, services: Services) => BucketAdapter<typeof $TrashBucket['#data']>;
|
|
41
|
+
};
|
|
42
|
+
}>;
|
|
41
43
|
export type AppControllerConfig<S extends $Space, Modules extends ModuleName<S>, Services extends Record<string, IService>> = Partial<{
|
|
42
44
|
[M in (Modules & keyof S['modules'])]: Partial<{
|
|
43
45
|
[K in keyof S['modules'][M]['controllers']]: ControllerConfig<S['modules'][M], S['modules'][M]['controllers'][K], Services>;
|
|
@@ -48,8 +50,8 @@ export type AppTrxEngineConfig<S extends $Space, Modules extends ModuleName<S>,
|
|
|
48
50
|
}>;
|
|
49
51
|
export type AppAuditConfig = {
|
|
50
52
|
adapter: ($: Overlay<$Bucket, {
|
|
51
|
-
'#data':
|
|
52
|
-
}>) => BucketAdapter<
|
|
53
|
+
'#data': NesoiObj;
|
|
54
|
+
}>) => BucketAdapter<NesoiObj>;
|
|
53
55
|
transform?: (trx: TrxStatus<any>) => Record<string, any>;
|
|
54
56
|
};
|
|
55
57
|
/**
|
|
@@ -65,7 +67,7 @@ export declare class AppConfigFactory<S extends $Space, Modules extends string =
|
|
|
65
67
|
i18n(config: AppI18nConfig): _App;
|
|
66
68
|
authn(config: AppAuthnConfig<S>): _App;
|
|
67
69
|
buckets(config: AppBucketConfig<S, Modules, Services>): _App;
|
|
68
|
-
trash(config: AppTrashConfig): _App;
|
|
70
|
+
trash(config: AppTrashConfig<S, Modules, Services>): _App;
|
|
69
71
|
controllers(config: AppControllerConfig<S, Modules, Services>): _App;
|
|
70
72
|
audit(config: AppI18nConfig): _App;
|
|
71
73
|
compiler(config: CompilerConfig): _App;
|
package/lib/engine/apps/app.js
CHANGED
|
@@ -74,9 +74,9 @@ class App {
|
|
|
74
74
|
makeModules() {
|
|
75
75
|
const modules = {};
|
|
76
76
|
if (this.space) {
|
|
77
|
-
space_1.Space.scan(this.space, (name, path) => {
|
|
77
|
+
space_1.Space.scan(this.space, (name, path, subdir) => {
|
|
78
78
|
if (this._spaceModuleNames.includes(name)) {
|
|
79
|
-
modules[name] = new module_1.Module(name, { dirpath: path });
|
|
79
|
+
modules[name] = new module_1.Module(name, { dirpath: path }, subdir);
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
}
|