@things-factory/headless-twin 10.0.8 → 10.0.10
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/attention-digest.d.ts +52 -0
- package/dist-server/engine/attention-digest.js +76 -0
- package/dist-server/engine/attention-digest.js.map +1 -0
- 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.d.ts +33 -0
- package/dist-server/engine/command-routing.js +53 -0
- package/dist-server/engine/command-routing.js.map +1 -0
- 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 +11 -0
- package/dist-server/engine/index.js +17 -0
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/kpi-baseline.d.ts +78 -0
- package/dist-server/engine/kpi-baseline.js +123 -0
- package/dist-server/engine/kpi-baseline.js.map +1 -0
- 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 +32 -1
- package/dist-server/engine/kpi-query.js +262 -20
- 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-attentions.d.ts +1 -0
- package/dist-server/engine/live-attentions.js +7 -1
- package/dist-server/engine/live-attentions.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/model-vocabulary.d.ts +17 -0
- package/dist-server/engine/model-vocabulary.js +81 -0
- 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 +15 -0
- package/dist-server/engine/runtime-key.js +64 -0
- package/dist-server/engine/runtime-key.js.map +1 -0
- 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 +21 -0
- package/dist-server/engine/state-axes.js +59 -0
- package/dist-server/engine/state-axes.js.map +1 -0
- 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 +418 -57
- package/dist-server/engine/twin-engine.js +1599 -306
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/engine/warm-start.d.ts +93 -13
- package/dist-server/engine/warm-start.js +114 -14
- 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 +34 -0
- package/dist-server/service/reference/discovery-result.js +84 -0
- package/dist-server/service/reference/discovery-result.js.map +1 -0
- package/dist-server/service/reference/ingest-space.d.ts +53 -0
- package/dist-server/service/reference/ingest-space.js +79 -0
- package/dist-server/service/reference/ingest-space.js.map +1 -0
- package/dist-server/service/reference/knob-defaults.d.ts +20 -0
- package/dist-server/service/reference/knob-defaults.js +59 -0
- package/dist-server/service/reference/knob-defaults.js.map +1 -0
- package/dist-server/service/reference/reference-live.d.ts +23 -0
- package/dist-server/service/reference/reference-live.js +123 -6
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +227 -11
- package/dist-server/service/reference/reference-master.js +206 -25
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-resolver.d.ts +33 -3
- package/dist-server/service/reference/reference-resolver.js +290 -23
- 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-attention/twin-attention-query.d.ts +8 -1
- package/dist-server/service/twin-attention/twin-attention-query.js +39 -8
- package/dist-server/service/twin-attention/twin-attention-query.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 +125 -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.d.ts +2 -0
- package/dist-server/service/twin-control/twin-control-mutation.js +50 -11
- 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 +46 -14
- 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 +219 -39
- 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 -18
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/twin-journal-query.d.ts +11 -4
- package/dist-server/service/twin-journal/twin-journal-query.js +95 -15
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +11 -5
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +46 -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 +63 -1
- 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 +365 -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-state/twin-state-subscription.js +1 -1
- package/dist-server/service/twin-state/twin-state-subscription.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 -7
- package/dist-server/service/twin-structure/twin-structure.js.map +1 -1
- package/dist-server/service/twin-target/twin-target-resolver.js +21 -4
- package/dist-server/service/twin-target/twin-target-resolver.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-shared/entity-delta.d.ts +29 -0
- package/dist-shared/entity-delta.js +287 -0
- package/dist-shared/entity-delta.js.map +1 -0
- package/dist-shared/kpi-broadcast.d.ts +4 -0
- package/dist-shared/kpi-broadcast.js +16 -0
- package/dist-shared/kpi-broadcast.js.map +1 -0
- package/dist-shared/twin-level.d.ts +23 -0
- package/dist-shared/twin-level.js +52 -0
- package/dist-shared/twin-level.js.map +1 -0
- package/package.json +14 -12
- package/server/engine/attention-digest.ts +102 -0
- package/server/engine/canonical-ingest.ts +36 -4
- package/server/engine/command-routing.ts +67 -0
- package/server/engine/energy-topology.ts +189 -0
- package/server/engine/index.ts +17 -0
- package/server/engine/kpi-baseline.ts +202 -0
- package/server/engine/kpi-fold.ts +389 -1
- package/server/engine/kpi-query.ts +295 -22
- package/server/engine/kpi-target.ts +24 -2
- package/server/engine/live-attentions.ts +7 -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/model-vocabulary.ts +82 -0
- 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 +58 -0
- package/server/engine/spec-coverage.ts +3 -3
- package/server/engine/state-axes.ts +60 -0
- package/server/engine/structure-diff.ts +1 -1
- package/server/engine/travel-estimator.ts +11 -6
- package/server/engine/twin-engine.ts +1710 -297
- package/server/engine/warm-start.ts +207 -22
- 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 +95 -0
- package/server/service/reference/ingest-space.ts +104 -0
- package/server/service/reference/knob-defaults.ts +59 -0
- package/server/service/reference/reference-live.ts +121 -6
- package/server/service/reference/reference-master.ts +362 -35
- package/server/service/reference/reference-resolver.ts +307 -23
- package/server/service/reference/template-registry.ts +20 -5
- package/server/service/twin-attention/twin-attention-query.ts +43 -6
- 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 +112 -0
- package/server/service/twin-audit/twin-audit-query.ts +72 -0
- package/server/service/twin-control/twin-control-mutation.ts +53 -13
- package/server/service/twin-event/twin-event-keys.ts +1 -1
- package/server/service/twin-event/twin-event.ts +52 -15
- 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 +211 -38
- package/server/service/twin-instance/twin-instance.ts +127 -22
- package/server/service/twin-journal/twin-journal-query.ts +108 -14
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +40 -23
- package/server/service/twin-metrics/twin-metrics-query.ts +60 -3
- 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 +150 -0
- package/server/service/twin-model/twin-lineage-query.ts +193 -0
- package/server/service/twin-model/twin-location.ts +140 -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 +150 -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 +365 -22
- package/server/service/twin-space/twin-space.ts +40 -6
- package/server/service/twin-state/twin-state-subscription.ts +1 -1
- package/server/service/twin-structure/twin-structure.ts +10 -7
- package/server/service/twin-target/twin-target-resolver.ts +22 -4
- package/shared/axis-read.ts +28 -0
- package/shared/entity-delta.ts +286 -0
- package/shared/kpi-broadcast.ts +13 -0
- package/shared/twin-level.ts +48 -0
- package/test/adopt-structure-live.test.ts +133 -0
- package/test/attention-digest.test.ts +135 -0
- 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 +5 -5
- package/test/command-routing.test.ts +61 -0
- package/test/declaration-reaches-model.test.ts +178 -0
- package/test/discovery-result.test.ts +75 -0
- package/test/energy-topology.test.ts +113 -0
- package/test/entity-delta.test.ts +195 -25
- 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 +9 -9
- package/test/ingest-running-guard.test.ts +136 -0
- package/test/ingest-space.test.ts +78 -0
- package/test/instance-cache-lifecycle.test.ts +110 -0
- package/test/kernel-kind-guard.test.ts +96 -0
- package/test/knob-defaults.test.ts +72 -0
- package/test/kpi-baseline-db.test.ts +216 -0
- package/test/kpi-baseline.test.ts +196 -0
- package/test/kpi-fold.test.ts +393 -2
- package/test/kpi-query-bench.test.ts +130 -0
- 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 +54 -14
- package/test/load-meter.test.ts +314 -0
- package/test/local-declarations.test.ts +554 -0
- package/test/master-to-twin.test.ts +128 -36
- package/test/model-basis.test.ts +56 -1
- package/test/model-vocabulary.test.ts +114 -0
- package/test/move-space.test.ts +149 -0
- package/test/mutation-gate.test.ts +122 -0
- package/test/oee-accumulator.test.ts +90 -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/registry-key-guard.test.ts +80 -0
- package/test/resync-origin-site.test.ts +77 -0
- package/test/runtime-key.test.ts +66 -0
- package/test/scale-twin-bench.test.ts +7 -7
- 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 +74 -0
- package/test/streamline-e2e.test.ts +16 -16
- package/test/structure-revision-db.test.ts +16 -15
- package/test/tenant-registry-db.test.ts +149 -0
- 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 +140 -0
- package/test/warm-start.test.ts +223 -4
- 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/entity-delta.d.ts +0 -19
- package/dist-server/engine/entity-delta.js +0 -161
- package/dist-server/engine/entity-delta.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/engine/entity-delta.ts +0 -169
- package/server/service/twin-event/backfill-keys.ts +0 -72
|
@@ -3,10 +3,31 @@ export declare class TwinReferenceResolver {
|
|
|
3
3
|
referenceSources(context: ResolverContext): Promise<any[]>;
|
|
4
4
|
/** 소스를 인제스트 → 공간 + 인스턴스 생성(provision). start 면 기동까지. */
|
|
5
5
|
importFromReference(source: string, context: ResolverContext, start?: boolean): Promise<any>;
|
|
6
|
+
/**
|
|
7
|
+
* **원본에서 다시 읽는다** — 이 트윈의 구조를 지금의 원본 모습으로 갱신한다.
|
|
8
|
+
*
|
|
9
|
+
* ── 왜 진입점이 하나여야 하나 ──────────────────────────────────────────────
|
|
10
|
+
* 지금까지 다시 읽기는 **만드는 경로에 얹혀 있었다**(`importFromReference`·`createFromTemplate`).
|
|
11
|
+
* 그래서 이미 있는 트윈을 갱신하려면 만들 때 무엇을 골랐는지 사람이 기억해 같은 화면을 다시
|
|
12
|
+
* 거쳐야 했고, 템플릿으로 세운 트윈은 노브를 어디에도 안 남겨서 **아예 갱신할 방법이 없었다.**
|
|
13
|
+
* 원천이 무엇이든 트윈 자신이 기억하게 하고(`TwinInstance.origin`), 여기 한 곳에서 그것을 따른다.
|
|
14
|
+
*
|
|
15
|
+
* ── 무엇이 일어나나 ────────────────────────────────────────────────────────
|
|
16
|
+
* 원본에서 마스터를 다시 얻어 인제스트에 그대로 태운다. 그다음은 인제스트가 아는 일이다 —
|
|
17
|
+
* 구조가 달라졌으면 새 리비전이 남고, 구조 행이 다시 그려지고, **실행 중인 미러는 멈추지 않고
|
|
18
|
+
* 전환한다.** 실행 중인 시뮬레이션은 거절된다(조건이 바뀐 실험은 다른 실험이다).
|
|
19
|
+
*
|
|
20
|
+
* ── 못 할 때는 못 한다고 한다 ──────────────────────────────────────────────
|
|
21
|
+
* `origin` 이 없는 트윈(이 자리가 생기기 전에 만들어진 것)은 다시 읽을 수 없다. 짐작으로
|
|
22
|
+
* 템플릿을 고르거나 첫 레퍼런스를 집지 않는다 — 엉뚱한 원본으로 현장을 덮는 것이 훨씬 나쁘다.
|
|
23
|
+
*/
|
|
24
|
+
resyncTwin(instanceId: string, context: ResolverContext): Promise<any>;
|
|
25
|
+
/** 기억해 둔 원천에서 마스터를 다시 얻는다 — 어댑터든 템플릿이든 이 한 곳에서 갈린다. */
|
|
26
|
+
private masterFromOrigin;
|
|
6
27
|
/** 등록된 트윈 템플릿(파라미터화 아키타입) 목록 — 노브 스키마 포함(클라이언트 폼용). */
|
|
7
28
|
twinTemplates(_context: ResolverContext): Promise<any[]>;
|
|
8
29
|
/** 템플릿 + 노브 → 합성 마스터 → 인제스트(+기동+시나리오). 레퍼런스 import 와 같은 경로, 원천만 합성. */
|
|
9
|
-
createFromTemplate(templateId: string, params: any, context: ResolverContext, start?: boolean): Promise<any>;
|
|
30
|
+
createFromTemplate(templateId: string, params: any, context: ResolverContext, start?: boolean, spaceId?: string): Promise<any>;
|
|
10
31
|
twinReferences(context: ResolverContext): Promise<any[]>;
|
|
11
32
|
referenceAdapterTypes(): string[];
|
|
12
33
|
/**
|
|
@@ -29,10 +50,19 @@ export declare class TwinReferenceResolver {
|
|
|
29
50
|
* P1 은 대개 N=1(virtual/단일). start 면 각 인스턴스 기동. 라이브 피드·mode 는 face2-inbound-live 소유.
|
|
30
51
|
*/
|
|
31
52
|
/** 레퍼런스가 노출하는 사이트/공장 발견 — 트윈 생성 시 "어느 공장" 선택용(§2.2). */
|
|
32
|
-
discoverReferenceSites(source: string, context: ResolverContext): Promise<any
|
|
53
|
+
discoverReferenceSites(source: string, context: ResolverContext): Promise<any>;
|
|
33
54
|
/**
|
|
34
55
|
* 트윈 생성 — 레퍼런스에서 사이트 발견 → (siteIds 있으면 그 공장만) → fetchMaster → provision. 사이트별 resilient.
|
|
35
56
|
* 여러 공장을 관할하는 소스는 siteIds 로 "어느 공장"을 골라 생성(1:N, §2.1·§2.2).
|
|
57
|
+
*
|
|
58
|
+
* ── 현장 선택이 이 경로에도 있다 (2026-08-13) ────────────────────────────
|
|
59
|
+
* 한 현실을 여러 렌즈가 비춘다(WMS·MES·YMS). 그런데 **그 선택이 템플릿 경로에만** 있어서
|
|
60
|
+
* (`createFromTemplate(spaceId)`), 실 시스템에서 가져온 트윈은 어댑터가 파생한 공간 id 가 우연히
|
|
61
|
+
* 일치할 때만 한 현장에 모였다 — 사람이 "이 MES 와 같은 현장에 넣어라" 를 말할 방법이 없었다.
|
|
62
|
+
* 데이터로는 가능한 일이 저작으로는 불가능한, `ingest-space` 가 이미 지적한 그 비대칭이다.
|
|
63
|
+
*
|
|
64
|
+
* 판정은 그 순수 모듈이 갖는다: 없는 공간은 거절(`resolveIngestSpace`), 사이트 여럿을 한 공간에
|
|
65
|
+
* 넣는 것도 거절(`refuseImportSpace`) — 서로 다른 현장이 조용히 합쳐지는 것을 막는다.
|
|
36
66
|
*/
|
|
37
|
-
importTwinReference(source: string, context: ResolverContext, siteIds?: string[], start?: boolean, live?: boolean): Promise<any>;
|
|
67
|
+
importTwinReference(source: string, context: ResolverContext, siteIds?: string[], start?: boolean, live?: boolean, spaceId?: string): Promise<any>;
|
|
38
68
|
}
|
|
@@ -5,16 +5,101 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const type_graphql_1 = require("type-graphql");
|
|
6
6
|
const shell_1 = require("@things-factory/shell");
|
|
7
7
|
const index_js_1 = require("../../engine/index.js");
|
|
8
|
+
const twin_kernel_1 = require("@operato/twin-kernel");
|
|
9
|
+
const knob_defaults_js_1 = require("./knob-defaults.js");
|
|
10
|
+
const reference_master_js_1 = require("./reference-master.js");
|
|
8
11
|
const twin_instance_js_1 = require("../twin-instance/twin-instance.js");
|
|
9
12
|
const twin_reference_js_1 = require("./twin-reference.js");
|
|
10
13
|
const reference_registry_js_1 = require("./reference-registry.js");
|
|
11
14
|
const reference_adapter_js_1 = require("./reference-adapter.js");
|
|
15
|
+
const discovery_result_js_1 = require("./discovery-result.js");
|
|
16
|
+
const ingest_space_js_1 = require("./ingest-space.js");
|
|
12
17
|
const reference_live_js_1 = require("./reference-live.js");
|
|
13
18
|
const template_registry_js_1 = require("./template-registry.js");
|
|
14
19
|
/*
|
|
15
20
|
* Face2 레퍼런스 인제스트 채널(ADR-0018) — 등록된 레퍼런스 소스를 열거하고, 골라서 트윈으로 인제스트.
|
|
16
21
|
* "연결하고 내 것을 불러온다" — 엔티티는 레퍼런스에서 오지 손배선/발명이 아니다.
|
|
17
22
|
*/
|
|
23
|
+
/**
|
|
24
|
+
* 발견 조회의 시간 상한 — 15초.
|
|
25
|
+
*
|
|
26
|
+
* 어댑터 계약에 시간 제한이 없다. 주소가 틀린 엔드포인트는 답하지 않고, 그러면 화면이 무한히 로딩된다 —
|
|
27
|
+
* 사용자에게는 "실패" 보다 못한 상태다(무엇을 기다리는지 모른 채 기다린다). 실 시스템 조회가 몇 초
|
|
28
|
+
* 걸리는 것은 정상이므로 넉넉히 두되, 끝은 있어야 한다.
|
|
29
|
+
*/
|
|
30
|
+
const DISCOVER_TIMEOUT_MS = 15_000;
|
|
31
|
+
const TIMEOUT = 'discover-timeout';
|
|
32
|
+
function withTimeout(work, ms) {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const timer = setTimeout(() => reject(Object.assign(new Error('timeout'), { code: TIMEOUT })), ms);
|
|
35
|
+
work.then(v => { clearTimeout(timer); resolve(v); }, e => { clearTimeout(timer); reject(e); });
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 거절을 **사용자 언어로 옮겨 보낸다** — 번역은 한 곳에서 한다.
|
|
40
|
+
*
|
|
41
|
+
* ── 왜 서버인가 (2026-08-14) ────────────────────────────────────────────────
|
|
42
|
+
* 실측: 실행 중인 트윈을 다시 프로비저닝하면 「instance "order-check" is running — stop before
|
|
43
|
+
* re-provisioning」 이라는 **영어 한 줄이 토스트로** 떴다(다섯 언어 제품에서).
|
|
44
|
+
*
|
|
45
|
+
* 서버와 앱은 **같은 사전**을 쓰고, 사용자의 현재 언어가 백엔드에 반영된다. 그래서 이 문구는 서버가
|
|
46
|
+
* 옮기는 것이 맞다 — 프레임워크가 이미 같은 규약이다(`authenticate-401-middleware` 가
|
|
47
|
+
* `context.t('error.' + errorCode, detail)` 로 옮긴다).
|
|
48
|
+
*
|
|
49
|
+
* ── 그러면 코드는 왜 함께 보내나 ────────────────────────────────────────────
|
|
50
|
+
* 화면이 **구조로** 다뤄야 하는 거절이 따로 있다(정합성 표의 행·심각도·수리 버튼 — 그것들은
|
|
51
|
+
* `twin.compose.chk.*` 처럼 화면이 옮긴다). 그리고 브라우저가 아닌 소비자(AI·스크립트·API)에게는
|
|
52
|
+
* 코드가 계약이다. 문장과 코드는 서로를 대신하지 않는다.
|
|
53
|
+
*
|
|
54
|
+
* **두 곳에서 같은 코드를 옮기지 않는다** — 문장이 두 벌이 되면 반드시 어긋난다.
|
|
55
|
+
*/
|
|
56
|
+
function refusal(context, e, fallback) {
|
|
57
|
+
const code = typeof e?.code === 'string' ? e.code : undefined;
|
|
58
|
+
const params = e?.params && typeof e.params === 'object' ? e.params : undefined;
|
|
59
|
+
/* 영어 canonical 은 항상 남긴다 — 번역 키가 없으면 그것이 보이고, 로그에는 그것이 남는다. */
|
|
60
|
+
const canonical = e?.message || fallback;
|
|
61
|
+
const message = code && typeof context.t === 'function'
|
|
62
|
+
? String(context.t(`twin.provision.err.${code}`, { ...(params ?? {}), defaultValue: canonical }))
|
|
63
|
+
: canonical;
|
|
64
|
+
return { ok: false, error: message, ...(code ? { errorCode: code } : {}), ...(params ? { errorParams: params } : {}) };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* `siteEquipmentIds` 노브를 이 현장의 설비로 채운다 — **비어 있을 때만.**
|
|
68
|
+
*
|
|
69
|
+
* 사용자가 목록을 직접 준 경우에는 손대지 않는다(고른 것이 정본이다). 현장이 없으면 채울 것도 없다.
|
|
70
|
+
* 등록부의 모델에서 읽는다(런타임이 아니다) — 트윈이 도는 중이 아니어도 그 현장의 설비는 사실이다.
|
|
71
|
+
*/
|
|
72
|
+
async function resolveSiteEquipmentKnobs(knobs, effective, domainId, spaceId) {
|
|
73
|
+
const targets = (knobs ?? []).filter(k => k?.type === 'siteEquipment');
|
|
74
|
+
if (!targets.length)
|
|
75
|
+
return [];
|
|
76
|
+
const out = [];
|
|
77
|
+
let ids;
|
|
78
|
+
for (const k of targets) {
|
|
79
|
+
const given = effective[k.key];
|
|
80
|
+
if (Array.isArray(given) && given.length)
|
|
81
|
+
continue; // 사용자가 고른 것이 정본이다
|
|
82
|
+
if (!spaceId) {
|
|
83
|
+
effective[k.key] = [];
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (ids === undefined) {
|
|
87
|
+
const rows = await (0, shell_1.getRepository)(twin_instance_js_1.TwinInstance).find({ where: { domain: { id: domainId }, spaceId } });
|
|
88
|
+
const seen = new Map();
|
|
89
|
+
for (const r of rows) {
|
|
90
|
+
for (const e of (0, twin_kernel_1.readBoardEquipment)(r.model ?? {})) {
|
|
91
|
+
if (!e?.id || seen.has(String(e.id)))
|
|
92
|
+
continue;
|
|
93
|
+
seen.set(String(e.id), { id: String(e.id), kind: String(e.kind ?? '') });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
ids = [...seen.values()];
|
|
97
|
+
}
|
|
98
|
+
effective[k.key] = ids;
|
|
99
|
+
out.push({ key: k.key, count: ids.length });
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
18
103
|
let TwinReferenceResolver = class TwinReferenceResolver {
|
|
19
104
|
/** 등록된 레퍼런스 소스 목록(요약 + 이미 인제스트됐는지). */
|
|
20
105
|
async referenceSources(context) {
|
|
@@ -30,7 +115,7 @@ let TwinReferenceResolver = class TwinReferenceResolver {
|
|
|
30
115
|
areaCount: m.locations.filter(l => l.role === 'area' || l.role === 'both').length,
|
|
31
116
|
equipmentCount: (m.equipment ?? []).length,
|
|
32
117
|
imported: !!reg,
|
|
33
|
-
running:
|
|
118
|
+
running: index_js_1.TwinEngine.owns(domainId, m.source)
|
|
34
119
|
});
|
|
35
120
|
}
|
|
36
121
|
return out;
|
|
@@ -42,42 +127,169 @@ let TwinReferenceResolver = class TwinReferenceResolver {
|
|
|
42
127
|
return { ok: false, error: `unknown reference source: ${source}` };
|
|
43
128
|
const domainId = context.state.domain.id;
|
|
44
129
|
try {
|
|
45
|
-
|
|
130
|
+
/* 어디서 왔는지 남긴다 — 이것이 없으면 이 트윈은 두 번 다시 읽을 수 없다.
|
|
131
|
+
이 경로는 **메모리에 등록된 마스터 하나**를 그대로 쓰므로 사이트 서술자가 없다(사이트 정체를
|
|
132
|
+
적을 것이 없다). 다시 읽기도 같은 등록본을 집으므로 사이트를 찾을 필요가 없다. */
|
|
133
|
+
const res = await index_js_1.TwinEngine.ingestMaster(domainId, { ...master, origin: { kind: 'reference', source } }, undefined, context.state.user);
|
|
46
134
|
if (start)
|
|
47
135
|
await index_js_1.TwinEngine.startFromRegistry(domainId, res.instanceId);
|
|
48
136
|
return { ok: true, instanceId: res.instanceId, spaceId: res.spaceId, warnings: res.warnings };
|
|
49
137
|
}
|
|
50
138
|
catch (e) {
|
|
51
|
-
return
|
|
139
|
+
return refusal(context, e, 'ingest failed');
|
|
52
140
|
}
|
|
53
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* **원본에서 다시 읽는다** — 이 트윈의 구조를 지금의 원본 모습으로 갱신한다.
|
|
144
|
+
*
|
|
145
|
+
* ── 왜 진입점이 하나여야 하나 ──────────────────────────────────────────────
|
|
146
|
+
* 지금까지 다시 읽기는 **만드는 경로에 얹혀 있었다**(`importFromReference`·`createFromTemplate`).
|
|
147
|
+
* 그래서 이미 있는 트윈을 갱신하려면 만들 때 무엇을 골랐는지 사람이 기억해 같은 화면을 다시
|
|
148
|
+
* 거쳐야 했고, 템플릿으로 세운 트윈은 노브를 어디에도 안 남겨서 **아예 갱신할 방법이 없었다.**
|
|
149
|
+
* 원천이 무엇이든 트윈 자신이 기억하게 하고(`TwinInstance.origin`), 여기 한 곳에서 그것을 따른다.
|
|
150
|
+
*
|
|
151
|
+
* ── 무엇이 일어나나 ────────────────────────────────────────────────────────
|
|
152
|
+
* 원본에서 마스터를 다시 얻어 인제스트에 그대로 태운다. 그다음은 인제스트가 아는 일이다 —
|
|
153
|
+
* 구조가 달라졌으면 새 리비전이 남고, 구조 행이 다시 그려지고, **실행 중인 미러는 멈추지 않고
|
|
154
|
+
* 전환한다.** 실행 중인 시뮬레이션은 거절된다(조건이 바뀐 실험은 다른 실험이다).
|
|
155
|
+
*
|
|
156
|
+
* ── 못 할 때는 못 한다고 한다 ──────────────────────────────────────────────
|
|
157
|
+
* `origin` 이 없는 트윈(이 자리가 생기기 전에 만들어진 것)은 다시 읽을 수 없다. 짐작으로
|
|
158
|
+
* 템플릿을 고르거나 첫 레퍼런스를 집지 않는다 — 엉뚱한 원본으로 현장을 덮는 것이 훨씬 나쁘다.
|
|
159
|
+
*/
|
|
160
|
+
async resyncTwin(instanceId, context) {
|
|
161
|
+
const domainId = context.state.domain.id;
|
|
162
|
+
const inst = await (0, shell_1.getRepository)(twin_instance_js_1.TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } });
|
|
163
|
+
if (!inst)
|
|
164
|
+
return { ok: false, error: `unknown twin: ${instanceId}` };
|
|
165
|
+
const origin = inst.origin;
|
|
166
|
+
if (!origin?.kind)
|
|
167
|
+
return {
|
|
168
|
+
ok: false,
|
|
169
|
+
error: `twin "${instanceId}" does not remember where it came from — it cannot be re-read. Re-create it from its template or reference so the origin is recorded.`
|
|
170
|
+
};
|
|
171
|
+
try {
|
|
172
|
+
const master = await this.masterFromOrigin(domainId, origin, instanceId);
|
|
173
|
+
/*
|
|
174
|
+
* **어느 현장의 트윈이었나를 지킨다** — 다시 읽기는 구조만 새로 그리는 일이고, 현장 소속은 그때
|
|
175
|
+
* 사람이 고른 것이다. 기억이 없는 옛 트윈은 **지금 있는 현장**을 그대로 쓴다(빈손으로 두면 템플릿
|
|
176
|
+
* 기본 공간으로 옮겨 간다 — 조용히 현장을 떠나고 그 현장의 값도 잃는다).
|
|
177
|
+
*/
|
|
178
|
+
const keepSpace = origin.spaceId || inst.spaceId;
|
|
179
|
+
const res = await index_js_1.TwinEngine.ingestMaster(domainId, master, keepSpace ? { spaceId: keepSpace } : undefined, context.state.user);
|
|
180
|
+
return { ok: true, instanceId: res.instanceId, spaceId: res.spaceId, warnings: res.warnings };
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
return refusal(context, e, 'resync failed');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/** 기억해 둔 원천에서 마스터를 다시 얻는다 — 어댑터든 템플릿이든 이 한 곳에서 갈린다. */
|
|
187
|
+
async masterFromOrigin(domainId, origin, instanceId) {
|
|
188
|
+
if (origin.kind === 'template') {
|
|
189
|
+
const tpl = (0, template_registry_js_1.getTemplate)(origin.templateId);
|
|
190
|
+
if (!tpl)
|
|
191
|
+
throw new Error(`unknown template: ${origin.templateId} — this twin cannot be rebuilt`);
|
|
192
|
+
/* 저장해 둔 노브 그대로 다시 짓는다. 기본값을 다시 입히지 않는다 — 그 사이 템플릿의 기본값이
|
|
193
|
+
바뀌었다면, 사용자가 고르지 않은 값이 조용히 현장을 바꾸게 된다. */
|
|
194
|
+
const { master } = tpl.build(origin.params ?? {});
|
|
195
|
+
master.origin = origin;
|
|
196
|
+
return master;
|
|
197
|
+
}
|
|
198
|
+
/* 레퍼런스 — 메모리 등록본이 있으면 그것, 없으면 저장된 어댑터 연결로 다시 가져온다.
|
|
199
|
+
(부팅 뒤에는 메모리 등록본이 비어 있으므로 어댑터 경로가 실제로 쓰이는 길이다.) */
|
|
200
|
+
const inMemory = (0, reference_registry_js_1.getReference)(origin.source);
|
|
201
|
+
if (inMemory)
|
|
202
|
+
return { ...inMemory, origin };
|
|
203
|
+
const ref = await (0, shell_1.getRepository)(twin_reference_js_1.TwinReference).findOne({ where: { domain: { id: domainId }, source: origin.source } });
|
|
204
|
+
if (!ref)
|
|
205
|
+
throw new Error(`reference "${origin.source}" is no longer registered — nothing to re-read from`);
|
|
206
|
+
const adapter = (0, reference_adapter_js_1.getAdapter)(ref.adapterType);
|
|
207
|
+
if (!adapter)
|
|
208
|
+
throw new Error(`no adapter for type: ${ref.adapterType}`);
|
|
209
|
+
const cfg = ref.connectionConfig ?? {};
|
|
210
|
+
const sites = await adapter.discoverSites(cfg);
|
|
211
|
+
/*
|
|
212
|
+
* ── 무엇을 무엇과 견주나 (2026-08-18 실측으로 고침) ────────────────────────
|
|
213
|
+
*
|
|
214
|
+
* 예전에는 `master.source === origin.source` 로 사이트를 찾았다. 그런데 `origin.source` 는 **레퍼런스
|
|
215
|
+
* 등록 이름**이고(그 참조의 사이트 전부에 같다) `master.source` 는 **사이트별 인스턴스 id** 다 —
|
|
216
|
+
* 서로 다른 것을 견줬으니 사이트가 멀쩡히 있어도 「더 이상 보고하지 않는다」로 거절했다. 사이트가
|
|
217
|
+
* 여럿인 참조에서 온 트윈은 그래서 **전부** 재동기가 불가했고, 오류 문장은 원인을 참조 쪽으로
|
|
218
|
+
* 잘못 가리켰다.
|
|
219
|
+
*
|
|
220
|
+
* 이제 ① 기억해 둔 사이트로 곧장 간다(`origin.siteId`) ② 기억이 없는 옛 트윈은 사이트를 살펴
|
|
221
|
+
* **마스터의 정체(=이 인스턴스 id)** 와 견준다. 어느 쪽도 못 찾으면 **첫 사이트로 때우지 않는다** —
|
|
222
|
+
* 다른 현장의 구조를 이 트윈에 덮는 것은 오류가 아니라 조용히 틀린 공장으로 나타난다.
|
|
223
|
+
*/
|
|
224
|
+
const picked = (0, reference_master_js_1.pickOriginSite)(sites, origin);
|
|
225
|
+
if (picked.site)
|
|
226
|
+
return { ...(await adapter.fetchMaster(cfg, picked.site)), origin };
|
|
227
|
+
if (picked.reason === 'site-gone')
|
|
228
|
+
throw new Error(`reference "${origin.source}" no longer reports site "${origin.siteId}" — refusing to overwrite this twin with a different site`);
|
|
229
|
+
for (const site of sites) {
|
|
230
|
+
const master = await adapter.fetchMaster(cfg, site);
|
|
231
|
+
if (master.source === instanceId)
|
|
232
|
+
return { ...master, origin: { ...origin, siteId: site.siteId } };
|
|
233
|
+
}
|
|
234
|
+
throw new Error(`reference "${origin.source}" does not report a site that rebuilds twin "${instanceId}" ` +
|
|
235
|
+
`(this twin was imported before the site identity was recorded, and no site's master carries its id) — refusing to overwrite it with a different site`);
|
|
236
|
+
}
|
|
54
237
|
/** 등록된 트윈 템플릿(파라미터화 아키타입) 목록 — 노브 스키마 포함(클라이언트 폼용). */
|
|
55
238
|
async twinTemplates(_context) {
|
|
56
239
|
return (0, template_registry_js_1.listTemplates)().map(t => ({ id: t.id, label: t.label, system: t.system, description: t.description, detail: t.detail, knobs: t.knobs }));
|
|
57
240
|
}
|
|
58
241
|
/** 템플릿 + 노브 → 합성 마스터 → 인제스트(+기동+시나리오). 레퍼런스 import 와 같은 경로, 원천만 합성. */
|
|
59
|
-
async createFromTemplate(templateId, params, context, start) {
|
|
242
|
+
async createFromTemplate(templateId, params, context, start, spaceId) {
|
|
60
243
|
const tpl = (0, template_registry_js_1.getTemplate)(templateId);
|
|
61
244
|
if (!tpl)
|
|
62
245
|
return { ok: false, error: `unknown template: ${templateId}` };
|
|
63
246
|
const domainId = context.state.domain.id;
|
|
64
247
|
try {
|
|
65
|
-
|
|
66
|
-
|
|
248
|
+
/*
|
|
249
|
+
* **빠진 노브를 서버가 채운다.** 기본값을 아는 곳은 노브 스키마(계약)인데 그것을 적용하는 곳이
|
|
250
|
+
* 위자드뿐이었다 — 그래서 화면을 거치지 않는 호출자(AI·스크립트·API)가 파라미터를 일부만 주면
|
|
251
|
+
* 템플릿 안에서 발생률이 0 이 되고 **아무것도 하지 않는 트윈**이 조용히 만들어졌다.
|
|
252
|
+
* 채운 노브 이름은 경고로 함께 돌려준다 — 조용히 채우는 것도 조용히 비우는 것만큼 위험하다.
|
|
253
|
+
*/
|
|
254
|
+
const filled = (0, knob_defaults_js_1.filledKnobKeys)(tpl.knobs, params);
|
|
255
|
+
const effective = (0, knob_defaults_js_1.applyKnobDefaults)(tpl.knobs, params);
|
|
256
|
+
/*
|
|
257
|
+
* **이 현장에 이미 있는 설비를 노브 값으로 확정한다** (`siteEquipmentIds`).
|
|
258
|
+
*
|
|
259
|
+
* 에너지 트윈이 「공장이 돌면 전기가 오른다」를 말하려면 부하를 **이웃 트윈의 설비 id 로**
|
|
260
|
+
* 선언해야 한다(설비 하나에 사실 둘). 그 목록을 빌드할 때마다 현장에서 다시 읽으면, 사이에
|
|
261
|
+
* 설비가 늘거나 준 만큼 **다시 지을 때 다른 트윈**이 된다. 그래서 여기서 한 번 해석하고
|
|
262
|
+
* 그 결과를 노브 값으로 남긴다(아래 `origin.params` 에 그대로 저장된다).
|
|
263
|
+
*/
|
|
264
|
+
const adopted = await resolveSiteEquipmentKnobs(tpl.knobs, effective, domainId, spaceId);
|
|
265
|
+
const { master, scenario } = tpl.build(effective);
|
|
266
|
+
/* **무엇으로 지었는지 남긴다.** 합성은 결정적이므로 같은 노브면 같은 마스터가 다시 나온다 —
|
|
267
|
+
그래서 템플릿 트윈도 어댑터 트윈과 똑같이 다시 읽을 수 있다. 남기지 않으면 그 트윈은
|
|
268
|
+
첫날의 모습에 영원히 머문다(원본을 잃은 트윈). */
|
|
269
|
+
/* 고른 현장도 남긴다 — 없으면 다시 읽기가 트윈을 템플릿 기본 공간으로 옮겨 버린다(현장 값도 잃는다). */
|
|
270
|
+
master.origin = { kind: 'template', templateId, params: effective, ...(spaceId ? { spaceId } : {}) };
|
|
271
|
+
/* 공간 선택은 템플릿을 거치지 않는다 — 템플릿마다 이 노브를 알고 있어야 한다면 새 템플릿이
|
|
272
|
+
조용히 무시하게 된다. 합성된 마스터에 한 곳에서 얹는다(레퍼런스 인제스트와 같은 경로). */
|
|
273
|
+
const res = await index_js_1.TwinEngine.ingestMaster(domainId, master, { spaceId }, context.state.user);
|
|
67
274
|
if (start !== false) {
|
|
68
275
|
await index_js_1.TwinEngine.startFromRegistry(domainId, res.instanceId);
|
|
69
276
|
if (scenario) {
|
|
70
|
-
const runtime = index_js_1.TwinEngine.runtime(res.instanceId);
|
|
277
|
+
const runtime = index_js_1.TwinEngine.runtime(domainId, res.instanceId);
|
|
71
278
|
if (runtime) {
|
|
72
279
|
runtime.scenario.load(scenario);
|
|
73
280
|
runtime.scenario.start();
|
|
74
281
|
}
|
|
75
282
|
}
|
|
76
283
|
}
|
|
77
|
-
|
|
284
|
+
const warnings = [
|
|
285
|
+
...(filled.length ? [(0, reference_master_js_1.knobDefaultsFilled)(filled)] : []),
|
|
286
|
+
...adopted.filter(a => a.count > 0).map(a => (0, reference_master_js_1.siteEquipmentAdopted)(a.key, a.count)),
|
|
287
|
+
...res.warnings
|
|
288
|
+
];
|
|
289
|
+
return { ok: true, instanceId: res.instanceId, spaceId: res.spaceId, warnings };
|
|
78
290
|
}
|
|
79
291
|
catch (e) {
|
|
80
|
-
return
|
|
292
|
+
return refusal(context, e, 'template instantiation failed');
|
|
81
293
|
}
|
|
82
294
|
}
|
|
83
295
|
/* ── 레퍼런스 관리(엔티티 기반·테넌트 스코프) — reference-management P1 ────────
|
|
@@ -137,7 +349,7 @@ let TwinReferenceResolver = class TwinReferenceResolver {
|
|
|
137
349
|
.filter(p => instMap.has(p.instanceId))
|
|
138
350
|
.map(p => {
|
|
139
351
|
const inst = instMap.get(p.instanceId);
|
|
140
|
-
return { instanceId: p.instanceId, spaceId: p.spaceId, siteId: p.siteId, kind: inst.kind, status: inst.status, running:
|
|
352
|
+
return { instanceId: p.instanceId, spaceId: p.spaceId, siteId: p.siteId, kind: inst.kind, status: inst.status, running: index_js_1.TwinEngine.owns(domainId, p.instanceId) };
|
|
141
353
|
});
|
|
142
354
|
return {
|
|
143
355
|
source: r.source,
|
|
@@ -230,24 +442,47 @@ let TwinReferenceResolver = class TwinReferenceResolver {
|
|
|
230
442
|
*/
|
|
231
443
|
/** 레퍼런스가 노출하는 사이트/공장 발견 — 트윈 생성 시 "어느 공장" 선택용(§2.2). */
|
|
232
444
|
async discoverReferenceSites(source, context) {
|
|
445
|
+
/*
|
|
446
|
+
* **"못 찾았다" 와 "없다" 를 구분한다.** 예전에는 넷을 빈 배열 하나로 접었고(레퍼런스 없음·어댑터
|
|
447
|
+
* 미상·조회 실패·정말 0건), 화면은 그 모두를 "사이트를 찾지 못했습니다" 라고만 말했다. 실 시스템
|
|
448
|
+
* 연결에서 가장 자주 막히는 자리인데 자격이 틀렸는지 주소가 틀렸는지 알 수 없었다.
|
|
449
|
+
* 판정과 문장 형태는 `discovery-result`(순수)가 갖는다.
|
|
450
|
+
*/
|
|
233
451
|
const ref = await (0, shell_1.getRepository)(twin_reference_js_1.TwinReference).findOne({ where: { domain: { id: context.state.domain.id }, source } });
|
|
234
452
|
if (!ref)
|
|
235
|
-
return
|
|
453
|
+
return (0, discovery_result_js_1.failed)((0, discovery_result_js_1.referenceNotFound)(source));
|
|
236
454
|
const adapter = (0, reference_adapter_js_1.getAdapter)(ref.adapterType);
|
|
237
455
|
if (!adapter)
|
|
238
|
-
return
|
|
456
|
+
return (0, discovery_result_js_1.failed)((0, discovery_result_js_1.adapterUnknown)(ref.adapterType, source));
|
|
239
457
|
try {
|
|
240
|
-
|
|
458
|
+
/*
|
|
459
|
+
* **기다려도 답이 없으면 사유를 준다.** 어댑터 계약에 시간 제한이 없어서, 주소가 틀린 엔드포인트는
|
|
460
|
+
* 화면을 무한히 돌게 만들었다 — 무한히 도는 화면은 조용한 실패의 다른 얼굴이다.
|
|
461
|
+
* 상한은 여기서 정한다(어댑터마다 다르게 두면 사용자가 어느 것을 기다리는지 알 수 없다).
|
|
462
|
+
*/
|
|
463
|
+
const sites = await withTimeout(adapter.discoverSites(ref.connectionConfig ?? {}), DISCOVER_TIMEOUT_MS);
|
|
464
|
+
return (0, discovery_result_js_1.discovered)(sites);
|
|
241
465
|
}
|
|
242
|
-
catch {
|
|
243
|
-
|
|
466
|
+
catch (e) {
|
|
467
|
+
if (e?.code === TIMEOUT)
|
|
468
|
+
return (0, discovery_result_js_1.failed)((0, discovery_result_js_1.discoveryTimedOut)(source, DISCOVER_TIMEOUT_MS / 1000));
|
|
469
|
+
return (0, discovery_result_js_1.failed)((0, discovery_result_js_1.discoveryFailed)(source, (0, discovery_result_js_1.detailOf)(e)));
|
|
244
470
|
}
|
|
245
471
|
}
|
|
246
472
|
/**
|
|
247
473
|
* 트윈 생성 — 레퍼런스에서 사이트 발견 → (siteIds 있으면 그 공장만) → fetchMaster → provision. 사이트별 resilient.
|
|
248
474
|
* 여러 공장을 관할하는 소스는 siteIds 로 "어느 공장"을 골라 생성(1:N, §2.1·§2.2).
|
|
475
|
+
*
|
|
476
|
+
* ── 현장 선택이 이 경로에도 있다 (2026-08-13) ────────────────────────────
|
|
477
|
+
* 한 현실을 여러 렌즈가 비춘다(WMS·MES·YMS). 그런데 **그 선택이 템플릿 경로에만** 있어서
|
|
478
|
+
* (`createFromTemplate(spaceId)`), 실 시스템에서 가져온 트윈은 어댑터가 파생한 공간 id 가 우연히
|
|
479
|
+
* 일치할 때만 한 현장에 모였다 — 사람이 "이 MES 와 같은 현장에 넣어라" 를 말할 방법이 없었다.
|
|
480
|
+
* 데이터로는 가능한 일이 저작으로는 불가능한, `ingest-space` 가 이미 지적한 그 비대칭이다.
|
|
481
|
+
*
|
|
482
|
+
* 판정은 그 순수 모듈이 갖는다: 없는 공간은 거절(`resolveIngestSpace`), 사이트 여럿을 한 공간에
|
|
483
|
+
* 넣는 것도 거절(`refuseImportSpace`) — 서로 다른 현장이 조용히 합쳐지는 것을 막는다.
|
|
249
484
|
*/
|
|
250
|
-
async importTwinReference(source, context, siteIds, start, live) {
|
|
485
|
+
async importTwinReference(source, context, siteIds, start, live, spaceId) {
|
|
251
486
|
const domainId = context.state.domain.id;
|
|
252
487
|
const repo = (0, shell_1.getRepository)(twin_reference_js_1.TwinReference);
|
|
253
488
|
const ref = await repo.findOne({ where: { domain: { id: domainId }, source } });
|
|
@@ -261,12 +496,18 @@ let TwinReferenceResolver = class TwinReferenceResolver {
|
|
|
261
496
|
let sites = await adapter.discoverSites(cfg);
|
|
262
497
|
if (siteIds?.length)
|
|
263
498
|
sites = sites.filter(s => siteIds.includes(s.siteId));
|
|
499
|
+
/* 아무것도 쓰기 전에 거절한다 — 한 사이트를 넘으면 "이 현장에 더한다" 가 성립하지 않는다. */
|
|
500
|
+
const refusal = (0, ingest_space_js_1.refuseImportSpace)(sites.length, spaceId);
|
|
501
|
+
if (refusal)
|
|
502
|
+
return { ok: false, error: refusal.message, errorCode: refusal.code, errorParams: refusal.params };
|
|
264
503
|
const instances = [];
|
|
265
504
|
const failed = [];
|
|
266
505
|
for (const site of sites) {
|
|
267
506
|
try {
|
|
268
507
|
const master = await adapter.fetchMaster(cfg, site);
|
|
269
|
-
|
|
508
|
+
/* 어느 레퍼런스의 **어느 사이트**에서 왔는지 남긴다 — 다시 읽기가 같은 어댑터·같은 사이트로 돌아오려면
|
|
509
|
+
사이트 정체가 있어야 한다(`source` 는 참조 이름이라 사이트 전부에 같다). */
|
|
510
|
+
const res = await index_js_1.TwinEngine.ingestMaster(domainId, { ...master, origin: { kind: 'reference', source, siteId: site.siteId, ...(spaceId ? { spaceId } : {}) } }, { spaceId }, context.state.user);
|
|
270
511
|
if (start !== false) {
|
|
271
512
|
// live=true + 어댑터가 openLiveFeed 지원 → mirror(실 이벤트 미러). 아니면 sim 기동(fallback).
|
|
272
513
|
const wentLive = live ? await (0, reference_live_js_1.startReferenceLiveFeed)(domainId, ref.adapterType, cfg, site, res.instanceId) : false;
|
|
@@ -288,14 +529,21 @@ let TwinReferenceResolver = class TwinReferenceResolver {
|
|
|
288
529
|
await repo.update({ id: ref.id }, {
|
|
289
530
|
status: 'connected',
|
|
290
531
|
lastSyncedAt: new Date().toISOString(),
|
|
291
|
-
|
|
532
|
+
/*
|
|
533
|
+
* **영어 canonical 로 남긴다.** 이 값은 DB 에 저장되고 연결 화면이 그대로 뿌린다 — 예전에는
|
|
534
|
+
* 한글 산문(`N개 사이트 실패`)이라 다섯 언어 화면에 한글이 새어 나갔다. 어댑터가 주는 사유도
|
|
535
|
+
* 같은 필드에 들어오므로(그것은 원 시스템의 말이다) 키가 아니라 영어 문장으로 통일한다.
|
|
536
|
+
* 어느 사이트가 왜 실패했는지는 `failed[]` 가 답한다 — 화면이 그것을 보여 준다.
|
|
537
|
+
*/
|
|
538
|
+
lastError: failed.length ? `${failed.length} of ${sites.length} site(s) failed: ${failed.map((f) => f.siteId).join(', ')}` : null,
|
|
292
539
|
scopeSpec: { ...(ref.scopeSpec ?? {}), produced: [...prev, ...producedNew] }
|
|
293
540
|
});
|
|
294
541
|
return { ok: instances.length > 0, instances, failed };
|
|
295
542
|
}
|
|
296
543
|
catch (e) {
|
|
544
|
+
/* 레퍼런스 행에는 **영어 canonical** 을 남긴다 — 저장되는 값은 언어중립이어야 다시 읽을 수 있다. */
|
|
297
545
|
await repo.update({ id: ref.id }, { status: 'error', lastError: e?.message ?? 'ingest failed' });
|
|
298
|
-
return
|
|
546
|
+
return refusal(context, e, 'ingest failed');
|
|
299
547
|
}
|
|
300
548
|
}
|
|
301
549
|
};
|
|
@@ -308,6 +556,7 @@ tslib_1.__decorate([
|
|
|
308
556
|
tslib_1.__metadata("design:returntype", Promise)
|
|
309
557
|
], TwinReferenceResolver.prototype, "referenceSources", null);
|
|
310
558
|
tslib_1.__decorate([
|
|
559
|
+
(0, type_graphql_1.Directive)('@privilege(category: "twin", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
|
|
311
560
|
(0, type_graphql_1.Mutation)(returns => shell_1.ScalarObject, { description: 'Ingest a registered reference source into a twin (space + instance). Optionally start it.' }),
|
|
312
561
|
tslib_1.__param(0, (0, type_graphql_1.Arg)('source')),
|
|
313
562
|
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
@@ -316,6 +565,17 @@ tslib_1.__decorate([
|
|
|
316
565
|
tslib_1.__metadata("design:paramtypes", [String, Object, Boolean]),
|
|
317
566
|
tslib_1.__metadata("design:returntype", Promise)
|
|
318
567
|
], TwinReferenceResolver.prototype, "importFromReference", null);
|
|
568
|
+
tslib_1.__decorate([
|
|
569
|
+
(0, type_graphql_1.Directive)('@privilege(category: "twin", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
|
|
570
|
+
(0, type_graphql_1.Mutation)(returns => shell_1.ScalarObject, {
|
|
571
|
+
description: "Re-read a twin's structure from the source it remembers (TwinInstance.origin). Works for both reference- and template-born twins. A running mirror adopts the new structure without stopping; a running simulation is refused."
|
|
572
|
+
}),
|
|
573
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('instanceId')),
|
|
574
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
575
|
+
tslib_1.__metadata("design:type", Function),
|
|
576
|
+
tslib_1.__metadata("design:paramtypes", [String, Object]),
|
|
577
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
578
|
+
], TwinReferenceResolver.prototype, "resyncTwin", null);
|
|
319
579
|
tslib_1.__decorate([
|
|
320
580
|
(0, type_graphql_1.Query)(returns => [shell_1.ScalarObject], { description: 'List registered twin templates (parameterized archetypes) with their knob schema.' }),
|
|
321
581
|
tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
|
|
@@ -324,13 +584,15 @@ tslib_1.__decorate([
|
|
|
324
584
|
tslib_1.__metadata("design:returntype", Promise)
|
|
325
585
|
], TwinReferenceResolver.prototype, "twinTemplates", null);
|
|
326
586
|
tslib_1.__decorate([
|
|
587
|
+
(0, type_graphql_1.Directive)('@privilege(category: "twin", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
|
|
327
588
|
(0, type_graphql_1.Mutation)(returns => shell_1.ScalarObject, { description: 'Instantiate a twin template with params → synthetic master → ingest (+start+scenario). Returns {ok, instanceId, spaceId}.' }),
|
|
328
589
|
tslib_1.__param(0, (0, type_graphql_1.Arg)('templateId')),
|
|
329
590
|
tslib_1.__param(1, (0, type_graphql_1.Arg)('params', type => shell_1.ScalarObject)),
|
|
330
591
|
tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
|
|
331
592
|
tslib_1.__param(3, (0, type_graphql_1.Arg)('start', { nullable: true })),
|
|
593
|
+
tslib_1.__param(4, (0, type_graphql_1.Arg)('spaceId', { nullable: true, description: 'Existing space to co-locate this twin into (add a lens to a site). Omit to create its own space.' })),
|
|
332
594
|
tslib_1.__metadata("design:type", Function),
|
|
333
|
-
tslib_1.__metadata("design:paramtypes", [String, Object, Object, Boolean]),
|
|
595
|
+
tslib_1.__metadata("design:paramtypes", [String, Object, Object, Boolean, String]),
|
|
334
596
|
tslib_1.__metadata("design:returntype", Promise)
|
|
335
597
|
], TwinReferenceResolver.prototype, "createFromTemplate", null);
|
|
336
598
|
tslib_1.__decorate([
|
|
@@ -376,6 +638,7 @@ tslib_1.__decorate([
|
|
|
376
638
|
tslib_1.__metadata("design:returntype", Array)
|
|
377
639
|
], TwinReferenceResolver.prototype, "referenceAdapters", null);
|
|
378
640
|
tslib_1.__decorate([
|
|
641
|
+
(0, type_graphql_1.Directive)('@privilege(category: "twin", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
|
|
379
642
|
(0, type_graphql_1.Mutation)(returns => shell_1.ScalarObject, { description: 'Create or update a tenant-scoped twin reference (persisted).' }),
|
|
380
643
|
tslib_1.__param(0, (0, type_graphql_1.Arg)('source')),
|
|
381
644
|
tslib_1.__param(1, (0, type_graphql_1.Arg)('patch', type => shell_1.ScalarObject)),
|
|
@@ -385,6 +648,7 @@ tslib_1.__decorate([
|
|
|
385
648
|
tslib_1.__metadata("design:returntype", Promise)
|
|
386
649
|
], TwinReferenceResolver.prototype, "saveTwinReference", null);
|
|
387
650
|
tslib_1.__decorate([
|
|
651
|
+
(0, type_graphql_1.Directive)('@privilege(category: "twin", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
|
|
388
652
|
(0, type_graphql_1.Mutation)(returns => Boolean, { description: 'Delete a tenant-scoped reference. If removeTwins, also remove the twin instances it produced (provenance cascade); otherwise twins are kept (detached).' }),
|
|
389
653
|
tslib_1.__param(0, (0, type_graphql_1.Arg)('source')),
|
|
390
654
|
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
@@ -394,6 +658,7 @@ tslib_1.__decorate([
|
|
|
394
658
|
tslib_1.__metadata("design:returntype", Promise)
|
|
395
659
|
], TwinReferenceResolver.prototype, "deleteTwinReference", null);
|
|
396
660
|
tslib_1.__decorate([
|
|
661
|
+
(0, type_graphql_1.Directive)('@privilege(category: "twin", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
|
|
397
662
|
(0, type_graphql_1.Mutation)(returns => shell_1.ScalarObject, { description: 'Test a reference connection via its adapter; updates status.' }),
|
|
398
663
|
tslib_1.__param(0, (0, type_graphql_1.Arg)('source')),
|
|
399
664
|
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
@@ -402,7 +667,7 @@ tslib_1.__decorate([
|
|
|
402
667
|
tslib_1.__metadata("design:returntype", Promise)
|
|
403
668
|
], TwinReferenceResolver.prototype, "testReferenceConnection", null);
|
|
404
669
|
tslib_1.__decorate([
|
|
405
|
-
(0, type_graphql_1.Query)(returns =>
|
|
670
|
+
(0, type_graphql_1.Query)(returns => shell_1.ScalarObject, { description: 'Discover sites/factories exposed by a reference. Returns { sites, error? } — an empty list with no error means the system genuinely has none, which is different from a failure.' }),
|
|
406
671
|
tslib_1.__param(0, (0, type_graphql_1.Arg)('source')),
|
|
407
672
|
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
408
673
|
tslib_1.__metadata("design:type", Function),
|
|
@@ -410,14 +675,16 @@ tslib_1.__decorate([
|
|
|
410
675
|
tslib_1.__metadata("design:returntype", Promise)
|
|
411
676
|
], TwinReferenceResolver.prototype, "discoverReferenceSites", null);
|
|
412
677
|
tslib_1.__decorate([
|
|
413
|
-
(0, type_graphql_1.
|
|
678
|
+
(0, type_graphql_1.Directive)('@privilege(category: "twin", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
|
|
679
|
+
(0, type_graphql_1.Mutation)(returns => shell_1.ScalarObject, { description: 'Create twins from a reference: discover sites → filter by siteIds (if given) → fetch master(s) → provision. spaceId co-locates the twin into an existing space (one site only). start=false to only provision; live=true to run as a mirror (adapter openLiveFeed → live projector) instead of sim.' }),
|
|
414
680
|
tslib_1.__param(0, (0, type_graphql_1.Arg)('source')),
|
|
415
681
|
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
416
682
|
tslib_1.__param(2, (0, type_graphql_1.Arg)('siteIds', type => [String], { nullable: true })),
|
|
417
683
|
tslib_1.__param(3, (0, type_graphql_1.Arg)('start', { nullable: true })),
|
|
418
684
|
tslib_1.__param(4, (0, type_graphql_1.Arg)('live', { nullable: true })),
|
|
685
|
+
tslib_1.__param(5, (0, type_graphql_1.Arg)('spaceId', { nullable: true, description: 'Existing space to co-locate this twin into (add a lens to a site). Only when importing a single site. Omit to give each site its own space.' })),
|
|
419
686
|
tslib_1.__metadata("design:type", Function),
|
|
420
|
-
tslib_1.__metadata("design:paramtypes", [String, Object, Array, Boolean, Boolean]),
|
|
687
|
+
tslib_1.__metadata("design:paramtypes", [String, Object, Array, Boolean, Boolean, String]),
|
|
421
688
|
tslib_1.__metadata("design:returntype", Promise)
|
|
422
689
|
], TwinReferenceResolver.prototype, "importTwinReference", null);
|
|
423
690
|
exports.TwinReferenceResolver = TwinReferenceResolver = tslib_1.__decorate([
|