@loutrejs/loutre 0.1.0
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/adapters/aws-lambda.d.ts +52 -0
- package/dist/adapters/aws-lambda.js +114 -0
- package/dist/adapters/bun.d.ts +20 -0
- package/dist/adapters/bun.js +82 -0
- package/dist/adapters/cloudflare-workers.d.ts +18 -0
- package/dist/adapters/cloudflare-workers.js +55 -0
- package/dist/adapters/deno.d.ts +28 -0
- package/dist/adapters/deno.js +106 -0
- package/dist/adapters/electron.d.ts +27 -0
- package/dist/adapters/electron.js +52 -0
- package/dist/application/binding.d.ts +33 -0
- package/dist/application/binding.js +292 -0
- package/dist/application/host.d.ts +8 -0
- package/dist/application/host.js +14 -0
- package/dist/application/index.d.ts +62 -0
- package/dist/application/index.js +11 -0
- package/dist/application/openapi.d.ts +28 -0
- package/dist/application/openapi.js +362 -0
- package/dist/application/queue.d.ts +3 -0
- package/dist/application/queue.js +4 -0
- package/dist/application/scheduler.d.ts +2 -0
- package/dist/application/scheduler.js +45 -0
- package/dist/core/args.d.ts +16 -0
- package/dist/core/args.js +29 -0
- package/dist/core/context-key.d.ts +14 -0
- package/dist/core/context-key.js +14 -0
- package/dist/core/contract.d.ts +54 -0
- package/dist/core/contract.js +30 -0
- package/dist/core/env.d.ts +16 -0
- package/dist/core/env.js +29 -0
- package/dist/core/error.d.ts +24 -0
- package/dist/core/error.js +25 -0
- package/dist/core/execution.d.ts +78 -0
- package/dist/core/execution.js +61 -0
- package/dist/core/implementation.d.ts +34 -0
- package/dist/core/implementation.js +30 -0
- package/dist/core/index.d.ts +15 -0
- package/dist/core/index.js +15 -0
- package/dist/core/injection.d.ts +28 -0
- package/dist/core/injection.js +35 -0
- package/dist/core/layer.d.ts +109 -0
- package/dist/core/layer.js +52 -0
- package/dist/core/lifecycle.d.ts +34 -0
- package/dist/core/lifecycle.js +3 -0
- package/dist/core/module.d.ts +53 -0
- package/dist/core/module.js +31 -0
- package/dist/core/provider.d.ts +57 -0
- package/dist/core/provider.js +63 -0
- package/dist/core/runtime-input.d.ts +11 -0
- package/dist/core/runtime-input.js +1 -0
- package/dist/core/schema.d.ts +13 -0
- package/dist/core/schema.js +20 -0
- package/dist/core/token.d.ts +16 -0
- package/dist/core/token.js +13 -0
- package/dist/graph/graph.d.ts +17 -0
- package/dist/graph/graph.js +1078 -0
- package/dist/graph/index.d.ts +2 -0
- package/dist/graph/index.js +2 -0
- package/dist/graph/ir.d.ts +159 -0
- package/dist/graph/ir.js +1 -0
- package/dist/http/application.d.ts +18 -0
- package/dist/http/application.js +506 -0
- package/dist/http/basic-auth.d.ts +37 -0
- package/dist/http/basic-auth.js +67 -0
- package/dist/http/cors.d.ts +17 -0
- package/dist/http/cors.js +171 -0
- package/dist/http/definitions.d.ts +217 -0
- package/dist/http/definitions.js +65 -0
- package/dist/http/hosted-protocol.d.ts +4 -0
- package/dist/http/hosted-protocol.js +4 -0
- package/dist/http/index.d.ts +7 -0
- package/dist/http/index.js +6 -0
- package/dist/http/params.d.ts +2 -0
- package/dist/http/params.js +19 -0
- package/dist/http/path.d.ts +55 -0
- package/dist/http/path.js +88 -0
- package/dist/http/request-body.d.ts +4 -0
- package/dist/http/request-body.js +6 -0
- package/dist/http/validate.d.ts +20 -0
- package/dist/http/validate.js +6 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/message-port/environment.d.ts +2 -0
- package/dist/message-port/environment.js +4 -0
- package/dist/message-port/index.d.ts +65 -0
- package/dist/message-port/index.js +182 -0
- package/dist/runtime/application.d.ts +37 -0
- package/dist/runtime/application.js +324 -0
- package/dist/runtime/capability.d.ts +16 -0
- package/dist/runtime/capability.js +18 -0
- package/dist/runtime/di.d.ts +37 -0
- package/dist/runtime/di.js +441 -0
- package/dist/runtime/error.d.ts +10 -0
- package/dist/runtime/error.js +15 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/logger.d.ts +36 -0
- package/dist/runtime/logger.js +207 -0
- package/dist/runtime/node-capabilities.d.ts +5 -0
- package/dist/runtime/node-capabilities.js +18 -0
- package/dist/runtime/pipeline.d.ts +11 -0
- package/dist/runtime/pipeline.js +161 -0
- package/package.json +81 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { argumentsProvider, loadArgs, loadEnv, normalizeProvider, } from '../core/index.js';
|
|
2
|
+
import { collectRuntimeModuleGraph, Container, } from './di.js';
|
|
3
|
+
import { Logger } from './logger.js';
|
|
4
|
+
const NO_ENVIRONMENT_SOURCE = Symbol('loutre.no-environment-source');
|
|
5
|
+
let currentEnvironmentSource = NO_ENVIRONMENT_SOURCE;
|
|
6
|
+
export function initializeWithEnvironment(application, environmentSource) {
|
|
7
|
+
const previous = currentEnvironmentSource;
|
|
8
|
+
currentEnvironmentSource = environmentSource;
|
|
9
|
+
try {
|
|
10
|
+
return application.initialize();
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
currentEnvironmentSource = previous;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class EnvironmentBindingError extends Error {
|
|
17
|
+
code = 'LUTRE_ENV_003';
|
|
18
|
+
constructor(environment, cause) {
|
|
19
|
+
super(`Environment validation failed for ${environment.name}.`, { cause });
|
|
20
|
+
this.name = 'EnvironmentBindingError';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class ArgumentsBindingError extends Error {
|
|
24
|
+
code = 'LUTRE_ARGS_003';
|
|
25
|
+
constructor(argumentsContract, cause) {
|
|
26
|
+
super(`Arguments validation failed for ${argumentsContract.name}.`, {
|
|
27
|
+
cause,
|
|
28
|
+
});
|
|
29
|
+
this.name = 'ArgumentsBindingError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class ApplicationRuntime {
|
|
33
|
+
graph;
|
|
34
|
+
container;
|
|
35
|
+
#instancesByModule = new Map();
|
|
36
|
+
#logger;
|
|
37
|
+
#environmentSource;
|
|
38
|
+
#arguments;
|
|
39
|
+
#argumentsSource;
|
|
40
|
+
#tasks;
|
|
41
|
+
#publicTasks;
|
|
42
|
+
#initialized = false;
|
|
43
|
+
#initializing;
|
|
44
|
+
#prepared = false;
|
|
45
|
+
#state = 'created';
|
|
46
|
+
#activeExecutions = 0;
|
|
47
|
+
#idleWaiters = new Set();
|
|
48
|
+
#shutdown;
|
|
49
|
+
constructor(roots, options = {}) {
|
|
50
|
+
this.#logger = options.logger ?? new Logger();
|
|
51
|
+
this.#environmentSource =
|
|
52
|
+
'environmentSource' in options
|
|
53
|
+
? options.environmentSource
|
|
54
|
+
: NO_ENVIRONMENT_SOURCE;
|
|
55
|
+
this.#arguments = options.arguments;
|
|
56
|
+
this.#argumentsSource =
|
|
57
|
+
'argumentsSource' in options ? options.argumentsSource : Object.freeze({});
|
|
58
|
+
this.#tasks = new Set(options.tasks ?? []);
|
|
59
|
+
this.#publicTasks = new Set(options.publicTasks ?? []);
|
|
60
|
+
this.graph = collectRuntimeModuleGraph(roots);
|
|
61
|
+
const providers = [
|
|
62
|
+
...this.graph.providers,
|
|
63
|
+
...(this.#arguments ? [argumentsProvider(this.#arguments)] : []),
|
|
64
|
+
];
|
|
65
|
+
this.container = new Container(providers, {
|
|
66
|
+
logger: this.#logger,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
initialize() {
|
|
70
|
+
if (this.#initialized)
|
|
71
|
+
return Promise.resolve();
|
|
72
|
+
if (this.#initializing)
|
|
73
|
+
return this.#initializing;
|
|
74
|
+
if (this.#state === 'stopping') {
|
|
75
|
+
return Promise.reject(applicationStateError('LUTRE_APP_STOPPING'));
|
|
76
|
+
}
|
|
77
|
+
if (this.#state === 'stopped') {
|
|
78
|
+
return Promise.reject(applicationStateError('LUTRE_APP_STOPPED'));
|
|
79
|
+
}
|
|
80
|
+
const source = this.#environmentSource === NO_ENVIRONMENT_SOURCE
|
|
81
|
+
? currentEnvironmentSource
|
|
82
|
+
: this.#environmentSource;
|
|
83
|
+
const initialization = this.#initialize(source).finally(() => {
|
|
84
|
+
if (this.#initializing === initialization) {
|
|
85
|
+
this.#initializing = undefined;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
this.#initializing = initialization;
|
|
89
|
+
return initialization;
|
|
90
|
+
}
|
|
91
|
+
async #initialize(environmentSource) {
|
|
92
|
+
this.#state = 'initializing';
|
|
93
|
+
try {
|
|
94
|
+
await this.#bindEnvironment(environmentSource);
|
|
95
|
+
await this.#bindArguments();
|
|
96
|
+
this.#prepareRuntime();
|
|
97
|
+
for (const module of this.graph.modules) {
|
|
98
|
+
const instances = await this.#resolveModuleProviders(module);
|
|
99
|
+
this.#instancesByModule.set(module, instances);
|
|
100
|
+
for (const instance of instances)
|
|
101
|
+
await callLifecycle(instance, 'onModuleInit');
|
|
102
|
+
await this.#runHook(module.definition.lifecycle?.onModuleInit);
|
|
103
|
+
}
|
|
104
|
+
for (const module of this.graph.modules) {
|
|
105
|
+
for (const instance of this.#instancesByModule.get(module) ?? []) {
|
|
106
|
+
await callLifecycle(instance, 'onApplicationBootstrap');
|
|
107
|
+
}
|
|
108
|
+
await this.#runHook(module.definition.lifecycle?.onApplicationBootstrap);
|
|
109
|
+
}
|
|
110
|
+
this.#initialized = true;
|
|
111
|
+
if (this.#state !== 'stopping')
|
|
112
|
+
this.#state = 'running';
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
const cleanupErrors = await this.#rollbackInitialization();
|
|
116
|
+
this.#state = 'stopped';
|
|
117
|
+
if (cleanupErrors.length > 0) {
|
|
118
|
+
throw new AggregateError([error, ...cleanupErrors], 'Application initialization failed and rollback cleanup also failed', { cause: error });
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async #bindEnvironment(source) {
|
|
124
|
+
const environmentProviders = this.graph.providers.filter((provider) => provider.kind === 'environment');
|
|
125
|
+
if (environmentProviders.length === 0)
|
|
126
|
+
return;
|
|
127
|
+
if (source === NO_ENVIRONMENT_SOURCE) {
|
|
128
|
+
throw new Error('LUTRE_ENV_005: Application declares Environment Contracts, but the Runtime did not provide an Environment source.');
|
|
129
|
+
}
|
|
130
|
+
for (const provider of environmentProviders) {
|
|
131
|
+
try {
|
|
132
|
+
const value = await loadEnv(provider.provide, source);
|
|
133
|
+
this.container.bindEnvironment(provider.provide, value);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
throw new EnvironmentBindingError(provider.provide, error);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async #bindArguments() {
|
|
141
|
+
if (!this.#arguments)
|
|
142
|
+
return;
|
|
143
|
+
try {
|
|
144
|
+
const value = await loadArgs(this.#arguments, this.#argumentsSource);
|
|
145
|
+
this.container.bindArguments(this.#arguments, value);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
throw new ArgumentsBindingError(this.#arguments, error);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
#prepareRuntime() {
|
|
152
|
+
if (this.#prepared)
|
|
153
|
+
return;
|
|
154
|
+
for (const module of this.graph.modules) {
|
|
155
|
+
for (const implementation of module.definition.implementations ?? []) {
|
|
156
|
+
this.container.prepareImplementation(implementation);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const pipeline of collectApplicationPipelines(this.graph.modules)) {
|
|
160
|
+
this.container.preparePipeline(pipeline);
|
|
161
|
+
}
|
|
162
|
+
for (const task of this.#tasks) {
|
|
163
|
+
this.container.prepareTask(task);
|
|
164
|
+
}
|
|
165
|
+
this.#prepared = true;
|
|
166
|
+
}
|
|
167
|
+
run(task, ...args) {
|
|
168
|
+
if (!this.#publicTasks.has(task)) {
|
|
169
|
+
return Promise.reject(new Error(`LUTRE_TASK_002: Task ${task.name} is not registered in Application.tasks.`));
|
|
170
|
+
}
|
|
171
|
+
return this.#invokeTask(task, args);
|
|
172
|
+
}
|
|
173
|
+
/** public run()ではTrigger専用Taskを拒否するため、Trigger Host専用経路を分ける。 */
|
|
174
|
+
runTask(task, ...args) {
|
|
175
|
+
if (!this.#tasks.has(task)) {
|
|
176
|
+
return Promise.reject(new Error(`LUTRE_TASK_NOT_REGISTERED: Task ${task.name} is not registered in this Application.`));
|
|
177
|
+
}
|
|
178
|
+
return this.#invokeTask(task, args);
|
|
179
|
+
}
|
|
180
|
+
#invokeTask(task, args) {
|
|
181
|
+
return this.execute(async () => {
|
|
182
|
+
const runtime = this.container.taskRuntime(task);
|
|
183
|
+
return Reflect.apply(runtime, undefined, args);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
async execute(execution) {
|
|
187
|
+
if (this.#state === 'stopping')
|
|
188
|
+
throw applicationStateError('LUTRE_APP_STOPPING');
|
|
189
|
+
if (this.#state === 'stopped')
|
|
190
|
+
throw applicationStateError('LUTRE_APP_STOPPED');
|
|
191
|
+
this.#activeExecutions += 1;
|
|
192
|
+
try {
|
|
193
|
+
await this.initialize();
|
|
194
|
+
return await execution();
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
this.#activeExecutions -= 1;
|
|
198
|
+
if (this.#activeExecutions === 0) {
|
|
199
|
+
for (const resolve of this.#idleWaiters)
|
|
200
|
+
resolve();
|
|
201
|
+
this.#idleWaiters.clear();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
stopAcceptingExecutions() {
|
|
206
|
+
if (this.#state !== 'stopped')
|
|
207
|
+
this.#state = 'stopping';
|
|
208
|
+
}
|
|
209
|
+
shutdown(signal) {
|
|
210
|
+
if (this.#state === 'stopped')
|
|
211
|
+
return Promise.resolve();
|
|
212
|
+
if (this.#shutdown)
|
|
213
|
+
return this.#shutdown;
|
|
214
|
+
this.stopAcceptingExecutions();
|
|
215
|
+
const shutdown = this.#shutdownRuntime(signal);
|
|
216
|
+
this.#shutdown = shutdown;
|
|
217
|
+
return shutdown;
|
|
218
|
+
}
|
|
219
|
+
async #shutdownRuntime(signal) {
|
|
220
|
+
if (this.#initializing) {
|
|
221
|
+
await this.#initializing.catch(() => undefined);
|
|
222
|
+
}
|
|
223
|
+
if (this.#activeExecutions > 0) {
|
|
224
|
+
await new Promise((resolve) => this.#idleWaiters.add(resolve));
|
|
225
|
+
}
|
|
226
|
+
const errors = [];
|
|
227
|
+
const modules = this.graph.modules.toReversed();
|
|
228
|
+
try {
|
|
229
|
+
for (const module of modules) {
|
|
230
|
+
for (const instance of (this.#instancesByModule.get(module) ?? []).toReversed()) {
|
|
231
|
+
await collectCleanupError(() => callLifecycle(instance, 'onModuleDestroy'), errors);
|
|
232
|
+
}
|
|
233
|
+
await collectCleanupError(() => this.#runHook(module.definition.lifecycle?.onModuleDestroy), errors);
|
|
234
|
+
}
|
|
235
|
+
for (const module of modules) {
|
|
236
|
+
for (const instance of (this.#instancesByModule.get(module) ?? []).toReversed()) {
|
|
237
|
+
await collectCleanupError(() => callLifecycle(instance, 'beforeApplicationShutdown', signal), errors);
|
|
238
|
+
}
|
|
239
|
+
await collectCleanupError(() => this.#runHook(module.definition.lifecycle?.beforeApplicationShutdown), errors);
|
|
240
|
+
}
|
|
241
|
+
for (const module of modules) {
|
|
242
|
+
for (const instance of (this.#instancesByModule.get(module) ?? []).toReversed()) {
|
|
243
|
+
await collectCleanupError(() => callLifecycle(instance, 'onApplicationShutdown', signal), errors);
|
|
244
|
+
}
|
|
245
|
+
await collectCleanupError(() => this.#runHook(module.definition.lifecycle?.onApplicationShutdown), errors);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
this.#state = 'stopped';
|
|
250
|
+
}
|
|
251
|
+
if (errors.length > 0) {
|
|
252
|
+
throw new AggregateError(errors, 'Application shutdown cleanup failed');
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async #rollbackInitialization() {
|
|
256
|
+
const errors = [];
|
|
257
|
+
const modules = [...this.#instancesByModule.keys()].toReversed();
|
|
258
|
+
for (const module of modules) {
|
|
259
|
+
await collectCleanupError(() => this.#runHook(module.definition.lifecycle?.onModuleDestroy), errors);
|
|
260
|
+
for (const instance of (this.#instancesByModule.get(module) ?? []).toReversed()) {
|
|
261
|
+
await collectCleanupError(() => callLifecycle(instance, 'onModuleDestroy'), errors);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return errors;
|
|
265
|
+
}
|
|
266
|
+
async #resolveModuleProviders(module) {
|
|
267
|
+
const providers = (module.definition.providers ?? []).map(normalizeProvider);
|
|
268
|
+
const applicationProviders = providers.filter((provider) => provider.scope === 'application' &&
|
|
269
|
+
provider.kind !== 'environment' &&
|
|
270
|
+
provider.kind !== 'arguments');
|
|
271
|
+
const instances = [];
|
|
272
|
+
this.#instancesByModule.set(module, instances);
|
|
273
|
+
for (const provider of applicationProviders) {
|
|
274
|
+
instances.push(this.container.resolve(provider.provide));
|
|
275
|
+
}
|
|
276
|
+
return instances;
|
|
277
|
+
}
|
|
278
|
+
async #runHook(hook) {
|
|
279
|
+
if (!hook)
|
|
280
|
+
return;
|
|
281
|
+
const dependencies = hook.inject.map((token) => this.container.resolve(token));
|
|
282
|
+
await hook.run(...dependencies);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function applicationStateError(code) {
|
|
286
|
+
return new Error(code === 'LUTRE_APP_STOPPING'
|
|
287
|
+
? `${code}: Application is stopping and cannot accept new executions.`
|
|
288
|
+
: `${code}: Application is stopped and cannot accept new executions.`);
|
|
289
|
+
}
|
|
290
|
+
function collectApplicationPipelines(modules) {
|
|
291
|
+
const pipelines = [];
|
|
292
|
+
for (const module of modules) {
|
|
293
|
+
for (const implementation of module.definition.implementations ?? []) {
|
|
294
|
+
for (const procedureName of implementation.procedures) {
|
|
295
|
+
const procedure = implementation.contract.procedures[procedureName];
|
|
296
|
+
const protocol = procedure?.protocols[implementation.protocol];
|
|
297
|
+
const pipeline = protocol?.pipeline ?? protocol?.definition?.pipeline;
|
|
298
|
+
if (pipeline)
|
|
299
|
+
pipelines.push(pipeline);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return pipelines;
|
|
304
|
+
}
|
|
305
|
+
async function collectCleanupError(cleanup, errors) {
|
|
306
|
+
try {
|
|
307
|
+
await cleanup();
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
errors.push(error);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
export function createApplicationRuntime(roots, options = {}) {
|
|
314
|
+
return new ApplicationRuntime(roots, options);
|
|
315
|
+
}
|
|
316
|
+
async function callLifecycle(instance, method, signal) {
|
|
317
|
+
if (!instance ||
|
|
318
|
+
(typeof instance !== 'object' && typeof instance !== 'function'))
|
|
319
|
+
return;
|
|
320
|
+
const candidate = instance[method];
|
|
321
|
+
if (typeof candidate !== 'function')
|
|
322
|
+
return;
|
|
323
|
+
await Reflect.apply(candidate, instance, signal === undefined ? [] : [signal]);
|
|
324
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type RuntimeCapability = string;
|
|
2
|
+
export interface RuntimeCapabilities {
|
|
3
|
+
readonly runtime: string;
|
|
4
|
+
readonly capabilities: ReadonlySet<RuntimeCapability>;
|
|
5
|
+
}
|
|
6
|
+
export interface CapabilityCheck {
|
|
7
|
+
readonly ok: boolean;
|
|
8
|
+
readonly required: readonly RuntimeCapability[];
|
|
9
|
+
readonly supported: readonly RuntimeCapability[];
|
|
10
|
+
readonly missing: readonly RuntimeCapability[];
|
|
11
|
+
}
|
|
12
|
+
export declare function checkCapabilities(required: Iterable<RuntimeCapability>, runtime: RuntimeCapabilities): CapabilityCheck;
|
|
13
|
+
export declare class MissingCapabilitiesError extends Error {
|
|
14
|
+
readonly check: CapabilityCheck;
|
|
15
|
+
constructor(check: CapabilityCheck);
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function checkCapabilities(required, runtime) {
|
|
2
|
+
const requirements = [...new Set(required)];
|
|
3
|
+
const missing = requirements.filter((capability) => !runtime.capabilities.has(capability));
|
|
4
|
+
return {
|
|
5
|
+
ok: missing.length === 0,
|
|
6
|
+
required: requirements,
|
|
7
|
+
supported: [...runtime.capabilities],
|
|
8
|
+
missing,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export class MissingCapabilitiesError extends Error {
|
|
12
|
+
check;
|
|
13
|
+
constructor(check) {
|
|
14
|
+
super(`Runtimeに必要なCapabilityがありません: ${check.missing.join(', ')}`);
|
|
15
|
+
this.check = check;
|
|
16
|
+
this.name = 'MissingCapabilitiesError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ArgsClass, type Class, type DependencyConsumer, type EnvClass, type ImplementationConsumer, type ImplementationDescriptor, type LayerConsumer, type LayerDescriptor, type LayerRuntime, type ModuleInstance, type ModuleTemplate, type ProviderDescriptor, type PipelineItem, type TaskConsumer, type TaskDescriptor, type TaskRuntime, type TokenLike } from '../core/index.js';
|
|
2
|
+
import { Logger } from './logger.js';
|
|
3
|
+
export declare class DependencyResolutionError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
export interface RuntimeModuleGraph {
|
|
7
|
+
readonly modules: readonly ModuleInstance[];
|
|
8
|
+
readonly providers: readonly ProviderDescriptor[];
|
|
9
|
+
}
|
|
10
|
+
export interface DependencyRecorder {
|
|
11
|
+
record(consumer: DependencyConsumer, dependency: TokenLike): void;
|
|
12
|
+
}
|
|
13
|
+
export interface ContainerOptions {
|
|
14
|
+
readonly logger?: Logger;
|
|
15
|
+
readonly recorder?: DependencyRecorder;
|
|
16
|
+
readonly environment?: ReadonlyMap<EnvClass, object>;
|
|
17
|
+
readonly arguments?: ReadonlyMap<ArgsClass, object>;
|
|
18
|
+
readonly probe?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function collectRuntimeModuleGraph(roots: readonly (ModuleInstance | ModuleTemplate<void>)[]): RuntimeModuleGraph;
|
|
21
|
+
export declare class Container {
|
|
22
|
+
#private;
|
|
23
|
+
constructor(providers: readonly ProviderDescriptor[], options?: Logger | ContainerOptions);
|
|
24
|
+
bindEnvironment(environment: EnvClass, value: object): void;
|
|
25
|
+
bindArguments(argumentsContract: ArgsClass, value: object): void;
|
|
26
|
+
resolve<T>(token: TokenLike<T>): T;
|
|
27
|
+
probeClass<T>(target: Class<T>): T;
|
|
28
|
+
prepareImplementation(implementation: ImplementationDescriptor): void;
|
|
29
|
+
implementationRuntime(implementation: ImplementationDescriptor): object;
|
|
30
|
+
prepareTask(task: TaskDescriptor): void;
|
|
31
|
+
taskRuntime<TInput, TOutput>(task: TaskDescriptor<TInput, TOutput>): TaskRuntime<TInput, TOutput>;
|
|
32
|
+
probeTask(task: TaskDescriptor, consumer: TaskConsumer): void;
|
|
33
|
+
probeImplementation(implementation: ImplementationDescriptor, consumer: ImplementationConsumer): object;
|
|
34
|
+
preparePipeline(pipeline: readonly PipelineItem[]): void;
|
|
35
|
+
layerRuntime(layer: LayerDescriptor): LayerRuntime<object, readonly [], unknown>;
|
|
36
|
+
probeLayer(layer: LayerDescriptor, consumer: LayerConsumer): void;
|
|
37
|
+
}
|