jitar 0.1.1 → 0.1.2
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/dist/core/Implementation.js +7 -0
- package/dist/core/errors/UnknownParameter.d.ts +3 -0
- package/dist/core/errors/UnknownParameter.js +6 -0
- package/dist/runtime/LocalRepository.d.ts +1 -1
- package/dist/runtime/LocalRepository.js +13 -4
- package/dist/server/configuration/RepositoryConfiguration.d.ts +1 -0
- package/dist/server/configuration/RepositoryConfiguration.js +7 -1
- package/dist/server/configuration/StandaloneConfiguration.d.ts +1 -0
- package/dist/server/configuration/StandaloneConfiguration.js +6 -0
- package/dist/server/utils/LocalFileManager.d.ts +1 -0
- package/dist/server/utils/LocalFileManager.js +19 -11
- package/dist/server/utils/RuntimeConfigurator.js +9 -4
- package/package.json +4 -1
- package/.eslintignore +0 -3
- package/.eslintrc +0 -16
- package/jest.config.js +0 -20
- package/src/client.ts +0 -18
- package/src/core/ErrorManager.ts +0 -18
- package/src/core/Implementation.ts +0 -53
- package/src/core/Procedure.ts +0 -98
- package/src/core/Segment.ts +0 -62
- package/src/core/SegmentBuilder.ts +0 -55
- package/src/core/Version.ts +0 -68
- package/src/core/definitions/AccessLevel.ts +0 -3
- package/src/core/errors/ImplementationNotFound.ts +0 -12
- package/src/core/errors/InvalidVersionNumber.ts +0 -12
- package/src/core/errors/MissingParameterValue.ts +0 -12
- package/src/core/errors/NotImplemented.ts +0 -12
- package/src/core/errors/ProcedureNotFound.ts +0 -12
- package/src/core/interfaces/Runner.ts +0 -7
- package/src/core/reflection/ParameterParser.ts +0 -74
- package/src/core/reflection/ReflectionHelper.ts +0 -118
- package/src/core/reflection/models/ReflectionField.ts +0 -22
- package/src/core/reflection/models/ReflectionParameter.ts +0 -18
- package/src/core/types/Component.ts +0 -8
- package/src/core/types/FlexObject.ts +0 -4
- package/src/core/types/Module.ts +0 -6
- package/src/core/types/SegmentImplementation.ts +0 -9
- package/src/core/types/SegmentModule.ts +0 -9
- package/src/core/types/SegmentProcedure.ts +0 -11
- package/src/core/utils/FqnBuilder.ts +0 -11
- package/src/hooks.ts +0 -2
- package/src/lib.ts +0 -7
- package/src/runtime/ClientId.ts +0 -18
- package/src/runtime/Gateway.ts +0 -18
- package/src/runtime/LocalGateway.ts +0 -93
- package/src/runtime/LocalNode.ts +0 -130
- package/src/runtime/LocalRepository.ts +0 -154
- package/src/runtime/Node.ts +0 -15
- package/src/runtime/NodeBalancer.ts +0 -61
- package/src/runtime/NodeMonitor.ts +0 -63
- package/src/runtime/Proxy.ts +0 -60
- package/src/runtime/Remote.ts +0 -157
- package/src/runtime/RemoteGateway.ts +0 -40
- package/src/runtime/RemoteNode.ts +0 -49
- package/src/runtime/RemoteRepository.ts +0 -60
- package/src/runtime/Repository.ts +0 -20
- package/src/runtime/Runtime.ts +0 -47
- package/src/runtime/caching/CacheBuilder.ts +0 -424
- package/src/runtime/caching/ImportRewriter.ts +0 -76
- package/src/runtime/caching/RemoteBuilder.ts +0 -51
- package/src/runtime/caching/SourceAppender.ts +0 -57
- package/src/runtime/caching/definitions/Keywords.ts +0 -3
- package/src/runtime/caching/errors/InvalidSegmentFilename.ts +0 -8
- package/src/runtime/caching/errors/MissingModuleExport.ts +0 -8
- package/src/runtime/caching/errors/SegmentFileNotLoaded.ts +0 -8
- package/src/runtime/caching/errors/SegmentModuleNotLoaded.ts +0 -8
- package/src/runtime/caching/models/ApplicationModule.ts +0 -30
- package/src/runtime/caching/models/Implementation.ts +0 -41
- package/src/runtime/caching/models/Procedure.ts +0 -26
- package/src/runtime/caching/models/Segment.ts +0 -28
- package/src/runtime/caching/models/SegmentModule.ts +0 -26
- package/src/runtime/caching/types/SegmentFile.ts +0 -6
- package/src/runtime/caching/types/SegmentImportProperties.ts +0 -9
- package/src/runtime/caching/types/SegmentImports.ts +0 -6
- package/src/runtime/errors/ClientNotFound.ts +0 -12
- package/src/runtime/errors/FileNotFound.ts +0 -12
- package/src/runtime/errors/InvalidClientId.ts +0 -12
- package/src/runtime/errors/InvalidJitarHooks.ts +0 -12
- package/src/runtime/errors/InvalidSegmentFile.ts +0 -12
- package/src/runtime/errors/ModuleNotLoaded.ts +0 -12
- package/src/runtime/errors/NoNodeAvailable.ts +0 -12
- package/src/runtime/errors/RepositoryNotAvaiable.ts +0 -12
- package/src/runtime/errors/RuntimeNotAvailable.ts +0 -12
- package/src/runtime/errors/SegmentNotFound.ts +0 -12
- package/src/runtime/hooks/dependencies.ts +0 -19
- package/src/runtime/hooks/runtime.ts +0 -25
- package/src/runtime/interfaces/FileManager.ts +0 -19
- package/src/runtime/interfaces/HealthCheck.ts +0 -5
- package/src/runtime/interfaces/ProcedureContainer.ts +0 -9
- package/src/runtime/models/File.ts +0 -22
- package/src/runtime/serialization/ArraySerializer.ts +0 -27
- package/src/runtime/serialization/ClassSerializer.ts +0 -133
- package/src/runtime/serialization/MapSerializer.ts +0 -60
- package/src/runtime/serialization/ObjectSerializer.ts +0 -42
- package/src/runtime/serialization/SetSerializer.ts +0 -42
- package/src/runtime/serialization/ValueSerializer.ts +0 -81
- package/src/runtime/serialization/errors/ClassNotFound.ts +0 -12
- package/src/runtime/serialization/errors/InvalidClass.ts +0 -12
- package/src/runtime/serialization/errors/InvalidPropertyType.ts +0 -12
- package/src/runtime/serialization/interfaces/Serializer.ts +0 -10
- package/src/runtime/serialization/types/SerializableObject.ts +0 -6
- package/src/runtime/serialization/types/Serialized.ts +0 -8
- package/src/runtime/serialization/types/SerializedClass.ts +0 -13
- package/src/runtime/serialization/types/SerializedMap.ts +0 -13
- package/src/runtime/serialization/types/SerializedObject.ts +0 -4
- package/src/runtime/serialization/types/SerializedSet.ts +0 -9
- package/src/runtime/types/JitarHooks.ts +0 -10
- package/src/runtime/types/ModuleImporter.ts +0 -6
- package/src/runtime/utils/ModuleAnalyser.ts +0 -60
- package/src/runtime/utils/ModuleLoader.ts +0 -51
- package/src/runtime/utils/UrlRewriter.ts +0 -59
- package/src/server/JitarServer.ts +0 -161
- package/src/server/configuration/GatewayConfiguration.ts +0 -9
- package/src/server/configuration/NodeConfiguration.ts +0 -15
- package/src/server/configuration/ProxyConfiguration.ts +0 -16
- package/src/server/configuration/RepositoryConfiguration.ts +0 -17
- package/src/server/configuration/RuntimeConfiguration.ts +0 -30
- package/src/server/configuration/ServerOptions.ts +0 -14
- package/src/server/configuration/StandaloneConfiguration.ts +0 -21
- package/src/server/controllers/AssetsController.ts +0 -59
- package/src/server/controllers/HealthController.ts +0 -41
- package/src/server/controllers/JitarController.ts +0 -18
- package/src/server/controllers/ModulesController.ts +0 -77
- package/src/server/controllers/NodesController.ts +0 -58
- package/src/server/controllers/ProceduresController.ts +0 -31
- package/src/server/controllers/ProxyController.ts +0 -38
- package/src/server/controllers/RPCController.ts +0 -173
- package/src/server/definitions/RuntimeDefaults.ts +0 -10
- package/src/server/errors/MissingConfigurationValue.ts +0 -8
- package/src/server/errors/RuntimeNotAvaiable.ts +0 -8
- package/src/server/errors/UnknownRuntimeMode.ts +0 -8
- package/src/server/models/HealthDto.ts +0 -11
- package/src/server/models/NodeDto.ts +0 -11
- package/src/server/utils/DataConverter.ts +0 -15
- package/src/server/utils/LocalFileManager.ts +0 -122
- package/src/server/utils/RuntimeConfigurationLoader.ts +0 -19
- package/src/server/utils/RuntimeConfigurator.ts +0 -207
- package/src/server/utils/ServerOptionsReader.ts +0 -17
- package/src/server.ts +0 -16
- package/test/_fixtures/core/Implementation.fixture.ts +0 -33
- package/test/_fixtures/core/Procedure.fixture.ts +0 -33
- package/test/_fixtures/core/Segment.fixture.ts +0 -36
- package/test/_fixtures/core/SegmentBuilder.fixture.ts +0 -45
- package/test/_fixtures/core/Version.fixture.ts +0 -18
- package/test/_fixtures/core/reflection/ReflectionHelper.fixture.ts +0 -56
- package/test/_fixtures/runtime/LocalGateway.fixture.ts +0 -24
- package/test/_fixtures/runtime/LocalNode.fixture.ts +0 -16
- package/test/_fixtures/runtime/LocalRepository.fixture.ts +0 -73
- package/test/_fixtures/runtime/NodeBalancer.fixture.ts +0 -19
- package/test/_fixtures/runtime/NodeMonitor.fixture.ts +0 -34
- package/test/_fixtures/runtime/RemoteNode.fixture.ts +0 -8
- package/test/_fixtures/runtime/caching/ImportRewriter.fixture.ts +0 -81
- package/test/_fixtures/runtime/caching/RemoteBuilder.fixture.ts +0 -50
- package/test/_fixtures/runtime/caching/SourceAppender.fixture.ts +0 -35
- package/test/_fixtures/runtime/segments.ts +0 -78
- package/test/_fixtures/runtime/serialization/ValueSerializer.fixture.ts +0 -134
- package/test/_fixtures/runtime/utils/ModuleAnaliser.fixture.ts +0 -26
- package/test/core/Implementation.spec.ts +0 -89
- package/test/core/Procedure.spec.ts +0 -108
- package/test/core/Segment.spec.ts +0 -74
- package/test/core/SegmentBuilder.spec.ts +0 -39
- package/test/core/Version.spec.ts +0 -103
- package/test/core/errors/ErrorManager.spec.ts +0 -32
- package/test/core/reflection/ReflectionHelper.spec.ts +0 -128
- package/test/core/utils/FqnBuilder.spec.ts +0 -22
- package/test/runtime/ClientId.spec.ts +0 -43
- package/test/runtime/LocalGateway.spec.ts +0 -40
- package/test/runtime/LocalNode.spec.ts +0 -87
- package/test/runtime/LocalRepository.spec.ts +0 -50
- package/test/runtime/NodeBalancer.spec.ts +0 -39
- package/test/runtime/NodeMonitor.spec.ts +0 -31
- package/test/runtime/RemoteNode.spec.ts +0 -43
- package/test/runtime/caching/ImportRewriter.spec.ts +0 -68
- package/test/runtime/caching/RemoteBuilder.spec.ts +0 -21
- package/test/runtime/caching/SourceAppender.spec.ts +0 -31
- package/test/runtime/serialization/ValueSerializer.spec.ts +0 -203
- package/test/runtime/utils/ModuleAnalyser.spec.ts +0 -54
- package/test/runtime/utils/UrlRewriter.spec.ts +0 -57
- package/tsconfig.json +0 -23
package/src/runtime/Runtime.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import HealthCheck from './interfaces/HealthCheck.js';
|
|
3
|
-
|
|
4
|
-
export default abstract class Runtime
|
|
5
|
-
{
|
|
6
|
-
#url?: string;
|
|
7
|
-
#healthChecks: Map<string, HealthCheck> = new Map();
|
|
8
|
-
|
|
9
|
-
constructor(url?: string)
|
|
10
|
-
{
|
|
11
|
-
this.#url = url;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
get url() { return this.#url; }
|
|
15
|
-
|
|
16
|
-
addHealthCheck(name: string, healthCheck: HealthCheck): void
|
|
17
|
-
{
|
|
18
|
-
this.#healthChecks.set(name, healthCheck);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async isHealthy(): Promise<boolean>
|
|
22
|
-
{
|
|
23
|
-
for (const healthCheck of this.#healthChecks.values())
|
|
24
|
-
{
|
|
25
|
-
if (await healthCheck.isHealthy() === false)
|
|
26
|
-
{
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async getHealth(): Promise<Map<string, boolean>>
|
|
35
|
-
{
|
|
36
|
-
const health: Map<string, boolean> = new Map();
|
|
37
|
-
|
|
38
|
-
for (const [name, healthCheck] of this.#healthChecks)
|
|
39
|
-
{
|
|
40
|
-
const healthy = await healthCheck.isHealthy();
|
|
41
|
-
|
|
42
|
-
health.set(name, healthy);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return health;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import Component from '../../core/types/Component.js';
|
|
3
|
-
import Module from '../../core/types/Module.js';
|
|
4
|
-
import * as AccessLevel from '../../core/definitions/AccessLevel.js';
|
|
5
|
-
import Version from '../../core/Version.js';
|
|
6
|
-
|
|
7
|
-
import FileManager from '../interfaces/FileManager.js';
|
|
8
|
-
import ModuleLoader from '../utils/ModuleLoader.js';
|
|
9
|
-
import ModuleAnalyser from '../utils/ModuleAnalyser.js';
|
|
10
|
-
|
|
11
|
-
import SourceAppender from './SourceAppender.js';
|
|
12
|
-
import ImportRewriter from './ImportRewriter.js';
|
|
13
|
-
import RemoteBuilder from './RemoteBuilder.js';
|
|
14
|
-
|
|
15
|
-
import SegmentFile from './types/SegmentFile.js';
|
|
16
|
-
import SegmentImports from './types/SegmentImports.js';
|
|
17
|
-
|
|
18
|
-
import ApplicationModule from './models/ApplicationModule.js';
|
|
19
|
-
import Procedure from './models/Procedure.js';
|
|
20
|
-
import Segment from './models/Segment.js';
|
|
21
|
-
import SegmentModule from './models/SegmentModule.js';
|
|
22
|
-
import Implementation from './models/Implementation.js';
|
|
23
|
-
|
|
24
|
-
import SegmentFileNotLoaded from './errors/SegmentFileNotLoaded.js';
|
|
25
|
-
import SegmentModuleNotLoaded from './errors/SegmentModuleNotLoaded.js';
|
|
26
|
-
import MissingModuleExport from './errors/MissingModuleExport.js';
|
|
27
|
-
import InvalidSegmentFilename from './errors/InvalidSegmentFilename.js';
|
|
28
|
-
|
|
29
|
-
const IGNORED_SOURCE_FILES = ['.min.js'];
|
|
30
|
-
|
|
31
|
-
const DEFAULT_ACCESS_LEVEL = AccessLevel.PRIVATE;
|
|
32
|
-
const DEFAULT_VERSION_NUMBER = Version.DEFAULT.toString();
|
|
33
|
-
|
|
34
|
-
export default class CacheBuilder
|
|
35
|
-
{
|
|
36
|
-
#sourceManager: FileManager;
|
|
37
|
-
#cacheManager: FileManager;
|
|
38
|
-
|
|
39
|
-
constructor(sourceManager: FileManager, cacheManager: FileManager)
|
|
40
|
-
{
|
|
41
|
-
this.#sourceManager = sourceManager;
|
|
42
|
-
this.#cacheManager = cacheManager;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async build(segmentFiles: string[], moduleFiles: string[]): Promise<void>
|
|
46
|
-
{
|
|
47
|
-
const applicationFiles = this.#filterApplicationFiles(moduleFiles);
|
|
48
|
-
|
|
49
|
-
const segments = await this.#createSegments(segmentFiles);
|
|
50
|
-
const applicationModules = await this.#createApplicationModules(applicationFiles);
|
|
51
|
-
|
|
52
|
-
await this.#buildSegmentCache(segments);
|
|
53
|
-
await this.#buildApplicationCache(applicationModules);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
#filterApplicationFiles(fileNames: string[]): string[]
|
|
57
|
-
{
|
|
58
|
-
return fileNames.filter(filename => this.#mustIgnoreFile(filename) === false);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
#mustIgnoreFile(filename: string): boolean
|
|
62
|
-
{
|
|
63
|
-
return IGNORED_SOURCE_FILES.some((ignored) => filename.endsWith(ignored));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async #createSegments(filenames: string[]): Promise<Segment[]>
|
|
67
|
-
{
|
|
68
|
-
const promises = filenames.map(async (filename) => this.#createSegment(filename));
|
|
69
|
-
|
|
70
|
-
return Promise.all(promises).then(segments => segments);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async #createSegment(filename: string): Promise<Segment>
|
|
74
|
-
{
|
|
75
|
-
const definition = await this.#loadSegmentDefinition(filename);
|
|
76
|
-
const modules = await this.#createSegmentModules(definition);
|
|
77
|
-
const procedures = this.#createSegmentProcedures(modules);
|
|
78
|
-
|
|
79
|
-
return new Segment(filename, modules, procedures);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async #loadSegmentDefinition(filename: string): Promise<SegmentFile>
|
|
83
|
-
{
|
|
84
|
-
try
|
|
85
|
-
{
|
|
86
|
-
const content = await this.#sourceManager.getContent(filename);
|
|
87
|
-
|
|
88
|
-
return JSON.parse(content.toString()) as SegmentFile;
|
|
89
|
-
}
|
|
90
|
-
catch (error: unknown)
|
|
91
|
-
{
|
|
92
|
-
throw new SegmentFileNotLoaded(filename);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async #createSegmentModules(definition: SegmentFile): Promise<SegmentModule[]>
|
|
97
|
-
{
|
|
98
|
-
const modules: SegmentModule[] = [];
|
|
99
|
-
|
|
100
|
-
for (const [moduleFilename, moduleImports] of Object.entries(definition))
|
|
101
|
-
{
|
|
102
|
-
const absoluteLocation = this.#sourceManager.getAbsoluteLocation(moduleFilename);
|
|
103
|
-
const module = await this.#createSegmentModule(absoluteLocation, moduleImports);
|
|
104
|
-
|
|
105
|
-
modules.push(module);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return modules;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async #createSegmentModule(absoluteLocation: string, imports: SegmentImports): Promise<SegmentModule>
|
|
112
|
-
{
|
|
113
|
-
const exports = await this.#loadSegmentModule(absoluteLocation);
|
|
114
|
-
const implementations = await this.#createSegmentModuleImplementations(absoluteLocation, exports, imports);
|
|
115
|
-
|
|
116
|
-
return new SegmentModule(absoluteLocation, exports, implementations);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async #loadSegmentModule(absoluteLocation: string): Promise<Module>
|
|
120
|
-
{
|
|
121
|
-
const module = await this.#loadModule(absoluteLocation);
|
|
122
|
-
|
|
123
|
-
if (module === undefined)
|
|
124
|
-
{
|
|
125
|
-
throw new SegmentModuleNotLoaded(absoluteLocation);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return module;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async #createSegmentModuleImplementations(absoluteLocation: string, exports: Module, imports: SegmentImports): Promise<Map<string, Implementation>>
|
|
132
|
-
{
|
|
133
|
-
const moduleName = this.#extractModuleName(absoluteLocation);
|
|
134
|
-
const implementations: Map<string, Implementation> = new Map();
|
|
135
|
-
|
|
136
|
-
for (const [importKey, properties] of Object.entries(imports))
|
|
137
|
-
{
|
|
138
|
-
const executable = exports[importKey] as Component;
|
|
139
|
-
|
|
140
|
-
if (executable === undefined)
|
|
141
|
-
{
|
|
142
|
-
throw new MissingModuleExport(moduleName, importKey);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const procedureName = properties.as ?? executable.name;
|
|
146
|
-
const access = properties.access ?? DEFAULT_ACCESS_LEVEL;
|
|
147
|
-
const version = properties.version ?? DEFAULT_VERSION_NUMBER;
|
|
148
|
-
|
|
149
|
-
const implementation = new Implementation(moduleName, procedureName, access, version, executable);
|
|
150
|
-
|
|
151
|
-
implementations.set(importKey, implementation);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return implementations;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
#createSegmentProcedures(modules: SegmentModule[]): Map<string, Procedure>
|
|
158
|
-
{
|
|
159
|
-
const procedures = new Map<string, Procedure>();
|
|
160
|
-
|
|
161
|
-
for (const module of modules)
|
|
162
|
-
{
|
|
163
|
-
for (const implementation of module.implementations.values())
|
|
164
|
-
{
|
|
165
|
-
let procedure = procedures.get(implementation.fqn);
|
|
166
|
-
|
|
167
|
-
if (procedure === undefined)
|
|
168
|
-
{
|
|
169
|
-
procedure = new Procedure(implementation.module, implementation.name);
|
|
170
|
-
|
|
171
|
-
procedures.set(implementation.fqn, procedure);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
procedure.addImplementation(implementation);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return procedures;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
#extractModuleName(absoluteLocation: string): string
|
|
182
|
-
{
|
|
183
|
-
const relativeLocation = this.#sourceManager.getRelativeLocation(absoluteLocation);
|
|
184
|
-
|
|
185
|
-
const moduleParts = relativeLocation.split('/');
|
|
186
|
-
moduleParts.pop();
|
|
187
|
-
|
|
188
|
-
return moduleParts.join('/');
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async #createApplicationModules(filenames: string[]): Promise<ApplicationModule[]>
|
|
192
|
-
{
|
|
193
|
-
const promises = filenames.map(async (filename) => this.#createApplicationModule(filename));
|
|
194
|
-
|
|
195
|
-
return Promise.all(promises).then(results => results);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async #createApplicationModule(filename: string): Promise<ApplicationModule>
|
|
199
|
-
{
|
|
200
|
-
const module = await this.#loadModule(filename);
|
|
201
|
-
const relativeLocation = this.#sourceManager.getRelativeLocation(filename);
|
|
202
|
-
|
|
203
|
-
if (module === undefined)
|
|
204
|
-
{
|
|
205
|
-
return new ApplicationModule(relativeLocation, new Map(), new Map());
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const classes = ModuleAnalyser.filterClasses(module);
|
|
209
|
-
const functions = ModuleAnalyser.filterFunctions(module);
|
|
210
|
-
|
|
211
|
-
return new ApplicationModule(relativeLocation, classes, functions);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
async #loadModule(filename: string): Promise<Module | undefined>
|
|
215
|
-
{
|
|
216
|
-
try
|
|
217
|
-
{
|
|
218
|
-
return await ModuleLoader.load(filename);
|
|
219
|
-
}
|
|
220
|
-
catch (error: unknown)
|
|
221
|
-
{
|
|
222
|
-
// If the module cannot load in this context it does not mean that the module is corrupted.
|
|
223
|
-
// Therefore we can ignore the error and continue to let it work (or fail) at runtime.
|
|
224
|
-
|
|
225
|
-
return undefined;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
async #buildSegmentCache(segments: Segment[]): Promise<void[]>
|
|
230
|
-
{
|
|
231
|
-
const promises = segments.map(async (segment) => this.#buildSegmentModuleCache(segment));
|
|
232
|
-
|
|
233
|
-
return Promise.all(promises);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
async #buildSegmentModuleCache(segment: Segment): Promise<void>
|
|
237
|
-
{
|
|
238
|
-
await this.#buildSegmentCacheForRepository(segment);
|
|
239
|
-
await this.#buildSegmentCacheForNode(segment);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async #buildSegmentCacheForRepository(segment: Segment): Promise<void>
|
|
243
|
-
{
|
|
244
|
-
return this.#buildSegmentDefinitionForRepository(segment);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
async #buildSegmentDefinitionForRepository(segment: Segment): Promise<void>
|
|
248
|
-
{
|
|
249
|
-
// For the repository we need to make a definition file that contains all segment filenames
|
|
250
|
-
// used for building a lookup table (mapping source files to segments).
|
|
251
|
-
|
|
252
|
-
const code = this.#createSegmentRepositoryCode(segment);
|
|
253
|
-
const filename = this.#createSegmentRepositoryFilename(segment);
|
|
254
|
-
|
|
255
|
-
return this.#cacheManager.store(filename, code);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
#createSegmentRepositoryCode(segment: Segment): string
|
|
259
|
-
{
|
|
260
|
-
const filenames = segment.getFilenames();
|
|
261
|
-
const relativeLocations = filenames.map(filename => this.#sourceManager.getRelativeLocation(filename));
|
|
262
|
-
|
|
263
|
-
return `export const files = [\n\t"${[...relativeLocations].join('",\n\t"')}"\n];`;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
#createSegmentRepositoryFilename(segment: Segment): string
|
|
267
|
-
{
|
|
268
|
-
const filename = this.#extractSegmentFilename(segment);
|
|
269
|
-
|
|
270
|
-
return filename.replace('.json', '.repository.js');
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
async #buildSegmentCacheForNode(segment: Segment): Promise<void>
|
|
274
|
-
{
|
|
275
|
-
await this.#buildSegmentDefinitionForNode(segment);
|
|
276
|
-
await this.#buildSegmentModulesForNode(segment);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
async #buildSegmentDefinitionForNode(segment: Segment): Promise<void>
|
|
280
|
-
{
|
|
281
|
-
// For the node we need to make a definition file that imports all segment procedures
|
|
282
|
-
// and exports them as a segment model containing the procedures with the meta-data.
|
|
283
|
-
|
|
284
|
-
const code = this.#createSegmentNodeCode(segment);
|
|
285
|
-
const filename = this.#createSegmentNodeFilename(segment);
|
|
286
|
-
|
|
287
|
-
return this.#cacheManager.store(filename, code);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
#createSegmentNodeCode(segment: Segment): string
|
|
291
|
-
{
|
|
292
|
-
const importCode = this.#createSegmentImportCode(segment);
|
|
293
|
-
const modelCode = this.#createSegmentModelCode(segment);
|
|
294
|
-
|
|
295
|
-
return `${importCode}\n\n${modelCode}`;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
#createSegmentImportCode(segment: Segment): string
|
|
299
|
-
{
|
|
300
|
-
const codes: string[] = [];
|
|
301
|
-
|
|
302
|
-
for (const module of segment.modules)
|
|
303
|
-
{
|
|
304
|
-
const relativeLocation = this.#sourceManager.getRelativeLocation(module.filename);
|
|
305
|
-
const imports: string[] = [];
|
|
306
|
-
|
|
307
|
-
for (const [importKey, implementation] of module.implementations)
|
|
308
|
-
{
|
|
309
|
-
imports.push(`${importKey} as $${implementation.id}`);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
codes.push(`import { ${imports.join(',')} } from "./${relativeLocation}";`);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return codes.join('\n');
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
#createSegmentModelCode(segment: Segment): string
|
|
319
|
-
{
|
|
320
|
-
const procedureCode: string[] = [];
|
|
321
|
-
|
|
322
|
-
for (const procedure of segment.procedures.values())
|
|
323
|
-
{
|
|
324
|
-
const implementationCode: string[] = [];
|
|
325
|
-
|
|
326
|
-
for (const implementation of procedure.implementations)
|
|
327
|
-
{
|
|
328
|
-
implementationCode.push(`{ access: "${implementation.access}", version: "${implementation.version}", executable: $${implementation.id} }`);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
procedureCode.push(`{ module: "${procedure.module}", name: "${procedure.name}", implementations: [\n\t\t${implementationCode.join(',\n\t\t')}\n\t]}`);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
return `export const procedures = [\n\t${procedureCode.join(',\n\t')}\n];`;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
async #buildSegmentModulesForNode(segment: Segment): Promise<void>
|
|
338
|
-
{
|
|
339
|
-
// For the node we need to create two new module files:
|
|
340
|
-
// 1) A copy of the original module file with distribution safe imports.
|
|
341
|
-
// 2) A remake of the original module file with remote implementations only.
|
|
342
|
-
|
|
343
|
-
for (const module of segment.modules)
|
|
344
|
-
{
|
|
345
|
-
const filename = module.filename;
|
|
346
|
-
|
|
347
|
-
const absoluteLocation = this.#sourceManager.getAbsoluteLocation(filename);
|
|
348
|
-
const relativeLocation = this.#sourceManager.getRelativeLocation(filename);
|
|
349
|
-
|
|
350
|
-
const file = await this.#sourceManager.load(absoluteLocation);
|
|
351
|
-
const code = file.content.toString();
|
|
352
|
-
|
|
353
|
-
await this.#buildSegmentModuleForLocal(code, relativeLocation);
|
|
354
|
-
await this.#buildSegmentModuleForRemote(module, relativeLocation);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
async #buildSegmentModuleForLocal(code: string, location: string): Promise<void>
|
|
359
|
-
{
|
|
360
|
-
const importedCode = ImportRewriter.rewrite(code);
|
|
361
|
-
const nodeLocation = location.replace('.js', '.local.js');
|
|
362
|
-
|
|
363
|
-
return this.#cacheManager.store(nodeLocation, importedCode);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
async #buildSegmentModuleForRemote(module: SegmentModule, location: string): Promise<void>
|
|
367
|
-
{
|
|
368
|
-
const remoteCode = RemoteBuilder.build(module);
|
|
369
|
-
const remoteLocation = location.replace('.js', '.remote.js');
|
|
370
|
-
|
|
371
|
-
return this.#cacheManager.store(remoteLocation, remoteCode);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
#createSegmentNodeFilename(segment: Segment): string
|
|
375
|
-
{
|
|
376
|
-
const filename = this.#extractSegmentFilename(segment);
|
|
377
|
-
|
|
378
|
-
return filename.replace('.json', '.local.js');
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
#extractSegmentFilename(segment: Segment): string
|
|
382
|
-
{
|
|
383
|
-
const filename = segment.filename.split('/').pop();
|
|
384
|
-
|
|
385
|
-
if (filename === undefined)
|
|
386
|
-
{
|
|
387
|
-
throw new InvalidSegmentFilename(segment.filename);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
return filename;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
async #buildApplicationCache(applicationModules: ApplicationModule[]): Promise<void[]>
|
|
394
|
-
{
|
|
395
|
-
const promises = applicationModules.map(async (module) => this.#buildApplicationModuleCache(module));
|
|
396
|
-
|
|
397
|
-
return Promise.all(promises);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
async #buildApplicationModuleCache(module: ApplicationModule): Promise<void>
|
|
401
|
-
{
|
|
402
|
-
return this.#buildApplicationShareables(module);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
async #buildApplicationShareables(module: ApplicationModule): Promise<void>
|
|
406
|
-
{
|
|
407
|
-
// Applications use class objects as shareables to share data between segments.
|
|
408
|
-
// In order to make make this work we need to append their source (file) to the
|
|
409
|
-
// class definition so that they can be (de)serialized.
|
|
410
|
-
|
|
411
|
-
if (module.hasClasses() === false)
|
|
412
|
-
{
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const filename = module.filename;
|
|
417
|
-
const file = await this.#sourceManager.load(filename);
|
|
418
|
-
const code = file.content.toString();
|
|
419
|
-
|
|
420
|
-
const sourcedCode = SourceAppender.append(module, code, filename);
|
|
421
|
-
|
|
422
|
-
return this.#cacheManager.store(filename, sourcedCode);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import * as Keywords from './definitions/Keywords.js';
|
|
3
|
-
|
|
4
|
-
const IMPORT_PATTERN = /import(?:["'\s]*([\w*{}\n, ]+)from\s*)?["'\s]*([@\w/_-]+)["'\s].*/g;
|
|
5
|
-
const NON_SYSTEM_INDICATORS = ['.', '/', 'http:', 'https:'];
|
|
6
|
-
|
|
7
|
-
class Dependency
|
|
8
|
-
{
|
|
9
|
-
items: string;
|
|
10
|
-
from: string;
|
|
11
|
-
|
|
12
|
-
constructor(items: string, from: string)
|
|
13
|
-
{
|
|
14
|
-
this.items = items;
|
|
15
|
-
this.from = from;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default class ImportRewriter
|
|
20
|
-
{
|
|
21
|
-
static rewrite(content: string): string
|
|
22
|
-
{
|
|
23
|
-
const replacer = (statement: string) => this.#replaceImport(statement);
|
|
24
|
-
const newContent = content.replaceAll(IMPORT_PATTERN, replacer);
|
|
25
|
-
|
|
26
|
-
return newContent !== content
|
|
27
|
-
? this.#insertGetDependency(newContent)
|
|
28
|
-
: newContent;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
static #replaceImport(statement: string): string
|
|
32
|
-
{
|
|
33
|
-
const dependency = this.#parseImport(statement);
|
|
34
|
-
|
|
35
|
-
return this.#isSystemDependency(dependency)
|
|
36
|
-
? this.#rewriteImport(dependency)
|
|
37
|
-
: statement;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
static #parseImport(statement: string): Dependency
|
|
41
|
-
{
|
|
42
|
-
const hasSemicolon = statement.endsWith(';');
|
|
43
|
-
const fromIndex = statement.indexOf('from');
|
|
44
|
-
const endIndex = statement.length - (hasSemicolon ? 1 : 0);
|
|
45
|
-
|
|
46
|
-
const items = statement.substring(6, fromIndex).trim();
|
|
47
|
-
const from = statement.substring(fromIndex + 4, endIndex).trim().slice(1, -1);
|
|
48
|
-
|
|
49
|
-
return new Dependency(items, from);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
static #isSystemDependency(dependency: Dependency): boolean
|
|
53
|
-
{
|
|
54
|
-
return NON_SYSTEM_INDICATORS.some(indicator => dependency.from.startsWith(indicator)) === false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
static #isJitarDependency(dependency: Dependency): boolean
|
|
58
|
-
{
|
|
59
|
-
return dependency.from === Keywords.JITAR;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
static #rewriteImport(dependency: Dependency): string
|
|
63
|
-
{
|
|
64
|
-
if (this.#isJitarDependency(dependency))
|
|
65
|
-
{
|
|
66
|
-
return `import ${dependency.items} from "/jitar/hooks.js";`;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return `const ${dependency.items} = await getDependency('${dependency.from}');`;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
static #insertGetDependency(module: string): string
|
|
73
|
-
{
|
|
74
|
-
return `import { getDependency } from "/jitar/hooks.js";\n${module}`;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import * as AccessLevel from '../../core/definitions/AccessLevel.js';
|
|
3
|
-
import ReflectionHelper from '../../core/reflection/ReflectionHelper.js';
|
|
4
|
-
|
|
5
|
-
import Implementation from './models/Implementation.js';
|
|
6
|
-
import SegmentModule from './models/SegmentModule.js';
|
|
7
|
-
import * as Keywords from './definitions/Keywords.js';
|
|
8
|
-
|
|
9
|
-
export default class RemoteBuilder
|
|
10
|
-
{
|
|
11
|
-
static build(module: SegmentModule): string
|
|
12
|
-
{
|
|
13
|
-
let code = this.#createRemoteImports();
|
|
14
|
-
|
|
15
|
-
for (const [importKey, implementation] of module.implementations)
|
|
16
|
-
{
|
|
17
|
-
if (implementation.access !== AccessLevel.PUBLIC)
|
|
18
|
-
{
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const asDefault = importKey === Keywords.DEFAULT;
|
|
23
|
-
|
|
24
|
-
code += this.#createRemoteCode(implementation, asDefault);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return code;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
static #createRemoteImports(): string
|
|
31
|
-
{
|
|
32
|
-
return `import { runProcedure } from "/jitar/hooks.js";\n`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
static #createRemoteCode(implementation: Implementation, asDefault: boolean): string
|
|
36
|
-
{
|
|
37
|
-
const parameters = ReflectionHelper.getFunctionParameters(implementation.executable as Function);
|
|
38
|
-
const parameterNames = parameters.map(parameter => parameter.name);
|
|
39
|
-
|
|
40
|
-
const procedureName = implementation.executable.name;
|
|
41
|
-
const procedureFqn = implementation.fqn;
|
|
42
|
-
const procedureVersion = implementation.version;
|
|
43
|
-
const procedueParameters = parameterNames.join(', ');
|
|
44
|
-
const procedureArguments = parameterNames.map(name => `'${name}': ${name}`).join(', ');
|
|
45
|
-
|
|
46
|
-
const functionName = `\nexport ${asDefault ? `${Keywords.DEFAULT} ` : ''}async function ${procedureName}(${procedueParameters})`;
|
|
47
|
-
const functionBody = `return runProcedure('${procedureFqn}', '${procedureVersion}', { ${procedureArguments} })`;
|
|
48
|
-
|
|
49
|
-
return `${functionName} {\n\t${functionBody}\n}\n`;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import ApplicationModule from './models/ApplicationModule.js';
|
|
3
|
-
import * as Keywords from './definitions/Keywords.js';
|
|
4
|
-
|
|
5
|
-
export default class SourceAppender
|
|
6
|
-
{
|
|
7
|
-
static append(module: ApplicationModule, code: string, filename: string): string
|
|
8
|
-
{
|
|
9
|
-
const classNames = this.#extractClassNames(module);
|
|
10
|
-
|
|
11
|
-
if (classNames.length === 0)
|
|
12
|
-
{
|
|
13
|
-
return code;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const sourceCode = this.#createSourceCode(filename, classNames);
|
|
17
|
-
|
|
18
|
-
return `${code}\n${sourceCode}`;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
static #extractClassNames(module: ApplicationModule): string[]
|
|
22
|
-
{
|
|
23
|
-
const classes = module.classes;
|
|
24
|
-
const names: string[] = [];
|
|
25
|
-
|
|
26
|
-
for (const key of classes.keys())
|
|
27
|
-
{
|
|
28
|
-
const clazz = classes.get(key) as Function;
|
|
29
|
-
|
|
30
|
-
if (clazz.name === '')
|
|
31
|
-
{
|
|
32
|
-
// The exported object does not have a name,
|
|
33
|
-
// so we can't add the source properties.
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (key !== Keywords.DEFAULT && key !== clazz.name)
|
|
38
|
-
{
|
|
39
|
-
// The object is being (re) exported under another name.
|
|
40
|
-
// We need to skip this because we can't be sure the real
|
|
41
|
-
// object is present in the module.
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
names.push(clazz.name);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return names;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
static #createSourceCode(filename: string, classNames: string[]): string
|
|
52
|
-
{
|
|
53
|
-
const codes = classNames.map(className => `${className}.source = '${filename}';`);
|
|
54
|
-
|
|
55
|
-
return codes.join('\n');
|
|
56
|
-
}
|
|
57
|
-
}
|