digitaltwin-core 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/LICENSE +21 -0
- package/README.md +125 -0
- package/dist/components/assets_manager.d.ts +384 -0
- package/dist/components/assets_manager.d.ts.map +1 -0
- package/dist/components/assets_manager.js +637 -0
- package/dist/components/assets_manager.js.map +1 -0
- package/dist/components/collector.d.ts +62 -0
- package/dist/components/collector.d.ts.map +1 -0
- package/dist/components/collector.js +80 -0
- package/dist/components/collector.js.map +1 -0
- package/dist/components/global_assets_handler.d.ts +63 -0
- package/dist/components/global_assets_handler.d.ts.map +1 -0
- package/dist/components/global_assets_handler.js +127 -0
- package/dist/components/global_assets_handler.js.map +1 -0
- package/dist/components/handler.d.ts +33 -0
- package/dist/components/handler.d.ts.map +1 -0
- package/dist/components/handler.js +27 -0
- package/dist/components/handler.js.map +1 -0
- package/dist/components/harvester.d.ts +54 -0
- package/dist/components/harvester.d.ts.map +1 -0
- package/dist/components/harvester.js +253 -0
- package/dist/components/harvester.js.map +1 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +6 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/interfaces.d.ts +18 -0
- package/dist/components/interfaces.d.ts.map +1 -0
- package/dist/components/interfaces.js +2 -0
- package/dist/components/interfaces.js.map +1 -0
- package/dist/components/types.d.ts +47 -0
- package/dist/components/types.d.ts.map +1 -0
- package/dist/components/types.js +2 -0
- package/dist/components/types.js.map +1 -0
- package/dist/database/adapters/knex_database_adapter.d.ts +47 -0
- package/dist/database/adapters/knex_database_adapter.d.ts.map +1 -0
- package/dist/database/adapters/knex_database_adapter.js +180 -0
- package/dist/database/adapters/knex_database_adapter.js.map +1 -0
- package/dist/database/database_adapter.d.ts +92 -0
- package/dist/database/database_adapter.d.ts.map +1 -0
- package/dist/database/database_adapter.js +6 -0
- package/dist/database/database_adapter.js.map +1 -0
- package/dist/engine/digital_twin_engine.d.ts +237 -0
- package/dist/engine/digital_twin_engine.d.ts.map +1 -0
- package/dist/engine/digital_twin_engine.js +574 -0
- package/dist/engine/digital_twin_engine.js.map +1 -0
- package/dist/engine/endpoints.d.ts +7 -0
- package/dist/engine/endpoints.d.ts.map +1 -0
- package/dist/engine/endpoints.js +18 -0
- package/dist/engine/endpoints.js.map +1 -0
- package/dist/engine/events.d.ts +13 -0
- package/dist/engine/events.d.ts.map +1 -0
- package/dist/engine/events.js +11 -0
- package/dist/engine/events.js.map +1 -0
- package/dist/engine/initializer.d.ts +8 -0
- package/dist/engine/initializer.d.ts.map +1 -0
- package/dist/engine/initializer.js +23 -0
- package/dist/engine/initializer.js.map +1 -0
- package/dist/engine/queue_manager.d.ts +78 -0
- package/dist/engine/queue_manager.d.ts.map +1 -0
- package/dist/engine/queue_manager.js +167 -0
- package/dist/engine/queue_manager.js.map +1 -0
- package/dist/engine/scheduler.d.ts +30 -0
- package/dist/engine/scheduler.d.ts.map +1 -0
- package/dist/engine/scheduler.js +378 -0
- package/dist/engine/scheduler.js.map +1 -0
- package/dist/env/env.d.ts +25 -0
- package/dist/env/env.d.ts.map +1 -0
- package/dist/env/env.js +55 -0
- package/dist/env/env.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/adapters/local_storage_service.d.ts +29 -0
- package/dist/storage/adapters/local_storage_service.d.ts.map +1 -0
- package/dist/storage/adapters/local_storage_service.js +50 -0
- package/dist/storage/adapters/local_storage_service.js.map +1 -0
- package/dist/storage/adapters/ovh_storage_service.d.ts +32 -0
- package/dist/storage/adapters/ovh_storage_service.d.ts.map +1 -0
- package/dist/storage/adapters/ovh_storage_service.js +70 -0
- package/dist/storage/adapters/ovh_storage_service.js.map +1 -0
- package/dist/storage/storage_factory.d.ts +14 -0
- package/dist/storage/storage_factory.d.ts.map +1 -0
- package/dist/storage/storage_factory.js +36 -0
- package/dist/storage/storage_factory.js.map +1 -0
- package/dist/storage/storage_service.d.ts +26 -0
- package/dist/storage/storage_service.d.ts.map +1 -0
- package/dist/storage/storage_service.js +7 -0
- package/dist/storage/storage_service.js.map +1 -0
- package/dist/types/data_record.d.ts +17 -0
- package/dist/types/data_record.d.ts.map +1 -0
- package/dist/types/data_record.js +2 -0
- package/dist/types/data_record.js.map +1 -0
- package/dist/utils/logger.d.ts +17 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +35 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/map_to_data_record.d.ts +10 -0
- package/dist/utils/map_to_data_record.d.ts.map +1 -0
- package/dist/utils/map_to_data_record.js +21 -0
- package/dist/utils/map_to_data_record.js.map +1 -0
- package/dist/utils/servable_endpoint.d.ts +6 -0
- package/dist/utils/servable_endpoint.d.ts.map +1 -0
- package/dist/utils/servable_endpoint.js +15 -0
- package/dist/utils/servable_endpoint.js.map +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
// src/engine/scheduler.ts
|
|
2
|
+
import { Collector } from '../components/collector.js';
|
|
3
|
+
import { Harvester } from '../components/harvester.js';
|
|
4
|
+
import { Worker } from 'bullmq';
|
|
5
|
+
import { Logger, LogLevel } from '../utils/logger.js';
|
|
6
|
+
import { engineEventBus } from './events.js';
|
|
7
|
+
import debounce from 'lodash/debounce.js';
|
|
8
|
+
/**
|
|
9
|
+
* Worker configuration constants
|
|
10
|
+
*/
|
|
11
|
+
const WORKER_CONFIG = {
|
|
12
|
+
COLLECTOR: {
|
|
13
|
+
concurrency: 5,
|
|
14
|
+
limiter: { max: 10, duration: 60000 }
|
|
15
|
+
},
|
|
16
|
+
HARVESTER: {
|
|
17
|
+
concurrency: 3,
|
|
18
|
+
limiter: { max: 20, duration: 60000 }
|
|
19
|
+
},
|
|
20
|
+
PRIORITY: {
|
|
21
|
+
concurrency: 1 // One priority task at a time
|
|
22
|
+
},
|
|
23
|
+
SINGLE_QUEUE: {
|
|
24
|
+
concurrency: (componentCount) => Math.max(componentCount, 1)
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Default job options for event-triggered harvesters
|
|
29
|
+
*/
|
|
30
|
+
const EVENT_JOB_OPTIONS = {
|
|
31
|
+
removeOnComplete: true,
|
|
32
|
+
attempts: 3,
|
|
33
|
+
backoff: { type: 'exponential', delay: 1000 }
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Component Scheduler - Manages scheduling and execution of collectors and harvesters
|
|
37
|
+
*
|
|
38
|
+
* The scheduler supports two modes:
|
|
39
|
+
* - Multi-queue mode: Separate queues for collectors, harvesters, and priority jobs
|
|
40
|
+
* - Single-queue mode: All components share one queue (legacy mode)
|
|
41
|
+
*
|
|
42
|
+
* @class ComponentScheduler
|
|
43
|
+
*/
|
|
44
|
+
class ComponentScheduler {
|
|
45
|
+
/**
|
|
46
|
+
* Creates a new Component Scheduler instance
|
|
47
|
+
* @param components - Array of components to schedule
|
|
48
|
+
* @param queueManager - Queue manager instance
|
|
49
|
+
* @param multiQueue - Whether to use multi-queue mode
|
|
50
|
+
* @param logLevel - Log level for the scheduler (optional)
|
|
51
|
+
*/
|
|
52
|
+
constructor(components, queueManager, multiQueue = true, logLevel) {
|
|
53
|
+
this.componentMap = {};
|
|
54
|
+
this.debouncedTriggers = {};
|
|
55
|
+
this.components = components;
|
|
56
|
+
this.queueManager = queueManager;
|
|
57
|
+
this.multiQueue = multiQueue;
|
|
58
|
+
this.logger = new Logger('Scheduler', logLevel ?? (process.env.NODE_ENV === 'test' ? LogLevel.SILENT : LogLevel.INFO));
|
|
59
|
+
this.#buildComponentMap();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Schedules all components and creates workers
|
|
63
|
+
* @returns Array of created workers
|
|
64
|
+
*/
|
|
65
|
+
async schedule() {
|
|
66
|
+
this.#setupEventListeners();
|
|
67
|
+
if (this.multiQueue) {
|
|
68
|
+
return this.#scheduleMultiQueue();
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return this.#scheduleSingleQueue();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Builds a map of component names to component instances
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
#buildComponentMap() {
|
|
79
|
+
for (const comp of this.components) {
|
|
80
|
+
const config = comp.getConfiguration();
|
|
81
|
+
this.componentMap[config.name] = comp;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Sets up event listeners for harvesters with on-source trigger
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
#setupEventListeners() {
|
|
89
|
+
this.#setupHarvesterTriggers();
|
|
90
|
+
this.#setupCollectorEventListener();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Creates debounced trigger functions for event-driven harvesters
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
#setupHarvesterTriggers() {
|
|
97
|
+
for (const comp of this.components) {
|
|
98
|
+
if (!(comp instanceof Harvester))
|
|
99
|
+
continue;
|
|
100
|
+
const config = comp.getConfiguration();
|
|
101
|
+
if (!this.#shouldSetupEventTrigger(config))
|
|
102
|
+
continue;
|
|
103
|
+
const triggerFunction = this.#createTriggerFunction(config);
|
|
104
|
+
const debounceMs = config.debounceMs || 1000;
|
|
105
|
+
this.debouncedTriggers[config.name] = debounce(triggerFunction, debounceMs);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Checks if a harvester should have event trigger setup
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
#shouldSetupEventTrigger(config) {
|
|
113
|
+
return config.triggerMode === 'on-source' || config.triggerMode === 'both';
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Creates a trigger function for a harvester
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
#createTriggerFunction(config) {
|
|
120
|
+
return async () => {
|
|
121
|
+
const queue = this.multiQueue ? this.queueManager.harvesterQueue : this.queueManager.collectorQueue;
|
|
122
|
+
await queue.add(config.name, {
|
|
123
|
+
type: 'harvester',
|
|
124
|
+
triggeredBy: 'source-event',
|
|
125
|
+
source: config.source
|
|
126
|
+
}, EVENT_JOB_OPTIONS);
|
|
127
|
+
this.logger.debug(`Triggered harvester ${config.name} from source event`);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Sets up listener for collector completion events
|
|
132
|
+
* @private
|
|
133
|
+
*/
|
|
134
|
+
#setupCollectorEventListener() {
|
|
135
|
+
engineEventBus.on('component:event', async (event) => {
|
|
136
|
+
if (event.type !== 'collector:completed')
|
|
137
|
+
return;
|
|
138
|
+
this.logger.debug(`Received collector:completed event from ${event.componentName}`);
|
|
139
|
+
await this.#triggerDependentHarvesters(event.componentName);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Triggers harvesters that depend on a completed collector
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
async #triggerDependentHarvesters(collectorName) {
|
|
147
|
+
for (const comp of this.components) {
|
|
148
|
+
if (!(comp instanceof Harvester))
|
|
149
|
+
continue;
|
|
150
|
+
const config = comp.getConfiguration();
|
|
151
|
+
if (config.source === collectorName && this.debouncedTriggers[config.name]) {
|
|
152
|
+
this.logger.info(`Triggering harvester ${config.name} due to ${collectorName} completion`);
|
|
153
|
+
this.debouncedTriggers[config.name]();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Schedules components in multi-queue mode
|
|
159
|
+
* @private
|
|
160
|
+
*/
|
|
161
|
+
async #scheduleMultiQueue() {
|
|
162
|
+
this.logger.info('Starting multi-queue scheduling mode');
|
|
163
|
+
await this.#scheduleCollectors();
|
|
164
|
+
await this.#scheduleHarvesters();
|
|
165
|
+
const workers = [
|
|
166
|
+
this.#createCollectorWorker(),
|
|
167
|
+
this.#createHarvesterWorker(),
|
|
168
|
+
this.#createPriorityWorker()
|
|
169
|
+
];
|
|
170
|
+
this.logger.info(`Multi-queue scheduler initialized with ${workers.length} workers`);
|
|
171
|
+
return workers;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Schedules all collectors in multi-queue mode
|
|
175
|
+
* @private
|
|
176
|
+
*/
|
|
177
|
+
async #scheduleCollectors() {
|
|
178
|
+
const collectors = this.components.filter((comp) => comp instanceof Collector);
|
|
179
|
+
for (const collector of collectors) {
|
|
180
|
+
const config = collector.getConfiguration();
|
|
181
|
+
const schedule = collector.getSchedule();
|
|
182
|
+
await this.queueManager.collectorQueue.upsertJobScheduler(config.name, { pattern: schedule }, {
|
|
183
|
+
name: config.name,
|
|
184
|
+
data: { type: 'collector', triggeredBy: 'schedule' }
|
|
185
|
+
});
|
|
186
|
+
this.logger.info(`Scheduled collector ${config.name} with pattern: ${schedule}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Schedules harvesters (only those not exclusively on-source) in multi-queue mode
|
|
191
|
+
* @private
|
|
192
|
+
*/
|
|
193
|
+
async #scheduleHarvesters() {
|
|
194
|
+
const harvesters = this.components.filter((comp) => comp instanceof Harvester);
|
|
195
|
+
for (const harvester of harvesters) {
|
|
196
|
+
const config = harvester.getConfiguration();
|
|
197
|
+
const schedule = harvester.getSchedule();
|
|
198
|
+
if (schedule && config.triggerMode !== 'on-source') {
|
|
199
|
+
await this.queueManager.harvesterQueue.upsertJobScheduler(config.name, { pattern: schedule }, {
|
|
200
|
+
name: config.name,
|
|
201
|
+
data: { type: 'harvester', triggeredBy: 'schedule' }
|
|
202
|
+
});
|
|
203
|
+
this.logger.info(`Scheduled harvester ${config.name} with pattern: ${schedule}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Creates collector worker for multi-queue mode
|
|
209
|
+
* @private
|
|
210
|
+
*/
|
|
211
|
+
#createCollectorWorker() {
|
|
212
|
+
return new Worker('dt-collectors', async (job) => this.#processCollectorJob(job), {
|
|
213
|
+
connection: this.queueManager.collectorQueue.opts.connection,
|
|
214
|
+
concurrency: WORKER_CONFIG.COLLECTOR.concurrency,
|
|
215
|
+
limiter: WORKER_CONFIG.COLLECTOR.limiter
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Creates harvester worker for multi-queue mode
|
|
220
|
+
* @private
|
|
221
|
+
*/
|
|
222
|
+
#createHarvesterWorker() {
|
|
223
|
+
return new Worker('dt-harvesters', async (job) => this.#processHarvesterJob(job), {
|
|
224
|
+
connection: this.queueManager.harvesterQueue.opts.connection,
|
|
225
|
+
concurrency: WORKER_CONFIG.HARVESTER.concurrency,
|
|
226
|
+
limiter: WORKER_CONFIG.HARVESTER.limiter
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Creates priority worker for multi-queue mode
|
|
231
|
+
* @private
|
|
232
|
+
*/
|
|
233
|
+
#createPriorityWorker() {
|
|
234
|
+
return new Worker('dt-priority', async (job) => this.#processPriorityJob(job), {
|
|
235
|
+
connection: this.queueManager.priorityQueue.opts.connection,
|
|
236
|
+
concurrency: WORKER_CONFIG.PRIORITY.concurrency
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Processes a collector job
|
|
241
|
+
* @private
|
|
242
|
+
*/
|
|
243
|
+
async #processCollectorJob(job) {
|
|
244
|
+
const comp = this.componentMap[job.name];
|
|
245
|
+
if (!comp)
|
|
246
|
+
return;
|
|
247
|
+
this.logger.info(`Running collector: ${job.name}`);
|
|
248
|
+
try {
|
|
249
|
+
const result = await comp.run();
|
|
250
|
+
return {
|
|
251
|
+
success: true,
|
|
252
|
+
bytes: result?.length || 0,
|
|
253
|
+
timestamp: new Date().toISOString()
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
this.logger.error(`Collector ${job.name} failed:`, error);
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Processes a harvester job
|
|
263
|
+
* @private
|
|
264
|
+
*/
|
|
265
|
+
async #processHarvesterJob(job) {
|
|
266
|
+
const comp = this.componentMap[job.name];
|
|
267
|
+
if (!comp)
|
|
268
|
+
return;
|
|
269
|
+
this.logger.info(`Running harvester: ${job.name} (triggered by: ${job.data.triggeredBy})`);
|
|
270
|
+
try {
|
|
271
|
+
const result = await comp.run();
|
|
272
|
+
// Emit harvester completion event
|
|
273
|
+
engineEventBus.emit('component:event', {
|
|
274
|
+
type: 'harvester:completed',
|
|
275
|
+
componentName: comp.getConfiguration().name,
|
|
276
|
+
timestamp: new Date(),
|
|
277
|
+
data: { success: result }
|
|
278
|
+
});
|
|
279
|
+
return {
|
|
280
|
+
success: result,
|
|
281
|
+
timestamp: new Date().toISOString()
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
this.logger.error(`Harvester ${job.name} failed:`, error);
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Processes a priority job
|
|
291
|
+
* @private
|
|
292
|
+
*/
|
|
293
|
+
async #processPriorityJob(job) {
|
|
294
|
+
const comp = this.componentMap[job.name];
|
|
295
|
+
if (!comp)
|
|
296
|
+
return;
|
|
297
|
+
this.logger.info(`Running priority job: ${job.name}`);
|
|
298
|
+
const result = await comp.run();
|
|
299
|
+
return { success: true, result };
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Schedules components in single-queue mode (legacy)
|
|
303
|
+
* @private
|
|
304
|
+
*/
|
|
305
|
+
async #scheduleSingleQueue() {
|
|
306
|
+
this.logger.warn('Running in single-queue mode (not recommended)');
|
|
307
|
+
const singleQueue = this.queueManager.collectorQueue;
|
|
308
|
+
await this.#scheduleAllComponentsInSingleQueue(singleQueue);
|
|
309
|
+
const worker = new Worker(singleQueue.name, async (job) => this.#processSingleQueueJob(job), {
|
|
310
|
+
connection: singleQueue.opts.connection,
|
|
311
|
+
concurrency: WORKER_CONFIG.SINGLE_QUEUE.concurrency(this.components.length)
|
|
312
|
+
});
|
|
313
|
+
this.logger.info('Single-queue scheduler initialized with 1 worker');
|
|
314
|
+
return [worker];
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Schedules all components in single queue
|
|
318
|
+
* @private
|
|
319
|
+
*/
|
|
320
|
+
async #scheduleAllComponentsInSingleQueue(singleQueue) {
|
|
321
|
+
for (const comp of this.components) {
|
|
322
|
+
const config = comp.getConfiguration();
|
|
323
|
+
const schedule = comp.getSchedule();
|
|
324
|
+
const shouldSchedule = comp instanceof Harvester
|
|
325
|
+
? schedule && comp.getConfiguration().triggerMode !== 'on-source'
|
|
326
|
+
: schedule !== null;
|
|
327
|
+
if (shouldSchedule) {
|
|
328
|
+
await singleQueue.upsertJobScheduler(config.name, { pattern: schedule }, {
|
|
329
|
+
name: config.name,
|
|
330
|
+
data: {
|
|
331
|
+
type: comp instanceof Collector ? 'collector' : 'harvester',
|
|
332
|
+
triggeredBy: 'schedule'
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Processes a job in single-queue mode
|
|
340
|
+
* @private
|
|
341
|
+
*/
|
|
342
|
+
async #processSingleQueueJob(job) {
|
|
343
|
+
const comp = this.componentMap[job.name];
|
|
344
|
+
if (!comp)
|
|
345
|
+
return;
|
|
346
|
+
this.logger.info(`Running ${job.data.type}: ${job.name}`);
|
|
347
|
+
const result = await comp.run();
|
|
348
|
+
return { success: true, result };
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Schedules components for execution using the queue manager
|
|
353
|
+
*
|
|
354
|
+
* This function creates a scheduler instance and sets up:
|
|
355
|
+
* - Job scheduling based on component schedules
|
|
356
|
+
* - Event-driven harvester triggers
|
|
357
|
+
* - Workers for processing jobs
|
|
358
|
+
*
|
|
359
|
+
* @param components - Array of components to schedule
|
|
360
|
+
* @param queueManager - Queue manager instance
|
|
361
|
+
* @param multiQueue - Whether to use multi-queue mode (default: true)
|
|
362
|
+
* @param logLevel - Log level for the scheduler (optional)
|
|
363
|
+
* @returns Promise that resolves to array of created workers
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```typescript
|
|
367
|
+
* const workers = await scheduleComponents(
|
|
368
|
+
* [collector1, harvester1],
|
|
369
|
+
* queueManager,
|
|
370
|
+
* true
|
|
371
|
+
* )
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
export async function scheduleComponents(components, queueManager, multiQueue = true, logLevel) {
|
|
375
|
+
const scheduler = new ComponentScheduler(components, queueManager, multiQueue, logLevel);
|
|
376
|
+
return scheduler.schedule();
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/engine/scheduler.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,QAAQ,MAAM,oBAAoB,CAAA;AAGzC;;GAEG;AACH,MAAM,aAAa,GAAG;IAClB,SAAS,EAAE;QACP,WAAW,EAAE,CAAC;QACd,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;KACxC;IACD,SAAS,EAAE;QACP,WAAW,EAAE,CAAC;QACd,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;KACxC;IACD,QAAQ,EAAE;QACN,WAAW,EAAE,CAAC,CAAC,8BAA8B;KAChD;IACD,YAAY,EAAE;QACV,WAAW,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC;KACvE;CACK,CAAA;AAEV;;GAEG;AACH,MAAM,iBAAiB,GAAG;IACtB,gBAAgB,EAAE,IAAI;IACtB,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE;CACvC,CAAA;AAEV;;;;;;;;GAQG;AACH,MAAM,kBAAkB;IAQpB;;;;;;OAMG;IACH,YACI,UAAwC,EACxC,YAA0B,EAC1B,aAAsB,IAAI,EAC1B,QAAmB;QAdN,iBAAY,GAA0C,EAAE,CAAA;QACxD,sBAAiB,GAA6B,EAAE,CAAA;QAe7D,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAChC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;QAEtH,IAAI,CAAC,kBAAkB,EAAE,CAAA;IAC7B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ;QACV,IAAI,CAAC,oBAAoB,EAAE,CAAA;QAE3B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,mBAAmB,EAAE,CAAA;QACrC,CAAC;aAAM,CAAC;YACJ,OAAO,IAAI,CAAC,oBAAoB,EAAE,CAAA;QACtC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,kBAAkB;QACd,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;YACtC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;QACzC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,oBAAoB;QAChB,IAAI,CAAC,uBAAuB,EAAE,CAAA;QAC9B,IAAI,CAAC,4BAA4B,EAAE,CAAA;IACvC,CAAC;IAED;;;OAGG;IACH,uBAAuB;QACnB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC,CAAC,IAAI,YAAY,SAAS,CAAC;gBAAE,SAAQ;YAE1C,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;YACtC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC;gBAAE,SAAQ;YAEpD,MAAM,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAA;YAC3D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,IAAI,CAAA;YAC5C,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QAC/E,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,wBAAwB,CAAC,MAA8B;QACnD,OAAO,MAAM,CAAC,WAAW,KAAK,WAAW,IAAI,MAAM,CAAC,WAAW,KAAK,MAAM,CAAA;IAC9E,CAAC;IAED;;;OAGG;IACH,sBAAsB,CAAC,MAA8B;QACjD,OAAO,KAAK,IAAI,EAAE;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAA;YAEnG,MAAM,KAAK,CAAC,GAAG,CACX,MAAM,CAAC,IAAI,EACX;gBACI,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,cAAc;gBAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;aACxB,EACD,iBAAiB,CACpB,CAAA;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,MAAM,CAAC,IAAI,oBAAoB,CAAC,CAAA;QAC7E,CAAC,CAAA;IACL,CAAC;IAED;;;OAGG;IACH,4BAA4B;QACxB,cAAc,CAAC,EAAE,CAAC,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACjD,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB;gBAAE,OAAM;YAEhD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,KAAK,CAAC,aAAa,EAAE,CAAC,CAAA;YACnF,MAAM,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;QAC/D,CAAC,CAAC,CAAA;IACN,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,2BAA2B,CAAC,aAAqB;QACnD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC,CAAC,IAAI,YAAY,SAAS,CAAC;gBAAE,SAAQ;YAE1C,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;YACtC,IAAI,MAAM,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,MAAM,CAAC,IAAI,WAAW,aAAa,aAAa,CAAC,CAAA;gBAC1F,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAA;YACzC,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mBAAmB;QACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAA;QAExD,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAA;QAChC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAA;QAEhC,MAAM,OAAO,GAAG;YACZ,IAAI,CAAC,sBAAsB,EAAE;YAC7B,IAAI,CAAC,sBAAsB,EAAE;YAC7B,IAAI,CAAC,qBAAqB,EAAE;SAC/B,CAAA;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,OAAO,CAAC,MAAM,UAAU,CAAC,CAAA;QACpF,OAAO,OAAO,CAAA;IAClB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mBAAmB;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAqB,EAAE,CAAC,IAAI,YAAY,SAAS,CAAC,CAAA;QAEjG,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,SAAS,CAAC,gBAAgB,EAAE,CAAA;YAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,EAAE,CAAA;YAExC,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,kBAAkB,CACrD,MAAM,CAAC,IAAI,EACX,EAAE,OAAO,EAAE,QAAQ,EAAE,EACrB;gBACI,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE;aACvD,CACJ,CAAA;YAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,IAAI,kBAAkB,QAAQ,EAAE,CAAC,CAAA;QACpF,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mBAAmB;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAqB,EAAE,CAAC,IAAI,YAAY,SAAS,CAAC,CAAA;QAEjG,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,SAAS,CAAC,gBAAgB,EAAE,CAAA;YAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,EAAE,CAAA;YAExC,IAAI,QAAQ,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;gBACjD,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,kBAAkB,CACrD,MAAM,CAAC,IAAI,EACX,EAAE,OAAO,EAAE,QAAQ,EAAE,EACrB;oBACI,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE;iBACvD,CACJ,CAAA;gBAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,IAAI,kBAAkB,QAAQ,EAAE,CAAC,CAAA;YACpF,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,sBAAsB;QAClB,OAAO,IAAI,MAAM,CACb,eAAe,EACf,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAC7C;YACI,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU;YAC5D,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,WAAW;YAChD,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO;SAC3C,CACJ,CAAA;IACL,CAAC;IAED;;;OAGG;IACH,sBAAsB;QAClB,OAAO,IAAI,MAAM,CACb,eAAe,EACf,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAC7C;YACI,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU;YAC5D,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,WAAW;YAChD,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO;SAC3C,CACJ,CAAA;IACL,CAAC;IAED;;;OAGG;IACH,qBAAqB;QACjB,OAAO,IAAI,MAAM,CACb,aAAa,EACb,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAC5C;YACI,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU;YAC3D,WAAW,EAAE,aAAa,CAAC,QAAQ,CAAC,WAAW;SAClD,CACJ,CAAA;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,oBAAoB,CAAC,GAAQ;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAc,CAAA;QACrD,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;QAElD,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;YAE/B,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;gBAC1B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACtC,CAAA;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,IAAI,UAAU,EAAE,KAAK,CAAC,CAAA;YACzD,MAAM,KAAK,CAAA;QACf,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,oBAAoB,CAAC,GAAQ;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAc,CAAA;QACrD,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,GAAG,CAAC,IAAI,mBAAmB,GAAG,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;QAE1F,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;YAE/B,kCAAkC;YAClC,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE;gBACnC,IAAI,EAAE,qBAAqB;gBAC3B,aAAa,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI;gBAC3C,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAA;YAEF,OAAO;gBACH,OAAO,EAAE,MAAM;gBACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACtC,CAAA;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,IAAI,UAAU,EAAE,KAAK,CAAC,CAAA;YACzD,MAAM,KAAK,CAAA;QACf,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mBAAmB,CAAC,GAAQ;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;QACrD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;QAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IACpC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,oBAAoB;QACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAA;QAElE,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAA;QACpD,MAAM,IAAI,CAAC,mCAAmC,CAAC,WAAW,CAAC,CAAA;QAE3D,MAAM,MAAM,GAAG,IAAI,MAAM,CACrB,WAAW,CAAC,IAAI,EAChB,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAC/C;YACI,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,UAAU;YACvC,WAAW,EAAE,aAAa,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;SAC9E,CACJ,CAAA;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAA;QACpE,OAAO,CAAC,MAAM,CAAC,CAAA;IACnB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,mCAAmC,CAAC,WAAgB;QACtD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;YAEnC,MAAM,cAAc,GAAG,IAAI,YAAY,SAAS;gBAC5C,CAAC,CAAC,QAAQ,IAAK,IAAI,CAAC,gBAAgB,EAA6B,CAAC,WAAW,KAAK,WAAW;gBAC7F,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAA;YAEvB,IAAI,cAAc,EAAE,CAAC;gBACjB,MAAM,WAAW,CAAC,kBAAkB,CAChC,MAAM,CAAC,IAAI,EACX,EAAE,OAAO,EAAE,QAAQ,EAAE,EACrB;oBACI,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,IAAI,EAAE;wBACF,IAAI,EAAE,IAAI,YAAY,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW;wBAC3D,WAAW,EAAE,UAAU;qBAC1B;iBACJ,CACJ,CAAA;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,sBAAsB,CAAC,GAAQ;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;QACzD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;QAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IACpC,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,UAAwC,EACxC,YAA0B,EAC1B,aAAsB,IAAI,EAC1B,QAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,kBAAkB,CAAC,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;IACxF,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAA;AAC/B,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare class Env {
|
|
2
|
+
static schema: {
|
|
3
|
+
string: (opts?: {
|
|
4
|
+
optional?: boolean;
|
|
5
|
+
format?: "url" | "email";
|
|
6
|
+
}) => {
|
|
7
|
+
optional?: boolean;
|
|
8
|
+
format?: "url" | "email";
|
|
9
|
+
type: "string";
|
|
10
|
+
};
|
|
11
|
+
number: (opts?: {
|
|
12
|
+
optional?: boolean;
|
|
13
|
+
}) => {
|
|
14
|
+
optional?: boolean;
|
|
15
|
+
type: "number";
|
|
16
|
+
};
|
|
17
|
+
enum: <T extends string[]>(values: T) => {
|
|
18
|
+
type: "enum";
|
|
19
|
+
values: T;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
static config: Record<string, any>;
|
|
23
|
+
static validate<T extends Record<string, any>>(schema: Record<string, any>, rawEnv?: NodeJS.ProcessEnv): T;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/env/env.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,CAAC,MAAM;wBACO;YAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO,CAAA;SAAE;uBAAnC,OAAO;qBAAW,KAAK,GAAG,OAAO;;;wBAK9C;YAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;SAAE;uBAAT,OAAO;;;eAK7B,CAAC,SAAS,MAAM,EAAE,UAAU,CAAC;;;;MAIvC;IAED,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAK;IAEvC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,oBAAc,GAAG,CAAC;CA0CvG"}
|
package/dist/env/env.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export class Env {
|
|
2
|
+
static { this.schema = {
|
|
3
|
+
string: (opts) => ({
|
|
4
|
+
type: 'string',
|
|
5
|
+
...opts,
|
|
6
|
+
}),
|
|
7
|
+
number: (opts) => ({
|
|
8
|
+
type: 'number',
|
|
9
|
+
...opts,
|
|
10
|
+
}),
|
|
11
|
+
enum: (values) => ({
|
|
12
|
+
type: 'enum',
|
|
13
|
+
values,
|
|
14
|
+
}),
|
|
15
|
+
}; }
|
|
16
|
+
static { this.config = {}; }
|
|
17
|
+
static validate(schema, rawEnv = process.env) {
|
|
18
|
+
const config = {};
|
|
19
|
+
for (const [key, rules] of Object.entries(schema)) {
|
|
20
|
+
const value = rawEnv[key];
|
|
21
|
+
if (value === undefined || value === '') {
|
|
22
|
+
if (rules.optional)
|
|
23
|
+
continue;
|
|
24
|
+
throw new Error(`Missing environment variable: ${key}`);
|
|
25
|
+
}
|
|
26
|
+
switch (rules.type) {
|
|
27
|
+
case 'string':
|
|
28
|
+
if (rules.format === 'url' && !/^https?:\/\/.+$/.test(value)) {
|
|
29
|
+
throw new Error(`Invalid URL format for ${key}`);
|
|
30
|
+
}
|
|
31
|
+
if (rules.format === 'email' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
|
|
32
|
+
throw new Error(`Invalid email format for ${key}`);
|
|
33
|
+
}
|
|
34
|
+
config[key] = value;
|
|
35
|
+
break;
|
|
36
|
+
case 'number':
|
|
37
|
+
const parsed = Number(value);
|
|
38
|
+
if (isNaN(parsed)) {
|
|
39
|
+
throw new Error(`Invalid number format for ${key}`);
|
|
40
|
+
}
|
|
41
|
+
config[key] = parsed;
|
|
42
|
+
break;
|
|
43
|
+
case 'enum':
|
|
44
|
+
if (!rules.values.includes(value)) {
|
|
45
|
+
throw new Error(`Invalid value for ${key}, expected one of ${rules.values.join(', ')}`);
|
|
46
|
+
}
|
|
47
|
+
config[key] = value;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.config = config;
|
|
52
|
+
return config;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/env/env.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG;aACL,WAAM,GAAG;QACZ,MAAM,EAAE,CAAC,IAAuD,EAAE,EAAE,CAAC,CAAC;YAClE,IAAI,EAAE,QAAiB;YACvB,GAAG,IAAI;SACV,CAAC;QAEF,MAAM,EAAE,CAAC,IAA6B,EAAE,EAAE,CAAC,CAAC;YACxC,IAAI,EAAE,QAAiB;YACvB,GAAG,IAAI;SACV,CAAC;QAEF,IAAI,EAAE,CAAqB,MAAS,EAAE,EAAE,CAAC,CAAC;YACtC,IAAI,EAAE,MAAe;YACrB,MAAM;SACT,CAAC;KACL,CAAA;aAEM,WAAM,GAAwB,EAAE,CAAA;IAEvC,MAAM,CAAC,QAAQ,CAAgC,MAA2B,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG;QAC5F,MAAM,MAAM,GAAQ,EAAE,CAAA;QAEtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;YAEzB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;gBACtC,IAAI,KAAK,CAAC,QAAQ;oBAAE,SAAQ;gBAC5B,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAA;YAC3D,CAAC;YAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACjB,KAAK,QAAQ;oBACT,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC3D,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAA;oBACpD,CAAC;oBACD,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;wBACxE,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAA;oBACtD,CAAC;oBACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;oBACnB,MAAK;gBAET,KAAK,QAAQ;oBACT,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;oBAC5B,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;wBAChB,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAA;oBACvD,CAAC;oBACD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAA;oBACpB,MAAK;gBAET,KAAK,MAAM;oBACP,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;wBAChC,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,qBAAqB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;oBAC3F,CAAC;oBACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;oBACnB,MAAK;YACb,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,OAAO,MAAM,CAAA;IACjB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { DigitalTwinEngine } from './engine/digital_twin_engine.js';
|
|
2
|
+
export { Collector } from './components/collector.js';
|
|
3
|
+
export { Harvester } from './components/harvester.js';
|
|
4
|
+
export { Handler } from './components/handler.js';
|
|
5
|
+
export { AssetsManager } from './components/assets_manager.js';
|
|
6
|
+
export { GlobalAssetsHandler } from './components/global_assets_handler.js';
|
|
7
|
+
export { StorageService } from './storage/storage_service.js';
|
|
8
|
+
export { LocalStorageService } from './storage/adapters/local_storage_service.js';
|
|
9
|
+
export { OvhS3StorageService } from './storage/adapters/ovh_storage_service.js';
|
|
10
|
+
export { StorageServiceFactory } from './storage/storage_factory.js';
|
|
11
|
+
export { DatabaseAdapter } from './database/database_adapter.js';
|
|
12
|
+
export { KnexDatabaseAdapter, PostgreSQLConfig, SQLiteConfig } from './database/adapters/knex_database_adapter.js';
|
|
13
|
+
export * from './components/types.js';
|
|
14
|
+
export * from './components/interfaces.js';
|
|
15
|
+
export * from './types/data_record.js';
|
|
16
|
+
export { Logger, LogLevel } from './utils/logger.js';
|
|
17
|
+
export { mapToDataRecord } from './utils/map_to_data_record.js';
|
|
18
|
+
export { servableEndpoint } from './utils/servable_endpoint.js';
|
|
19
|
+
export { QueueManager } from './engine/queue_manager.js';
|
|
20
|
+
export { initializeComponents } from './engine/initializer.js';
|
|
21
|
+
export * from './engine/events.js';
|
|
22
|
+
export * from './engine/endpoints.js';
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAA;AAG3E,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAA;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAA;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAA;AAGlH,cAAc,uBAAuB,CAAA;AACrC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AAGtC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAG/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Main entry point for digitaltwin-core package
|
|
2
|
+
// Core Engine
|
|
3
|
+
export { DigitalTwinEngine } from './engine/digital_twin_engine.js';
|
|
4
|
+
// Base Components
|
|
5
|
+
export { Collector } from './components/collector.js';
|
|
6
|
+
export { Harvester } from './components/harvester.js';
|
|
7
|
+
export { Handler } from './components/handler.js';
|
|
8
|
+
export { AssetsManager } from './components/assets_manager.js';
|
|
9
|
+
export { GlobalAssetsHandler } from './components/global_assets_handler.js';
|
|
10
|
+
// Storage Services
|
|
11
|
+
export { StorageService } from './storage/storage_service.js';
|
|
12
|
+
export { LocalStorageService } from './storage/adapters/local_storage_service.js';
|
|
13
|
+
export { OvhS3StorageService } from './storage/adapters/ovh_storage_service.js';
|
|
14
|
+
export { StorageServiceFactory } from './storage/storage_factory.js';
|
|
15
|
+
// Database Services
|
|
16
|
+
export { DatabaseAdapter } from './database/database_adapter.js';
|
|
17
|
+
export { KnexDatabaseAdapter } from './database/adapters/knex_database_adapter.js';
|
|
18
|
+
// Types and Interfaces
|
|
19
|
+
export * from './components/types.js';
|
|
20
|
+
export * from './components/interfaces.js';
|
|
21
|
+
export * from './types/data_record.js';
|
|
22
|
+
// Utilities
|
|
23
|
+
export { Logger, LogLevel } from './utils/logger.js';
|
|
24
|
+
export { mapToDataRecord } from './utils/map_to_data_record.js';
|
|
25
|
+
export { servableEndpoint } from './utils/servable_endpoint.js';
|
|
26
|
+
// Engine Components
|
|
27
|
+
export { QueueManager } from './engine/queue_manager.js';
|
|
28
|
+
export { initializeComponents } from './engine/initializer.js';
|
|
29
|
+
export * from './engine/events.js';
|
|
30
|
+
export * from './engine/endpoints.js';
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD,cAAc;AACd,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAEnE,kBAAkB;AAClB,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAA;AAE3E,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAA;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAA;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAEpE,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAkC,MAAM,8CAA8C,CAAA;AAElH,uBAAuB;AACvB,cAAc,uBAAuB,CAAA;AACrC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AAEtC,YAAY;AACZ,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAE/D,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { StorageService } from '../storage_service.js';
|
|
2
|
+
/**
|
|
3
|
+
* Local filesystem-based implementation of the StorageService.
|
|
4
|
+
* Saves files in a configured folder using a timestamp as filename.
|
|
5
|
+
*/
|
|
6
|
+
export declare class LocalStorageService extends StorageService {
|
|
7
|
+
private baseDir;
|
|
8
|
+
constructor(baseDir?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Saves the given buffer to disk under a unique filename.
|
|
11
|
+
* @param buffer - Content to save
|
|
12
|
+
* @param collectorName - Name of the collector (used for folder)
|
|
13
|
+
* @param extension - Optional file extension (e.g. 'json', 'txt')
|
|
14
|
+
* @returns Relative path to the saved file
|
|
15
|
+
*/
|
|
16
|
+
save(buffer: Buffer, collectorName: string, extension?: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Retrieves a file as buffer using its relative path.
|
|
19
|
+
* @param relativePath - Filename previously returned by `save`
|
|
20
|
+
* @returns File content as Buffer
|
|
21
|
+
*/
|
|
22
|
+
retrieve(relativePath: string): Promise<Buffer>;
|
|
23
|
+
/**
|
|
24
|
+
* Deletes a stored file.
|
|
25
|
+
* @param relativePath - Filename previously returned by `save`
|
|
26
|
+
*/
|
|
27
|
+
delete(relativePath: string): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=local_storage_service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local_storage_service.d.ts","sourceRoot":"","sources":["../../../src/storage/adapters/local_storage_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAItD;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,cAAc;IACvC,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE,MAAe;IAI5C;;;;;;OAMG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAetF;;;;OAIG;IACG,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKrD;;;OAGG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAIpD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { StorageService } from '../storage_service.js';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Local filesystem-based implementation of the StorageService.
|
|
6
|
+
* Saves files in a configured folder using a timestamp as filename.
|
|
7
|
+
*/
|
|
8
|
+
export class LocalStorageService extends StorageService {
|
|
9
|
+
constructor(baseDir = 'data') {
|
|
10
|
+
super();
|
|
11
|
+
this.baseDir = baseDir;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Saves the given buffer to disk under a unique filename.
|
|
15
|
+
* @param buffer - Content to save
|
|
16
|
+
* @param collectorName - Name of the collector (used for folder)
|
|
17
|
+
* @param extension - Optional file extension (e.g. 'json', 'txt')
|
|
18
|
+
* @returns Relative path to the saved file
|
|
19
|
+
*/
|
|
20
|
+
async save(buffer, collectorName, extension) {
|
|
21
|
+
const now = new Date();
|
|
22
|
+
const timestamp = now.toISOString().replace(/[:.]/g, '-');
|
|
23
|
+
const folder = collectorName || 'default';
|
|
24
|
+
const filename = extension ? `${timestamp}.${extension}` : timestamp;
|
|
25
|
+
const dirPath = path.join(this.baseDir, folder);
|
|
26
|
+
const filePath = path.join(dirPath, filename);
|
|
27
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
28
|
+
await fs.writeFile(filePath, buffer);
|
|
29
|
+
// return relative path (e.g., 'mycollector/2025-07-07T15-45-22-456Z.json')
|
|
30
|
+
return path.join(folder, filename);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Retrieves a file as buffer using its relative path.
|
|
34
|
+
* @param relativePath - Filename previously returned by `save`
|
|
35
|
+
* @returns File content as Buffer
|
|
36
|
+
*/
|
|
37
|
+
async retrieve(relativePath) {
|
|
38
|
+
const filePath = path.join(this.baseDir, relativePath);
|
|
39
|
+
return fs.readFile(filePath);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Deletes a stored file.
|
|
43
|
+
* @param relativePath - Filename previously returned by `save`
|
|
44
|
+
*/
|
|
45
|
+
async delete(relativePath) {
|
|
46
|
+
const filePath = path.join(this.baseDir, relativePath);
|
|
47
|
+
await fs.rm(filePath, { force: true });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=local_storage_service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local_storage_service.js","sourceRoot":"","sources":["../../../src/storage/adapters/local_storage_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,MAAM,aAAa,CAAA;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,cAAc;IACnD,YAAoB,UAAkB,MAAM;QACxC,KAAK,EAAE,CAAA;QADS,YAAO,GAAP,OAAO,CAAiB;IAE5C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,aAAqB,EAAE,SAAkB;QAChE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;QACtB,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QACzD,MAAM,MAAM,GAAG,aAAa,IAAI,SAAS,CAAA;QACzC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAE7C,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC5C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAEpC,2EAA2E;QAC3E,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,YAAoB;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;QACtD,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAChC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,YAAoB;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;QACtD,MAAM,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,CAAC;CACJ"}
|