@things-factory/headless-twin 10.0.6 → 10.0.7

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.
Files changed (150) hide show
  1. package/README.md +37 -24
  2. package/dist-server/engine/entity-delta.d.ts +13 -1
  3. package/dist-server/engine/entity-delta.js +130 -16
  4. package/dist-server/engine/entity-delta.js.map +1 -1
  5. package/dist-server/engine/index.d.ts +4 -0
  6. package/dist-server/engine/index.js +4 -0
  7. package/dist-server/engine/index.js.map +1 -1
  8. package/dist-server/engine/kpi-fold.d.ts +20 -3
  9. package/dist-server/engine/kpi-fold.js +21 -4
  10. package/dist-server/engine/kpi-fold.js.map +1 -1
  11. package/dist-server/engine/kpi-query.d.ts +9 -0
  12. package/dist-server/engine/kpi-query.js +118 -19
  13. package/dist-server/engine/kpi-query.js.map +1 -1
  14. package/dist-server/engine/kpi-target.d.ts +141 -0
  15. package/dist-server/engine/kpi-target.js +137 -0
  16. package/dist-server/engine/kpi-target.js.map +1 -0
  17. package/dist-server/engine/live-attentions.d.ts +4 -2
  18. package/dist-server/engine/live-attentions.js +5 -1
  19. package/dist-server/engine/live-attentions.js.map +1 -1
  20. package/dist-server/engine/measured-estimator.d.ts +50 -0
  21. package/dist-server/engine/measured-estimator.js +78 -0
  22. package/dist-server/engine/measured-estimator.js.map +1 -0
  23. package/dist-server/engine/model-basis.d.ts +23 -0
  24. package/dist-server/engine/model-basis.js +100 -0
  25. package/dist-server/engine/model-basis.js.map +1 -0
  26. package/dist-server/engine/oee-accumulator.d.ts +2 -2
  27. package/dist-server/engine/oee-accumulator.js +4 -4
  28. package/dist-server/engine/oee-accumulator.js.map +1 -1
  29. package/dist-server/engine/spec-coverage.d.ts +49 -0
  30. package/dist-server/engine/spec-coverage.js +60 -0
  31. package/dist-server/engine/spec-coverage.js.map +1 -0
  32. package/dist-server/engine/structure-diff.d.ts +25 -0
  33. package/dist-server/engine/structure-diff.js +63 -0
  34. package/dist-server/engine/structure-diff.js.map +1 -0
  35. package/dist-server/engine/travel-estimator.d.ts +57 -0
  36. package/dist-server/engine/travel-estimator.js +120 -0
  37. package/dist-server/engine/travel-estimator.js.map +1 -0
  38. package/dist-server/engine/twin-engine.d.ts +153 -17
  39. package/dist-server/engine/twin-engine.js +473 -81
  40. package/dist-server/engine/twin-engine.js.map +1 -1
  41. package/dist-server/engine/warm-start.d.ts +5 -5
  42. package/dist-server/engine/warm-start.js +4 -4
  43. package/dist-server/engine/warm-start.js.map +1 -1
  44. package/dist-server/service/index.d.ts +4 -2
  45. package/dist-server/service/index.js +21 -14
  46. package/dist-server/service/index.js.map +1 -1
  47. package/dist-server/service/reference/reference-live.js +2 -1
  48. package/dist-server/service/reference/reference-live.js.map +1 -1
  49. package/dist-server/service/reference/reference-master.d.ts +307 -1
  50. package/dist-server/service/reference/reference-master.js +96 -8
  51. package/dist-server/service/reference/reference-master.js.map +1 -1
  52. package/dist-server/service/reference/reference-resolver.js +3 -3
  53. package/dist-server/service/reference/reference-resolver.js.map +1 -1
  54. package/dist-server/service/reference/template-registry.d.ts +1 -1
  55. package/dist-server/service/reference/template-registry.js.map +1 -1
  56. package/dist-server/service/twin-attention/twin-attention-query.js +1 -1
  57. package/dist-server/service/twin-attention/twin-attention-query.js.map +1 -1
  58. package/dist-server/service/twin-control/twin-control-mutation.js +1 -1
  59. package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
  60. package/dist-server/service/twin-event/twin-event-keys.d.ts +1 -1
  61. package/dist-server/service/twin-event/twin-event-keys.js +3 -3
  62. package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
  63. package/dist-server/service/twin-event/twin-event.d.ts +11 -0
  64. package/dist-server/service/twin-event/twin-event.js +6 -1
  65. package/dist-server/service/twin-event/twin-event.js.map +1 -1
  66. package/dist-server/service/twin-forecast/twin-forecast-query.js +50 -7
  67. package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
  68. package/dist-server/service/twin-instance/twin-instance.js +1 -1
  69. package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
  70. package/dist-server/service/twin-journal/twin-journal-query.d.ts +9 -0
  71. package/dist-server/service/twin-journal/twin-journal-query.js +54 -3
  72. package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
  73. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +1 -1
  74. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +4 -3
  75. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
  76. package/dist-server/service/twin-space/twin-space-area.js +1 -1
  77. package/dist-server/service/twin-space/twin-space-area.js.map +1 -1
  78. package/dist-server/service/twin-space/twin-space-resolver.js +3 -3
  79. package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
  80. package/dist-server/service/twin-space/twin-space.d.ts +11 -0
  81. package/dist-server/service/twin-space/twin-space.js +5 -0
  82. package/dist-server/service/twin-space/twin-space.js.map +1 -1
  83. package/dist-server/service/twin-structure/index.d.ts +2 -0
  84. package/dist-server/service/twin-structure/index.js +6 -0
  85. package/dist-server/service/twin-structure/index.js.map +1 -0
  86. package/dist-server/service/twin-structure/twin-structure.d.ts +28 -0
  87. package/dist-server/service/twin-structure/twin-structure.js +97 -0
  88. package/dist-server/service/twin-structure/twin-structure.js.map +1 -0
  89. package/dist-server/service/twin-target/index.d.ts +4 -0
  90. package/dist-server/service/twin-target/index.js +8 -0
  91. package/dist-server/service/twin-target/index.js.map +1 -0
  92. package/dist-server/service/twin-target/twin-target-resolver.d.ts +7 -0
  93. package/dist-server/service/twin-target/twin-target-resolver.js +143 -0
  94. package/dist-server/service/twin-target/twin-target-resolver.js.map +1 -0
  95. package/dist-server/service/twin-target/twin-target.d.ts +25 -0
  96. package/dist-server/service/twin-target/twin-target.js +112 -0
  97. package/dist-server/service/twin-target/twin-target.js.map +1 -0
  98. package/dist-server/tsconfig.tsbuildinfo +1 -1
  99. package/package.json +6 -6
  100. package/server/engine/entity-delta.ts +135 -15
  101. package/server/engine/index.ts +4 -0
  102. package/server/engine/kpi-fold.ts +40 -8
  103. package/server/engine/kpi-query.ts +129 -19
  104. package/server/engine/kpi-target.ts +226 -0
  105. package/server/engine/live-attentions.ts +12 -2
  106. package/server/engine/measured-estimator.ts +91 -0
  107. package/server/engine/model-basis.ts +94 -0
  108. package/server/engine/oee-accumulator.ts +5 -5
  109. package/server/engine/spec-coverage.ts +85 -0
  110. package/server/engine/structure-diff.ts +88 -0
  111. package/server/engine/travel-estimator.ts +133 -0
  112. package/server/engine/twin-engine.ts +498 -84
  113. package/server/engine/warm-start.ts +8 -8
  114. package/server/service/index.ts +7 -0
  115. package/server/service/reference/reference-live.ts +2 -1
  116. package/server/service/reference/reference-master.ts +383 -10
  117. package/server/service/reference/reference-resolver.ts +3 -3
  118. package/server/service/reference/template-registry.ts +1 -1
  119. package/server/service/twin-attention/twin-attention-query.ts +1 -1
  120. package/server/service/twin-control/twin-control-mutation.ts +1 -1
  121. package/server/service/twin-event/twin-event-keys.ts +2 -2
  122. package/server/service/twin-event/twin-event.ts +15 -1
  123. package/server/service/twin-forecast/twin-forecast-query.ts +56 -8
  124. package/server/service/twin-instance/twin-instance.ts +1 -1
  125. package/server/service/twin-journal/twin-journal-query.ts +52 -4
  126. package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +4 -3
  127. package/server/service/twin-space/twin-space-area.ts +1 -1
  128. package/server/service/twin-space/twin-space-resolver.ts +3 -3
  129. package/server/service/twin-space/twin-space.ts +14 -0
  130. package/server/service/twin-structure/index.ts +3 -0
  131. package/server/service/twin-structure/twin-structure.ts +93 -0
  132. package/server/service/twin-target/index.ts +5 -0
  133. package/server/service/twin-target/twin-target-resolver.ts +124 -0
  134. package/server/service/twin-target/twin-target.ts +97 -0
  135. package/test/capability-mapping.test.ts +5 -5
  136. package/test/duration-estimators.test.ts +144 -0
  137. package/test/entity-delta.test.ts +150 -19
  138. package/test/ingest-bench.test.ts +9 -9
  139. package/test/kpi-fold.test.ts +232 -3
  140. package/test/live-mirror-parity.test.ts +53 -19
  141. package/test/master-to-twin.test.ts +87 -13
  142. package/test/model-basis.test.ts +86 -0
  143. package/test/oee-accumulator.test.ts +9 -9
  144. package/test/scale-twin-bench.test.ts +22 -22
  145. package/test/spec-coverage.test.ts +113 -0
  146. package/test/streamline-e2e.test.ts +10 -10
  147. package/test/structure-revision-db.test.ts +310 -0
  148. package/test/twin-event-keys.test.ts +2 -2
  149. package/test/vocabulary-guard.test.ts +43 -0
  150. package/test/warm-start.test.ts +9 -9
@@ -0,0 +1,43 @@
1
+ /*
2
+ * 어휘 가드 — 규칙은 커널이 한 벌 들고 있고(`@operato/twin-kernel` `retiredVocabularyIn`),
3
+ * 이 테스트는 **자기 패키지 소스를 훑는다.** 판정이 패키지마다 갈릴 수 없다.
4
+ *
5
+ * 계기(2026-08-01): 개명을 손으로 쓸다 같은 실수를 세 번 반복했다. 단어 경계로 찾으면 파생 식별자가
6
+ * 빠지고(`moverCount`·`locationType`), 빠진 것은 다음 파도에서야 드러난다. 그 사이 코드에는 두 어휘가
7
+ * 섞여 있고 다음 사람은 어느 쪽을 믿을지 모른다.
8
+ *
9
+ * 실패하면 위반 목록이 그대로 나온다 — 고치거나, 정당하면 그 줄에 `vocabulary-guard: allow <이유>` 를
10
+ * 남긴다(예외가 코드에 이유와 함께 남는다).
11
+ */
12
+ import { test } from 'node:test'
13
+ import assert from 'node:assert/strict'
14
+ import { readdirSync, readFileSync, statSync } from 'node:fs'
15
+ import { join } from 'node:path'
16
+
17
+ import { retiredVocabularyIn } from '@operato/twin-kernel'
18
+
19
+ const ROOTS = ['server', 'client'].map(d => new URL(`../${d}`, import.meta.url).pathname)
20
+
21
+ function walk(dir: string, out: string[] = []): string[] {
22
+ let entries: string[]
23
+ try { entries = readdirSync(dir) } catch { return out }
24
+ for (const e of entries) {
25
+ const p = join(dir, e)
26
+ if (statSync(p).isDirectory()) walk(p, out)
27
+ else if (p.endsWith('.ts') && !p.endsWith('.d.ts')) out.push(p)
28
+ }
29
+ return out
30
+ }
31
+
32
+ test('소스에 은퇴한 어휘(location·mover)가 남아 있지 않다', () => {
33
+ const bad: string[] = []
34
+ for (const root of ROOTS) {
35
+ for (const f of walk(root)) {
36
+ readFileSync(f, 'utf-8').split('\n').forEach((line, i) => {
37
+ const hits = retiredVocabularyIn(line)
38
+ if (hits.length) bad.push(`${f.split('/').slice(-2).join('/')}:${i + 1} ${[...new Set(hits)].join(', ')}`)
39
+ })
40
+ }
41
+ }
42
+ assert.deepEqual(bad, [], `은퇴 어휘 ${bad.length}곳:\n${bad.slice(0, 60).join('\n')}${bad.length > 60 ? `\n… ${bad.length - 60} more` : ''}`)
43
+ })
@@ -11,9 +11,9 @@ import assert from 'node:assert/strict'
11
11
  import { planWarmStart } from '../server/engine/warm-start.ts'
12
12
 
13
13
  const STATE = {
14
- nodes: [{ id: 'dock-recv' }, { id: 'rack-1' }],
14
+ locations: [{ id: 'dock-recv' }, { id: 'rack-1' }],
15
15
  items: [{ epc: 'a' }, { epc: 'b' }, { epc: 'c' }],
16
- movers: [{ id: 'fork-1' }],
16
+ equipment: [{ id: 'fork-1' }],
17
17
  orders: [{ id: 'SO-1', kind: 'outbound', status: 'created', progress: 0.5 }],
18
18
  tasks: [{ id: 't1' }]
19
19
  }
@@ -23,15 +23,15 @@ test('상태가 있으면 심는다 — 재고·노드·무버', () => {
23
23
  assert.equal(plan.action, 'hydrate')
24
24
  if (plan.action !== 'hydrate') return
25
25
  assert.equal(plan.itemCount, 3)
26
- assert.equal(plan.moverCount, 1)
27
- assert.deepEqual(plan.seed.nodes, STATE.nodes)
26
+ assert.equal(plan.equipmentCount, 1)
27
+ assert.deepEqual(plan.seed.locations, STATE.locations)
28
28
  })
29
29
 
30
30
  test('오더는 심지 않는다 — 스냅샷에 requested/fulfilled 가 없어 지어내야 하기 때문', () => {
31
31
  const plan = planWarmStart(STATE, undefined, true)
32
32
  assert.equal(plan.action, 'hydrate')
33
33
  if (plan.action !== 'hydrate') return
34
- assert.deepEqual(Object.keys(plan.seed).sort(), ['items', 'movers', 'nodes'])
34
+ assert.deepEqual(Object.keys(plan.seed).sort(), ['equipment', 'items', 'locations'])
35
35
  assert.equal((plan.seed as any).orders, undefined)
36
36
  assert.equal((plan.seed as any).tasks, undefined)
37
37
  })
@@ -49,11 +49,11 @@ test('벤치 판정은 상태 유무보다 먼저다 — 상태가 없어도 이
49
49
  test('심을 상태가 없으면 조용히 넘어간다 — 처음 만든 트윈의 정상 경로다', () => {
50
50
  assert.deepEqual(planWarmStart(null, undefined, true), { action: 'skip', reason: 'no-state' })
51
51
  assert.deepEqual(planWarmStart(undefined, undefined, true), { action: 'skip', reason: 'no-state' })
52
- assert.deepEqual(planWarmStart({ nodes: [], items: [], movers: [] }, undefined, true), { action: 'skip', reason: 'no-state' })
52
+ assert.deepEqual(planWarmStart({ locations: [], items: [], equipment: [] }, undefined, true), { action: 'skip', reason: 'no-state' })
53
53
  })
54
54
 
55
55
  test('노드만 있어도 심는다 — 구조 배치가 복원되면 화면이 살아난다', () => {
56
- const plan = planWarmStart({ nodes: [{ id: 'n1' }], items: [], movers: [] }, undefined, true)
56
+ const plan = planWarmStart({ locations: [{ id: 'n1' }], items: [], equipment: [] }, undefined, true)
57
57
  assert.equal(plan.action, 'hydrate')
58
58
  if (plan.action !== 'hydrate') return
59
59
  assert.equal(plan.itemCount, 0)
@@ -72,7 +72,7 @@ test('빠진 배열은 빈 배열로 다뤄지되 없는 것을 지어내지 않
72
72
  const plan = planWarmStart({ items: [{ epc: 'a' }] } as any, undefined, true)
73
73
  assert.equal(plan.action, 'hydrate')
74
74
  if (plan.action !== 'hydrate') return
75
- assert.deepEqual(plan.seed.nodes, [])
76
- assert.deepEqual(plan.seed.movers, [])
75
+ assert.deepEqual(plan.seed.locations, [])
76
+ assert.deepEqual(plan.seed.equipment, [])
77
77
  assert.equal(plan.itemCount, 1)
78
78
  })