@things-factory/headless-twin 10.0.9 → 10.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/engine/canonical-ingest.d.ts +2 -2
- package/dist-server/engine/canonical-ingest.js +24 -2
- package/dist-server/engine/canonical-ingest.js.map +1 -1
- package/dist-server/engine/command-routing.js +1 -1
- package/dist-server/engine/command-routing.js.map +1 -1
- package/dist-server/engine/energy-topology.d.ts +86 -0
- package/dist-server/engine/energy-topology.js +144 -0
- package/dist-server/engine/energy-topology.js.map +1 -0
- package/dist-server/engine/index.d.ts +8 -3
- package/dist-server/engine/index.js +10 -3
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/kpi-baseline.d.ts +1 -1
- package/dist-server/engine/kpi-baseline.js.map +1 -1
- package/dist-server/engine/kpi-fold.d.ts +137 -1
- package/dist-server/engine/kpi-fold.js +225 -0
- package/dist-server/engine/kpi-fold.js.map +1 -1
- package/dist-server/engine/kpi-query.d.ts +1 -1
- package/dist-server/engine/kpi-query.js +212 -18
- package/dist-server/engine/kpi-query.js.map +1 -1
- package/dist-server/engine/kpi-target.d.ts +17 -0
- package/dist-server/engine/kpi-target.js +24 -2
- package/dist-server/engine/kpi-target.js.map +1 -1
- package/dist-server/engine/live-feed-registry.d.ts +25 -0
- package/dist-server/engine/live-feed-registry.js +51 -0
- package/dist-server/engine/live-feed-registry.js.map +1 -0
- package/dist-server/engine/load-meter.d.ts +181 -0
- package/dist-server/engine/load-meter.js +267 -0
- package/dist-server/engine/load-meter.js.map +1 -0
- package/dist-server/engine/local-declarations.d.ts +262 -0
- package/dist-server/engine/local-declarations.js +528 -0
- package/dist-server/engine/local-declarations.js.map +1 -0
- package/dist-server/engine/model-basis.d.ts +39 -6
- package/dist-server/engine/model-basis.js +69 -9
- package/dist-server/engine/model-basis.js.map +1 -1
- package/dist-server/engine/{board-vocabulary.d.ts → model-vocabulary.d.ts} +4 -4
- package/dist-server/engine/{board-vocabulary.js → model-vocabulary.js} +37 -19
- package/dist-server/engine/model-vocabulary.js.map +1 -0
- package/dist-server/engine/oee-accumulator.d.ts +28 -0
- package/dist-server/engine/oee-accumulator.js +26 -1
- package/dist-server/engine/oee-accumulator.js.map +1 -1
- package/dist-server/engine/operation-basis.d.ts +32 -0
- package/dist-server/engine/operation-basis.js +87 -0
- package/dist-server/engine/operation-basis.js.map +1 -0
- package/dist-server/engine/property-effects.d.ts +30 -0
- package/dist-server/engine/property-effects.js +192 -0
- package/dist-server/engine/property-effects.js.map +1 -0
- package/dist-server/engine/runtime-key.d.ts +1 -1
- package/dist-server/engine/runtime-key.js +1 -1
- package/dist-server/engine/runtime-key.js.map +1 -1
- package/dist-server/engine/spec-coverage.js +3 -3
- package/dist-server/engine/spec-coverage.js.map +1 -1
- package/dist-server/engine/state-axes.d.ts +7 -2
- package/dist-server/engine/state-axes.js +8 -3
- package/dist-server/engine/state-axes.js.map +1 -1
- package/dist-server/engine/structure-diff.js +1 -1
- package/dist-server/engine/structure-diff.js.map +1 -1
- package/dist-server/engine/travel-estimator.d.ts +9 -2
- package/dist-server/engine/travel-estimator.js +11 -6
- package/dist-server/engine/travel-estimator.js.map +1 -1
- package/dist-server/engine/twin-engine.d.ts +332 -47
- package/dist-server/engine/twin-engine.js +1314 -279
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/engine/warm-start.d.ts +38 -4
- package/dist-server/engine/warm-start.js +38 -9
- package/dist-server/engine/warm-start.js.map +1 -1
- package/dist-server/index.d.ts +1 -0
- package/dist-server/index.js +17 -11
- package/dist-server/index.js.map +1 -1
- package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.d.ts +5 -0
- package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js +48 -0
- package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js.map +1 -0
- package/dist-server/migrations/index.d.ts +2 -0
- package/dist-server/migrations/index.js +10 -0
- package/dist-server/migrations/index.js.map +1 -0
- package/dist-server/service/index.d.ts +3 -2
- package/dist-server/service/index.js +25 -17
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/reference/discovery-result.d.ts +1 -1
- package/dist-server/service/reference/discovery-result.js +2 -2
- package/dist-server/service/reference/discovery-result.js.map +1 -1
- package/dist-server/service/reference/ingest-space.d.ts +24 -1
- package/dist-server/service/reference/ingest-space.js +17 -1
- package/dist-server/service/reference/ingest-space.js.map +1 -1
- package/dist-server/service/reference/reference-live.d.ts +23 -0
- package/dist-server/service/reference/reference-live.js +121 -4
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +194 -13
- package/dist-server/service/reference/reference-master.js +159 -28
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-resolver.d.ts +31 -1
- package/dist-server/service/reference/reference-resolver.js +223 -12
- package/dist-server/service/reference/reference-resolver.js.map +1 -1
- package/dist-server/service/reference/template-registry.d.ts +19 -3
- package/dist-server/service/reference/template-registry.js.map +1 -1
- package/dist-server/service/twin-audit/command-audit.d.ts +37 -0
- package/dist-server/service/twin-audit/command-audit.js +53 -0
- package/dist-server/service/twin-audit/command-audit.js.map +1 -0
- package/dist-server/service/twin-audit/index.d.ts +4 -0
- package/dist-server/service/twin-audit/index.js +8 -0
- package/dist-server/service/twin-audit/index.js.map +1 -0
- package/dist-server/service/twin-audit/twin-audit-event.d.ts +24 -0
- package/dist-server/service/twin-audit/twin-audit-event.js +141 -0
- package/dist-server/service/twin-audit/twin-audit-event.js.map +1 -0
- package/dist-server/service/twin-audit/twin-audit-query.d.ts +4 -0
- package/dist-server/service/twin-audit/twin-audit-query.js +76 -0
- package/dist-server/service/twin-audit/twin-audit-query.js.map +1 -0
- package/dist-server/service/twin-control/twin-control-mutation.js +21 -1
- package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
- package/dist-server/service/twin-event/twin-event-keys.d.ts +1 -1
- package/dist-server/service/twin-event/twin-event-keys.js +1 -1
- package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
- package/dist-server/service/twin-event/twin-event.d.ts +14 -5
- package/dist-server/service/twin-event/twin-event.js +45 -13
- package/dist-server/service/twin-event/twin-event.js.map +1 -1
- package/dist-server/service/twin-forecast/forecast-metrics.d.ts +13 -0
- package/dist-server/service/twin-forecast/forecast-metrics.js +57 -0
- package/dist-server/service/twin-forecast/forecast-metrics.js.map +1 -0
- package/dist-server/service/twin-forecast/forecast-tuning.d.ts +12 -0
- package/dist-server/service/twin-forecast/forecast-tuning.js +44 -0
- package/dist-server/service/twin-forecast/forecast-tuning.js.map +1 -0
- package/dist-server/service/twin-forecast/gap-analytics.d.ts +28 -2
- package/dist-server/service/twin-forecast/gap-analytics.js +43 -17
- package/dist-server/service/twin-forecast/gap-analytics.js.map +1 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js +217 -38
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
- package/dist-server/service/twin-instance/twin-instance.d.ts +38 -5
- package/dist-server/service/twin-instance/twin-instance.js +66 -20
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/twin-journal-query.d.ts +5 -2
- package/dist-server/service/twin-journal/twin-journal-query.js +71 -9
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +3 -5
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +24 -27
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.d.ts +1 -0
- package/dist-server/service/twin-metrics/twin-metrics-query.js +62 -0
- package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
- package/dist-server/service/twin-model/epcis-coverage.d.ts +14 -0
- package/dist-server/service/twin-model/epcis-coverage.js +174 -0
- package/dist-server/service/twin-model/epcis-coverage.js.map +1 -0
- package/dist-server/service/twin-model/iec61850-coverage.d.ts +14 -0
- package/dist-server/service/twin-model/iec61850-coverage.js +98 -0
- package/dist-server/service/twin-model/iec61850-coverage.js.map +1 -0
- package/dist-server/service/twin-model/index.d.ts +13 -0
- package/dist-server/service/twin-model/index.js +29 -0
- package/dist-server/service/twin-model/index.js.map +1 -0
- package/dist-server/service/twin-model/isa95-coverage.d.ts +48 -0
- package/dist-server/service/twin-model/isa95-coverage.js +155 -0
- package/dist-server/service/twin-model/isa95-coverage.js.map +1 -0
- package/dist-server/service/twin-model/project-structure.d.ts +16 -0
- package/dist-server/service/twin-model/project-structure.js +173 -0
- package/dist-server/service/twin-model/project-structure.js.map +1 -0
- package/dist-server/service/twin-model/standard-coverage.d.ts +9 -0
- package/dist-server/service/twin-model/standard-coverage.js +37 -0
- package/dist-server/service/twin-model/standard-coverage.js.map +1 -0
- package/dist-server/service/twin-model/twin-equipment.d.ts +64 -0
- package/dist-server/service/twin-model/twin-equipment.js +134 -0
- package/dist-server/service/twin-model/twin-equipment.js.map +1 -0
- package/dist-server/service/twin-model/twin-lineage-query.d.ts +3 -0
- package/dist-server/service/twin-model/twin-lineage-query.js +206 -0
- package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -0
- package/dist-server/service/twin-model/twin-location.d.ts +58 -0
- package/dist-server/service/twin-model/twin-location.js +130 -0
- package/dist-server/service/twin-model/twin-location.js.map +1 -0
- package/dist-server/service/twin-model/twin-model-item-query.d.ts +141 -0
- package/dist-server/service/twin-model/twin-model-item-query.js +852 -0
- package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -0
- package/dist-server/service/twin-model/twin-model-mutation.d.ts +57 -0
- package/dist-server/service/twin-model/twin-model-mutation.js +490 -0
- package/dist-server/service/twin-model/twin-model-mutation.js.map +1 -0
- package/dist-server/service/twin-model/twin-model-query.d.ts +43 -0
- package/dist-server/service/twin-model/twin-model-query.js +551 -0
- package/dist-server/service/twin-model/twin-model-query.js.map +1 -0
- package/dist-server/service/twin-model/twin-model-tree-query.d.ts +3 -0
- package/dist-server/service/twin-model/twin-model-tree-query.js +158 -0
- package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -0
- package/dist-server/service/twin-model/twin-operation.d.ts +61 -0
- package/dist-server/service/twin-model/twin-operation.js +137 -0
- package/dist-server/service/twin-model/twin-operation.js.map +1 -0
- package/dist-server/service/twin-space/move-space.d.ts +65 -0
- package/dist-server/service/twin-space/move-space.js +166 -0
- package/dist-server/service/twin-space/move-space.js.map +1 -0
- package/dist-server/service/twin-space/space-integrity.d.ts +97 -0
- package/dist-server/service/twin-space/space-integrity.js +182 -0
- package/dist-server/service/twin-space/space-integrity.js.map +1 -0
- package/dist-server/service/twin-space/twin-space-area.js +4 -4
- package/dist-server/service/twin-space/twin-space-area.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-representation.js +6 -6
- package/dist-server/service/twin-space/twin-space-representation.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-resolver.d.ts +63 -1
- package/dist-server/service/twin-space/twin-space-resolver.js +356 -18
- package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
- package/dist-server/service/twin-space/twin-space.d.ts +17 -1
- package/dist-server/service/twin-space/twin-space.js +15 -5
- package/dist-server/service/twin-space/twin-space.js.map +1 -1
- package/dist-server/service/twin-structure/twin-structure.d.ts +1 -1
- package/dist-server/service/twin-structure/twin-structure.js +8 -8
- package/dist-server/service/twin-structure/twin-structure.js.map +1 -1
- package/dist-shared/axis-read.d.ts +12 -0
- package/dist-shared/axis-read.js +32 -0
- package/dist-shared/axis-read.js.map +1 -0
- package/{dist-server/engine → dist-shared}/entity-delta.d.ts +3 -0
- package/{dist-server/engine → dist-shared}/entity-delta.js +102 -2
- package/dist-shared/entity-delta.js.map +1 -0
- package/dist-shared/kpi-broadcast.js.map +1 -0
- package/dist-shared/twin-level.js.map +1 -0
- package/package.json +14 -12
- package/server/engine/canonical-ingest.ts +36 -4
- package/server/engine/command-routing.ts +1 -1
- package/server/engine/energy-topology.ts +189 -0
- package/server/engine/index.ts +10 -3
- package/server/engine/kpi-baseline.ts +1 -1
- package/server/engine/kpi-fold.ts +389 -1
- package/server/engine/kpi-query.ts +214 -19
- package/server/engine/kpi-target.ts +24 -2
- package/server/engine/live-feed-registry.ts +58 -0
- package/server/engine/load-meter.ts +384 -0
- package/server/engine/local-declarations.ts +700 -0
- package/server/engine/model-basis.ts +78 -10
- package/server/engine/{board-vocabulary.ts → model-vocabulary.ts} +36 -15
- package/server/engine/oee-accumulator.ts +34 -1
- package/server/engine/operation-basis.ts +100 -0
- package/server/engine/property-effects.ts +199 -0
- package/server/engine/runtime-key.ts +1 -1
- package/server/engine/spec-coverage.ts +3 -3
- package/server/engine/state-axes.ts +8 -3
- package/server/engine/structure-diff.ts +1 -1
- package/server/engine/travel-estimator.ts +11 -6
- package/server/engine/twin-engine.ts +1414 -274
- package/server/engine/warm-start.ts +83 -12
- package/server/index.ts +13 -10
- package/server/migrations/1786000000000-RenameTwinInstanceBoardToModel.ts +43 -0
- package/server/migrations/index.ts +7 -0
- package/server/service/index.ts +9 -1
- package/server/service/reference/discovery-result.ts +2 -2
- package/server/service/reference/ingest-space.ts +35 -1
- package/server/service/reference/reference-live.ts +119 -4
- package/server/service/reference/reference-master.ts +276 -35
- package/server/service/reference/reference-resolver.ts +232 -12
- package/server/service/reference/template-registry.ts +20 -5
- package/server/service/twin-audit/command-audit.ts +81 -0
- package/server/service/twin-audit/index.ts +5 -0
- package/server/service/twin-audit/twin-audit-event.ts +138 -0
- package/server/service/twin-audit/twin-audit-query.ts +72 -0
- package/server/service/twin-control/twin-control-mutation.ts +22 -1
- package/server/service/twin-event/twin-event-keys.ts +1 -1
- package/server/service/twin-event/twin-event.ts +59 -14
- package/server/service/twin-forecast/forecast-metrics.ts +60 -0
- package/server/service/twin-forecast/forecast-tuning.ts +40 -0
- package/server/service/twin-forecast/gap-analytics.ts +48 -9
- package/server/service/twin-forecast/twin-forecast-query.ts +208 -36
- package/server/service/twin-instance/twin-instance.ts +126 -25
- package/server/service/twin-journal/twin-journal-query.ts +74 -10
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +23 -22
- package/server/service/twin-metrics/twin-metrics-query.ts +59 -2
- package/server/service/twin-model/epcis-coverage.ts +195 -0
- package/server/service/twin-model/iec61850-coverage.ts +117 -0
- package/server/service/twin-model/index.ts +25 -0
- package/server/service/twin-model/isa95-coverage.ts +190 -0
- package/server/service/twin-model/project-structure.ts +199 -0
- package/server/service/twin-model/standard-coverage.ts +35 -0
- package/server/service/twin-model/twin-equipment.ts +157 -0
- package/server/service/twin-model/twin-lineage-query.ts +193 -0
- package/server/service/twin-model/twin-location.ts +147 -0
- package/server/service/twin-model/twin-model-item-query.ts +848 -0
- package/server/service/twin-model/twin-model-mutation.ts +503 -0
- package/server/service/twin-model/twin-model-query.ts +537 -0
- package/server/service/twin-model/twin-model-tree-query.ts +180 -0
- package/server/service/twin-model/twin-operation.ts +157 -0
- package/server/service/twin-space/move-space.ts +262 -0
- package/server/service/twin-space/space-integrity.ts +293 -0
- package/server/service/twin-space/twin-space-area.ts +4 -4
- package/server/service/twin-space/twin-space-representation.ts +6 -6
- package/server/service/twin-space/twin-space-resolver.ts +355 -21
- package/server/service/twin-space/twin-space.ts +40 -6
- package/server/service/twin-structure/twin-structure.ts +10 -10
- package/shared/axis-read.ts +28 -0
- package/{server/engine → shared}/entity-delta.ts +96 -1
- package/test/adopt-structure-live.test.ts +133 -0
- package/test/attention-digest.test.ts +3 -3
- package/test/axis-read.test.ts +87 -0
- package/test/boot-resume.test.ts +205 -0
- package/test/canonical-ingest-vocabularies.test.ts +118 -0
- package/test/capability-mapping.test.ts +1 -1
- package/test/column-type-portability.test.ts +122 -0
- package/test/command-routing.test.ts +1 -1
- package/test/declaration-reaches-model.test.ts +178 -0
- package/test/discovery-result.test.ts +1 -1
- package/test/energy-topology.test.ts +113 -0
- package/test/entity-delta.test.ts +171 -1
- package/test/event-time-column.test.ts +67 -0
- package/test/forecast-metrics.test.ts +71 -0
- package/test/forecast-tuning.test.ts +42 -0
- package/test/gap-analytics.test.ts +34 -7
- package/test/ingest-bench.test.ts +6 -6
- package/test/ingest-running-guard.test.ts +136 -0
- package/test/ingest-space.test.ts +29 -1
- package/test/instance-cache-lifecycle.test.ts +110 -0
- package/test/kernel-kind-guard.test.ts +96 -0
- package/test/kpi-baseline-db.test.ts +3 -1
- package/test/kpi-baseline.test.ts +3 -3
- package/test/kpi-fold.test.ts +393 -2
- package/test/kpi-query-bench.test.ts +5 -3
- package/test/lineage-survives-restart.test.ts +203 -0
- package/test/live-feed-registry.test.ts +67 -0
- package/test/live-kernel-facts.test.ts +161 -0
- package/test/live-mirror-parity.test.ts +22 -15
- package/test/load-meter.test.ts +314 -0
- package/test/local-declarations.test.ts +554 -0
- package/test/master-to-twin.test.ts +121 -33
- package/test/model-basis.test.ts +56 -1
- package/test/{board-vocabulary.test.ts → model-vocabulary.test.ts} +25 -25
- package/test/move-space.test.ts +149 -0
- package/test/mutation-gate.test.ts +19 -5
- package/test/oee-accumulator.test.ts +26 -7
- package/test/operation-basis.test.ts +100 -0
- package/test/operations-capability-db.test.ts +165 -0
- package/test/project-structure-db.test.ts +226 -0
- package/test/projection-reaches-screen.test.ts +272 -0
- package/test/property-effects.test.ts +96 -0
- package/test/resync-origin-site.test.ts +77 -0
- package/test/scale-twin-bench.test.ts +5 -5
- package/test/snapshot-freshness.test.ts +60 -0
- package/test/space-integrity.test.ts +223 -0
- package/test/standard-coverage.test.ts +94 -0
- package/test/state-axes.test.ts +1 -1
- package/test/streamline-e2e.test.ts +14 -14
- package/test/structure-revision-db.test.ts +11 -11
- package/test/tenant-registry-db.test.ts +5 -5
- package/test/twin-audit.test.ts +83 -0
- package/test/twin-model-item-db.test.ts +275 -0
- package/test/twin-model-tree-db.test.ts +176 -0
- package/test/twin-origin-resync.test.ts +114 -0
- package/test/warm-start-seam.test.ts +6 -6
- package/test/warm-start.test.ts +88 -3
- package/tsconfig.json +6 -1
- package/tsconfig.shared.json +23 -0
- package/tsconfig.shared.tsbuildinfo +1 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/dist-server/engine/board-vocabulary.js.map +0 -1
- package/dist-server/engine/entity-delta.js.map +0 -1
- package/dist-server/engine/kpi-broadcast.js.map +0 -1
- package/dist-server/engine/twin-level.js.map +0 -1
- package/dist-server/service/twin-event/backfill-keys.d.ts +0 -11
- package/dist-server/service/twin-event/backfill-keys.js +0 -63
- package/dist-server/service/twin-event/backfill-keys.js.map +0 -1
- package/dist-server/tsconfig.tsbuildinfo +0 -1
- package/server/service/twin-event/backfill-keys.ts +0 -72
- /package/{dist-server/engine → dist-shared}/kpi-broadcast.d.ts +0 -0
- /package/{dist-server/engine → dist-shared}/kpi-broadcast.js +0 -0
- /package/{dist-server/engine → dist-shared}/twin-level.d.ts +0 -0
- /package/{dist-server/engine → dist-shared}/twin-level.js +0 -0
- /package/{server/engine → shared}/kpi-broadcast.ts +0 -0
- /package/{server/engine → shared}/twin-level.ts +0 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type { ReducerCheckpoint } from '@operato/twin-kernel';
|
|
2
|
+
import type { OeeCheckpoint } from './oee-accumulator.js';
|
|
1
3
|
import { type ReferenceMaster } from '../service/reference/reference-master.js';
|
|
2
4
|
import { type IngestWarning } from '../service/reference/reference-master.js';
|
|
3
5
|
import { type ModelBasis } from './model-basis.js';
|
|
6
|
+
import { type LoadMeter, type LoadPhase } from './load-meter.js';
|
|
4
7
|
import { type StructureDiff } from './structure-diff.js';
|
|
5
8
|
import { OeeAccumulator } from './oee-accumulator.js';
|
|
6
|
-
import type {
|
|
9
|
+
import type { TwinModelDef, StructureShift, TwinRuntime as TwinRuntimeType, CanonicalEnvelope } from '@operato/twin-kernel';
|
|
7
10
|
interface TwinMetrics {
|
|
8
11
|
ingestedTotal: number;
|
|
9
12
|
broadcastTotal: number;
|
|
@@ -20,6 +23,8 @@ interface TwinMetrics {
|
|
|
20
23
|
export type RealityMode = 'mirror' | 'sim-world' | 'sim-experiment';
|
|
21
24
|
export declare const DEFAULT_REALITY_MODE: RealityMode;
|
|
22
25
|
interface InstanceRuntime {
|
|
26
|
+
/** 부하 계기판 — 작업별 소요. 시뮬·라이브 모두 붙는다(누가 루프를 점유하는지 보려면 둘 다 필요하다). */
|
|
27
|
+
load?: LoadMeter;
|
|
23
28
|
/** 현실 출처 선언(§0 프레임 ①). 부팅 거동(reset/resume/resync)의 근거. */
|
|
24
29
|
realityMode?: RealityMode;
|
|
25
30
|
id: string;
|
|
@@ -28,6 +33,8 @@ interface InstanceRuntime {
|
|
|
28
33
|
runtime?: TwinRuntimeType;
|
|
29
34
|
kernel?: any;
|
|
30
35
|
mode?: 'sim' | 'live';
|
|
36
|
+
/** 이 트윈이 선 현장 — 같은 현장의 트윈끼리 서로의 설비 상태를 읽을 수 있게 하는 열쇠. */
|
|
37
|
+
spaceId?: string;
|
|
31
38
|
/**
|
|
32
39
|
* live 의 상태 접근 어댑터 — 이제 **관측 모드 커널**을 가리킨다(`kernel` 과 같은 것).
|
|
33
40
|
* 이름은 소비처 호환으로 남았고, P3 에서 커널 어휘로 정리하면 사라진다.
|
|
@@ -35,6 +42,11 @@ interface InstanceRuntime {
|
|
|
35
42
|
projector?: any;
|
|
36
43
|
oee?: OeeAccumulator;
|
|
37
44
|
unsub: () => void;
|
|
45
|
+
/**
|
|
46
|
+
* 방금 인입한 봉투들 — 커널이 그것을 재방출할 때 **저널에 두 번 적지 않기** 위한 표시.
|
|
47
|
+
* 라이브만 쓴다(sim 은 커널이 스스로 낸 것만 흘린다). 약한 참조라 따로 비울 것이 없다.
|
|
48
|
+
*/
|
|
49
|
+
applying?: WeakSet<object>;
|
|
38
50
|
timer?: any;
|
|
39
51
|
/** 엔티티별 마지막 발행 시그니처 — 값이 바뀐 엔티티만 재발행(무변화 반복 push 방지). */
|
|
40
52
|
entitySigs?: Map<string, string>;
|
|
@@ -47,23 +59,93 @@ interface InstanceRuntime {
|
|
|
47
59
|
/** live 처리량 계측(모니터, ④-1). */
|
|
48
60
|
metrics?: TwinMetrics;
|
|
49
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* 트윈이 **스스로 멈춘 이유** — 문장이 아니라 코드다.
|
|
64
|
+
*
|
|
65
|
+
* 서버가 만든 영어 문장을 그대로 실으면 한국어·일본어 화면에 그 영어가 뜬다. 이 시스템은 거절 메시지에서
|
|
66
|
+
* 같은 결론에 이르렀다(코드+파라미터를 내고 화면이 옮긴다). `reason` 만은 원문 그대로다 — 커널·런타임이
|
|
67
|
+
* 낸 오류 문구는 옮길 수 있는 어휘가 아니고, 옮기려 들면 원인을 잃는다.
|
|
68
|
+
*/
|
|
69
|
+
export interface StopNote {
|
|
70
|
+
code: 'starved' | 'tick-failed';
|
|
71
|
+
params: Record<string, string | number>;
|
|
72
|
+
}
|
|
50
73
|
export declare class TwinEngine {
|
|
51
74
|
static instances: Record<string, InstanceRuntime>;
|
|
52
75
|
/** 라이브 런타임이 없을 때(복구 후 미기동) 저널에서 재구성한 상태 캐시. */
|
|
53
76
|
/** 웜스타트 씨앗 — `instances` 와 **같은 키**(겹치면 남의 스냅샷으로 재고가 섞인다). */
|
|
54
77
|
static recovered: Record<string, any>;
|
|
55
78
|
static TICK_MS: number;
|
|
79
|
+
/** 굶김 문턱 — 틱 간격의 배수(1초 간격이면 5초). 이 시간만큼 호스트가 멈춘다. */
|
|
80
|
+
static STARVE_FACTOR: number;
|
|
81
|
+
/** 연속 몇 번이면 멈추나 — 3번이면 15초를 굶긴 셈이고, 그건 우연이 아니다. */
|
|
82
|
+
static STARVE_STREAK: number;
|
|
83
|
+
private static starveStreak;
|
|
84
|
+
/**
|
|
85
|
+
* 왜 멈췄나 — **화면이 그대로 말할 수 있게.** 스스로 멈춘 트윈이 이유 없이 「정지」로만 보이면
|
|
86
|
+
* 사람은 자기가 멈춘 줄 안다. 메모리에만 둔다(재기동하면 사라진다 — 그때는 「모른다」가 사실이다).
|
|
87
|
+
*/
|
|
88
|
+
private static stopNotes;
|
|
56
89
|
static SNAPSHOT_CACHE_ID: string;
|
|
90
|
+
static CHAIN_CACHE_ID: string;
|
|
91
|
+
static CHAIN_INDEX_CACHE_ID: string;
|
|
92
|
+
static CHAIN_STRIDE: number;
|
|
93
|
+
static CHAIN_KEEP: number;
|
|
57
94
|
static SNAPSHOT_TTL_S: number;
|
|
58
95
|
static CHECKPOINT_MS: number;
|
|
59
96
|
private static checkpointTimer?;
|
|
60
97
|
/** 최신 스냅샷을 cache-service 에 체크포인트(도메인+instanceId 키). display-only·비차단·오류흡수. */
|
|
61
98
|
static persistSnapshot(domainId: string, instanceId: string): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* 접기의 **재개점** — 리듀서 내부 상태 전부 + 가동 누적기.
|
|
101
|
+
*
|
|
102
|
+
* 스냅샷(`state`)은 소비처가 보는 값이라 이어 접기의 씨앗이 되지 못한다(보류된 담김·집합·반영 못 한
|
|
103
|
+
* 사건 집계가 없다 — 그 상태로 뒤를 접으면 0부터 접은 결과와 조용히 달라진다). 그래서 씨앗은 따로 든다.
|
|
104
|
+
*/
|
|
105
|
+
private static readonly FOLD_NOTE;
|
|
62
106
|
/** 체크포인트된 최신 스냅샷 로드(없으면 null). getFromCache 는 CacheStore 엔티티를 반환 → 페이로드는 .value. */
|
|
63
107
|
static loadSnapshot(domainId: string, instanceId: string): Promise<{
|
|
64
108
|
revision: number;
|
|
65
109
|
state: any;
|
|
110
|
+
structureRev?: number | null;
|
|
111
|
+
fold?: {
|
|
112
|
+
reducer: ReducerCheckpoint;
|
|
113
|
+
oee: OeeCheckpoint;
|
|
114
|
+
};
|
|
66
115
|
} | null>;
|
|
116
|
+
/**
|
|
117
|
+
* 접은 상태를 스냅샷으로 남긴다 — **라이브가 아니어도.**
|
|
118
|
+
*
|
|
119
|
+
* `persistSnapshot` 은 기동 중인 인스턴스에서만 뜬다(메모리가 진실이므로 옳다). 그런데 **멈춘**
|
|
120
|
+
* 트윈을 조회할 때마다 저널을 전량 다시 접고 있었다(23,731건짜리 트윈에서 4.6초). 그 폴드의 결과를
|
|
121
|
+
* 남겨 두면 **처음 한 번만 느리다.**
|
|
122
|
+
*
|
|
123
|
+
* `structureRev` 를 함께 적는다: 이벤트가 하나도 안 늘어도 구조를 갈아치우면(재프로비저닝) 그
|
|
124
|
+
* 상태는 낡은 것이다. 리비전만 보면 새 설비가 없는 옛 상태를 "지금" 으로 내게 된다.
|
|
125
|
+
*/
|
|
126
|
+
static saveFoldedSnapshot(domainId: string, instanceId: string, value: {
|
|
127
|
+
revision: number;
|
|
128
|
+
state: any;
|
|
129
|
+
structureRev?: number | null;
|
|
130
|
+
fold?: {
|
|
131
|
+
reducer: ReducerCheckpoint;
|
|
132
|
+
oee: OeeCheckpoint;
|
|
133
|
+
};
|
|
134
|
+
}): Promise<void>;
|
|
135
|
+
/** 사슬 색인 — 어떤 리비전 지점을 들고 있나(최신순 아님, 오름차순). */
|
|
136
|
+
private static chainIndex;
|
|
137
|
+
/**
|
|
138
|
+
* 목표 이전의 **가장 가까운 지점**을 고른다 — 없으면 `null`(0부터 접는다).
|
|
139
|
+
*
|
|
140
|
+
* 시각으로 물었으면 그 지점의 마지막 사실 시각이 목표 이내여야 한다(리비전만 보면 목표보다 뒤의
|
|
141
|
+
* 사실이 씨앗에 섞인다). 구조가 바뀐 트윈에서는 쓰지 않는다 — 마디를 건너뛴 씨앗은 그 경계의
|
|
142
|
+
* 판정을 잃는다(그 경우는 0부터 접는 것이 옳다).
|
|
143
|
+
*/
|
|
144
|
+
private static chainSeedFor;
|
|
145
|
+
/** 눈금을 넘었으면 한 지점을 남긴다 — 오래된 것은 버린다(색인도 함께 줄인다). */
|
|
146
|
+
private static keepChainPoint;
|
|
147
|
+
/** 이 트윈 저널의 끝 리비전 · 최신 구조 리비전 — 스냅샷이 지금의 사실인지 가리는 두 값. */
|
|
148
|
+
private static tipOf;
|
|
67
149
|
/** 체크포인트 루프 기동(1회) — 라이브 인스턴스들의 최신 스냅샷을 주기 영속. */
|
|
68
150
|
static startCheckpointLoop(): void;
|
|
69
151
|
/**
|
|
@@ -72,10 +154,30 @@ export declare class TwinEngine {
|
|
|
72
154
|
*/
|
|
73
155
|
static bootstrap(): Promise<void>;
|
|
74
156
|
/**
|
|
75
|
-
*
|
|
157
|
+
* 부팅 때 **도는 트윈을 실제로 되살린다** — 「도는 중」이 사실이 되게.
|
|
158
|
+
*
|
|
159
|
+
* ── 무엇이 거짓말이었나 (2026-08-14) ────────────────────────────────────────
|
|
160
|
+
* `bootstrap()` 은 상태만 되찾아 `recovered` 에 담았고, 커널을 세우는 것은 **명시 mutation 뿐**이었다
|
|
161
|
+
* (이 파일 위쪽 주석이 「향후」라고 적어 둔 그 자리다). 그래서 서버를 한 번 재기동하면 등록부는
|
|
162
|
+
* `running` 이라 말하는데 **아무 커널도 돌지 않았다** — 화면은 도는 트윈을, 실제로는 멈춘 트윈을.
|
|
163
|
+
* 미러 트윈에서는 더 나쁘다: 계측이 조용히 끊기고, 사람은 「값이 안 변하네」로 알게 된다.
|
|
164
|
+
*
|
|
165
|
+
* ── 모드를 지어내지 않는다 ──────────────────────────────────────────────────
|
|
166
|
+
* 미러였던 트윈을 시뮬로 되살리면 **없던 움직임을 만들어 낸다**(관측 트윈이 스스로 물건을 옮긴다).
|
|
167
|
+
* 그래서 선언된 `realityMode` 그대로 되살린다 — 미러는 관측 구동으로, 시뮬은 시뮬로.
|
|
168
|
+
*
|
|
169
|
+
* ── 되살릴 수 없으면 그렇게 적는다 ──────────────────────────────────────────
|
|
170
|
+
* 실패를 삼키면 등록부가 계속 `running` 이라 말한다 — 우리가 고치려던 그 거짓말이다. 그래서 실패한
|
|
171
|
+
* 행은 `stopped` 로 적고 이유를 남긴다. 「멈췄다」는 사실이고, 「도는 중」은 사실이 아니었다.
|
|
172
|
+
*/
|
|
173
|
+
private static resumeRow;
|
|
174
|
+
/** 되살리지 못한 행을 정직하게 적는다 — 「도는 중」이라 말하는 채로 두지 않는다. */
|
|
175
|
+
private static markStopped;
|
|
176
|
+
/**
|
|
177
|
+
* 웜스타트 — 기동하는 커널에 **직전 관측 상태**를 주입한다.
|
|
76
178
|
*
|
|
77
179
|
* ── 왜 필요한가 ─────────────────────────────────────────────────────────────
|
|
78
|
-
* `
|
|
180
|
+
* `loadTwinModel` 는 **구조만** 싣는다(자리·설비). 상태(무엇이 어디에 얼마나)는 없다. 그래서 재기동한
|
|
79
181
|
* 트윈은 저널에 입고 540건이 남아 있어도 재고가 0 이었고, 화면은 "보유 중인 것이 없습니다" 라고
|
|
80
182
|
* 말했다 — 있는 재고를 없다고 하는 셈이다(2026-07-31 hatiolab-wms 실측으로 확인).
|
|
81
183
|
* `bootstrap()` 이 이미 체크포인트 캐시(없으면 저널 replay)로 상태를 복구해 `recovered` 에 담아 두는데,
|
|
@@ -92,19 +194,19 @@ export declare class TwinEngine {
|
|
|
92
194
|
* (이행 완료 오더 제외·고아 작업 제외)은 커널에 있고, 호스트가 미리 골라내지 않는다.
|
|
93
195
|
*
|
|
94
196
|
* ── 남은 한계는 숨기지 않고 센다 ────────────────────────────────────────────
|
|
95
|
-
* · 원값이 없는 오더(progress 만 있는 것)는 남은 수량을 알 수 없어
|
|
197
|
+
* · 원값이 없는 오더(progress 만 있는 것)는 남은 수량을 알 수 없어 주입하지 않는다. **지어내지 않는
|
|
96
198
|
* 대신 몇 건인지 말한다** — 세지 않으면 "주문이 없다" 와 "주문을 못 심었다" 가 화면에서 같아진다.
|
|
97
199
|
* · 진행 중 개별 작업의 내부 상태는 관측만으로 완전히 복원되지 않는다(커널이 명시한 한계, 재계획에 맡김).
|
|
98
200
|
*
|
|
99
201
|
* ── 벤치는 시드하지 않는다 ──────────────────────────────────────────────────
|
|
100
|
-
* 부하 벤치는 **새 시작에서 용량을 재는 것**이 목적이라 현재 상태를
|
|
202
|
+
* 부하 벤치는 **새 시작에서 용량을 재는 것**이 목적이라 현재 상태를 주입하면 측정이 오염된다.
|
|
101
203
|
*/
|
|
102
204
|
private static warmStart;
|
|
103
|
-
/** 트윈 인스턴스 시작 — 커널 생성 +
|
|
205
|
+
/** 트윈 인스턴스 시작 — 커널 생성 + 모델 로드 + 직전 상태 웜스타트 + State 스트림 브리지 + 워커 tick + 레지스트리 영속. */
|
|
104
206
|
/**
|
|
105
207
|
* 공정 명세를 커널에 싣는다 — **시뮬레이션의 시간을 데이터가 말하게 하는 마지막 한 칸.**
|
|
106
208
|
*
|
|
107
|
-
* `
|
|
209
|
+
* `model.operations`(마스터 인제스트가 통과시킨 ISA-95 OperationsSegment 명세)를 커널이 소비한다.
|
|
108
210
|
* 없으면 커널 기본 상수로 굴러가고, 커널 `specCoverage()` 가 무엇을 기본값으로 썼는지 보고한다.
|
|
109
211
|
*
|
|
110
212
|
* 커널이 아직 이 API 를 갖지 않은 버전이면(발행 이전) **조용히 넘어가지 않고 경고한다** — 명세를
|
|
@@ -116,14 +218,14 @@ export declare class TwinEngine {
|
|
|
116
218
|
*
|
|
117
219
|
* 커널 `durationOf` 의 우선순위는 추정기 > 명세 > 상수다. 그 추정기 자리에 두 가지를 사슬로 넣는다:
|
|
118
220
|
* ① **실측**(저널의 작업 종류별 작업시간 p50) — 그 현장에서 실제로 얼마 걸렸나. 가장 강한 근거.
|
|
119
|
-
* ② **거리 × 속도**(
|
|
221
|
+
* ② **거리 × 속도**(model.layout + 설비 속도 속성) — 이동은 거리에 비례한다. 커널은 좌표를 모르므로
|
|
120
222
|
* 호스트가 계산해 넣는다.
|
|
121
223
|
* 둘 다 못 만들면 주입하지 않는다 — 커널이 명세·상수로 굴러가고 `specCoverage()` 가 그 사실을 남긴다.
|
|
122
224
|
*
|
|
123
225
|
* 실측은 DB 조회라 비동기다. 그래서 이 함수는 **await 하지 않는 쪽에서도 안전**하도록 실패를 삼키되,
|
|
124
226
|
* 무엇을 왜 못 넣었는지는 로그로 남긴다(조용한 무효화 금지).
|
|
125
227
|
*/
|
|
126
|
-
static installEstimators(kernel: any, domainId: string, instanceId: string,
|
|
228
|
+
static installEstimators(kernel: any, domainId: string, instanceId: string, model: any): Promise<void>;
|
|
127
229
|
/**
|
|
128
230
|
* 실측 추정기 — **예측 요청마다 저널을 다시 접지 않는다.**
|
|
129
231
|
*
|
|
@@ -133,7 +235,33 @@ export declare class TwinEngine {
|
|
|
133
235
|
*/
|
|
134
236
|
private static measuredCache;
|
|
135
237
|
private static readonly MEASURED_TTL_MS;
|
|
238
|
+
/**
|
|
239
|
+
* 캐시 항목 상한 — **라이프사이클이 놓친 것까지 막는 두 번째 방어.**
|
|
240
|
+
*
|
|
241
|
+
* 지움은 `forgetInstance` 가 한다(그것이 첫 번째 방어이고 정확한 쪽이다). 그런데 트윈이 우리 API 를
|
|
242
|
+
* 지나지 않고 사라지는 길이 있다: 도메인(테넌트)째로 지워지거나 DB 를 직접 손대는 경우다. 그때
|
|
243
|
+
* 남은 항목을 지울 주인이 없으므로 상한이 필요하다.
|
|
244
|
+
*
|
|
245
|
+
* 넘치면 **가장 오래 손대지 않은 것**부터 버린다(Map 의 삽입 순서가 곧 그 순서다 — 값을 쓸 때마다
|
|
246
|
+
* 다시 넣으므로). 버리는 것이 손해가 아닌 이유: 이 값은 캐시이고, 없으면 다시 계산한다.
|
|
247
|
+
*
|
|
248
|
+
* 수를 크게 잡는다 — 트윈 규모는 늘 크고, 항목 하나는 작업 종류별 소요 몇 줄이다. 상한이 작으면
|
|
249
|
+
* 정상 규모에서 서로 밀어내며 캐시가 무의미해진다(그게 더 나쁘다: 조용히 느려진다).
|
|
250
|
+
*/
|
|
251
|
+
private static readonly MEASURED_MAX;
|
|
136
252
|
private static measuredEstimator;
|
|
253
|
+
/**
|
|
254
|
+
* 이 트윈이 **이력에서 시간을 배운 작업 종류들** — 재기동에도 남는 근거.
|
|
255
|
+
*
|
|
256
|
+
* ── 왜 필요한가 (2026-08-18 실측) ────────────────────────────────────────
|
|
257
|
+
* 커널의 자기보고(`specCoverage()`)는 **작업이 새로 생길 때** 채워진다. 그래서 재기동 직후에는 이력이
|
|
258
|
+
* 풍부한 트윈에서도 목록이 비고, 「이 트윈이 무슨 공정을 돌리나」 화면이 빈칸이 된다 — 값을 채울 곳을
|
|
259
|
+
* 보여야 하는 화면이 정작 그때 아무 말도 못 한다.
|
|
260
|
+
*
|
|
261
|
+
* 그 빈칸을 이력로 메운다: 저널에서 배운 종류는 **추정기가 이미 답할 수 있는 종류**이므로, 지어내는
|
|
262
|
+
* 것이 아니라 있는 사실을 꺼내는 것이다. 같은 캐시(60초)를 쓰므로 조회마다 저널을 다시 접지 않는다.
|
|
263
|
+
*/
|
|
264
|
+
static measuredOperationKinds(domainId: string, instanceId: string): Promise<string[]>;
|
|
137
265
|
/**
|
|
138
266
|
* 지금 이 트윈이 어떤 모델로 굴러가는가 — 예측 출력 보정이 **자기가 배운 모델**에만 적용되도록
|
|
139
267
|
* 비교하는 지문. 재료는 호스트가 아는 것(실측·속도·선언 명세)이라 커널 발행 상태와 무관하다.
|
|
@@ -141,13 +269,13 @@ export declare class TwinEngine {
|
|
|
141
269
|
*/
|
|
142
270
|
static modelBasis(domainId: string, instanceId: string): Promise<ModelBasis | undefined>;
|
|
143
271
|
/**
|
|
144
|
-
* **이 트윈이 하루 몇 대를 낼 수 있는가** —
|
|
272
|
+
* **이 트윈이 하루 몇 대를 낼 수 있는가** — 실행해 보지 않고 답한다.
|
|
145
273
|
*
|
|
146
274
|
* 계산은 커널이 자기 상태에서 한다(`kernel.capacity`). 여기서 하는 일은 **기준 주를 정해 주는
|
|
147
275
|
* 것**뿐이다: 공휴일이 없는 평상주여야 한다 — 공휴일은 연간 가용량을 따로 깎지, 이 공장의 평상시
|
|
148
|
-
*
|
|
276
|
+
* 상한을 정하지 않는다. 커널이 임의로 고르게 두면 그 주에 공휴일이 끼었을 때 상한이 조용히 낮아진다.
|
|
149
277
|
*
|
|
150
|
-
* 트윈이
|
|
278
|
+
* 트윈이 기동 중이 아니면 `undefined` 다 — 0 이 아니다. 기동하지 않은 트윈의 상한을 0 이라고 답하면 화면은
|
|
151
279
|
* "이 공장은 아무것도 못 만든다" 고 말한다.
|
|
152
280
|
*/
|
|
153
281
|
static capacity(domainId: string, target: {
|
|
@@ -159,7 +287,33 @@ export declare class TwinEngine {
|
|
|
159
287
|
analysis?: any;
|
|
160
288
|
reason?: 'not-running' | 'no-operations';
|
|
161
289
|
}[]>;
|
|
162
|
-
|
|
290
|
+
/**
|
|
291
|
+
* **생산 능력 보고서** — ISA-95 Part 4 `OperationsCapability`. 구간의 양을 종류로 구분한다
|
|
292
|
+
* (약정·가용·달성불가). 용량(`capacity`)은 비율을 내고 이것은 **구간의 양**을 낸다.
|
|
293
|
+
*
|
|
294
|
+
* 대상 선정·거절 사유는 `capacity` 와 **같은 규율**이다: 등록부가 대상을 정하고(안 기동 중인 것과
|
|
295
|
+
* 없는 것을 구별한다), 공정을 선언하지 않은 트윈은 판정 대상이 아니라고 말한다(0 으로 채우면
|
|
296
|
+
* "야드가 병목" 이라는 없는 사실이 생긴다).
|
|
297
|
+
*/
|
|
298
|
+
static operationsCapability(domainId: string, target: {
|
|
299
|
+
instanceId?: string;
|
|
300
|
+
spaceId?: string;
|
|
301
|
+
}, unitsPerDay: number, sampleWeekStartMs: number, window: {
|
|
302
|
+
fromTime: string;
|
|
303
|
+
toTime: string;
|
|
304
|
+
}): Promise<{
|
|
305
|
+
instanceId: string;
|
|
306
|
+
kind?: string;
|
|
307
|
+
report?: any;
|
|
308
|
+
reason?: 'not-running' | 'no-operations';
|
|
309
|
+
}[]>;
|
|
310
|
+
/**
|
|
311
|
+
* 미러 기동의 연속성 씨앗 — 이어받은 것은 **말한다**(조용히 잇지 않는다).
|
|
312
|
+
*
|
|
313
|
+
* 커널이 그 문을 열어 두지 않았으면 그 사실도 말한다: 그 트윈은 재기동마다 열린 구간을 잃는다.
|
|
314
|
+
*/
|
|
315
|
+
private static seedLiveContinuity;
|
|
316
|
+
static start(id: string, domainId: string, kind: string, model: TwinModelDef, realityMode?: RealityMode, purpose?: string, resumeFrom?: number): InstanceRuntime;
|
|
163
317
|
/**
|
|
164
318
|
* live-모드 기동 — **관측 모드 커널**로 실 이벤트를 미러한다(통합 P2).
|
|
165
319
|
*
|
|
@@ -173,14 +327,14 @@ export declare class TwinEngine {
|
|
|
173
327
|
* 실 이벤트원 = reference 어댑터 openLiveFeed → face2-adapter.ingest → CanonicalEnvelope → ingestLive().
|
|
174
328
|
*/
|
|
175
329
|
/**
|
|
176
|
-
*
|
|
330
|
+
* 모델이 실은 **생산 정의**(레시피·라우트·바인딩)를 꺼낸다 — 커널의 정의-구동 모드 입구.
|
|
177
331
|
*
|
|
178
332
|
* ── 없을 때 무엇이 일어났나 ──────────────────────────────────────────────
|
|
179
333
|
* 커널에는 정의-구동 MES 경로가 있는데 **호스트가 그것을 한 번도 넘기지 않았다.** 그래서 모든 MES
|
|
180
334
|
* 트윈이 **하드코딩된 레거시 흐름**으로 돌았다 — 현장 레시피를 아무리 정성껏 적어도 커널은 그것을
|
|
181
335
|
* 보지 못하고 토이 부품으로 토이 제품을 만들었다. 선언과 실행이 갈라져 있던 자리다.
|
|
182
336
|
*
|
|
183
|
-
*
|
|
337
|
+
* 모델에 없으면 `undefined` — 레거시 경로 그대로다(기존 트윈의 거동을 바꾸지 않는다).
|
|
184
338
|
*/
|
|
185
339
|
/**
|
|
186
340
|
* 생산 선언을 꺼낸다 — 커널 생성자에 넘긴다.
|
|
@@ -189,23 +343,23 @@ export declare class TwinEngine {
|
|
|
189
343
|
* 이름이 그대로 굳은 것), 일반 기제에 한 시스템 이름이 붙어 있었기 때문에 창고 트윈이 이 자리를
|
|
190
344
|
* 쓰지 못했다. 별명으로 남겨 두면 그 혼동이 계속되므로 하나로 통일했다.
|
|
191
345
|
*
|
|
192
|
-
* 옛 이름만 가진
|
|
346
|
+
* 옛 이름만 가진 모델이 있으면 **조용히 생산 선언을 잃는 대신 분명히 멈춘다** — 그 트윈은 공정이
|
|
193
347
|
* 없는 채로 돌게 되고(라인이 서 있는 창고), 원인을 찾기 어렵다.
|
|
194
348
|
*/
|
|
195
349
|
private static productionSpecOf;
|
|
196
350
|
/**
|
|
197
|
-
* 현장(공간)의 **시각 기준**을
|
|
351
|
+
* 현장(공간)의 **시각 기준**을 모델에 얹는다 — 커널이 교대의 `HH:MM` 을 읽을 기준.
|
|
198
352
|
*
|
|
199
353
|
* **테넌트가 아니라 공간이 권위다.** 한 테넌트가 Rosarito(태평양)와 한국 공장을 함께 가질 수 있고,
|
|
200
|
-
* 테넌트 단위(`Domain.timezone`)로 두면 둘 중 하나는 반드시 틀린다. 그래서 인스턴스가
|
|
354
|
+
* 테넌트 단위(`Domain.timezone`)로 두면 둘 중 하나는 반드시 틀린다. 그래서 인스턴스가 연결된 공간의
|
|
201
355
|
* `timezone` 을 읽는다. 공간이 말하지 않으면 **테넌트로 내려가지 않는다** — 잘못된 입자로 답하는 것이
|
|
202
356
|
* 모르는 것보다 나쁘다(그때는 커널이 UTC 로 읽고, 그 기본값은 계약에 밝혀져 있다).
|
|
203
357
|
*
|
|
204
358
|
* 커널은 zero-dep 이라 시간대 데이터베이스를 갖지 않으므로 **분 오프셋**으로 풀어 넘긴다. 그 값은
|
|
205
359
|
* 지금 계절의 것이다(일광절약시간) — 계절을 넘는 긴 예측은 한 시간 어긋난다(계약에 명시).
|
|
206
360
|
*/
|
|
207
|
-
static withSpaceTimeBase(
|
|
208
|
-
static startLive(id: string, domainId: string, kind: string,
|
|
361
|
+
static withSpaceTimeBase(model: TwinModelDef, domainId: string, spaceId?: string): Promise<TwinModelDef>;
|
|
362
|
+
static startLive(id: string, domainId: string, kind: string, model: TwinModelDef): InstanceRuntime;
|
|
209
363
|
/**
|
|
210
364
|
* live 이벤트 인제스트 — projector 구동 + data(tag) 방송(폐루프의 인바운드 도착 지점, command-routing §8.2).
|
|
211
365
|
* reference 어댑터가 낸 records → 커널 face2-adapter.ingest → CanonicalEnvelope 를 여기로 밀어넣는다.
|
|
@@ -216,7 +370,7 @@ export declare class TwinEngine {
|
|
|
216
370
|
* 구간 성과 방송은 **없앴다**(2026-08-06). 카드가 `twinKpi` 를 직접 묻는다.
|
|
217
371
|
*
|
|
218
372
|
* 왜: 카드를 여러 단계(공간·트윈·구역·자리·설비)에 붙이려면 방송으로는 태그가 트윈당 1,200개가 되고,
|
|
219
|
-
*
|
|
373
|
+
* **모델에 카드를 하나도 안 놓아도** 30초마다 트윈마다 저널을 접었다. 질의로 바꾸니 보고 있는 카드
|
|
220
374
|
* 수만큼만 들고, 같은 (대상·창·축) 은 클라이언트가 하나로 합친다.
|
|
221
375
|
*
|
|
222
376
|
* 덤으로 질의만 할 수 있는 것이 둘 생겼다 — **과거 시각**(`toTime`)과 **공간 단위 합산**(여러 트윈을
|
|
@@ -229,13 +383,21 @@ export declare class TwinEngine {
|
|
|
229
383
|
private static broadcastTimer?;
|
|
230
384
|
/** live 방송 coalescer — dirty 인 live 인스턴스만 주기적으로 1회 방송(entitySigs 로 변경 엔티티만). */
|
|
231
385
|
private static ensureBroadcastCoalescer;
|
|
232
|
-
/**
|
|
386
|
+
/**
|
|
387
|
+
* dirty 인스턴스 방송 flush(주기 tick 또는 명시 호출) — **시뮬과 라이브 둘 다.**
|
|
388
|
+
*
|
|
389
|
+
* 예전에는 라이브만 봤다(`mode !== 'live'` 면 건너뜀). 시뮬은 delta 마다 곧바로 방송했고, 그것이
|
|
390
|
+
* 한 tick 에서 수백 번 반복되며 이벤트 루프를 막았다(위 `start()` 주석의 35초 틱). 방송을 모으는
|
|
391
|
+
* 규율은 모드의 성질이 아니라 **채널의 성질**이다 — 최신-상태 채널이면 중간 상태는 보낼 값이 없다.
|
|
392
|
+
*/
|
|
233
393
|
static flushLiveBroadcasts(): void;
|
|
234
394
|
/**
|
|
235
395
|
* 저널 행 한 줄 — **기록 경로가 둘이라(라이브 벌크·심 단건) 행 모양은 반드시 한 곳에서 만든다.**
|
|
236
396
|
* 두 곳에 각자 적으면 승격 검색 키가 한쪽에만 채워지고, 반쯤 빈 색인은 "저널에는 있는데
|
|
237
397
|
* 검색으로는 안 나오는 이벤트" 를 만든다 — 저널에서 가장 나쁜 종류의 결함이다.
|
|
238
398
|
*/
|
|
399
|
+
/** 저널의 시각 축은 날짜다 — 못 읽는 값은 비운다(0 이나 지금으로 위장하지 않는다). */
|
|
400
|
+
private static toEventTimeValue;
|
|
239
401
|
private static journalRow;
|
|
240
402
|
/**
|
|
241
403
|
* 이 트윈이 지금 어느 구조로 도는가 — 이벤트에 찍을 번호. 한 번 읽고 캐시한다(쓰기마다 조회 금지).
|
|
@@ -248,33 +410,72 @@ export declare class TwinEngine {
|
|
|
248
410
|
/** live 저널 배치 기록 — 모아둔 CanonicalEnvelope 들에 startRevision+1.. 을 부여해 벌크 저장(coalescer tick 당 1회). */
|
|
249
411
|
static persistBatch(domainId: string, instanceId: string, envelopes: any[], startRevision: number): Promise<void>;
|
|
250
412
|
/** 레지스트리 upsert(도메인+instanceId 유니크). status 인자로 provision(stopped)/start(running) 공용. */
|
|
251
|
-
static register(domainId: string, instanceId: string, kind: string,
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
413
|
+
static register(domainId: string, instanceId: string, kind: string, model: TwinModelDef, status?: 'running' | 'stopped', realityMode?: RealityMode, origin?: any, meta?: {
|
|
414
|
+
name?: string;
|
|
415
|
+
description?: string;
|
|
416
|
+
actor?: {
|
|
417
|
+
id: string;
|
|
418
|
+
};
|
|
419
|
+
}): Promise<void>;
|
|
420
|
+
/**
|
|
421
|
+
* 라이브 구조 변이(resource.add 등)를 저장된 model 에 반영 — 런타임 커널의 무버를 registry model.equipment 에 동기.
|
|
422
|
+
* 이게 없으면 런타임엔 추가돼도(상태·저널엔 반영) 저장 model 는 원본이라 프로비저닝 편집기·재기동(loadTwinModel)이
|
|
423
|
+
* 추가분을 잃는다. 기존 model.equipment 항목은 보존(homeLocation 유지)하고 새 id 만 append(추가 시점 location=homeLocation).
|
|
256
424
|
* 좌표(layout)만 다루는 register 와 달리 equipment 집합을 갱신하나, 재프로비전(purge)이 아니라 in-place 갱신이라
|
|
257
425
|
* 저널은 보존된다(추가는 이미 equipment 델타로 저널됨 → replay 는 id-keyed upsert 라 이중계산 없음).
|
|
258
426
|
*/
|
|
259
427
|
static syncBoardEquipment(domainId: string, instanceId: string): Promise<void>;
|
|
260
428
|
/**
|
|
261
|
-
* 프로비저닝 — 레지스트리에 구조(
|
|
429
|
+
* 프로비저닝 — 레지스트리에 구조(model)를 등록만 하고 기동하지 않음(status='stopped').
|
|
262
430
|
* 재프로비전 시 구조 시그니처가 바뀌면(노드·무버 집합/속성 변경) 기존 저널을 purge 한다(ADR-0015):
|
|
263
|
-
*
|
|
431
|
+
* model 는 replay 의 마스터라 구조가 바뀌면 과거 이벤트의 전제가 깨진다. 좌표(layout)만 바뀌면 저널 보존.
|
|
432
|
+
*/
|
|
433
|
+
/**
|
|
434
|
+
* 실행 중이면 구조를 교체하지 않는다 — **판정 문장을 한 곳에 둔다.**
|
|
435
|
+
*
|
|
436
|
+
* 인제스트는 전량 교체라, 이벤트를 접고 있는 커널 밑에서 바닥을 바꾸는 셈이 된다. 지금은 거절이
|
|
437
|
+
* 유일한 답이지만 최종형은 아니다(`adoptStructure` 배선). 두 곳에서 같은 문장으로 거절해야
|
|
438
|
+
* 나중에 이 규칙을 걷어낼 때 걷어낼 것이 하나로 보인다.
|
|
439
|
+
*/
|
|
440
|
+
private static assertNotRunning;
|
|
441
|
+
/**
|
|
442
|
+
* 돌면서 공장을 전환한다 — **미러 전용.**
|
|
443
|
+
*
|
|
444
|
+
* 미러가 비추는 현실은 안 멈춘다. 설비 한 대가 늘었다고 트윈을 멈췄다 세우면 그 사이의 사실을
|
|
445
|
+
* 잃고, 라이브에서 유실은 곧 거짓이다. 그래서 미러는 **동작 중에** 새 구조를 받는다.
|
|
446
|
+
*
|
|
447
|
+
* 시뮬레이션은 여기 오지 않는다. 조건이 바뀐 실험은 다른 실험이므로 멈추고 다시 세우는 것이
|
|
448
|
+
* 옳다 — 커널이 그렇게 거절한다(`FlowEngine.adoptStructure`).
|
|
449
|
+
*
|
|
450
|
+
* 세 가지가 **함께** 일어나야 한다. 하나라도 빠지면 층이 어긋난다:
|
|
451
|
+
* ① 리비전 — 이 시점 이후의 이벤트가 새 번호를 달고 다닌다(재생이 마디를 나눌 수 있게)
|
|
452
|
+
* ② 저장 model·구조 행 — 조회가 새 구조를 본다
|
|
453
|
+
* ③ 커널 — 지금 접히는 이벤트가 새 구조 위에서 접힌다
|
|
264
454
|
*/
|
|
265
|
-
static
|
|
455
|
+
static adoptStructure(domainId: string, instanceId: string, model: TwinModelDef, comment?: string, origin?: any): Promise<{
|
|
456
|
+
rev: number;
|
|
457
|
+
} & StructureShift>;
|
|
458
|
+
static provision(domainId: string, instanceId: string, kind: string, model: TwinModelDef, comment?: string, origin?: any,
|
|
459
|
+
/** 이름·저자 — 업무키를 나눠 둔 대가로 이름을 함께 남긴다(`register` 의 `meta` 그대로). */
|
|
460
|
+
meta?: {
|
|
461
|
+
name?: string;
|
|
462
|
+
description?: string;
|
|
463
|
+
actor?: {
|
|
464
|
+
id: string;
|
|
465
|
+
};
|
|
466
|
+
}): Promise<void>;
|
|
266
467
|
/**
|
|
267
468
|
* 이 구조를 리비전으로 남기고 그 번호를 돌려준다 — **바뀌었을 때만** 새 번호가 생긴다.
|
|
268
469
|
*
|
|
269
470
|
* 프로비저닝은 부팅마다 다시 도는데, 그때마다 리비전이 늘면 이력이 뜻 없는 마디로 잘게 쪼개진다.
|
|
270
471
|
* 그래서 **구조 서명이 같으면 있던 리비전을 그대로 쓴다.**
|
|
271
472
|
*/
|
|
272
|
-
static recordStructure(domainId: string, instanceId: string,
|
|
473
|
+
static recordStructure(domainId: string, instanceId: string, model: TwinModelDef, comment?: string): Promise<number>;
|
|
273
474
|
/**
|
|
274
475
|
* 이 트윈이 거쳐 온 구조들 — **무엇이 언제 달라졌나.**
|
|
275
476
|
*
|
|
276
477
|
* 리비전은 그 시절 공장을 통째로 담지만(재생에 필요하다), 사람이 보고 싶은 것은 통째가 아니라
|
|
277
|
-
* 차이다.
|
|
478
|
+
* 차이다. 모델은 빼고 **차이 요약만** 내보낸다 — 62KB 짜리 보드를 화면에 실어 보낼 이유가 없다.
|
|
278
479
|
*/
|
|
279
480
|
static structureHistory(domainId: string, instanceId: string): Promise<{
|
|
280
481
|
rev: number;
|
|
@@ -284,7 +485,7 @@ export declare class TwinEngine {
|
|
|
284
485
|
diff: StructureDiff;
|
|
285
486
|
}[]>;
|
|
286
487
|
/** 지금 쓰이는 구조 리비전 — 이벤트에 찍을 번호. 아직 없으면 기록하며 만든다. */
|
|
287
|
-
static currentStructureRev(domainId: string, instanceId: string,
|
|
488
|
+
static currentStructureRev(domainId: string, instanceId: string, model?: TwinModelDef): Promise<number | undefined>;
|
|
288
489
|
/** 구조 동일성 지문 — 좌표(layout) 등 뷰 관심사는 제외하고 커널이 보는 위상·용량·무버만. */
|
|
289
490
|
/**
|
|
290
491
|
* 지문을 **64자로 줄인다** — 컬럼이 varchar(64) 다.
|
|
@@ -295,10 +496,10 @@ export declare class TwinEngine {
|
|
|
295
496
|
*/
|
|
296
497
|
private static structureFingerprint;
|
|
297
498
|
private static structureSignature;
|
|
298
|
-
/** 레지스트리
|
|
499
|
+
/** 레지스트리 model 로 기동(프로비전된 인스턴스 start). model 인자 없이 저장된 구조로 재기동. */
|
|
299
500
|
static startFromRegistry(domainId: string, instanceId: string, realityMode?: RealityMode): Promise<InstanceRuntime>;
|
|
300
501
|
/**
|
|
301
|
-
* 선언 기반 부팅(§0 프레임 ① → 부팅 거동 매핑) — 트윈이 선언한 realityMode 에 따라 재기동 방식을
|
|
502
|
+
* 선언 기반 부팅(§0 프레임 ① → 부팅 거동 매핑) — 트윈이 선언한 realityMode 에 따라 재기동 방식을 구분한다.
|
|
302
503
|
* 부팅 경로를 한 곳에 모아 "런타임 ≠ 현실" 범주오류를 코드로 강제한다.
|
|
303
504
|
* - 'mirror' : 현실=외부 실물 → startLive(재동기). 이벤트는 어댑터 ingest 로 유입, 커널 tick 없음.
|
|
304
505
|
* - 'sim-world' : 생성 타임라인 지속 → 저널 보존 + resume(현실 이어감).
|
|
@@ -316,11 +517,20 @@ export declare class TwinEngine {
|
|
|
316
517
|
static resetJournal(domainId: string, instanceId: string): Promise<void>;
|
|
317
518
|
/** 삭제 — 정지 + 레지스트리 삭제 + 저널 purge(domain 스코프). */
|
|
318
519
|
static remove(domainId: string, instanceId: string): Promise<void>;
|
|
520
|
+
/**
|
|
521
|
+
* 이 트윈에 대해 **메모리에 남은 것을 전부 잊는다** — 지움의 한 자리.
|
|
522
|
+
*
|
|
523
|
+
* 캐시가 라이프사이클과 어긋나 있었다: 저널·등록부는 지우면서 인스턴스별 캐시는 남겨, 삭제된 트윈의
|
|
524
|
+
* 항목이 **서버 재기동까지 살아 있었다.** 항목 하나가 하루치 KPI 그룹을 물고 있으므로 잊지 않으면
|
|
525
|
+
* 지운 트윈이 계속 메모리를 차지한다. TTL 은 값이 낡는 것을 막을 뿐 **없어진 주인을 지우지 않는다.**
|
|
526
|
+
*
|
|
527
|
+
* 잊을 것을 여기 모아 두는 이유: 캐시를 새로 만드는 사람이 지우는 자리를 찾아 헤매지 않게 한다.
|
|
528
|
+
* 새 인스턴스별 캐시를 만들면 **이 함수에 한 줄을 더한다** — 그러지 않으면 같은 누수가 다시 생긴다.
|
|
529
|
+
*/
|
|
530
|
+
private static forgetInstance;
|
|
319
531
|
/** 관리 목록 — domain 의 등록 인스턴스 전체(라이브 여부·최신 저널 revision·노드/무버 수 포함). */
|
|
320
532
|
static list(domainId: string): Promise<any[]>;
|
|
321
|
-
/**
|
|
322
|
-
static isBenchSpace(spaceId?: string): boolean;
|
|
323
|
-
/** 운영 공간 목록(벤치 소스 선택기) — 이름·규모 포함, 벤치 사본·잔재 제외. */
|
|
533
|
+
/** 운영 공간 목록(벤치 소스 선택기) — 이름·규모 포함, 벤치 사본 제외. */
|
|
324
534
|
static listSpaces(domainId: string): Promise<{
|
|
325
535
|
spaceId: string;
|
|
326
536
|
name: string;
|
|
@@ -331,17 +541,23 @@ export declare class TwinEngine {
|
|
|
331
541
|
/** 인스턴스 목적 표식(운영/벤치) 설정 — 벤치 사본을 1급 속성으로 구별(이름 접두사 아님). */
|
|
332
542
|
static setPurpose(domainId: string, instanceId: string, purpose: 'operational' | 'bench', copyOf?: string): Promise<void>;
|
|
333
543
|
/**
|
|
334
|
-
* 공간 구조 판독 — 완전복제(벤치 사본)의 소스. 저장물이
|
|
544
|
+
* 공간 구조 판독 — 완전복제(벤치 사본)의 소스. 저장물이 model(위상)·TwinSpace.content(치수·geo·표현)·TwinArea(영역)로
|
|
335
545
|
* 분산돼 있으므로 셋을 모아 돌려준다. 호출측이 ReferenceMaster 로 재구성 → 재식별 → ingestMaster.
|
|
336
546
|
*/
|
|
337
547
|
static spaceStructure(domainId: string, spaceId: string): Promise<{
|
|
338
548
|
name?: string;
|
|
339
|
-
|
|
549
|
+
/** 설계 좌표계 범위(미터)와 지오레퍼런스 — 사본이 원본과 같은 자리에 서려면 함께 가야 한다. */
|
|
550
|
+
frame: {
|
|
551
|
+
extentX?: number;
|
|
552
|
+
extentY?: number;
|
|
553
|
+
geo?: any;
|
|
554
|
+
primaryRepresentationId?: string;
|
|
555
|
+
};
|
|
340
556
|
areas: any[];
|
|
341
557
|
instances: {
|
|
342
558
|
instanceId: string;
|
|
343
559
|
kind?: string;
|
|
344
|
-
|
|
560
|
+
model: any;
|
|
345
561
|
}[];
|
|
346
562
|
} | null>;
|
|
347
563
|
/** 공간(+표현·영역) 삭제 — 벤치 정리 등. 호출측이 바인딩 인스턴스를 먼저 제거하는 전제(가드 없음). deleteTwinSpace 리졸버와 동형. */
|
|
@@ -357,23 +573,42 @@ export declare class TwinEngine {
|
|
|
357
573
|
*/
|
|
358
574
|
static ingestMaster(domainId: string, master: ReferenceMaster, into?: {
|
|
359
575
|
spaceId?: string;
|
|
576
|
+
},
|
|
577
|
+
/** 누가 인제스트했나 — 사람이 없는 경로(부팅)는 주지 않는다(감사 기록을 지어내지 않는다). */
|
|
578
|
+
actor?: {
|
|
579
|
+
id: string;
|
|
360
580
|
}): Promise<{
|
|
361
581
|
instanceId: string;
|
|
362
582
|
spaceId: string;
|
|
363
583
|
warnings: IngestWarning[];
|
|
364
584
|
}>;
|
|
365
|
-
/** 단건 상세 — 프로비저닝 에디터가 편집할
|
|
585
|
+
/** 단건 상세 — 프로비저닝 에디터가 편집할 model(구조+layout) 포함. */
|
|
366
586
|
static detail(domainId: string, instanceId: string): Promise<any | null>;
|
|
367
587
|
/**
|
|
368
588
|
* 라이브 바인딩 브리지(P3, ADR-0018) — 트윈 엔티티 상태를 `data(tag=엔티티id)` 채널로 publish.
|
|
369
589
|
* 보드 컴포넌트가 tag 로 구독(board-ui provider)해 `component.data` 로 라이브 갱신. delta 시에만(희소).
|
|
370
590
|
* tag=엔티티 id(데모=단일 인스턴스). 멀티 인스턴스/보드 재사용 시 tag 네임스페이스는 후속.
|
|
371
591
|
*/
|
|
592
|
+
/** 방송 실패 로그 조절 — 창마다 한 줄(막힌 구독자는 초당 수십 번 실패한다). */
|
|
593
|
+
private static publishDrops;
|
|
594
|
+
private static readonly PUBLISH_DROP_LOG_MS;
|
|
595
|
+
/**
|
|
596
|
+
* 한 번의 방송 — **구독자 하나가 호스트를 죽이지 못하게.**
|
|
597
|
+
*
|
|
598
|
+
* ── 무엇이 죽였나 (2026-08-14) ─────────────────────────────────────────────
|
|
599
|
+
* 밀린 push 가 1024를 넘으면 pubsub 이 던진다(`RepeaterOverflowError`). 그 방송은 타이머 콜백
|
|
600
|
+
* 안에서 일어나므로 예외가 잡히는 곳 없이 올라가 **프로세스가 끝났다** — 트윈 14개가 도는 호스트가
|
|
601
|
+
* 소비를 멈춘 구독자 하나 때문에 통째로.
|
|
602
|
+
*
|
|
603
|
+
* 못 보낸 것은 **사실로 남긴다**(횟수를 세고 창마다 한 줄 남긴다). 삼키면 「보냈는데 화면이 낡았다」가
|
|
604
|
+
* 되고, 그건 가장 찾기 어려운 부류다.
|
|
605
|
+
*/
|
|
606
|
+
private static publishGuarded;
|
|
372
607
|
static publishEntityData(inst: InstanceRuntime): void;
|
|
373
608
|
static persist(domainId: string, instanceId: string, msg: any): Promise<void>;
|
|
374
609
|
/**
|
|
375
610
|
* 재부팅 복구 / 시간여행 — DB 저널을 replay 해 상태 재구성.
|
|
376
|
-
*
|
|
611
|
+
* model 는 레지스트리(TwinInstance)에서, 이벤트는 TwinEvent(revision ASC)에서.
|
|
377
612
|
* 커서 두 축(runtime-state-model §4): **시각(untilTime, 사용자 모국어·공간 공통축)** 우선, 없으면 리비전(untilRevision, 렌즈 내부).
|
|
378
613
|
* - untilTime 주면 `eventTime ≤ T` 인 이벤트만(그 시점 watermark) — 공동배치 여러 트윈을 하나의 시각 T로 통일 해소.
|
|
379
614
|
* - 둘 다 없으면 최신(라이브 인메모리 진실).
|
|
@@ -392,7 +627,40 @@ export declare class TwinEngine {
|
|
|
392
627
|
static stopHooks: ((id: string) => void)[];
|
|
393
628
|
static onStop(fn: (id: string) => void): void;
|
|
394
629
|
static stop(domainId: string, id: string): Promise<void>;
|
|
630
|
+
/**
|
|
631
|
+
* 같은 현장 트윈들의 **설비 상태**를 커널에 넘긴다 — 커널이 요청할 때만.
|
|
632
|
+
*
|
|
633
|
+
* ── 경계 (2026-08-14) ──────────────────────────────────────────────────────
|
|
634
|
+
* 호스트가 아는 것은 **누가 같은 현장에 있는가** 하나다. 무엇을 읽고 그것을 어떻게 부하로 바꿀지는
|
|
635
|
+
* 커널이 정한다(계수는 트윈의 모델이 선언한다). 호스트가 kW 를 계산해 주면 트윈마다 다른 규칙이
|
|
636
|
+
* 생기고, 그 규칙은 어디에도 적혀 있지 않게 된다.
|
|
637
|
+
*
|
|
638
|
+
* 상태만 넘긴다. 스냅샷을 통째로 넘기면 상태 크기에 비례한 비용을 매 tick 치르게 된다 —
|
|
639
|
+
* 설비 목록은 그 트윈의 커널이 이미 들고 있는 것이라 훑는 값이 싸다.
|
|
640
|
+
*/
|
|
641
|
+
private static feedPeerEquipment;
|
|
395
642
|
private static tickGuarded;
|
|
643
|
+
/**
|
|
644
|
+
* 호스트를 굶기는 트윈을 멈춘다 — **도는 척하는 것보다 멈춘 것이 낫다.**
|
|
645
|
+
*
|
|
646
|
+
* 굶김 문턱을 넘는 틱이 연속 `STARVE_STREAK` 번이면 그 트윈은 구조적으로 무겁다(우연이 아니다).
|
|
647
|
+
* 문턱 아래로 한 번만 내려와도 연속을 끊는다 — 무거운 순간 하나로 트윈을 내리지 않는다.
|
|
648
|
+
*/
|
|
649
|
+
private static guardStarvation;
|
|
650
|
+
/** 멈추고 **이유를 남긴다** — 이유 없는 「정지」는 사람이 자기가 멈춘 것으로 읽는다. */
|
|
651
|
+
private static stopWithNote;
|
|
652
|
+
/** 이 트윈이 스스로 멈춘 이유(있으면) — 화면이 옮겨 말한다. */
|
|
653
|
+
static stopNoteOf(domainId: string, id: string): StopNote | undefined;
|
|
654
|
+
/**
|
|
655
|
+
* 이 트윈이 **지금 실행 중인가** — 판정의 집 하나.
|
|
656
|
+
*
|
|
657
|
+
* "스냅샷이 있나" 로는 답이 되지 않는다: 웜스타트가 되살린 상태가 캐시에 남아 있으면 멈춘 트윈도
|
|
658
|
+
* 스냅샷을 낸다. 그것을 관측 중으로 읽으면 화면이 **멈춘 트윈의 작업을 0 건이라고 단언**한다
|
|
659
|
+
* (실제로 그렇게 나왔다 — 관측이 없는 것과 0 건은 다르다는 이 프로젝트의 규율을 화면이 어겼다).
|
|
660
|
+
*
|
|
661
|
+
* 목록이 쓰는 것과 **같은 술어**다(`list()` 의 `running`) — 두 벌이면 어긋난다.
|
|
662
|
+
*/
|
|
663
|
+
static isRunning(domainId: string, id: string): boolean;
|
|
396
664
|
static runtime(domainId: string, id: string): TwinRuntimeType | undefined;
|
|
397
665
|
static dispatchCommand(domainId: string, instanceId: string, command: any): Promise<{
|
|
398
666
|
accepted: boolean;
|
|
@@ -407,7 +675,7 @@ export declare class TwinEngine {
|
|
|
407
675
|
* 검증 없이 접근하면 크로스테넌트 읽기/정지가 가능해진다.
|
|
408
676
|
*/
|
|
409
677
|
/**
|
|
410
|
-
* 이 런타임의 **관측 모드** — `'live'`(외부 실물을 미러) 또는 `'sim'`(커널이
|
|
678
|
+
* 이 런타임의 **관측 모드** — `'live'`(외부 실물을 미러) 또는 `'sim'`(커널이 실행한다). 기동 중이 아니면 없다.
|
|
411
679
|
*
|
|
412
680
|
* 소비처가 `instances[id].mode` 를 직접 읽던 자리를 대신한다. 레지스트리를 밖에 열면 도메인 확인이
|
|
413
681
|
* 자리마다 제각각이 되고, 실제로 그렇게 됐다(테넌트 격리 전수 확인, 2026-08-06).
|
|
@@ -417,10 +685,10 @@ export declare class TwinEngine {
|
|
|
417
685
|
/**
|
|
418
686
|
* 이 트윈이 이 테넌트 것인가 — **떠 있든 아니든.**
|
|
419
687
|
*
|
|
420
|
-
* `owns()` 는
|
|
688
|
+
* `owns()` 는 **기동 중인** 런타임만 안다. 그것을 이력 조회의 관문으로 쓰면, 꺼진 트윈의 저널을
|
|
421
689
|
* 읽으려 할 때 "이 테넌트에 없다" 는 답이 돌아온다 — 두 가지가 틀렸다. 첫째, 저널은 트윈이 꺼져
|
|
422
690
|
* 있을 때 **가장 필요한 것**이다(그게 이력의 존재 이유다). 둘째, 그 문장은 남의 것이라는 뜻이라
|
|
423
|
-
* 사용자가 권한 문제로 오해한다. 실제로는 그냥
|
|
691
|
+
* 사용자가 권한 문제로 오해한다. 실제로는 그냥 실행 중이 아닐 뿐이다.
|
|
424
692
|
*
|
|
425
693
|
* 소유는 **등록부**가 안다. 이력·집계처럼 런타임과 무관한 질문은 이쪽에 묻는다.
|
|
426
694
|
*/
|
|
@@ -453,11 +721,28 @@ export declare class TwinEngine {
|
|
|
453
721
|
static kernel(domainId: string, id: string): any;
|
|
454
722
|
/** 라이브 처리량 계측 스냅샷(모니터, ④-1) — 내부 누적(_acc*) 제외한 공개 지표. live 아니면 null. */
|
|
455
723
|
static metrics(domainId: string, id: string): any;
|
|
724
|
+
/**
|
|
725
|
+
* 부하 계기판만 따로 — **시뮬 트윈도 포함한다.**
|
|
726
|
+
*
|
|
727
|
+
* `metrics()` 는 라이브 지표(`inst.metrics`)가 있어야 무언가를 돌려준다. 그런데 이벤트 루프를 점유하는
|
|
728
|
+
* 것은 주로 **시뮬 틱**이고, 시뮬 인스턴스에는 그 지표가 없어 통째로 안 보였다.
|
|
729
|
+
*/
|
|
730
|
+
static load(domainId: string, id: string): any;
|
|
731
|
+
/**
|
|
732
|
+
* **한 곳에서 보는 전체 부하** — 몇 개가 실행 중이고, 누가 루프를 점유하고 있나.
|
|
733
|
+
*
|
|
734
|
+
* 시뮬 트윈도 포함한다(`metrics()` 는 라이브 지표가 있어야 답해서 시뮬이 통째로 안 보였다).
|
|
735
|
+
*/
|
|
736
|
+
static fleet(domainId?: string): any;
|
|
737
|
+
/** 이 트윈에서 fork 가 만들어졌다 — 예측 한 번이 수십 개를 만든다. */
|
|
738
|
+
static countForks(domainId: string, id: string, count: number): void;
|
|
739
|
+
/** 엔진 밖(예측 질의 등)에서 무거운 작업을 잰다 — 같은 계기판에 모인다. */
|
|
740
|
+
static recordLoad(domainId: string, id: string, phase: LoadPhase, tookMs: number): void;
|
|
456
741
|
/** 전체 라이브 인스턴스 계측(모니터 대시보드용). */
|
|
457
742
|
static allMetrics(domainId?: string): Promise<any[]>;
|
|
458
743
|
/**
|
|
459
744
|
* 예측용 커널을 **임의 시각 T 기준**으로 재구성 — 과거-vantage 예측(백테스트)·"그때 서서 본 미래".
|
|
460
|
-
* recover(untilTime)로 T 시점 상태를, T 이하 오더 관측을 모아 hydrate → monteCarloForecast 가 T 에서 앞으로
|
|
745
|
+
* recover(untilTime)로 T 시점 상태를, T 이하 오더 관측을 모아 hydrate → monteCarloForecast 가 T 에서 앞으로 실행한다.
|
|
461
746
|
* sim/live 무관(저널 기반 재구성). untilTime 생략 시 최신. 도메인 스코프(reg·journal 조회가 domainId).
|
|
462
747
|
*/
|
|
463
748
|
static buildForecastKernelAt(domainId: string, instanceId: string, untilTime?: string): Promise<any | null>;
|