@twin.org/engine-core 0.0.3-next.26 → 0.0.3-next.27

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # TWIN Engine Core
2
2
 
3
- Engine implementation for the core.
3
+ Engine Core provides the runtime lifecycle and orchestration layer for engine instances. It manages component initialisation, context handling, state persistence, and cloning workflows that higher-level packages rely on.
4
4
 
5
5
  ## Installation
6
6
 
package/docs/changelog.md CHANGED
@@ -1,4 +1,18 @@
1
- # @twin.org/engine-core - Changelog
1
+ # Changelog
2
+
3
+ ## [0.0.3-next.27](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.26...engine-core-v0.0.3-next.27) (2026-03-20)
4
+
5
+
6
+ ### Features
7
+
8
+ * update dependencies ([e6ebe42](https://github.com/twinfoundation/engine/commit/e6ebe42b9d61066227ad8b45dae14c8f8615b760))
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.26 to 0.0.3-next.27
2
16
 
3
17
  ## [0.0.3-next.26](https://github.com/twinfoundation/engine/compare/engine-core-v0.0.3-next.25...engine-core-v0.0.3-next.26) (2026-03-05)
4
18
 
package/docs/examples.md CHANGED
@@ -1 +1,156 @@
1
- # @twin.org/engine-core - Examples
1
+ # Engine Core Examples
2
+
3
+ These examples focus on common runtime patterns such as lifecycle control, cloning, state storage, and module loading.
4
+
5
+ ## EngineCore
6
+
7
+ ```typescript
8
+ import { EngineCore, MemoryStateStorage } from '@twin.org/engine-core';
9
+ import type { IEngineCoreConfig, IEngineState } from '@twin.org/engine-models';
10
+
11
+ interface AppState extends IEngineState {
12
+ runCount?: number;
13
+ }
14
+
15
+ const config: IEngineCoreConfig = {
16
+ debug: true,
17
+ silent: false,
18
+ types: {}
19
+ };
20
+
21
+ const stateStorage = new MemoryStateStorage<AppState>();
22
+ const engineCore = new EngineCore<IEngineCoreConfig, AppState>({
23
+ config,
24
+ stateStorage,
25
+ skipBootstrap: true
26
+ });
27
+
28
+ engineCore.addTypeInitialiser('loggingConnector', '@twin.org/engine-types', 'initLoggingConnector');
29
+ console.log(engineCore.getTypeConfig('loggingConnector')?.length ?? 0); // 0
30
+
31
+ engineCore.addContextIdKey('tenant', ['tenant']);
32
+ engineCore.addContextId('tenant', 'tenant-a');
33
+
34
+ console.log(engineCore.getContextIdKeys()); // ["tenant"]
35
+ console.log(engineCore.getContextIds()); // { tenant: "tenant-a" }
36
+ console.log(engineCore.isPrimary()); // true
37
+ console.log(engineCore.isClone()); // false
38
+ console.log(engineCore.isStarted()); // false
39
+
40
+ await engineCore.start(true);
41
+ console.log(engineCore.isStarted()); // true
42
+
43
+ await engineCore.logInfo('Engine started for tenant-a');
44
+
45
+ const state = engineCore.getState();
46
+ state.runCount = (state.runCount ?? 0) + 1;
47
+ engineCore.setStateDirty();
48
+
49
+ console.log(engineCore.getConfig().debug); // true
50
+ console.log(engineCore.getRegisteredInstances()); // { loggingConnector: [...], loggingComponent: [...] }
51
+ console.log(engineCore.getRegisteredInstanceType('loggingComponent')); // "engine-logging-service"
52
+ console.log(engineCore.getRegisteredInstanceTypeOptional('hostingComponent')); // undefined
53
+
54
+ await engineCore.stop();
55
+ console.log(engineCore.isStarted()); // false
56
+ ```
57
+
58
+ ```typescript
59
+ import { BaseError, GeneralError } from '@twin.org/core';
60
+ import { EngineCore } from '@twin.org/engine-core';
61
+
62
+ const engineCore = new EngineCore({
63
+ config: { debug: false, silent: true, types: {} },
64
+ skipBootstrap: true
65
+ });
66
+
67
+ const wrapped = new GeneralError(
68
+ EngineCore.CLASS_NAME,
69
+ 'sampleFailure',
70
+ { area: 'examples' },
71
+ BaseError.fromError(new Error('Sample failure'))
72
+ );
73
+ await engineCore.logError(wrapped);
74
+ ```
75
+
76
+ ```typescript
77
+ import { EngineCore } from '@twin.org/engine-core';
78
+
79
+ const primary = new EngineCore({
80
+ config: { debug: false, silent: true, types: {} },
81
+ skipBootstrap: true
82
+ });
83
+ primary.addContextIdKey('node', ['node']);
84
+
85
+ const cloneData = primary.getCloneData();
86
+
87
+ const clone = new EngineCore({ config: { debug: false, silent: true, types: {} } });
88
+ clone.populateClone(cloneData, { node: 'node-1', tenant: 'tenant-a' }, true);
89
+
90
+ console.log(clone.isClone()); // true
91
+ console.log(clone.getContextIds()); // { node: "node-1", tenant: "tenant-a" }
92
+ ```
93
+
94
+ ## FileStateStorage
95
+
96
+ ```typescript
97
+ import { EngineCore, FileStateStorage } from '@twin.org/engine-core';
98
+
99
+ const engineCore = new EngineCore({
100
+ config: { debug: false, silent: true, types: {} },
101
+ skipBootstrap: true
102
+ });
103
+ const fileStorage = new FileStateStorage('./data/engine-state.json');
104
+
105
+ await fileStorage.save(engineCore, { ready: true });
106
+
107
+ const loaded = await fileStorage.load(engineCore);
108
+ console.log(loaded); // { ready: true }
109
+ ```
110
+
111
+ ## MemoryStateStorage
112
+
113
+ ```typescript
114
+ import { EngineCore, MemoryStateStorage } from '@twin.org/engine-core';
115
+
116
+ const engineCore = new EngineCore({
117
+ config: { debug: false, silent: true, types: {} },
118
+ skipBootstrap: true
119
+ });
120
+ const memoryStorage = new MemoryStateStorage(false, { retries: 1 });
121
+
122
+ console.log(await memoryStorage.load(engineCore)); // { retries: 1 }
123
+
124
+ await memoryStorage.save(engineCore, { retries: 2 });
125
+ console.log(await memoryStorage.load(engineCore)); // { retries: 2 }
126
+ ```
127
+
128
+ ## EngineModuleHelper
129
+
130
+ ```typescript
131
+ import { EngineCore, EngineModuleHelper } from '@twin.org/engine-core';
132
+ import type { IEngineModuleConfig } from '@twin.org/engine-models';
133
+
134
+ const engineCore = new EngineCore({
135
+ config: { debug: false, silent: true, types: {} },
136
+ skipBootstrap: true
137
+ });
138
+
139
+ const moduleConfig: IEngineModuleConfig = {
140
+ moduleName: '@twin.org/logging-service',
141
+ className: 'LoggingService',
142
+ dependencies: [
143
+ {
144
+ propertyName: 'loggingConnectorType',
145
+ componentName: 'loggingConnector',
146
+ isOptional: false
147
+ }
148
+ ],
149
+ config: {
150
+ level: 'info'
151
+ }
152
+ };
153
+
154
+ const component = await EngineModuleHelper.loadComponent<unknown>(engineCore, moduleConfig);
155
+ console.log(component !== undefined); // true
156
+ ```
@@ -38,7 +38,7 @@ The options for the engine.
38
38
 
39
39
  ## Properties
40
40
 
41
- ### LOGGING\_COMPONENT\_TYPE\_NAME
41
+ ### LOGGING\_COMPONENT\_TYPE\_NAME {#logging_component_type_name}
42
42
 
43
43
  > `readonly` `static` **LOGGING\_COMPONENT\_TYPE\_NAME**: `string` = `"engine-logging-service"`
44
44
 
@@ -46,7 +46,7 @@ Name for the engine logger component, used for direct console logging.
46
46
 
47
47
  ***
48
48
 
49
- ### LOGGING\_CONNECTOR\_TYPE\_NAME
49
+ ### LOGGING\_CONNECTOR\_TYPE\_NAME {#logging_connector_type_name}
50
50
 
51
51
  > `readonly` `static` **LOGGING\_CONNECTOR\_TYPE\_NAME**: `string` = `"engine-logging-connector"`
52
52
 
@@ -54,7 +54,7 @@ Name for the engine logger connector, used for direct console logging.
54
54
 
55
55
  ***
56
56
 
57
- ### CLASS\_NAME
57
+ ### CLASS\_NAME {#class_name}
58
58
 
59
59
  > `readonly` `static` **CLASS\_NAME**: `string`
60
60
 
@@ -62,7 +62,7 @@ Runtime name for the class.
62
62
 
63
63
  ***
64
64
 
65
- ### \_context
65
+ ### \_context {#_context}
66
66
 
67
67
  > `protected` **\_context**: `IEngineCoreContext`\<`C`, `S`\>
68
68
 
@@ -70,7 +70,7 @@ The core context.
70
70
 
71
71
  ***
72
72
 
73
- ### \_contextIdKeys
73
+ ### \_contextIdKeys {#_contextidkeys}
74
74
 
75
75
  > `protected` `readonly` **\_contextIdKeys**: `object`[]
76
76
 
@@ -86,15 +86,15 @@ The context ID keys.
86
86
 
87
87
  ***
88
88
 
89
- ### \_contextIds?
89
+ ### \_contextIds? {#_contextids}
90
90
 
91
- > `protected` `optional` **\_contextIds**: `IContextIds`
91
+ > `protected` `optional` **\_contextIds?**: `IContextIds`
92
92
 
93
93
  The context IDs.
94
94
 
95
95
  ## Methods
96
96
 
97
- ### addTypeInitialiser()
97
+ ### addTypeInitialiser() {#addtypeinitialiser}
98
98
 
99
99
  > **addTypeInitialiser**(`type`, `module`, `method`): `void`
100
100
 
@@ -130,7 +130,7 @@ The name of the method to call.
130
130
 
131
131
  ***
132
132
 
133
- ### getTypeConfig()
133
+ ### getTypeConfig() {#gettypeconfig}
134
134
 
135
135
  > **getTypeConfig**(`type`): `IEngineCoreTypeConfig`[] \| `undefined`
136
136
 
@@ -156,7 +156,7 @@ The type config or undefined if not found.
156
156
 
157
157
  ***
158
158
 
159
- ### addContextIdKey()
159
+ ### addContextIdKey() {#addcontextidkey}
160
160
 
161
161
  > **addContextIdKey**(`key`, `componentFeatures`): `void`
162
162
 
@@ -186,7 +186,7 @@ The component features for the context ID handler.
186
186
 
187
187
  ***
188
188
 
189
- ### getContextIdKeys()
189
+ ### getContextIdKeys() {#getcontextidkeys}
190
190
 
191
191
  > **getContextIdKeys**(): `string`[]
192
192
 
@@ -204,7 +204,7 @@ The context IDs keys.
204
204
 
205
205
  ***
206
206
 
207
- ### addContextId()
207
+ ### addContextId() {#addcontextid}
208
208
 
209
209
  > **addContextId**(`key`, `value`): `void`
210
210
 
@@ -234,7 +234,7 @@ The context ID value.
234
234
 
235
235
  ***
236
236
 
237
- ### getContextIds()
237
+ ### getContextIds() {#getcontextids}
238
238
 
239
239
  > **getContextIds**(): `IContextIds` \| `undefined`
240
240
 
@@ -252,7 +252,7 @@ The context IDs or undefined if none are set.
252
252
 
253
253
  ***
254
254
 
255
- ### start()
255
+ ### start() {#start}
256
256
 
257
257
  > **start**(`skipComponentStart?`): `Promise`\<`void`\>
258
258
 
@@ -278,7 +278,7 @@ Nothing.
278
278
 
279
279
  ***
280
280
 
281
- ### stop()
281
+ ### stop() {#stop}
282
282
 
283
283
  > **stop**(): `Promise`\<`void`\>
284
284
 
@@ -296,7 +296,7 @@ Nothing.
296
296
 
297
297
  ***
298
298
 
299
- ### isStarted()
299
+ ### isStarted() {#isstarted}
300
300
 
301
301
  > **isStarted**(): `boolean`
302
302
 
@@ -314,7 +314,7 @@ True if the engine is started.
314
314
 
315
315
  ***
316
316
 
317
- ### isPrimary()
317
+ ### isPrimary() {#isprimary}
318
318
 
319
319
  > **isPrimary**(): `boolean`
320
320
 
@@ -332,7 +332,7 @@ True if the engine is the primary instance.
332
332
 
333
333
  ***
334
334
 
335
- ### isClone()
335
+ ### isClone() {#isclone}
336
336
 
337
337
  > **isClone**(): `boolean`
338
338
 
@@ -350,7 +350,7 @@ True if the engine instance is a clone.
350
350
 
351
351
  ***
352
352
 
353
- ### logInfo()
353
+ ### logInfo() {#loginfo}
354
354
 
355
355
  > **logInfo**(`message`): `Promise`\<`void`\>
356
356
 
@@ -374,7 +374,7 @@ The message to log.
374
374
 
375
375
  ***
376
376
 
377
- ### logError()
377
+ ### logError() {#logerror}
378
378
 
379
379
  > **logError**(`error`): `Promise`\<`void`\>
380
380
 
@@ -398,7 +398,7 @@ The error to log.
398
398
 
399
399
  ***
400
400
 
401
- ### getConfig()
401
+ ### getConfig() {#getconfig}
402
402
 
403
403
  > **getConfig**(): `C`
404
404
 
@@ -416,7 +416,7 @@ The config for the engine.
416
416
 
417
417
  ***
418
418
 
419
- ### getState()
419
+ ### getState() {#getstate}
420
420
 
421
421
  > **getState**(): `S`
422
422
 
@@ -434,7 +434,7 @@ The state of the engine.
434
434
 
435
435
  ***
436
436
 
437
- ### setStateDirty()
437
+ ### setStateDirty() {#setstatedirty}
438
438
 
439
439
  > **setStateDirty**(): `void`
440
440
 
@@ -450,7 +450,7 @@ Set the state to dirty so it gets saved.
450
450
 
451
451
  ***
452
452
 
453
- ### getRegisteredInstances()
453
+ ### getRegisteredInstances() {#getregisteredinstances}
454
454
 
455
455
  > **getRegisteredInstances**(): `object`
456
456
 
@@ -468,7 +468,7 @@ The registered instances.
468
468
 
469
469
  ***
470
470
 
471
- ### getRegisteredInstanceType()
471
+ ### getRegisteredInstanceType() {#getregisteredinstancetype}
472
472
 
473
473
  > **getRegisteredInstanceType**(`componentConnectorType`, `features?`): `string`
474
474
 
@@ -504,7 +504,7 @@ If a matching instance was not found.
504
504
 
505
505
  ***
506
506
 
507
- ### getRegisteredInstanceTypeOptional()
507
+ ### getRegisteredInstanceTypeOptional() {#getregisteredinstancetypeoptional}
508
508
 
509
509
  > **getRegisteredInstanceTypeOptional**(`componentConnectorType`, `features?`): `string` \| `undefined`
510
510
 
@@ -536,7 +536,7 @@ The instance type matching the criteria if one is registered.
536
536
 
537
537
  ***
538
538
 
539
- ### getCloneData()
539
+ ### getCloneData() {#getclonedata}
540
540
 
541
541
  > **getCloneData**(): `IEngineCoreClone`\<`C`, `S`\>
542
542
 
@@ -554,7 +554,7 @@ The clone data.
554
554
 
555
555
  ***
556
556
 
557
- ### populateClone()
557
+ ### populateClone() {#populateclone}
558
558
 
559
559
  > **populateClone**(`cloneData`, `contextIds?`, `silent?`): `void`
560
560
 
@@ -14,7 +14,7 @@ Helper class for engine modules.
14
14
 
15
15
  ## Properties
16
16
 
17
- ### CLASS\_NAME
17
+ ### CLASS\_NAME {#class_name}
18
18
 
19
19
  > `readonly` `static` **CLASS\_NAME**: `string`
20
20
 
@@ -22,7 +22,7 @@ Runtime name for the class.
22
22
 
23
23
  ## Methods
24
24
 
25
- ### loadComponent()
25
+ ### loadComponent() {#loadcomponent}
26
26
 
27
27
  > `static` **loadComponent**\<`T`\>(`engineCore`, `engineModuleConfig`): `Promise`\<`T`\>
28
28
 
@@ -40,7 +40,7 @@ Whether the file is in read-only mode.
40
40
 
41
41
  ## Properties
42
42
 
43
- ### CLASS\_NAME
43
+ ### CLASS\_NAME {#class_name}
44
44
 
45
45
  > `readonly` `static` **CLASS\_NAME**: `string`
46
46
 
@@ -48,7 +48,7 @@ Runtime name for the class.
48
48
 
49
49
  ## Methods
50
50
 
51
- ### load()
51
+ ### load() {#load}
52
52
 
53
53
  > **load**(`engineCore`): `Promise`\<`S` \| `undefined`\>
54
54
 
@@ -74,7 +74,7 @@ The state of the engine or undefined if it doesn't exist.
74
74
 
75
75
  ***
76
76
 
77
- ### save()
77
+ ### save() {#save}
78
78
 
79
79
  > **save**(`engineCore`, `state`): `Promise`\<`void`\>
80
80
 
@@ -40,7 +40,7 @@ The initial state.
40
40
 
41
41
  ## Properties
42
42
 
43
- ### CLASS\_NAME
43
+ ### CLASS\_NAME {#class_name}
44
44
 
45
45
  > `readonly` `static` **CLASS\_NAME**: `string`
46
46
 
@@ -48,7 +48,7 @@ Runtime name for the class.
48
48
 
49
49
  ## Methods
50
50
 
51
- ### load()
51
+ ### load() {#load}
52
52
 
53
53
  > **load**(`engineCore`): `Promise`\<`S` \| `undefined`\>
54
54
 
@@ -74,7 +74,7 @@ The state of the engine or undefined if it doesn't exist.
74
74
 
75
75
  ***
76
76
 
77
- ### save()
77
+ ### save() {#save}
78
78
 
79
79
  > **save**(`engineCore`, `state`): `Promise`\<`void`\>
80
80
 
@@ -14,33 +14,33 @@ The options for creating engine core.
14
14
 
15
15
  ## Properties
16
16
 
17
- ### config?
17
+ ### config? {#config}
18
18
 
19
- > `optional` **config**: `C`
19
+ > `optional` **config?**: `C`
20
20
 
21
21
  The engine core config.
22
22
 
23
23
  ***
24
24
 
25
- ### stateStorage?
25
+ ### stateStorage? {#statestorage}
26
26
 
27
- > `optional` **stateStorage**: `IEngineStateStorage`\<`S`\>
27
+ > `optional` **stateStorage?**: `IEngineStateStorage`\<`S`\>
28
28
 
29
29
  The state storage component.
30
30
 
31
31
  ***
32
32
 
33
- ### skipBootstrap?
33
+ ### skipBootstrap? {#skipbootstrap}
34
34
 
35
- > `optional` **skipBootstrap**: `boolean`
35
+ > `optional` **skipBootstrap?**: `boolean`
36
36
 
37
37
  Skip the bootstrap process, useful for additional engine instances.
38
38
 
39
39
  ***
40
40
 
41
- ### populateTypeInitialisers()?
41
+ ### populateTypeInitialisers? {#populatetypeinitialisers}
42
42
 
43
- > `optional` **populateTypeInitialisers**: (`engineCore`, `context`) => `void`
43
+ > `optional` **populateTypeInitialisers?**: (`engineCore`, `context`) => `void`
44
44
 
45
45
  Populate the type initialisers for the engine.
46
46
 
@@ -60,9 +60,9 @@ Populate the type initialisers for the engine.
60
60
 
61
61
  ***
62
62
 
63
- ### customBootstrap()?
63
+ ### customBootstrap? {#custombootstrap}
64
64
 
65
- > `optional` **customBootstrap**: (`engineCore`, `context`) => `Promise`\<`void`\>
65
+ > `optional` **customBootstrap?**: (`engineCore`, `context`) => `Promise`\<`void`\>
66
66
 
67
67
  Custom bootstrap method for the engine.
68
68
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@twin.org/engine-core",
3
- "version": "0.0.3-next.26",
4
- "description": "Engine core.",
3
+ "version": "0.0.3-next.27",
4
+ "description": "Core runtime lifecycle and state orchestration for engine instances.",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/twinfoundation/engine.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.26",
21
+ "@twin.org/engine-models": "0.0.3-next.27",
22
22
  "@twin.org/entity": "next",
23
23
  "@twin.org/logging-connector-console": "next",
24
24
  "@twin.org/logging-models": "next",