@twin.org/engine-core 0.0.3-next.2 → 0.0.3-next.21

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.
@@ -1,7 +1,7 @@
1
1
  // Copyright 2024 IOTA Stiftung.
2
2
  // SPDX-License-Identifier: Apache-2.0.
3
3
  import { isMainThread } from "node:worker_threads";
4
- import { ContextIdStore } from "@twin.org/context";
4
+ import { ContextIdHandlerFactory, ContextIdStore } from "@twin.org/context";
5
5
  import { BaseError, ComponentFactory, ErrorHelper, GeneralError, Guards, I18n, Is } from "@twin.org/core";
6
6
  import { EntitySchemaFactory } from "@twin.org/entity";
7
7
  import { ConsoleLoggingConnector } from "@twin.org/logging-connector-console";
@@ -141,10 +141,12 @@ export class EngineCore {
141
141
  /**
142
142
  * Add a context ID key to the engine.
143
143
  * @param key The context ID key.
144
+ * @param componentFeatures The component features for the context ID handler.
144
145
  */
145
- addContextIdKey(key) {
146
- if (!this._contextIdKeys.includes(key)) {
147
- this._contextIdKeys.push(key);
146
+ addContextIdKey(key, componentFeatures) {
147
+ const exists = this._contextIdKeys.find(k => k.key === key);
148
+ if (Is.empty(exists)) {
149
+ this._contextIdKeys.push({ key, componentFeatures });
148
150
  }
149
151
  }
150
152
  /**
@@ -152,7 +154,7 @@ export class EngineCore {
152
154
  * @returns The context IDs keys.
153
155
  */
154
156
  getContextIdKeys() {
155
- return this._contextIdKeys;
157
+ return this._contextIdKeys.map(k => k.key);
156
158
  }
157
159
  /**
158
160
  * Add a context ID to the engine.
@@ -172,102 +174,108 @@ export class EngineCore {
172
174
  }
173
175
  /**
174
176
  * Start the engine core.
175
- * @returns True if the start was successful.
177
+ * @param skipComponentStart Should the component start be skipped.
178
+ * @returns Nothing.
176
179
  */
177
- async start() {
178
- if (this._isStarted) {
179
- return false;
180
- }
181
- this.setupEngineLogger();
182
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.starting`));
183
- if (this._context.config.debug) {
184
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.debuggingEnabled`));
185
- }
186
- let canContinue;
187
- try {
188
- canContinue = await this.stateLoad();
189
- if (canContinue) {
180
+ async start(skipComponentStart) {
181
+ if (!this._isStarted) {
182
+ this.setupEngineLogger();
183
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.starting`));
184
+ if (this._context.config.debug) {
185
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.debuggingEnabled`));
186
+ }
187
+ const skipComponent = skipComponentStart ?? false;
188
+ try {
189
+ await this.stateLoad();
190
190
  for (const { type, module, method } of this._typeInitialisers) {
191
191
  await this.initialiseTypeConfig(type, module, method);
192
192
  }
193
+ this.initialiseContextIdHandlers();
193
194
  await this.bootstrap();
194
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentsStarting`));
195
- await ContextIdStore.run(this._contextIds ?? {}, async () => {
196
- for (const instance of this._context.componentInstances) {
197
- if (!instance.started) {
198
- const startMethod = instance.component.start?.bind(instance.component);
199
- if (Is.function(startMethod)) {
200
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentStarting`, {
201
- className: instance.component.className(),
202
- instanceType: instance.instanceType
203
- }));
204
- try {
205
- await startMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);
206
- instance.started = true;
207
- }
208
- catch (err) {
209
- await this.logError(new GeneralError(EngineCore.CLASS_NAME, "componentStartFailed", {
195
+ this._isStarted = true;
196
+ if (!skipComponent) {
197
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentsStarting`));
198
+ await ContextIdStore.run(this._contextIds ?? {}, async () => {
199
+ for (const instance of this._context.componentInstances) {
200
+ if (!instance.initialised) {
201
+ instance.initialised = true;
202
+ const startMethod = instance.component.start?.bind(instance.component);
203
+ if (Is.function(startMethod)) {
204
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentStarting`, {
210
205
  className: instance.component.className(),
211
206
  instanceType: instance.instanceType
212
- }, BaseError.fromError(err)));
213
- throw err;
207
+ }));
208
+ try {
209
+ await startMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);
210
+ }
211
+ catch (err) {
212
+ await this.logError(new GeneralError(EngineCore.CLASS_NAME, "componentStartFailed", {
213
+ className: instance.component.className(),
214
+ instanceType: instance.instanceType
215
+ }, BaseError.fromError(err)));
216
+ throw err;
217
+ }
214
218
  }
215
219
  }
216
220
  }
221
+ });
222
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentsComplete`));
223
+ }
224
+ else {
225
+ // If we are skipping component start then just mark them as initialised
226
+ // we still need to be able to call stop on them to clean up
227
+ for (const instance of this._context.componentInstances) {
228
+ instance.initialised = true;
217
229
  }
218
- });
219
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentsComplete`));
230
+ }
231
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.started`));
220
232
  }
221
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.started`));
222
- this._isStarted = true;
223
- }
224
- catch (err) {
225
- canContinue = false;
226
- await this.logError(BaseError.fromError(err));
227
- }
228
- finally {
229
- if (!(await this.stateSave())) {
230
- canContinue = false;
233
+ catch (err) {
234
+ await this.stop();
235
+ await this.logError(BaseError.fromError(err));
236
+ throw err;
237
+ }
238
+ finally {
239
+ await this.stateSave();
231
240
  }
232
241
  }
233
- if (!canContinue) {
234
- await this.stop();
235
- }
236
- return canContinue;
237
242
  }
238
243
  /**
239
244
  * Stop the engine core.
240
245
  * @returns Nothing.
241
246
  */
242
247
  async stop() {
243
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.stopping`));
244
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentsStopping`));
245
- await ContextIdStore.run(this._contextIds ?? {}, async () => {
246
- for (const instance of this._context.componentInstances) {
247
- if (instance.started) {
248
- instance.started = false;
249
- const stopMethod = instance.component.stop?.bind(instance.component);
250
- if (Is.function(stopMethod)) {
251
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentStopping`, {
252
- className: instance.component.className(),
253
- instanceType: instance.instanceType
254
- }));
255
- try {
256
- await stopMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);
257
- }
258
- catch (err) {
259
- await this.logError(new GeneralError(EngineCore.CLASS_NAME, "componentStopFailed", {
248
+ if (this._isStarted) {
249
+ this._isStarted = false;
250
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.stopping`));
251
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentsStopping`));
252
+ await ContextIdStore.run(this._contextIds ?? {}, async () => {
253
+ for (const instance of this._context.componentInstances) {
254
+ if (instance.initialised) {
255
+ instance.initialised = false;
256
+ const stopMethod = instance.component.stop?.bind(instance.component);
257
+ if (Is.function(stopMethod)) {
258
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentStopping`, {
260
259
  className: instance.component.className(),
261
260
  instanceType: instance.instanceType
262
- }, BaseError.fromError(err)));
261
+ }));
262
+ try {
263
+ await stopMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);
264
+ }
265
+ catch (err) {
266
+ await this.logError(new GeneralError(EngineCore.CLASS_NAME, "componentStopFailed", {
267
+ className: instance.component.className(),
268
+ instanceType: instance.instanceType
269
+ }, BaseError.fromError(err)));
270
+ }
263
271
  }
264
272
  }
265
273
  }
266
- }
267
- });
274
+ });
275
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentsStopped`));
276
+ await this.logInfo(I18n.formatMessage(`${"engineCore"}.stopped`));
277
+ }
268
278
  await this.stateSave();
269
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.componentsStopped`));
270
- await this.logInfo(I18n.formatMessage(`${"engineCore"}.stopped`));
271
279
  }
272
280
  /**
273
281
  * Is the engine started.
@@ -335,6 +343,12 @@ export class EngineCore {
335
343
  getState() {
336
344
  return this._context.state;
337
345
  }
346
+ /**
347
+ * Set the state to dirty so it gets saved.
348
+ */
349
+ setStateDirty() {
350
+ this._context.stateDirty = true;
351
+ }
338
352
  /**
339
353
  * Get all the registered instances.
340
354
  * @returns The registered instances.
@@ -353,9 +367,14 @@ export class EngineCore {
353
367
  Guards.stringValue(EngineCore.CLASS_NAME, "componentConnectorType", componentConnectorType);
354
368
  const registeredType = this.getRegisteredInstanceTypeOptional(componentConnectorType, features);
355
369
  if (!Is.stringValue(registeredType)) {
370
+ if (Is.arrayValue(features)) {
371
+ throw new GeneralError(EngineCore.CLASS_NAME, "instanceTypeNotFoundWithFeatures", {
372
+ type: componentConnectorType,
373
+ features: features.join(",")
374
+ });
375
+ }
356
376
  throw new GeneralError(EngineCore.CLASS_NAME, "instanceTypeNotFound", {
357
- type: componentConnectorType,
358
- features: (features ?? ["default"]).join(",")
377
+ type: componentConnectorType
359
378
  });
360
379
  }
361
380
  return registeredType;
@@ -406,9 +425,10 @@ export class EngineCore {
406
425
  /**
407
426
  * Populate the engine from the clone data.
408
427
  * @param cloneData The clone data to populate from.
428
+ * @param contextIds The context IDs to use for the clone.
409
429
  * @param silent Should the clone be silent.
410
430
  */
411
- populateClone(cloneData, silent) {
431
+ populateClone(cloneData, contextIds, silent) {
412
432
  Guards.object(EngineCore.CLASS_NAME, "cloneData", cloneData);
413
433
  Guards.object(EngineCore.CLASS_NAME, "cloneData.config", cloneData.config);
414
434
  Guards.object(EngineCore.CLASS_NAME, "cloneData.state", cloneData.state);
@@ -427,6 +447,7 @@ export class EngineCore {
427
447
  };
428
448
  this._typeInitialisers = cloneData.typeInitialisers;
429
449
  this._contextIdKeys.push(...cloneData.contextIdKeys);
450
+ this._contextIds = contextIds;
430
451
  for (const schemaName of Object.keys(cloneData.entitySchemas)) {
431
452
  EntitySchemaFactory.register(schemaName, () => cloneData.entitySchemas[schemaName]);
432
453
  }
@@ -448,15 +469,32 @@ export class EngineCore {
448
469
  componentType: typeKey,
449
470
  configType: typeConfig[i].type
450
471
  }));
451
- const result = await instanceMethod(this, this._context, typeConfig[i]);
452
- if (Is.stringValue(result.instanceType) && Is.object(result.component)) {
453
- const finalInstanceType = typeConfig[i].overrideInstanceType ?? result.instanceType;
454
- this._context.componentInstances.push({
455
- instanceType: finalInstanceType,
456
- component: result.component,
457
- started: false
458
- });
459
- result.factory?.register(finalInstanceType, () => result.component);
472
+ const result = instanceMethod(this, this._context, typeConfig[i]);
473
+ const componentCreateMethod = result.createComponent;
474
+ if (Is.stringValue(result.instanceTypeName) && Is.function(componentCreateMethod)) {
475
+ const finalInstanceType = typeConfig[i].overrideInstanceType ?? result.instanceTypeName;
476
+ // If this is a multi instance component we need to make sure we
477
+ // generate a unique instance for every factory call
478
+ // this is often used for REST clients where each instance might
479
+ // use a different endpoint url
480
+ // They are generated using the create method of factory
481
+ // passing custom options, instead of the regular get method
482
+ // which doesn't allow for custom options
483
+ if (typeConfig[i].isMultiInstance ?? false) {
484
+ result.factory?.register(finalInstanceType, params => componentCreateMethod({
485
+ type: typeConfig[i].type,
486
+ options: params
487
+ }));
488
+ }
489
+ else {
490
+ const component = componentCreateMethod(typeConfig[i]);
491
+ this._context.componentInstances.push({
492
+ instanceType: finalInstanceType,
493
+ component,
494
+ initialised: false
495
+ });
496
+ result.factory?.register(finalInstanceType, () => component);
497
+ }
460
498
  this._context.registeredInstances[typeKey] ??= [];
461
499
  this._context.registeredInstances[typeKey].push({
462
500
  type: finalInstanceType,
@@ -490,7 +528,7 @@ export class EngineCore {
490
528
  this._context.componentInstances.push({
491
529
  instanceType: EngineCore.LOGGING_CONNECTOR_TYPE_NAME,
492
530
  component: engineLoggerConnector,
493
- started: false
531
+ initialised: false
494
532
  });
495
533
  LoggingConnectorFactory.register(EngineCore.LOGGING_CONNECTOR_TYPE_NAME, () => engineLoggerConnector);
496
534
  this._context.registeredInstances.loggingConnector = [
@@ -511,7 +549,6 @@ export class EngineCore {
511
549
  }
512
550
  /**
513
551
  * Load the state.
514
- * @returns True if the state was loaded and can continue.
515
552
  * @internal
516
553
  */
517
554
  async stateLoad() {
@@ -519,18 +556,16 @@ export class EngineCore {
519
556
  try {
520
557
  this._context.state = ((await this._stateStorage.load(this)) ?? {});
521
558
  this._context.stateDirty = false;
522
- return true;
523
559
  }
524
560
  catch (err) {
525
561
  await this.logError(BaseError.fromError(err));
526
- return false;
562
+ throw err;
527
563
  }
528
564
  }
529
- return true;
530
565
  }
531
566
  /**
532
567
  * Save the state.
533
- * @returns True if the state was saved.
568
+ * @returns Nothing.
534
569
  * @internal
535
570
  */
536
571
  async stateSave() {
@@ -538,14 +573,11 @@ export class EngineCore {
538
573
  try {
539
574
  await this._stateStorage.save(this, this._context.state);
540
575
  this._context.stateDirty = false;
541
- return true;
542
576
  }
543
577
  catch (err) {
544
578
  await this.logError(BaseError.fromError(err));
545
579
  }
546
- return false;
547
580
  }
548
- return true;
549
581
  }
550
582
  /**
551
583
  * Bootstrap the engine.
@@ -580,5 +612,18 @@ export class EngineCore {
580
612
  await this.logInfo(I18n.formatMessage(`${"engineCore"}.bootstrapComplete`));
581
613
  }
582
614
  }
615
+ /**
616
+ * Initialise the context ID handlers.
617
+ * @internal
618
+ */
619
+ initialiseContextIdHandlers() {
620
+ for (const contextIdKey of this._contextIdKeys) {
621
+ const handlerType = this.getRegisteredInstanceTypeOptional("contextIdHandlerComponent", contextIdKey.componentFeatures);
622
+ if (Is.stringValue(handlerType)) {
623
+ const handler = ComponentFactory.get(handlerType);
624
+ ContextIdHandlerFactory.register(contextIdKey.key, () => handler);
625
+ }
626
+ }
627
+ }
583
628
  }
584
629
  //# sourceMappingURL=engineCore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"engineCore.js","sourceRoot":"","sources":["../../src/engineCore.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { isMainThread } from \"node:worker_threads\";\nimport { ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tErrorHelper,\n\tGeneralError,\n\tGuards,\n\tI18n,\n\ttype IError,\n\tIs\n} from \"@twin.org/core\";\nimport type {\n\tEngineTypeInitialiser,\n\tIEngineCore,\n\tIEngineCoreClone,\n\tIEngineCoreConfig,\n\tIEngineCoreContext,\n\tIEngineCoreTypeConfig,\n\tIEngineState,\n\tIEngineStateStorage\n} from \"@twin.org/engine-models\";\nimport { EntitySchemaFactory, type IEntitySchema } from \"@twin.org/entity\";\nimport { ConsoleLoggingConnector } from \"@twin.org/logging-connector-console\";\nimport {\n\ttype ILoggingComponent,\n\tLoggingConnectorFactory,\n\tSilentLoggingConnector\n} from \"@twin.org/logging-models\";\nimport { LoggingService } from \"@twin.org/logging-service\";\nimport { ModuleHelper } from \"@twin.org/modules\";\nimport { nameof, nameofCamelCase } from \"@twin.org/nameof\";\nimport type { IEngineCoreOptions } from \"./models/IEngineCoreOptions.js\";\nimport { MemoryStateStorage } from \"./storage/memoryStateStorage.js\";\n\n/**\n * Core for the engine.\n */\nexport class EngineCore<\n\tC extends IEngineCoreConfig = IEngineCoreConfig,\n\tS extends IEngineState = IEngineState\n> implements IEngineCore<C, S>\n{\n\t/**\n\t * Name for the engine logger component, used for direct console logging.\n\t */\n\tpublic static readonly LOGGING_COMPONENT_TYPE_NAME: string = \"engine-logging-service\";\n\n\t/**\n\t * Name for the engine logger connector, used for direct console logging.\n\t */\n\tpublic static readonly LOGGING_CONNECTOR_TYPE_NAME: string = \"engine-logging-connector\";\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<EngineCore>();\n\n\t/**\n\t * The core context.\n\t */\n\tprotected _context: IEngineCoreContext<C, S>;\n\n\t/**\n\t * The context ID keys.\n\t */\n\tprotected readonly _contextIdKeys: string[];\n\n\t/**\n\t * The context IDs.\n\t */\n\tprotected _contextIds?: IContextIds;\n\n\t/**\n\t * The state storage interface.\n\t * @internal\n\t */\n\tprivate _stateStorage?: IEngineStateStorage<S>;\n\n\t/**\n\t * The logging component for the engine.\n\t * @internal\n\t */\n\tprivate _engineLoggingComponent?: ILoggingComponent;\n\n\t/**\n\t * Skip the bootstrap process.\n\t * @internal\n\t */\n\tprivate _skipBootstrap?: boolean;\n\n\t/**\n\t * The type initialisers.\n\t * @internal\n\t */\n\tprivate _typeInitialisers: {\n\t\ttype: string;\n\t\tmodule: string;\n\t\tmethod: string;\n\t}[];\n\n\t/**\n\t * Is the engine started.\n\t * @internal\n\t */\n\tprivate _isStarted: boolean;\n\n\t/**\n\t * Is the engine a clone.\n\t * @internal\n\t */\n\tprivate _isClone: boolean;\n\n\t/**\n\t * Add type initialisers to the engine.\n\t * @internal\n\t */\n\tprivate readonly _populateTypeInitialisers?: (\n\t\tengineCore: IEngineCore<C, S>,\n\t\tcontext: IEngineCoreContext<C, S>\n\t) => void;\n\n\t/**\n\t * Method for bootstrapping any data for the engine.\n\t * @internal\n\t */\n\tprivate readonly _customBootstrap?: (\n\t\tengineCore: IEngineCore<C, S>,\n\t\tcontext: IEngineCoreContext<C, S>\n\t) => Promise<void>;\n\n\t/**\n\t * Create a new instance of EngineCore.\n\t * @param options The options for the engine.\n\t */\n\tconstructor(options?: IEngineCoreOptions<C, S>) {\n\t\toptions = options ?? {};\n\t\toptions.config = options.config ?? ({} as C);\n\t\toptions.config.debug = options.config.debug ?? false;\n\t\toptions.config.silent = options.config.silent ?? false;\n\t\toptions.config.types ??= {};\n\n\t\tthis._skipBootstrap = options.skipBootstrap ?? false;\n\t\tthis._populateTypeInitialisers = options.populateTypeInitialisers;\n\t\tthis._customBootstrap = options.customBootstrap;\n\t\tthis._typeInitialisers = [];\n\t\tthis._contextIdKeys = [];\n\n\t\tthis._context = {\n\t\t\tconfig: options.config,\n\t\t\tregisteredInstances: {},\n\t\t\tcomponentInstances: [],\n\t\t\tstate: {} as S,\n\t\t\tstateDirty: false\n\t\t};\n\t\tthis._stateStorage = options.stateStorage;\n\t\tthis._isStarted = false;\n\t\tthis._isClone = false;\n\n\t\tif (Is.function(this._populateTypeInitialisers)) {\n\t\t\tthis._populateTypeInitialisers(this, this._context);\n\t\t}\n\t}\n\n\t/**\n\t * Add a type initialiser.\n\t * @param type The type to add the initialiser for.\n\t * @param module The name of the module which contains the initialiser method.\n\t * @param method The name of the method to call.\n\t */\n\tpublic addTypeInitialiser(type: string, module: string, method: string): void {\n\t\tGuards.stringValue(EngineCore.CLASS_NAME, nameof(type), type);\n\t\tGuards.stringValue(EngineCore.CLASS_NAME, nameof(module), module);\n\t\tGuards.stringValue(EngineCore.CLASS_NAME, nameof(method), method);\n\n\t\tconst currentIndex = this._typeInitialisers.findIndex(t => t.type === type);\n\t\tif (currentIndex >= 0) {\n\t\t\tthis._typeInitialisers[currentIndex].module = module;\n\t\t\tthis._typeInitialisers[currentIndex].method = method;\n\t\t} else {\n\t\t\tthis._typeInitialisers.push({\n\t\t\t\ttype,\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Get the type config for a specific type.\n\t * @param type The type to get the config for.\n\t * @returns The type config or undefined if not found.\n\t */\n\tpublic getTypeConfig(type: string): IEngineCoreTypeConfig[] | undefined {\n\t\tGuards.stringValue(EngineCore.CLASS_NAME, nameof(type), type);\n\t\treturn this._context.config.types?.[type];\n\t}\n\n\t/**\n\t * Add a context ID key to the engine.\n\t * @param key The context ID key.\n\t */\n\tpublic addContextIdKey(key: string): void {\n\t\tif (!this._contextIdKeys.includes(key)) {\n\t\t\tthis._contextIdKeys.push(key);\n\t\t}\n\t}\n\n\t/**\n\t * Get the context ID keys for the engine.\n\t * @returns The context IDs keys.\n\t */\n\tpublic getContextIdKeys(): string[] {\n\t\treturn this._contextIdKeys;\n\t}\n\n\t/**\n\t * Add a context ID to the engine.\n\t * @param key The context ID key.\n\t * @param value The context ID value.\n\t */\n\tpublic addContextId(key: string, value: string): void {\n\t\tthis._contextIds ??= {};\n\t\tthis._contextIds[key] = value;\n\t}\n\n\t/**\n\t * Get the context IDs for the engine.\n\t * @returns The context IDs or undefined if none are set.\n\t */\n\tpublic getContextIds(): IContextIds | undefined {\n\t\treturn this._contextIds;\n\t}\n\n\t/**\n\t * Start the engine core.\n\t * @returns True if the start was successful.\n\t */\n\tpublic async start(): Promise<boolean> {\n\t\tif (this._isStarted) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.setupEngineLogger();\n\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.starting`));\n\n\t\tif (this._context.config.debug) {\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.debuggingEnabled`));\n\t\t}\n\n\t\tlet canContinue;\n\t\ttry {\n\t\t\tcanContinue = await this.stateLoad();\n\n\t\t\tif (canContinue) {\n\t\t\t\tfor (const { type, module, method } of this._typeInitialisers) {\n\t\t\t\t\tawait this.initialiseTypeConfig(type, module, method);\n\t\t\t\t}\n\n\t\t\t\tawait this.bootstrap();\n\n\t\t\t\tawait this.logInfo(\n\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentsStarting`)\n\t\t\t\t);\n\n\t\t\t\tawait ContextIdStore.run(this._contextIds ?? {}, async () => {\n\t\t\t\t\tfor (const instance of this._context.componentInstances) {\n\t\t\t\t\t\tif (!instance.started) {\n\t\t\t\t\t\t\tconst startMethod = instance.component.start?.bind(instance.component);\n\t\t\t\t\t\t\tif (Is.function(startMethod)) {\n\t\t\t\t\t\t\t\tawait this.logInfo(\n\t\t\t\t\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentStarting`, {\n\t\t\t\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait startMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);\n\n\t\t\t\t\t\t\t\t\tinstance.started = true;\n\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\tawait this.logError(\n\t\t\t\t\t\t\t\t\t\tnew GeneralError(\n\t\t\t\t\t\t\t\t\t\t\tEngineCore.CLASS_NAME,\n\t\t\t\t\t\t\t\t\t\t\t\"componentStartFailed\",\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tBaseError.fromError(err)\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tawait this.logInfo(\n\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentsComplete`)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.started`));\n\t\t\tthis._isStarted = true;\n\t\t} catch (err) {\n\t\t\tcanContinue = false;\n\t\t\tawait this.logError(BaseError.fromError(err));\n\t\t} finally {\n\t\t\tif (!(await this.stateSave())) {\n\t\t\t\tcanContinue = false;\n\t\t\t}\n\t\t}\n\n\t\tif (!canContinue) {\n\t\t\tawait this.stop();\n\t\t}\n\n\t\treturn canContinue;\n\t}\n\n\t/**\n\t * Stop the engine core.\n\t * @returns Nothing.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.stopping`));\n\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentsStopping`));\n\n\t\tawait ContextIdStore.run(this._contextIds ?? {}, async () => {\n\t\t\tfor (const instance of this._context.componentInstances) {\n\t\t\t\tif (instance.started) {\n\t\t\t\t\tinstance.started = false;\n\t\t\t\t\tconst stopMethod = instance.component.stop?.bind(instance.component);\n\t\t\t\t\tif (Is.function(stopMethod)) {\n\t\t\t\t\t\tawait this.logInfo(\n\t\t\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentStopping`, {\n\t\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait stopMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tawait this.logError(\n\t\t\t\t\t\t\t\tnew GeneralError(\n\t\t\t\t\t\t\t\t\tEngineCore.CLASS_NAME,\n\t\t\t\t\t\t\t\t\t\"componentStopFailed\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tBaseError.fromError(err)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait this.stateSave();\n\n\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentsStopped`));\n\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.stopped`));\n\t}\n\n\t/**\n\t * Is the engine started.\n\t * @returns True if the engine is started.\n\t */\n\tpublic isStarted(): boolean {\n\t\treturn this._isStarted;\n\t}\n\n\t/**\n\t * Is this the primary engine instance.\n\t * @returns True if the engine is the primary instance.\n\t */\n\tpublic isPrimary(): boolean {\n\t\treturn isMainThread && !this._isClone;\n\t}\n\n\t/**\n\t * Is this engine instance a clone.\n\t * @returns True if the engine instance is a clone.\n\t */\n\tpublic isClone(): boolean {\n\t\treturn this._isClone;\n\t}\n\n\t/**\n\t * Log info.\n\t * @param message The message to log.\n\t */\n\tpublic async logInfo(message: string): Promise<void> {\n\t\tawait this._engineLoggingComponent?.log({\n\t\t\tsource: EngineCore.CLASS_NAME,\n\t\t\tlevel: \"info\",\n\t\t\tmessage\n\t\t});\n\t}\n\n\t/**\n\t * Log error.\n\t * @param error The error to log.\n\t */\n\tpublic async logError(error: IError): Promise<void> {\n\t\tconst formattedErrors = ErrorHelper.localizeErrors(error);\n\t\tfor (const formattedError of formattedErrors) {\n\t\t\tlet message = Is.stringValue(formattedError.source)\n\t\t\t\t? `${formattedError.source}: ${formattedError.message}`\n\t\t\t\t: formattedError.message;\n\t\t\tif (this._context.config.debug && Is.stringValue(formattedError.stack)) {\n\t\t\t\tmessage += `\\n${formattedError.stack}`;\n\t\t\t}\n\t\t\tawait this._engineLoggingComponent?.log({\n\t\t\t\tsource: EngineCore.CLASS_NAME,\n\t\t\t\tlevel: \"error\",\n\t\t\t\tmessage\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Get the config for the engine.\n\t * @returns The config for the engine.\n\t */\n\tpublic getConfig(): C {\n\t\treturn this._context.config;\n\t}\n\n\t/**\n\t * Get the state of the engine.\n\t * @returns The state of the engine.\n\t */\n\tpublic getState(): S {\n\t\treturn this._context.state;\n\t}\n\n\t/**\n\t * Get all the registered instances.\n\t * @returns The registered instances.\n\t */\n\tpublic getRegisteredInstances(): {\n\t\t[name: string]: {\n\t\t\ttype: string;\n\t\t\tisDefault?: boolean;\n\t\t\tfeatures?: string[];\n\t\t}[];\n\t} {\n\t\treturn this._context.registeredInstances;\n\t}\n\n\t/**\n\t * Get the registered instance type for the component/connector.\n\t * @param componentConnectorType The type of the component/connector.\n\t * @param features The requested features of the component, if not specified the default entry will be retrieved.\n\t * @returns The instance type matching the criteria if one is registered.\n\t * @throws If a matching instance was not found.\n\t */\n\tpublic getRegisteredInstanceType(componentConnectorType: string, features?: string[]): string {\n\t\tGuards.stringValue(\n\t\t\tEngineCore.CLASS_NAME,\n\t\t\tnameof(componentConnectorType),\n\t\t\tcomponentConnectorType\n\t\t);\n\n\t\tconst registeredType = this.getRegisteredInstanceTypeOptional(componentConnectorType, features);\n\n\t\tif (!Is.stringValue(registeredType)) {\n\t\t\tthrow new GeneralError(EngineCore.CLASS_NAME, \"instanceTypeNotFound\", {\n\t\t\t\ttype: componentConnectorType,\n\t\t\t\tfeatures: (features ?? [\"default\"]).join(\",\")\n\t\t\t});\n\t\t}\n\n\t\treturn registeredType;\n\t}\n\n\t/**\n\t * Get the registered instance type for the component/connector if it exists.\n\t * @param componentConnectorType The type of the component/connector.\n\t * @param features The requested features of the component, if not specified the default entry will be retrieved.\n\t * @returns The instance type matching the criteria if one is registered.\n\t */\n\tpublic getRegisteredInstanceTypeOptional(\n\t\tcomponentConnectorType: string,\n\t\tfeatures?: string[]\n\t): string | undefined {\n\t\tlet registeredType: string | undefined;\n\n\t\tconst registeredTypes = this._context.registeredInstances[componentConnectorType];\n\t\tif (Is.arrayValue(registeredTypes)) {\n\t\t\tif (Is.arrayValue(features)) {\n\t\t\t\tregisteredType = registeredTypes.find(t =>\n\t\t\t\t\tt.features?.every(f => features.includes(f))\n\t\t\t\t)?.type;\n\t\t\t} else {\n\t\t\t\t// First look for the default entry\n\t\t\t\tregisteredType = registeredTypes.find(t => t.isDefault)?.type;\n\n\t\t\t\t// Can't find a default so just use the first entry\n\t\t\t\tif (!Is.stringValue(registeredType)) {\n\t\t\t\t\tregisteredType = registeredTypes[0]?.type;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn registeredType;\n\t}\n\n\t/**\n\t * Get the data required to create a clone of the engine.\n\t * @returns The clone data.\n\t */\n\tpublic getCloneData(): IEngineCoreClone<C, S> {\n\t\tconst entitySchemas: {\n\t\t\t[schema: string]: IEntitySchema;\n\t\t} = {};\n\n\t\tconst entitySchemaNames = EntitySchemaFactory.names();\n\t\tfor (const schemaName of entitySchemaNames) {\n\t\t\tentitySchemas[schemaName] = EntitySchemaFactory.get(schemaName);\n\t\t}\n\n\t\tconst cloneData: IEngineCoreClone<C, S> = {\n\t\t\tconfig: this._context.config,\n\t\t\tstate: this._context.state,\n\t\t\ttypeInitialisers: this._typeInitialisers,\n\t\t\tentitySchemas,\n\t\t\tcontextIdKeys: this._contextIdKeys\n\t\t};\n\n\t\treturn cloneData;\n\t}\n\n\t/**\n\t * Populate the engine from the clone data.\n\t * @param cloneData The clone data to populate from.\n\t * @param silent Should the clone be silent.\n\t */\n\tpublic populateClone(cloneData: IEngineCoreClone<C, S>, silent?: boolean): void {\n\t\tGuards.object(EngineCore.CLASS_NAME, nameof(cloneData), cloneData);\n\t\tGuards.object(EngineCore.CLASS_NAME, nameof(cloneData.config), cloneData.config);\n\t\tGuards.object(EngineCore.CLASS_NAME, nameof(cloneData.state), cloneData.state);\n\t\tGuards.array(\n\t\t\tEngineCore.CLASS_NAME,\n\t\t\tnameof(cloneData.typeInitialisers),\n\t\t\tcloneData.typeInitialisers\n\t\t);\n\n\t\tthis._skipBootstrap = true;\n\t\tthis._isClone = true;\n\n\t\tif (silent ?? false) {\n\t\t\tcloneData.config.silent = true;\n\t\t}\n\n\t\tthis._context = {\n\t\t\tconfig: cloneData.config,\n\t\t\tregisteredInstances: {},\n\t\t\tcomponentInstances: [],\n\t\t\tstate: {} as S,\n\t\t\tstateDirty: false\n\t\t};\n\n\t\tthis._typeInitialisers = cloneData.typeInitialisers;\n\t\tthis._contextIdKeys.push(...cloneData.contextIdKeys);\n\n\t\tfor (const schemaName of Object.keys(cloneData.entitySchemas)) {\n\t\t\tEntitySchemaFactory.register(schemaName, () => cloneData.entitySchemas[schemaName]);\n\t\t}\n\n\t\tthis._stateStorage = new MemoryStateStorage(true, cloneData.state);\n\t\tthis._isStarted = false;\n\t}\n\n\t/**\n\t * Initialise the types from connector.\n\t * @param typeKey The key for the default types.\n\t * @param instanceMethod The function to initialise the instance.\n\t * @internal\n\t */\n\tprivate async initialiseTypeConfig(\n\t\ttypeKey: string,\n\t\tmodule: string,\n\t\tmethod: string\n\t): Promise<void> {\n\t\tconst typeConfig: IEngineCoreTypeConfig[] | undefined = this._context.config.types?.[typeKey];\n\n\t\tif (Is.arrayValue(typeConfig)) {\n\t\t\tconst instanceMethod = await ModuleHelper.getModuleEntry<EngineTypeInitialiser>(\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t);\n\n\t\t\tfor (let i = 0; i < typeConfig.length; i++) {\n\t\t\t\tawait this.logInfo(\n\t\t\t\t\tI18n.formatMessage(\"engineCore.configuring\", {\n\t\t\t\t\t\tcomponentType: typeKey,\n\t\t\t\t\t\tconfigType: typeConfig[i].type\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tconst result = await instanceMethod(this, this._context, typeConfig[i]);\n\n\t\t\t\tif (Is.stringValue(result.instanceType) && Is.object(result.component)) {\n\t\t\t\t\tconst finalInstanceType = typeConfig[i].overrideInstanceType ?? result.instanceType;\n\t\t\t\t\tthis._context.componentInstances.push({\n\t\t\t\t\t\tinstanceType: finalInstanceType,\n\t\t\t\t\t\tcomponent: result.component,\n\t\t\t\t\t\tstarted: false\n\t\t\t\t\t});\n\n\t\t\t\t\tresult.factory?.register(finalInstanceType, () => result.component);\n\n\t\t\t\t\tthis._context.registeredInstances[typeKey] ??= [];\n\n\t\t\t\t\tthis._context.registeredInstances[typeKey].push({\n\t\t\t\t\t\ttype: finalInstanceType,\n\t\t\t\t\t\tisDefault: typeConfig[i].isDefault,\n\t\t\t\t\t\tfeatures: typeConfig[i].features\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthrow new GeneralError(\"engineCore\", \"componentUnknownType\", {\n\t\t\t\t\t\ttype: typeConfig[i].type,\n\t\t\t\t\t\tcomponentType: typeKey\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Setup the engine logger.\n\t * @internal\n\t */\n\tprivate setupEngineLogger(): void {\n\t\tconst silent = this._context.config.silent ?? false;\n\t\tconst engineLoggerConnector = silent\n\t\t\t? new SilentLoggingConnector()\n\t\t\t: new ConsoleLoggingConnector({\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\ttranslateMessages: true,\n\t\t\t\t\t\thideGroups: true\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\tthis._context.componentInstances.push({\n\t\t\tinstanceType: EngineCore.LOGGING_CONNECTOR_TYPE_NAME,\n\t\t\tcomponent: engineLoggerConnector,\n\t\t\tstarted: false\n\t\t});\n\n\t\tLoggingConnectorFactory.register(\n\t\t\tEngineCore.LOGGING_CONNECTOR_TYPE_NAME,\n\t\t\t() => engineLoggerConnector\n\t\t);\n\n\t\tthis._context.registeredInstances.loggingConnector = [\n\t\t\t{\n\t\t\t\ttype: EngineCore.LOGGING_CONNECTOR_TYPE_NAME\n\t\t\t}\n\t\t];\n\n\t\tconst engineLoggerComponent = new LoggingService({\n\t\t\tloggingConnectorType: EngineCore.LOGGING_CONNECTOR_TYPE_NAME\n\t\t});\n\t\tthis._engineLoggingComponent = engineLoggerComponent;\n\n\t\tComponentFactory.register(EngineCore.LOGGING_COMPONENT_TYPE_NAME, () => engineLoggerComponent);\n\t\tthis._context.registeredInstances.loggingComponent = [\n\t\t\t{\n\t\t\t\ttype: EngineCore.LOGGING_COMPONENT_TYPE_NAME\n\t\t\t}\n\t\t];\n\t}\n\n\t/**\n\t * Load the state.\n\t * @returns True if the state was loaded and can continue.\n\t * @internal\n\t */\n\tprivate async stateLoad(): Promise<boolean> {\n\t\tif (this._stateStorage) {\n\t\t\ttry {\n\t\t\t\tthis._context.state = ((await this._stateStorage.load(this)) ?? {}) as S;\n\t\t\t\tthis._context.stateDirty = false;\n\n\t\t\t\treturn true;\n\t\t\t} catch (err) {\n\t\t\t\tawait this.logError(BaseError.fromError(err));\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Save the state.\n\t * @returns True if the state was saved.\n\t * @internal\n\t */\n\tprivate async stateSave(): Promise<boolean> {\n\t\tif (this._stateStorage && !Is.empty(this._context.state) && this._context.stateDirty) {\n\t\t\ttry {\n\t\t\t\tawait this._stateStorage.save(this, this._context.state);\n\t\t\t\tthis._context.stateDirty = false;\n\t\t\t\treturn true;\n\t\t\t} catch (err) {\n\t\t\t\tawait this.logError(BaseError.fromError(err));\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Bootstrap the engine.\n\t * @internal\n\t */\n\tprivate async bootstrap(): Promise<void> {\n\t\tif (!this._skipBootstrap) {\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.bootstrapStarted`));\n\n\t\t\t// First bootstrap the components.\n\t\t\tfor (const instance of this._context.componentInstances) {\n\t\t\t\tconst bootstrapMethod = instance.component.bootstrap?.bind(instance.component);\n\t\t\t\tif (Is.function(bootstrapMethod)) {\n\t\t\t\t\tawait this.logInfo(\n\t\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.bootstrapping`, {\n\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\n\t\t\t\t\tconst bootstrapSuccess = await bootstrapMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);\n\n\t\t\t\t\t// If the bootstrap method failed then throw an error\n\t\t\t\t\tif (!bootstrapSuccess) {\n\t\t\t\t\t\tthrow new GeneralError(EngineCore.CLASS_NAME, \"bootstrapFailed\", {\n\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Now perform any custom bootstrap operations\n\t\t\tconst customBootstrap = this._customBootstrap;\n\t\t\tif (Is.function(customBootstrap)) {\n\t\t\t\tawait customBootstrap.call(this, this, this._context);\n\t\t\t}\n\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.bootstrapComplete`));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"engineCore.js","sourceRoot":"","sources":["../../src/engineCore.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { isMainThread } from \"node:worker_threads\";\nimport {\n\tContextIdHandlerFactory,\n\tContextIdStore,\n\ttype IContextIdHandler,\n\ttype IContextIds\n} from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tErrorHelper,\n\tGeneralError,\n\tGuards,\n\tI18n,\n\ttype IError,\n\tIs\n} from \"@twin.org/core\";\nimport type {\n\tEngineTypeInitialiser,\n\tIEngineCore,\n\tIEngineCoreClone,\n\tIEngineCoreConfig,\n\tIEngineCoreContext,\n\tIEngineCoreTypeConfig,\n\tIEngineState,\n\tIEngineStateStorage\n} from \"@twin.org/engine-models\";\nimport { EntitySchemaFactory, type IEntitySchema } from \"@twin.org/entity\";\nimport { ConsoleLoggingConnector } from \"@twin.org/logging-connector-console\";\nimport {\n\ttype ILoggingComponent,\n\tLoggingConnectorFactory,\n\tSilentLoggingConnector\n} from \"@twin.org/logging-models\";\nimport { LoggingService } from \"@twin.org/logging-service\";\nimport { ModuleHelper } from \"@twin.org/modules\";\nimport { nameof, nameofCamelCase } from \"@twin.org/nameof\";\nimport type { IEngineCoreOptions } from \"./models/IEngineCoreOptions.js\";\nimport { MemoryStateStorage } from \"./storage/memoryStateStorage.js\";\n\n/**\n * Core for the engine.\n */\nexport class EngineCore<\n\tC extends IEngineCoreConfig = IEngineCoreConfig,\n\tS extends IEngineState = IEngineState\n> implements IEngineCore<C, S>\n{\n\t/**\n\t * Name for the engine logger component, used for direct console logging.\n\t */\n\tpublic static readonly LOGGING_COMPONENT_TYPE_NAME: string = \"engine-logging-service\";\n\n\t/**\n\t * Name for the engine logger connector, used for direct console logging.\n\t */\n\tpublic static readonly LOGGING_CONNECTOR_TYPE_NAME: string = \"engine-logging-connector\";\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<EngineCore>();\n\n\t/**\n\t * The core context.\n\t */\n\tprotected _context: IEngineCoreContext<C, S>;\n\n\t/**\n\t * The context ID keys.\n\t */\n\tprotected readonly _contextIdKeys: { key: string; componentFeatures: string[] }[];\n\n\t/**\n\t * The context IDs.\n\t */\n\tprotected _contextIds?: IContextIds;\n\n\t/**\n\t * The state storage interface.\n\t * @internal\n\t */\n\tprivate _stateStorage?: IEngineStateStorage<S>;\n\n\t/**\n\t * The logging component for the engine.\n\t * @internal\n\t */\n\tprivate _engineLoggingComponent?: ILoggingComponent;\n\n\t/**\n\t * Skip the bootstrap process.\n\t * @internal\n\t */\n\tprivate _skipBootstrap?: boolean;\n\n\t/**\n\t * The type initialisers.\n\t * @internal\n\t */\n\tprivate _typeInitialisers: {\n\t\ttype: string;\n\t\tmodule: string;\n\t\tmethod: string;\n\t}[];\n\n\t/**\n\t * Is the engine started.\n\t * @internal\n\t */\n\tprivate _isStarted: boolean;\n\n\t/**\n\t * Is the engine a clone.\n\t * @internal\n\t */\n\tprivate _isClone: boolean;\n\n\t/**\n\t * Add type initialisers to the engine.\n\t * @internal\n\t */\n\tprivate readonly _populateTypeInitialisers?: (\n\t\tengineCore: IEngineCore<C, S>,\n\t\tcontext: IEngineCoreContext<C, S>\n\t) => void;\n\n\t/**\n\t * Method for bootstrapping any data for the engine.\n\t * @internal\n\t */\n\tprivate readonly _customBootstrap?: (\n\t\tengineCore: IEngineCore<C, S>,\n\t\tcontext: IEngineCoreContext<C, S>\n\t) => Promise<void>;\n\n\t/**\n\t * Create a new instance of EngineCore.\n\t * @param options The options for the engine.\n\t */\n\tconstructor(options?: IEngineCoreOptions<C, S>) {\n\t\toptions = options ?? {};\n\t\toptions.config = options.config ?? ({} as C);\n\t\toptions.config.debug = options.config.debug ?? false;\n\t\toptions.config.silent = options.config.silent ?? false;\n\t\toptions.config.types ??= {};\n\n\t\tthis._skipBootstrap = options.skipBootstrap ?? false;\n\t\tthis._populateTypeInitialisers = options.populateTypeInitialisers;\n\t\tthis._customBootstrap = options.customBootstrap;\n\t\tthis._typeInitialisers = [];\n\t\tthis._contextIdKeys = [];\n\n\t\tthis._context = {\n\t\t\tconfig: options.config,\n\t\t\tregisteredInstances: {},\n\t\t\tcomponentInstances: [],\n\t\t\tstate: {} as S,\n\t\t\tstateDirty: false\n\t\t};\n\t\tthis._stateStorage = options.stateStorage;\n\t\tthis._isStarted = false;\n\t\tthis._isClone = false;\n\n\t\tif (Is.function(this._populateTypeInitialisers)) {\n\t\t\tthis._populateTypeInitialisers(this, this._context);\n\t\t}\n\t}\n\n\t/**\n\t * Add a type initialiser.\n\t * @param type The type to add the initialiser for.\n\t * @param module The name of the module which contains the initialiser method.\n\t * @param method The name of the method to call.\n\t */\n\tpublic addTypeInitialiser(type: string, module: string, method: string): void {\n\t\tGuards.stringValue(EngineCore.CLASS_NAME, nameof(type), type);\n\t\tGuards.stringValue(EngineCore.CLASS_NAME, nameof(module), module);\n\t\tGuards.stringValue(EngineCore.CLASS_NAME, nameof(method), method);\n\n\t\tconst currentIndex = this._typeInitialisers.findIndex(t => t.type === type);\n\t\tif (currentIndex >= 0) {\n\t\t\tthis._typeInitialisers[currentIndex].module = module;\n\t\t\tthis._typeInitialisers[currentIndex].method = method;\n\t\t} else {\n\t\t\tthis._typeInitialisers.push({\n\t\t\t\ttype,\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Get the type config for a specific type.\n\t * @param type The type to get the config for.\n\t * @returns The type config or undefined if not found.\n\t */\n\tpublic getTypeConfig(type: string): IEngineCoreTypeConfig[] | undefined {\n\t\tGuards.stringValue(EngineCore.CLASS_NAME, nameof(type), type);\n\t\treturn this._context.config.types?.[type];\n\t}\n\n\t/**\n\t * Add a context ID key to the engine.\n\t * @param key The context ID key.\n\t * @param componentFeatures The component features for the context ID handler.\n\t */\n\tpublic addContextIdKey(key: string, componentFeatures: string[]): void {\n\t\tconst exists = this._contextIdKeys.find(k => k.key === key);\n\t\tif (Is.empty(exists)) {\n\t\t\tthis._contextIdKeys.push({ key, componentFeatures });\n\t\t}\n\t}\n\n\t/**\n\t * Get the context ID keys for the engine.\n\t * @returns The context IDs keys.\n\t */\n\tpublic getContextIdKeys(): string[] {\n\t\treturn this._contextIdKeys.map(k => k.key);\n\t}\n\n\t/**\n\t * Add a context ID to the engine.\n\t * @param key The context ID key.\n\t * @param value The context ID value.\n\t */\n\tpublic addContextId(key: string, value: string): void {\n\t\tthis._contextIds ??= {};\n\t\tthis._contextIds[key] = value;\n\t}\n\n\t/**\n\t * Get the context IDs for the engine.\n\t * @returns The context IDs or undefined if none are set.\n\t */\n\tpublic getContextIds(): IContextIds | undefined {\n\t\treturn this._contextIds;\n\t}\n\n\t/**\n\t * Start the engine core.\n\t * @param skipComponentStart Should the component start be skipped.\n\t * @returns Nothing.\n\t */\n\tpublic async start(skipComponentStart?: boolean): Promise<void> {\n\t\tif (!this._isStarted) {\n\t\t\tthis.setupEngineLogger();\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.starting`));\n\n\t\t\tif (this._context.config.debug) {\n\t\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.debuggingEnabled`));\n\t\t\t}\n\n\t\t\tconst skipComponent = skipComponentStart ?? false;\n\t\t\ttry {\n\t\t\t\tawait this.stateLoad();\n\n\t\t\t\tfor (const { type, module, method } of this._typeInitialisers) {\n\t\t\t\t\tawait this.initialiseTypeConfig(type, module, method);\n\t\t\t\t}\n\n\t\t\t\tthis.initialiseContextIdHandlers();\n\n\t\t\t\tawait this.bootstrap();\n\n\t\t\t\tthis._isStarted = true;\n\n\t\t\t\tif (!skipComponent) {\n\t\t\t\t\tawait this.logInfo(\n\t\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentsStarting`)\n\t\t\t\t\t);\n\n\t\t\t\t\tawait ContextIdStore.run(this._contextIds ?? {}, async () => {\n\t\t\t\t\t\tfor (const instance of this._context.componentInstances) {\n\t\t\t\t\t\t\tif (!instance.initialised) {\n\t\t\t\t\t\t\t\tinstance.initialised = true;\n\n\t\t\t\t\t\t\t\tconst startMethod = instance.component.start?.bind(instance.component);\n\t\t\t\t\t\t\t\tif (Is.function(startMethod)) {\n\t\t\t\t\t\t\t\t\tawait this.logInfo(\n\t\t\t\t\t\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentStarting`, {\n\t\t\t\t\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tawait startMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\tawait this.logError(\n\t\t\t\t\t\t\t\t\t\t\tnew GeneralError(\n\t\t\t\t\t\t\t\t\t\t\t\tEngineCore.CLASS_NAME,\n\t\t\t\t\t\t\t\t\t\t\t\t\"componentStartFailed\",\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tBaseError.fromError(err)\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tawait this.logInfo(\n\t\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentsComplete`)\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t// If we are skipping component start then just mark them as initialised\n\t\t\t\t\t// we still need to be able to call stop on them to clean up\n\t\t\t\t\tfor (const instance of this._context.componentInstances) {\n\t\t\t\t\t\tinstance.initialised = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.started`));\n\t\t\t} catch (err) {\n\t\t\t\tawait this.stop();\n\t\t\t\tawait this.logError(BaseError.fromError(err));\n\t\t\t\tthrow err;\n\t\t\t} finally {\n\t\t\t\tawait this.stateSave();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stop the engine core.\n\t * @returns Nothing.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tif (this._isStarted) {\n\t\t\tthis._isStarted = false;\n\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.stopping`));\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentsStopping`));\n\n\t\t\tawait ContextIdStore.run(this._contextIds ?? {}, async () => {\n\t\t\t\tfor (const instance of this._context.componentInstances) {\n\t\t\t\t\tif (instance.initialised) {\n\t\t\t\t\t\tinstance.initialised = false;\n\t\t\t\t\t\tconst stopMethod = instance.component.stop?.bind(instance.component);\n\t\t\t\t\t\tif (Is.function(stopMethod)) {\n\t\t\t\t\t\t\tawait this.logInfo(\n\t\t\t\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentStopping`, {\n\t\t\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait stopMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\tawait this.logError(\n\t\t\t\t\t\t\t\t\tnew GeneralError(\n\t\t\t\t\t\t\t\t\t\tEngineCore.CLASS_NAME,\n\t\t\t\t\t\t\t\t\t\t\"componentStopFailed\",\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tBaseError.fromError(err)\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.componentsStopped`));\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.stopped`));\n\t\t}\n\n\t\tawait this.stateSave();\n\t}\n\n\t/**\n\t * Is the engine started.\n\t * @returns True if the engine is started.\n\t */\n\tpublic isStarted(): boolean {\n\t\treturn this._isStarted;\n\t}\n\n\t/**\n\t * Is this the primary engine instance.\n\t * @returns True if the engine is the primary instance.\n\t */\n\tpublic isPrimary(): boolean {\n\t\treturn isMainThread && !this._isClone;\n\t}\n\n\t/**\n\t * Is this engine instance a clone.\n\t * @returns True if the engine instance is a clone.\n\t */\n\tpublic isClone(): boolean {\n\t\treturn this._isClone;\n\t}\n\n\t/**\n\t * Log info.\n\t * @param message The message to log.\n\t */\n\tpublic async logInfo(message: string): Promise<void> {\n\t\tawait this._engineLoggingComponent?.log({\n\t\t\tsource: EngineCore.CLASS_NAME,\n\t\t\tlevel: \"info\",\n\t\t\tmessage\n\t\t});\n\t}\n\n\t/**\n\t * Log error.\n\t * @param error The error to log.\n\t */\n\tpublic async logError(error: IError): Promise<void> {\n\t\tconst formattedErrors = ErrorHelper.localizeErrors(error);\n\t\tfor (const formattedError of formattedErrors) {\n\t\t\tlet message = Is.stringValue(formattedError.source)\n\t\t\t\t? `${formattedError.source}: ${formattedError.message}`\n\t\t\t\t: formattedError.message;\n\t\t\tif (this._context.config.debug && Is.stringValue(formattedError.stack)) {\n\t\t\t\tmessage += `\\n${formattedError.stack}`;\n\t\t\t}\n\t\t\tawait this._engineLoggingComponent?.log({\n\t\t\t\tsource: EngineCore.CLASS_NAME,\n\t\t\t\tlevel: \"error\",\n\t\t\t\tmessage\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Get the config for the engine.\n\t * @returns The config for the engine.\n\t */\n\tpublic getConfig(): C {\n\t\treturn this._context.config;\n\t}\n\n\t/**\n\t * Get the state of the engine.\n\t * @returns The state of the engine.\n\t */\n\tpublic getState(): S {\n\t\treturn this._context.state;\n\t}\n\n\t/**\n\t * Set the state to dirty so it gets saved.\n\t */\n\tpublic setStateDirty(): void {\n\t\tthis._context.stateDirty = true;\n\t}\n\n\t/**\n\t * Get all the registered instances.\n\t * @returns The registered instances.\n\t */\n\tpublic getRegisteredInstances(): {\n\t\t[name: string]: {\n\t\t\ttype: string;\n\t\t\tisDefault?: boolean;\n\t\t\tfeatures?: string[];\n\t\t}[];\n\t} {\n\t\treturn this._context.registeredInstances;\n\t}\n\n\t/**\n\t * Get the registered instance type for the component/connector.\n\t * @param componentConnectorType The type of the component/connector.\n\t * @param features The requested features of the component, if not specified the default entry will be retrieved.\n\t * @returns The instance type matching the criteria if one is registered.\n\t * @throws If a matching instance was not found.\n\t */\n\tpublic getRegisteredInstanceType(componentConnectorType: string, features?: string[]): string {\n\t\tGuards.stringValue(\n\t\t\tEngineCore.CLASS_NAME,\n\t\t\tnameof(componentConnectorType),\n\t\t\tcomponentConnectorType\n\t\t);\n\n\t\tconst registeredType = this.getRegisteredInstanceTypeOptional(componentConnectorType, features);\n\n\t\tif (!Is.stringValue(registeredType)) {\n\t\t\tif (Is.arrayValue(features)) {\n\t\t\t\tthrow new GeneralError(EngineCore.CLASS_NAME, \"instanceTypeNotFoundWithFeatures\", {\n\t\t\t\t\ttype: componentConnectorType,\n\t\t\t\t\tfeatures: features.join(\",\")\n\t\t\t\t});\n\t\t\t}\n\t\t\tthrow new GeneralError(EngineCore.CLASS_NAME, \"instanceTypeNotFound\", {\n\t\t\t\ttype: componentConnectorType\n\t\t\t});\n\t\t}\n\n\t\treturn registeredType;\n\t}\n\n\t/**\n\t * Get the registered instance type for the component/connector if it exists.\n\t * @param componentConnectorType The type of the component/connector.\n\t * @param features The requested features of the component, if not specified the default entry will be retrieved.\n\t * @returns The instance type matching the criteria if one is registered.\n\t */\n\tpublic getRegisteredInstanceTypeOptional(\n\t\tcomponentConnectorType: string,\n\t\tfeatures?: string[]\n\t): string | undefined {\n\t\tlet registeredType: string | undefined;\n\n\t\tconst registeredTypes = this._context.registeredInstances[componentConnectorType];\n\t\tif (Is.arrayValue(registeredTypes)) {\n\t\t\tif (Is.arrayValue(features)) {\n\t\t\t\tregisteredType = registeredTypes.find(t =>\n\t\t\t\t\tt.features?.every(f => features.includes(f))\n\t\t\t\t)?.type;\n\t\t\t} else {\n\t\t\t\t// First look for the default entry\n\t\t\t\tregisteredType = registeredTypes.find(t => t.isDefault)?.type;\n\n\t\t\t\t// Can't find a default so just use the first entry\n\t\t\t\tif (!Is.stringValue(registeredType)) {\n\t\t\t\t\tregisteredType = registeredTypes[0]?.type;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn registeredType;\n\t}\n\n\t/**\n\t * Get the data required to create a clone of the engine.\n\t * @returns The clone data.\n\t */\n\tpublic getCloneData(): IEngineCoreClone<C, S> {\n\t\tconst entitySchemas: {\n\t\t\t[schema: string]: IEntitySchema;\n\t\t} = {};\n\n\t\tconst entitySchemaNames = EntitySchemaFactory.names();\n\t\tfor (const schemaName of entitySchemaNames) {\n\t\t\tentitySchemas[schemaName] = EntitySchemaFactory.get(schemaName);\n\t\t}\n\n\t\tconst cloneData: IEngineCoreClone<C, S> = {\n\t\t\tconfig: this._context.config,\n\t\t\tstate: this._context.state,\n\t\t\ttypeInitialisers: this._typeInitialisers,\n\t\t\tentitySchemas,\n\t\t\tcontextIdKeys: this._contextIdKeys\n\t\t};\n\n\t\treturn cloneData;\n\t}\n\n\t/**\n\t * Populate the engine from the clone data.\n\t * @param cloneData The clone data to populate from.\n\t * @param contextIds The context IDs to use for the clone.\n\t * @param silent Should the clone be silent.\n\t */\n\tpublic populateClone(\n\t\tcloneData: IEngineCoreClone<C, S>,\n\t\tcontextIds?: IContextIds,\n\t\tsilent?: boolean\n\t): void {\n\t\tGuards.object(EngineCore.CLASS_NAME, nameof(cloneData), cloneData);\n\t\tGuards.object(EngineCore.CLASS_NAME, nameof(cloneData.config), cloneData.config);\n\t\tGuards.object(EngineCore.CLASS_NAME, nameof(cloneData.state), cloneData.state);\n\t\tGuards.array(\n\t\t\tEngineCore.CLASS_NAME,\n\t\t\tnameof(cloneData.typeInitialisers),\n\t\t\tcloneData.typeInitialisers\n\t\t);\n\n\t\tthis._skipBootstrap = true;\n\t\tthis._isClone = true;\n\n\t\tif (silent ?? false) {\n\t\t\tcloneData.config.silent = true;\n\t\t}\n\n\t\tthis._context = {\n\t\t\tconfig: cloneData.config,\n\t\t\tregisteredInstances: {},\n\t\t\tcomponentInstances: [],\n\t\t\tstate: {} as S,\n\t\t\tstateDirty: false\n\t\t};\n\n\t\tthis._typeInitialisers = cloneData.typeInitialisers;\n\t\tthis._contextIdKeys.push(...cloneData.contextIdKeys);\n\t\tthis._contextIds = contextIds;\n\n\t\tfor (const schemaName of Object.keys(cloneData.entitySchemas)) {\n\t\t\tEntitySchemaFactory.register(schemaName, () => cloneData.entitySchemas[schemaName]);\n\t\t}\n\n\t\tthis._stateStorage = new MemoryStateStorage(true, cloneData.state);\n\t\tthis._isStarted = false;\n\t}\n\n\t/**\n\t * Initialise the types from connector.\n\t * @param typeKey The key for the default types.\n\t * @param instanceMethod The function to initialise the instance.\n\t * @internal\n\t */\n\tprivate async initialiseTypeConfig(\n\t\ttypeKey: string,\n\t\tmodule: string,\n\t\tmethod: string\n\t): Promise<void> {\n\t\tconst typeConfig: IEngineCoreTypeConfig[] | undefined = this._context.config.types?.[typeKey];\n\n\t\tif (Is.arrayValue(typeConfig)) {\n\t\t\tconst instanceMethod = await ModuleHelper.getModuleEntry<EngineTypeInitialiser>(\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t);\n\n\t\t\tfor (let i = 0; i < typeConfig.length; i++) {\n\t\t\t\tawait this.logInfo(\n\t\t\t\t\tI18n.formatMessage(\"engineCore.configuring\", {\n\t\t\t\t\t\tcomponentType: typeKey,\n\t\t\t\t\t\tconfigType: typeConfig[i].type\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tconst result = instanceMethod(this, this._context, typeConfig[i]);\n\t\t\t\tconst componentCreateMethod = result.createComponent;\n\n\t\t\t\tif (Is.stringValue(result.instanceTypeName) && Is.function(componentCreateMethod)) {\n\t\t\t\t\tconst finalInstanceType = typeConfig[i].overrideInstanceType ?? result.instanceTypeName;\n\n\t\t\t\t\t// If this is a multi instance component we need to make sure we\n\t\t\t\t\t// generate a unique instance for every factory call\n\t\t\t\t\t// this is often used for REST clients where each instance might\n\t\t\t\t\t// use a different endpoint url\n\t\t\t\t\t// They are generated using the create method of factory\n\t\t\t\t\t// passing custom options, instead of the regular get method\n\t\t\t\t\t// which doesn't allow for custom options\n\t\t\t\t\tif (typeConfig[i].isMultiInstance ?? false) {\n\t\t\t\t\t\tresult.factory?.register(finalInstanceType, params =>\n\t\t\t\t\t\t\tcomponentCreateMethod({\n\t\t\t\t\t\t\t\ttype: typeConfig[i].type,\n\t\t\t\t\t\t\t\toptions: params\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst component = componentCreateMethod(typeConfig[i]);\n\t\t\t\t\t\tthis._context.componentInstances.push({\n\t\t\t\t\t\t\tinstanceType: finalInstanceType,\n\t\t\t\t\t\t\tcomponent,\n\t\t\t\t\t\t\tinitialised: false\n\t\t\t\t\t\t});\n\t\t\t\t\t\tresult.factory?.register(finalInstanceType, () => component);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._context.registeredInstances[typeKey] ??= [];\n\t\t\t\t\tthis._context.registeredInstances[typeKey].push({\n\t\t\t\t\t\ttype: finalInstanceType,\n\t\t\t\t\t\tisDefault: typeConfig[i].isDefault,\n\t\t\t\t\t\tfeatures: typeConfig[i].features\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthrow new GeneralError(\"engineCore\", \"componentUnknownType\", {\n\t\t\t\t\t\ttype: typeConfig[i].type,\n\t\t\t\t\t\tcomponentType: typeKey\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Setup the engine logger.\n\t * @internal\n\t */\n\tprivate setupEngineLogger(): void {\n\t\tconst silent = this._context.config.silent ?? false;\n\t\tconst engineLoggerConnector = silent\n\t\t\t? new SilentLoggingConnector()\n\t\t\t: new ConsoleLoggingConnector({\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\ttranslateMessages: true,\n\t\t\t\t\t\thideGroups: true\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\tthis._context.componentInstances.push({\n\t\t\tinstanceType: EngineCore.LOGGING_CONNECTOR_TYPE_NAME,\n\t\t\tcomponent: engineLoggerConnector,\n\t\t\tinitialised: false\n\t\t});\n\n\t\tLoggingConnectorFactory.register(\n\t\t\tEngineCore.LOGGING_CONNECTOR_TYPE_NAME,\n\t\t\t() => engineLoggerConnector\n\t\t);\n\n\t\tthis._context.registeredInstances.loggingConnector = [\n\t\t\t{\n\t\t\t\ttype: EngineCore.LOGGING_CONNECTOR_TYPE_NAME\n\t\t\t}\n\t\t];\n\n\t\tconst engineLoggerComponent = new LoggingService({\n\t\t\tloggingConnectorType: EngineCore.LOGGING_CONNECTOR_TYPE_NAME\n\t\t});\n\t\tthis._engineLoggingComponent = engineLoggerComponent;\n\n\t\tComponentFactory.register(EngineCore.LOGGING_COMPONENT_TYPE_NAME, () => engineLoggerComponent);\n\t\tthis._context.registeredInstances.loggingComponent = [\n\t\t\t{\n\t\t\t\ttype: EngineCore.LOGGING_COMPONENT_TYPE_NAME\n\t\t\t}\n\t\t];\n\t}\n\n\t/**\n\t * Load the state.\n\t * @internal\n\t */\n\tprivate async stateLoad(): Promise<void> {\n\t\tif (this._stateStorage) {\n\t\t\ttry {\n\t\t\t\tthis._context.state = ((await this._stateStorage.load(this)) ?? {}) as S;\n\t\t\t\tthis._context.stateDirty = false;\n\t\t\t} catch (err) {\n\t\t\t\tawait this.logError(BaseError.fromError(err));\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Save the state.\n\t * @returns Nothing.\n\t * @internal\n\t */\n\tprivate async stateSave(): Promise<void> {\n\t\tif (this._stateStorage && !Is.empty(this._context.state) && this._context.stateDirty) {\n\t\t\ttry {\n\t\t\t\tawait this._stateStorage.save(this, this._context.state);\n\t\t\t\tthis._context.stateDirty = false;\n\t\t\t} catch (err) {\n\t\t\t\tawait this.logError(BaseError.fromError(err));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Bootstrap the engine.\n\t * @internal\n\t */\n\tprivate async bootstrap(): Promise<void> {\n\t\tif (!this._skipBootstrap) {\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.bootstrapStarted`));\n\n\t\t\t// First bootstrap the components.\n\t\t\tfor (const instance of this._context.componentInstances) {\n\t\t\t\tconst bootstrapMethod = instance.component.bootstrap?.bind(instance.component);\n\t\t\t\tif (Is.function(bootstrapMethod)) {\n\t\t\t\t\tawait this.logInfo(\n\t\t\t\t\t\tI18n.formatMessage(`${nameofCamelCase<EngineCore>()}.bootstrapping`, {\n\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\n\t\t\t\t\tconst bootstrapSuccess = await bootstrapMethod(EngineCore.LOGGING_COMPONENT_TYPE_NAME);\n\n\t\t\t\t\t// If the bootstrap method failed then throw an error\n\t\t\t\t\tif (!bootstrapSuccess) {\n\t\t\t\t\t\tthrow new GeneralError(EngineCore.CLASS_NAME, \"bootstrapFailed\", {\n\t\t\t\t\t\t\tclassName: instance.component.className(),\n\t\t\t\t\t\t\tinstanceType: instance.instanceType\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Now perform any custom bootstrap operations\n\t\t\tconst customBootstrap = this._customBootstrap;\n\t\t\tif (Is.function(customBootstrap)) {\n\t\t\t\tawait customBootstrap.call(this, this, this._context);\n\t\t\t}\n\n\t\t\tawait this.logInfo(I18n.formatMessage(`${nameofCamelCase<EngineCore>()}.bootstrapComplete`));\n\t\t}\n\t}\n\n\t/**\n\t * Initialise the context ID handlers.\n\t * @internal\n\t */\n\tprivate initialiseContextIdHandlers(): void {\n\t\tfor (const contextIdKey of this._contextIdKeys) {\n\t\t\tconst handlerType: string | undefined = this.getRegisteredInstanceTypeOptional(\n\t\t\t\t\"contextIdHandlerComponent\",\n\t\t\t\tcontextIdKey.componentFeatures\n\t\t\t);\n\t\t\tif (Is.stringValue(handlerType)) {\n\t\t\t\tconst handler = ComponentFactory.get<IContextIdHandler>(handlerType);\n\t\t\t\tContextIdHandlerFactory.register(contextIdKey.key, () => handler);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -25,7 +25,10 @@ export declare class EngineCore<C extends IEngineCoreConfig = IEngineCoreConfig,
25
25
  /**
26
26
  * The context ID keys.
27
27
  */
28
- protected readonly _contextIdKeys: string[];
28
+ protected readonly _contextIdKeys: {
29
+ key: string;
30
+ componentFeatures: string[];
31
+ }[];
29
32
  /**
30
33
  * The context IDs.
31
34
  */
@@ -51,8 +54,9 @@ export declare class EngineCore<C extends IEngineCoreConfig = IEngineCoreConfig,
51
54
  /**
52
55
  * Add a context ID key to the engine.
53
56
  * @param key The context ID key.
57
+ * @param componentFeatures The component features for the context ID handler.
54
58
  */
55
- addContextIdKey(key: string): void;
59
+ addContextIdKey(key: string, componentFeatures: string[]): void;
56
60
  /**
57
61
  * Get the context ID keys for the engine.
58
62
  * @returns The context IDs keys.
@@ -71,9 +75,10 @@ export declare class EngineCore<C extends IEngineCoreConfig = IEngineCoreConfig,
71
75
  getContextIds(): IContextIds | undefined;
72
76
  /**
73
77
  * Start the engine core.
74
- * @returns True if the start was successful.
78
+ * @param skipComponentStart Should the component start be skipped.
79
+ * @returns Nothing.
75
80
  */
76
- start(): Promise<boolean>;
81
+ start(skipComponentStart?: boolean): Promise<void>;
77
82
  /**
78
83
  * Stop the engine core.
79
84
  * @returns Nothing.
@@ -114,6 +119,10 @@ export declare class EngineCore<C extends IEngineCoreConfig = IEngineCoreConfig,
114
119
  * @returns The state of the engine.
115
120
  */
116
121
  getState(): S;
122
+ /**
123
+ * Set the state to dirty so it gets saved.
124
+ */
125
+ setStateDirty(): void;
117
126
  /**
118
127
  * Get all the registered instances.
119
128
  * @returns The registered instances.
@@ -148,7 +157,8 @@ export declare class EngineCore<C extends IEngineCoreConfig = IEngineCoreConfig,
148
157
  /**
149
158
  * Populate the engine from the clone data.
150
159
  * @param cloneData The clone data to populate from.
160
+ * @param contextIds The context IDs to use for the clone.
151
161
  * @param silent Should the clone be silent.
152
162
  */
153
- populateClone(cloneData: IEngineCoreClone<C, S>, silent?: boolean): void;
163
+ populateClone(cloneData: IEngineCoreClone<C, S>, contextIds?: IContextIds, silent?: boolean): void;
154
164
  }
package/docs/changelog.md CHANGED
@@ -1,5 +1,309 @@
1
1
  # @twin.org/engine-core - Changelog
2
2
 
3
+ ## [0.0.3-next.21](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.20...engine-core-v0.0.3-next.21) (2026-02-13)
4
+
5
+
6
+ ### Features
7
+
8
+ * multi instance component support ([#83](https://github.com/twinfoundation/engine/issues/83)) ([6012b50](https://github.com/twinfoundation/engine/commit/6012b50959df5af893f05516d42eea2e0800b31a))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/engine-models bumped from 0.0.3-next.20 to 0.0.3-next.21
16
+
17
+ ## [0.0.3-next.20](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.19...engine-core-v0.0.3-next.20) (2026-02-06)
18
+
19
+
20
+ ### Miscellaneous Chores
21
+
22
+ * **engine-core:** Synchronize repo versions
23
+
24
+
25
+ ### Dependencies
26
+
27
+ * The following workspace dependencies were updated
28
+ * dependencies
29
+ * @twin.org/engine-models bumped from 0.0.3-next.19 to 0.0.3-next.20
30
+
31
+ ## [0.0.3-next.19](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.18...engine-core-v0.0.3-next.19) (2026-02-05)
32
+
33
+
34
+ ### Features
35
+
36
+ * set initialised flag when skipping start ([039b4df](https://github.com/twinfoundation/engine/commit/039b4dff22c90d0ba3703372a11213709d26aa52))
37
+
38
+
39
+ ### Bug Fixes
40
+
41
+ * pass contextIds to populateClone ([#79](https://github.com/twinfoundation/engine/issues/79)) ([b22f1bb](https://github.com/twinfoundation/engine/commit/b22f1bbf0319069914e316d27de4c2a8623421cf))
42
+
43
+
44
+ ### Dependencies
45
+
46
+ * The following workspace dependencies were updated
47
+ * dependencies
48
+ * @twin.org/engine-models bumped from 0.0.3-next.18 to 0.0.3-next.19
49
+
50
+ ## [0.0.3-next.18](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.17...engine-core-v0.0.3-next.18) (2026-02-04)
51
+
52
+
53
+ ### Features
54
+
55
+ * add tenant admin routes ([#76](https://github.com/twinfoundation/engine/issues/76)) ([3c0af90](https://github.com/twinfoundation/engine/commit/3c0af90a572fcda08d8720bdcee9b9f1cd02b872))
56
+
57
+
58
+ ### Dependencies
59
+
60
+ * The following workspace dependencies were updated
61
+ * dependencies
62
+ * @twin.org/engine-models bumped from 0.0.3-next.17 to 0.0.3-next.18
63
+
64
+ ## [0.0.3-next.17](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.16...engine-core-v0.0.3-next.17) (2026-02-02)
65
+
66
+
67
+ ### Miscellaneous Chores
68
+
69
+ * **engine-core:** Synchronize repo versions
70
+
71
+
72
+ ### Dependencies
73
+
74
+ * The following workspace dependencies were updated
75
+ * dependencies
76
+ * @twin.org/engine-models bumped from 0.0.3-next.16 to 0.0.3-next.17
77
+
78
+ ## [0.0.3-next.16](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.15...engine-core-v0.0.3-next.16) (2026-01-28)
79
+
80
+
81
+ ### Miscellaneous Chores
82
+
83
+ * **engine-core:** Synchronize repo versions
84
+
85
+
86
+ ### Dependencies
87
+
88
+ * The following workspace dependencies were updated
89
+ * dependencies
90
+ * @twin.org/engine-models bumped from 0.0.3-next.15 to 0.0.3-next.16
91
+
92
+ ## [0.0.3-next.15](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.14...engine-core-v0.0.3-next.15) (2026-01-26)
93
+
94
+
95
+ ### Miscellaneous Chores
96
+
97
+ * **engine-core:** Synchronize repo versions
98
+
99
+
100
+ ### Dependencies
101
+
102
+ * The following workspace dependencies were updated
103
+ * dependencies
104
+ * @twin.org/engine-models bumped from 0.0.3-next.14 to 0.0.3-next.15
105
+
106
+ ## [0.0.3-next.14](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.13...engine-core-v0.0.3-next.14) (2026-01-19)
107
+
108
+
109
+ ### Features
110
+
111
+ * add auth admin component ([201cd06](https://github.com/twinfoundation/engine/commit/201cd061be83afccb5a6b06856ffe7cf8db7d6b3))
112
+ * add context id features ([#51](https://github.com/twinfoundation/engine/issues/51)) ([eaef180](https://github.com/twinfoundation/engine/commit/eaef1807397a907bc7655ef1545a151a710ca2f1))
113
+ * add default logging component for web server ([8ad94f0](https://github.com/twinfoundation/engine/commit/8ad94f0d2d9a5241a8854b1e59fb9a55ce310142))
114
+ * add isPrimary and isClone methods ([a7c63e9](https://github.com/twinfoundation/engine/commit/a7c63e97f54c95b104cc81e66d3fa42c6607bdc1))
115
+ * add mimeTypeProcessors and disableNodeIdentity ([bb7e81e](https://github.com/twinfoundation/engine/commit/bb7e81e2036fe042068a5645ec59b22e20d33aad))
116
+ * add rights management negotiation ([84ef46b](https://github.com/twinfoundation/engine/commit/84ef46bff110611a19512793425c8c873ee2a590))
117
+ * add skipComponentStart flag ([#62](https://github.com/twinfoundation/engine/issues/62)) ([07e90af](https://github.com/twinfoundation/engine/commit/07e90afa4ba1baaa79c0c6f0f45200d781801534))
118
+ * add synchronised storage support ([5142e34](https://github.com/twinfoundation/engine/commit/5142e3488f09195cf9f48a9c6c6d1014231a4c2c))
119
+ * add validate-locales ([b92ea09](https://github.com/twinfoundation/engine/commit/b92ea09dbcfe35225271a51f24d231f59e2d363e))
120
+ * close already started components on startup error ([a55a117](https://github.com/twinfoundation/engine/commit/a55a117a508998288c8ae804e732fc6085cb22fa))
121
+ * context id handlers repopulated after engine clone ([9712e32](https://github.com/twinfoundation/engine/commit/9712e328f4607f5b2c82355c394c61bde0ee39bf))
122
+ * eslint migration to flat config ([6b978da](https://github.com/twinfoundation/engine/commit/6b978daf777a615d7758b63c3df57d5a376f6dfb))
123
+ * improve startup error handling ([#65](https://github.com/twinfoundation/engine/issues/65)) ([5b2d1c5](https://github.com/twinfoundation/engine/commit/5b2d1c539cf5484afa85e294d6d6c18f24ef8274))
124
+ * initialise context id handlers before bootstrap ([e94df44](https://github.com/twinfoundation/engine/commit/e94df440aa553350dba5da2ae93b5c34e0ac3692))
125
+ * interlock stop method ([3806ba7](https://github.com/twinfoundation/engine/commit/3806ba7b44b3cb3ce130f4e3684a666533674663))
126
+ * maintain isDefault flag for registered instances ([2ac5bee](https://github.com/twinfoundation/engine/commit/2ac5bee094bef42b396cc82b0d18bb6aebe27352))
127
+ * override type initialisers with new registrations ([5b4ff56](https://github.com/twinfoundation/engine/commit/5b4ff561d06b6513c870a72bb20ba23c0653cfe8))
128
+ * remove bootstrapped components, component should manage their own state ([5c7e9e4](https://github.com/twinfoundation/engine/commit/5c7e9e419ef26933e49c9c5a21a20a8961244e7f))
129
+ * remove unused component states ([d56d648](https://github.com/twinfoundation/engine/commit/d56d6486119ea8b8501a33f9e3a3101a08b826ed))
130
+ * simplify config building ([732c871](https://github.com/twinfoundation/engine/commit/732c871c5aca236759168f4bc15aeffd98a330a8))
131
+ * standardised engine logging naming ([0dbf857](https://github.com/twinfoundation/engine/commit/0dbf857587641f86ddf010143519d0e8333489ff))
132
+ * update dependencies ([97c9f64](https://github.com/twinfoundation/engine/commit/97c9f64b6ef096963bcc5de338a2a9e99bdc1a11))
133
+ * update framework core ([acc0f8d](https://github.com/twinfoundation/engine/commit/acc0f8d455a4b8ec47f1da643139fa0f07775fa6))
134
+ * upgrade framework components ([efd52e8](https://github.com/twinfoundation/engine/commit/efd52e80564fff29c3897bfa09b6305b3a322812))
135
+ * use peer dependencies ([69dd744](https://github.com/twinfoundation/engine/commit/69dd7449010b8e6f5f35e7fad201ad4c1cab400c))
136
+ * use shared store mechanism ([#2](https://github.com/twinfoundation/engine/issues/2)) ([9eed8d7](https://github.com/twinfoundation/engine/commit/9eed8d7766388479b42f03e2542fe761f2156408))
137
+
138
+
139
+ ### Bug Fixes
140
+
141
+ * make sure stop is called even if start is not implemented ([ece2b9d](https://github.com/twinfoundation/engine/commit/ece2b9de5c6dff2b5ccf2a3115c1a7328a330125))
142
+ * save state if dirty even if not started ([1abe4b9](https://github.com/twinfoundation/engine/commit/1abe4b97e6d27364dd673f62f83034b88b7fae0c))
143
+ * use correct instance type name ([6278486](https://github.com/twinfoundation/engine/commit/6278486d8f0f2d601d3cf521a647898cd7cc1f31))
144
+
145
+
146
+ ### Dependencies
147
+
148
+ * The following workspace dependencies were updated
149
+ * dependencies
150
+ * @twin.org/engine-models bumped from 0.0.3-next.13 to 0.0.3-next.14
151
+
152
+ ## [0.0.3-next.13](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.12...engine-core-v0.0.3-next.13) (2026-01-19)
153
+
154
+
155
+ ### Miscellaneous Chores
156
+
157
+ * **engine-core:** Synchronize repo versions
158
+
159
+
160
+ ### Dependencies
161
+
162
+ * The following workspace dependencies were updated
163
+ * dependencies
164
+ * @twin.org/engine-models bumped from 0.0.3-next.12 to 0.0.3-next.13
165
+
166
+ ## [0.0.3-next.12](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.11...engine-core-v0.0.3-next.12) (2026-01-19)
167
+
168
+
169
+ ### Features
170
+
171
+ * improve startup error handling ([#65](https://github.com/twinfoundation/engine/issues/65)) ([5b2d1c5](https://github.com/twinfoundation/engine/commit/5b2d1c539cf5484afa85e294d6d6c18f24ef8274))
172
+
173
+
174
+ ### Dependencies
175
+
176
+ * The following workspace dependencies were updated
177
+ * dependencies
178
+ * @twin.org/engine-models bumped from 0.0.3-next.11 to 0.0.3-next.12
179
+
180
+ ## [0.0.3-next.11](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.10...engine-core-v0.0.3-next.11) (2026-01-16)
181
+
182
+
183
+ ### Bug Fixes
184
+
185
+ * save state if dirty even if not started ([1abe4b9](https://github.com/twinfoundation/engine/commit/1abe4b97e6d27364dd673f62f83034b88b7fae0c))
186
+
187
+
188
+ ### Dependencies
189
+
190
+ * The following workspace dependencies were updated
191
+ * dependencies
192
+ * @twin.org/engine-models bumped from 0.0.3-next.10 to 0.0.3-next.11
193
+
194
+ ## [0.0.3-next.10](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.9...engine-core-v0.0.3-next.10) (2026-01-13)
195
+
196
+
197
+ ### Features
198
+
199
+ * add skipComponentStart flag ([#62](https://github.com/twinfoundation/engine/issues/62)) ([07e90af](https://github.com/twinfoundation/engine/commit/07e90afa4ba1baaa79c0c6f0f45200d781801534))
200
+
201
+
202
+ ### Dependencies
203
+
204
+ * The following workspace dependencies were updated
205
+ * dependencies
206
+ * @twin.org/engine-models bumped from 0.0.3-next.9 to 0.0.3-next.10
207
+
208
+ ## [0.0.3-next.9](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.8...engine-core-v0.0.3-next.9) (2026-01-07)
209
+
210
+
211
+ ### Miscellaneous Chores
212
+
213
+ * **engine-core:** Synchronize repo versions
214
+
215
+
216
+ ### Dependencies
217
+
218
+ * The following workspace dependencies were updated
219
+ * dependencies
220
+ * @twin.org/engine-models bumped from 0.0.3-next.8 to 0.0.3-next.9
221
+
222
+ ## [0.0.3-next.8](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.7...engine-core-v0.0.3-next.8) (2026-01-06)
223
+
224
+
225
+ ### Miscellaneous Chores
226
+
227
+ * **engine-core:** Synchronize repo versions
228
+
229
+
230
+ ### Dependencies
231
+
232
+ * The following workspace dependencies were updated
233
+ * dependencies
234
+ * @twin.org/engine-models bumped from 0.0.3-next.7 to 0.0.3-next.8
235
+
236
+ ## [0.0.3-next.7](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.6...engine-core-v0.0.3-next.7) (2025-12-04)
237
+
238
+
239
+ ### Miscellaneous Chores
240
+
241
+ * **engine-core:** Synchronize repo versions
242
+
243
+
244
+ ### Dependencies
245
+
246
+ * The following workspace dependencies were updated
247
+ * dependencies
248
+ * @twin.org/engine-models bumped from 0.0.3-next.6 to 0.0.3-next.7
249
+
250
+ ## [0.0.3-next.6](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.5...engine-core-v0.0.3-next.6) (2025-11-28)
251
+
252
+
253
+ ### Miscellaneous Chores
254
+
255
+ * **engine-core:** Synchronize repo versions
256
+
257
+
258
+ ### Dependencies
259
+
260
+ * The following workspace dependencies were updated
261
+ * dependencies
262
+ * @twin.org/engine-models bumped from 0.0.3-next.5 to 0.0.3-next.6
263
+
264
+ ## [0.0.3-next.5](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.4...engine-core-v0.0.3-next.5) (2025-11-20)
265
+
266
+
267
+ ### Features
268
+
269
+ * initialise context id handlers before bootstrap ([e94df44](https://github.com/twinfoundation/engine/commit/e94df440aa553350dba5da2ae93b5c34e0ac3692))
270
+
271
+
272
+ ### Dependencies
273
+
274
+ * The following workspace dependencies were updated
275
+ * dependencies
276
+ * @twin.org/engine-models bumped from 0.0.3-next.4 to 0.0.3-next.5
277
+
278
+ ## [0.0.3-next.4](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.3...engine-core-v0.0.3-next.4) (2025-11-20)
279
+
280
+
281
+ ### Features
282
+
283
+ * context id handlers repopulated after engine clone ([9712e32](https://github.com/twinfoundation/engine/commit/9712e328f4607f5b2c82355c394c61bde0ee39bf))
284
+ * interlock stop method ([3806ba7](https://github.com/twinfoundation/engine/commit/3806ba7b44b3cb3ce130f4e3684a666533674663))
285
+
286
+
287
+ ### Dependencies
288
+
289
+ * The following workspace dependencies were updated
290
+ * dependencies
291
+ * @twin.org/engine-models bumped from 0.0.3-next.3 to 0.0.3-next.4
292
+
293
+ ## [0.0.3-next.3](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.2...engine-core-v0.0.3-next.3) (2025-11-14)
294
+
295
+
296
+ ### Bug Fixes
297
+
298
+ * make sure stop is called even if start is not implemented ([ece2b9d](https://github.com/twinfoundation/engine/commit/ece2b9de5c6dff2b5ccf2a3115c1a7328a330125))
299
+
300
+
301
+ ### Dependencies
302
+
303
+ * The following workspace dependencies were updated
304
+ * dependencies
305
+ * @twin.org/engine-models bumped from 0.0.3-next.2 to 0.0.3-next.3
306
+
3
307
  ## [0.0.3-next.2](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.1...engine-core-v0.0.3-next.2) (2025-11-13)
4
308
 
5
309
 
@@ -72,10 +72,18 @@ The core context.
72
72
 
73
73
  ### \_contextIdKeys
74
74
 
75
- > `protected` `readonly` **\_contextIdKeys**: `string`[]
75
+ > `protected` `readonly` **\_contextIdKeys**: `object`[]
76
76
 
77
77
  The context ID keys.
78
78
 
79
+ #### key
80
+
81
+ > **key**: `string`
82
+
83
+ #### componentFeatures
84
+
85
+ > **componentFeatures**: `string`[]
86
+
79
87
  ***
80
88
 
81
89
  ### \_contextIds?
@@ -150,7 +158,7 @@ The type config or undefined if not found.
150
158
 
151
159
  ### addContextIdKey()
152
160
 
153
- > **addContextIdKey**(`key`): `void`
161
+ > **addContextIdKey**(`key`, `componentFeatures`): `void`
154
162
 
155
163
  Add a context ID key to the engine.
156
164
 
@@ -162,6 +170,12 @@ Add a context ID key to the engine.
162
170
 
163
171
  The context ID key.
164
172
 
173
+ ##### componentFeatures
174
+
175
+ `string`[]
176
+
177
+ The component features for the context ID handler.
178
+
165
179
  #### Returns
166
180
 
167
181
  `void`
@@ -240,15 +254,23 @@ The context IDs or undefined if none are set.
240
254
 
241
255
  ### start()
242
256
 
243
- > **start**(): `Promise`\<`boolean`\>
257
+ > **start**(`skipComponentStart?`): `Promise`\<`void`\>
244
258
 
245
259
  Start the engine core.
246
260
 
261
+ #### Parameters
262
+
263
+ ##### skipComponentStart?
264
+
265
+ `boolean`
266
+
267
+ Should the component start be skipped.
268
+
247
269
  #### Returns
248
270
 
249
- `Promise`\<`boolean`\>
271
+ `Promise`\<`void`\>
250
272
 
251
- True if the start was successful.
273
+ Nothing.
252
274
 
253
275
  #### Implementation of
254
276
 
@@ -412,6 +434,22 @@ The state of the engine.
412
434
 
413
435
  ***
414
436
 
437
+ ### setStateDirty()
438
+
439
+ > **setStateDirty**(): `void`
440
+
441
+ Set the state to dirty so it gets saved.
442
+
443
+ #### Returns
444
+
445
+ `void`
446
+
447
+ #### Implementation of
448
+
449
+ `IEngineCore.setStateDirty`
450
+
451
+ ***
452
+
415
453
  ### getRegisteredInstances()
416
454
 
417
455
  > **getRegisteredInstances**(): `object`
@@ -518,7 +556,7 @@ The clone data.
518
556
 
519
557
  ### populateClone()
520
558
 
521
- > **populateClone**(`cloneData`, `silent?`): `void`
559
+ > **populateClone**(`cloneData`, `contextIds?`, `silent?`): `void`
522
560
 
523
561
  Populate the engine from the clone data.
524
562
 
@@ -530,6 +568,12 @@ Populate the engine from the clone data.
530
568
 
531
569
  The clone data to populate from.
532
570
 
571
+ ##### contextIds?
572
+
573
+ `IContextIds`
574
+
575
+ The context IDs to use for the clone.
576
+
533
577
  ##### silent?
534
578
 
535
579
  `boolean`
package/locales/en.json CHANGED
@@ -5,7 +5,8 @@
5
5
  "bootstrapFailed": "Failed to bootstrap component type \"{className}\" with instance type \"{instanceType}\"",
6
6
  "componentStartFailed": "Failed to start component type \"{className}\" with instance type \"{instanceType}\"",
7
7
  "componentStopFailed": "Failed to stop component type \"{className}\" with instance type \"{instanceType}\"",
8
- "instanceTypeNotFound": "Instance type not found for \"{type}\" with features \"{features}\""
8
+ "instanceTypeNotFound": "Instance type not found for \"{type}\"",
9
+ "instanceTypeNotFoundWithFeatures": "Instance type not found for \"{type}\" with features \"{features}\""
9
10
  },
10
11
  "fileStateStorage": {
11
12
  "failedLoading": "Failed to load file state storage from \"{filename}\"",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/engine-core",
3
- "version": "0.0.3-next.2",
3
+ "version": "0.0.3-next.21",
4
4
  "description": "Engine core.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,7 +18,7 @@
18
18
  "@twin.org/core": "next",
19
19
  "@twin.org/crypto": "next",
20
20
  "@twin.org/data-core": "next",
21
- "@twin.org/engine-models": "0.0.3-next.2",
21
+ "@twin.org/engine-models": "0.0.3-next.21",
22
22
  "@twin.org/entity": "next",
23
23
  "@twin.org/logging-connector-console": "next",
24
24
  "@twin.org/logging-models": "next",