@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.
- package/README.md +37 -24
- package/dist-server/engine/entity-delta.d.ts +13 -1
- package/dist-server/engine/entity-delta.js +130 -16
- package/dist-server/engine/entity-delta.js.map +1 -1
- package/dist-server/engine/index.d.ts +4 -0
- package/dist-server/engine/index.js +4 -0
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/kpi-fold.d.ts +20 -3
- package/dist-server/engine/kpi-fold.js +21 -4
- package/dist-server/engine/kpi-fold.js.map +1 -1
- package/dist-server/engine/kpi-query.d.ts +9 -0
- package/dist-server/engine/kpi-query.js +118 -19
- package/dist-server/engine/kpi-query.js.map +1 -1
- package/dist-server/engine/kpi-target.d.ts +141 -0
- package/dist-server/engine/kpi-target.js +137 -0
- package/dist-server/engine/kpi-target.js.map +1 -0
- package/dist-server/engine/live-attentions.d.ts +4 -2
- package/dist-server/engine/live-attentions.js +5 -1
- package/dist-server/engine/live-attentions.js.map +1 -1
- package/dist-server/engine/measured-estimator.d.ts +50 -0
- package/dist-server/engine/measured-estimator.js +78 -0
- package/dist-server/engine/measured-estimator.js.map +1 -0
- package/dist-server/engine/model-basis.d.ts +23 -0
- package/dist-server/engine/model-basis.js +100 -0
- package/dist-server/engine/model-basis.js.map +1 -0
- package/dist-server/engine/oee-accumulator.d.ts +2 -2
- package/dist-server/engine/oee-accumulator.js +4 -4
- package/dist-server/engine/oee-accumulator.js.map +1 -1
- package/dist-server/engine/spec-coverage.d.ts +49 -0
- package/dist-server/engine/spec-coverage.js +60 -0
- package/dist-server/engine/spec-coverage.js.map +1 -0
- package/dist-server/engine/structure-diff.d.ts +25 -0
- package/dist-server/engine/structure-diff.js +63 -0
- package/dist-server/engine/structure-diff.js.map +1 -0
- package/dist-server/engine/travel-estimator.d.ts +57 -0
- package/dist-server/engine/travel-estimator.js +120 -0
- package/dist-server/engine/travel-estimator.js.map +1 -0
- package/dist-server/engine/twin-engine.d.ts +153 -17
- package/dist-server/engine/twin-engine.js +473 -81
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/engine/warm-start.d.ts +5 -5
- package/dist-server/engine/warm-start.js +4 -4
- package/dist-server/engine/warm-start.js.map +1 -1
- package/dist-server/service/index.d.ts +4 -2
- package/dist-server/service/index.js +21 -14
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/reference/reference-live.js +2 -1
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +307 -1
- package/dist-server/service/reference/reference-master.js +96 -8
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-resolver.js +3 -3
- package/dist-server/service/reference/reference-resolver.js.map +1 -1
- package/dist-server/service/reference/template-registry.d.ts +1 -1
- package/dist-server/service/reference/template-registry.js.map +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.js +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.js.map +1 -1
- package/dist-server/service/twin-control/twin-control-mutation.js +1 -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 +3 -3
- package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
- package/dist-server/service/twin-event/twin-event.d.ts +11 -0
- package/dist-server/service/twin-event/twin-event.js +6 -1
- package/dist-server/service/twin-event/twin-event.js.map +1 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js +50 -7
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
- package/dist-server/service/twin-instance/twin-instance.js +1 -1
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/twin-journal-query.d.ts +9 -0
- package/dist-server/service/twin-journal/twin-journal-query.js +54 -3
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +4 -3
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-area.js +1 -1
- package/dist-server/service/twin-space/twin-space-area.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-resolver.js +3 -3
- package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
- package/dist-server/service/twin-space/twin-space.d.ts +11 -0
- package/dist-server/service/twin-space/twin-space.js +5 -0
- package/dist-server/service/twin-space/twin-space.js.map +1 -1
- package/dist-server/service/twin-structure/index.d.ts +2 -0
- package/dist-server/service/twin-structure/index.js +6 -0
- package/dist-server/service/twin-structure/index.js.map +1 -0
- package/dist-server/service/twin-structure/twin-structure.d.ts +28 -0
- package/dist-server/service/twin-structure/twin-structure.js +97 -0
- package/dist-server/service/twin-structure/twin-structure.js.map +1 -0
- package/dist-server/service/twin-target/index.d.ts +4 -0
- package/dist-server/service/twin-target/index.js +8 -0
- package/dist-server/service/twin-target/index.js.map +1 -0
- package/dist-server/service/twin-target/twin-target-resolver.d.ts +7 -0
- package/dist-server/service/twin-target/twin-target-resolver.js +143 -0
- package/dist-server/service/twin-target/twin-target-resolver.js.map +1 -0
- package/dist-server/service/twin-target/twin-target.d.ts +25 -0
- package/dist-server/service/twin-target/twin-target.js +112 -0
- package/dist-server/service/twin-target/twin-target.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/server/engine/entity-delta.ts +135 -15
- package/server/engine/index.ts +4 -0
- package/server/engine/kpi-fold.ts +40 -8
- package/server/engine/kpi-query.ts +129 -19
- package/server/engine/kpi-target.ts +226 -0
- package/server/engine/live-attentions.ts +12 -2
- package/server/engine/measured-estimator.ts +91 -0
- package/server/engine/model-basis.ts +94 -0
- package/server/engine/oee-accumulator.ts +5 -5
- package/server/engine/spec-coverage.ts +85 -0
- package/server/engine/structure-diff.ts +88 -0
- package/server/engine/travel-estimator.ts +133 -0
- package/server/engine/twin-engine.ts +498 -84
- package/server/engine/warm-start.ts +8 -8
- package/server/service/index.ts +7 -0
- package/server/service/reference/reference-live.ts +2 -1
- package/server/service/reference/reference-master.ts +383 -10
- package/server/service/reference/reference-resolver.ts +3 -3
- package/server/service/reference/template-registry.ts +1 -1
- package/server/service/twin-attention/twin-attention-query.ts +1 -1
- package/server/service/twin-control/twin-control-mutation.ts +1 -1
- package/server/service/twin-event/twin-event-keys.ts +2 -2
- package/server/service/twin-event/twin-event.ts +15 -1
- package/server/service/twin-forecast/twin-forecast-query.ts +56 -8
- package/server/service/twin-instance/twin-instance.ts +1 -1
- package/server/service/twin-journal/twin-journal-query.ts +52 -4
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +4 -3
- package/server/service/twin-space/twin-space-area.ts +1 -1
- package/server/service/twin-space/twin-space-resolver.ts +3 -3
- package/server/service/twin-space/twin-space.ts +14 -0
- package/server/service/twin-structure/index.ts +3 -0
- package/server/service/twin-structure/twin-structure.ts +93 -0
- package/server/service/twin-target/index.ts +5 -0
- package/server/service/twin-target/twin-target-resolver.ts +124 -0
- package/server/service/twin-target/twin-target.ts +97 -0
- package/test/capability-mapping.test.ts +5 -5
- package/test/duration-estimators.test.ts +144 -0
- package/test/entity-delta.test.ts +150 -19
- package/test/ingest-bench.test.ts +9 -9
- package/test/kpi-fold.test.ts +232 -3
- package/test/live-mirror-parity.test.ts +53 -19
- package/test/master-to-twin.test.ts +87 -13
- package/test/model-basis.test.ts +86 -0
- package/test/oee-accumulator.test.ts +9 -9
- package/test/scale-twin-bench.test.ts +22 -22
- package/test/spec-coverage.test.ts +113 -0
- package/test/streamline-e2e.test.ts +10 -10
- package/test/structure-revision-db.test.ts +310 -0
- package/test/twin-event-keys.test.ts +2 -2
- package/test/vocabulary-guard.test.ts +43 -0
- 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
|
+
})
|
package/test/warm-start.test.ts
CHANGED
|
@@ -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
|
-
|
|
14
|
+
locations: [{ id: 'dock-recv' }, { id: 'rack-1' }],
|
|
15
15
|
items: [{ epc: 'a' }, { epc: 'b' }, { epc: 'c' }],
|
|
16
|
-
|
|
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.
|
|
27
|
-
assert.deepEqual(plan.seed.
|
|
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(), ['
|
|
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({
|
|
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({
|
|
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.
|
|
76
|
-
assert.deepEqual(plan.seed.
|
|
75
|
+
assert.deepEqual(plan.seed.locations, [])
|
|
76
|
+
assert.deepEqual(plan.seed.equipment, [])
|
|
77
77
|
assert.equal(plan.itemCount, 1)
|
|
78
78
|
})
|