nesoi 3.0.13 → 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/engine/apps/app.js +2 -2
- package/lib/engine/data/trash.d.ts +1 -1
- package/lib/engine/data/trash.js +2 -2
- package/lib/engine/dependency.d.ts +6 -0
- package/lib/engine/dependency.js +1 -0
- package/lib/engine/module.d.ts +2 -1
- package/lib/engine/module.js +2 -1
- package/lib/engine/space.d.ts +1 -1
- package/lib/engine/space.js +14 -5
- 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)
|
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
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NesoiObj } from './obj';
|
|
2
2
|
import { AnyTrxNode } from '../transaction/trx_node';
|
|
3
|
-
import { $Bucket } from "../../elements";
|
|
3
|
+
import { $Bucket } from "../../elements/entities/bucket/bucket.schema";
|
|
4
4
|
import { AnyModule } from '../module';
|
|
5
5
|
export type TrashObj = {
|
|
6
6
|
id: number;
|
package/lib/engine/data/trash.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Trash = exports.$TrashBucket = void 0;
|
|
4
|
-
const
|
|
4
|
+
const bucket_schema_1 = require("../../elements/entities/bucket/bucket.schema");
|
|
5
5
|
const bucket_model_schema_1 = require("../../elements/entities/bucket/model/bucket_model.schema");
|
|
6
6
|
const bucket_graph_schema_1 = require("../../elements/entities/bucket/graph/bucket_graph.schema");
|
|
7
|
-
exports.$TrashBucket = new
|
|
7
|
+
exports.$TrashBucket = new bucket_schema_1.$Bucket('__trash__', 'trash', 'Trash', new bucket_model_schema_1.$BucketModel({
|
|
8
8
|
id: new bucket_model_schema_1.$BucketModelField('id', 'id', 'int', 'id', false, true),
|
|
9
9
|
module: new bucket_model_schema_1.$BucketModelField('module', 'module', 'string', 'Module Name', false, true),
|
|
10
10
|
bucket: new bucket_model_schema_1.$BucketModelField('bucket', 'bucket', 'string', 'Bucket Name', false, true),
|
|
@@ -96,6 +96,9 @@ export declare class BuilderNode {
|
|
|
96
96
|
filepath: string | string[];
|
|
97
97
|
dependencies: $Dependency[];
|
|
98
98
|
builder: AnyBuilder;
|
|
99
|
+
progressive?: {
|
|
100
|
+
schema: AnyElementSchema;
|
|
101
|
+
};
|
|
99
102
|
constructor($: {
|
|
100
103
|
module: string;
|
|
101
104
|
type: BuilderType;
|
|
@@ -104,6 +107,9 @@ export declare class BuilderNode {
|
|
|
104
107
|
filepath: string | string[];
|
|
105
108
|
dependencies: $Dependency[];
|
|
106
109
|
builder: AnyBuilder;
|
|
110
|
+
progressive?: {
|
|
111
|
+
schema: AnyElementSchema;
|
|
112
|
+
};
|
|
107
113
|
});
|
|
108
114
|
}
|
|
109
115
|
/**
|
package/lib/engine/dependency.js
CHANGED
package/lib/engine/module.d.ts
CHANGED
|
@@ -63,6 +63,7 @@ export type VirtualModuleDef = {
|
|
|
63
63
|
*/
|
|
64
64
|
export declare class Module<S extends $Space, $ extends $Module> {
|
|
65
65
|
name: string;
|
|
66
|
+
subdir: string[];
|
|
66
67
|
schema: $;
|
|
67
68
|
buckets: { [B in keyof $["buckets"]]: Bucket<$, $["buckets"][B]>; };
|
|
68
69
|
messages: { [B in keyof $["messages"]]: MessageParser<$["messages"][B]>; };
|
|
@@ -101,7 +102,7 @@ export declare class Module<S extends $Space, $ extends $Module> {
|
|
|
101
102
|
dirpath: string;
|
|
102
103
|
} | {
|
|
103
104
|
builders: AnyBuilder[];
|
|
104
|
-
});
|
|
105
|
+
}, subdir?: string[]);
|
|
105
106
|
/**
|
|
106
107
|
* Log the module elements
|
|
107
108
|
*/
|
package/lib/engine/module.js
CHANGED
|
@@ -79,8 +79,9 @@ class Module {
|
|
|
79
79
|
* @param name A module name
|
|
80
80
|
* @param boot The boot source for this module
|
|
81
81
|
*/
|
|
82
|
-
constructor(name, boot) {
|
|
82
|
+
constructor(name, boot, subdir = []) {
|
|
83
83
|
this.name = name;
|
|
84
|
+
this.subdir = subdir;
|
|
84
85
|
this.schema = {
|
|
85
86
|
constants: new constants_schema_1.$Constants(this.name),
|
|
86
87
|
externals: new externals_schema_1.$Externals(this.name),
|
package/lib/engine/space.d.ts
CHANGED
|
@@ -203,6 +203,6 @@ export declare class Space<$ extends $Space> {
|
|
|
203
203
|
* @param space A `Space` instance
|
|
204
204
|
* @param buildFn A callback to run for each module directory
|
|
205
205
|
*/
|
|
206
|
-
static scan(space: Space<any>, buildFn: (name: string, path: string) => void): void;
|
|
206
|
+
static scan(space: Space<any>, buildFn: (name: string, path: string, subdir: string[]) => void): void;
|
|
207
207
|
}
|
|
208
208
|
export type AnySpace = Space<$Space>;
|
package/lib/engine/space.js
CHANGED
|
@@ -296,11 +296,20 @@ class Space {
|
|
|
296
296
|
if (!fs.existsSync(modulesPath)) {
|
|
297
297
|
throw error_1.CompilerError.NoModulesFolder();
|
|
298
298
|
}
|
|
299
|
-
const
|
|
300
|
-
.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
299
|
+
const perform = (dirpath, subdir) => {
|
|
300
|
+
const dirs = fs.readdirSync(dirpath, { withFileTypes: true })
|
|
301
|
+
.filter(node => node.isDirectory());
|
|
302
|
+
for (const dir of dirs) {
|
|
303
|
+
const modulePath = path.join(dirpath, dir.name);
|
|
304
|
+
if (fs.existsSync(path.join(modulePath, '.modules'))) {
|
|
305
|
+
perform(modulePath, [...subdir, dir.name]);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
buildFn(dir.name, modulePath, subdir);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
perform(modulesPath, []);
|
|
304
313
|
}
|
|
305
314
|
}
|
|
306
315
|
exports.Space = Space;
|
package/lib/engine/tree.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { BuilderType } from "../schema";
|
|
|
2
2
|
import { ResolvedBuilderNode } from './dependency';
|
|
3
3
|
import { AnyModule } from './module';
|
|
4
4
|
import { TreeshakeConfig } from "../compiler/treeshake";
|
|
5
|
+
import { ProgressiveBuildCache } from "../compiler/progressive";
|
|
5
6
|
type TraverseCallback = (node: ResolvedBuilderNode) => Promise<void>;
|
|
6
7
|
/**
|
|
7
8
|
* A tree of module elements which allows building in the correct order.
|
|
@@ -23,7 +24,7 @@ export declare class ModuleTree {
|
|
|
23
24
|
* - Resolves each found dependency forming a tree
|
|
24
25
|
* - Groups tree into layers which can be built in isolation
|
|
25
26
|
*/
|
|
26
|
-
resolve(): Promise<void>;
|
|
27
|
+
resolve(cache?: ProgressiveBuildCache): Promise<void>;
|
|
27
28
|
/**
|
|
28
29
|
* Read the module elements from files and identify
|
|
29
30
|
* all related nodes.
|
|
@@ -82,5 +83,11 @@ export declare class ModuleTree {
|
|
|
82
83
|
* @returns A list of resolved builder nodes
|
|
83
84
|
*/
|
|
84
85
|
allNodes(): ResolvedBuilderNode[];
|
|
86
|
+
/**
|
|
87
|
+
* Return a list of all nodes of all modules on the tree.
|
|
88
|
+
*
|
|
89
|
+
* @returns A list of resolved builder nodes
|
|
90
|
+
*/
|
|
91
|
+
allNodesByModule(): Record<string, ResolvedBuilderNode[]>;
|
|
85
92
|
}
|
|
86
93
|
export {};
|