@operato/twin-kernel 0.7.88 → 0.7.90
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/class-master-table.d.ts +35 -0
- package/dist/class-master-table.js +72 -0
- package/dist/contract.d.ts +21 -1
- package/dist/contract.js +2 -12
- package/dist/counterfactual.d.ts +1 -1
- package/dist/divergence.d.ts +1 -1
- package/dist/divergence.js +1 -1
- package/dist/ems-kernel.d.ts +1 -1
- package/dist/ems-kernel.js +20 -10
- package/dist/event-journal.d.ts +1 -1
- package/dist/flow-engine.d.ts +6 -6
- package/dist/flow-engine.js +8 -8
- package/dist/forecast.d.ts +1 -1
- package/dist/index.d.ts +21 -20
- package/dist/index.js +19 -18
- package/dist/job-response.d.ts +1 -1
- package/dist/kernel.d.ts +1 -1
- package/dist/kernel.js +4 -4
- package/dist/make-to-order.d.ts +1 -1
- package/dist/mes-kernel.d.ts +3 -3
- package/dist/mes-kernel.js +4 -4
- package/dist/observed-reducer.d.ts +2 -2
- package/dist/observed-reducer.js +5 -3
- package/dist/runtime.d.ts +1 -1
- package/dist/task-fold.d.ts +1 -1
- package/dist/twin-observer.d.ts +1 -1
- package/dist/yms-kernel.d.ts +1 -1
- package/dist/yms-kernel.js +3 -3
- package/dist-cjs/index.cjs +9513 -9164
- package/package.json +4 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { VocabularyElement } from '@operato/operations-contract';
|
|
2
|
+
/**
|
|
3
|
+
* 클래스 단위 마스터 표 — 관측 리듀서가 든다.
|
|
4
|
+
*
|
|
5
|
+
* 물품은 자리마다 따로 서지만(`클래스@자리`) 이 속성은 **클래스의 것**이다. 그래서 물품마다 복사해
|
|
6
|
+
* 두지 않고 클래스로 한 번 들고, 물품을 세울 때 본다. 마스터가 관측보다 늦게 와도 값이 서는 이유다.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ClassMasterTable {
|
|
9
|
+
private byId;
|
|
10
|
+
/**
|
|
11
|
+
* 속성을 **합친다** — 덮지 않는다(한 번에 일부만 오는 원본이 있다). 바뀐 식별자를 돌려준다.
|
|
12
|
+
*
|
|
13
|
+
* ── 지우는 법 ───────────────────────────────────────────────────────────────
|
|
14
|
+
* 값에 `null` 을 실으면 **그 속성을 지운다**(「모름으로 되돌린다」). 합치기만 하면 원본에서 지운 값이
|
|
15
|
+
* 트윈에 영원히 남고, 그것을 표현할 방법이 없으면 「지웠다」와 「이번엔 말하지 않았다」가 같아진다.
|
|
16
|
+
*
|
|
17
|
+
* `undefined` 는 지우지 않는다 — 그것은 「이 진술에 그 속성이 없다」이고, 원본이 일부만 보내는
|
|
18
|
+
* 정상이다. 두 뜻을 갈라 둔다.
|
|
19
|
+
*
|
|
20
|
+
* 속성이 하나도 남지 않으면 그 요소를 표에서 버린다(빈 껍데기를 들고 있지 않는다).
|
|
21
|
+
*/
|
|
22
|
+
merge(elements: readonly VocabularyElement[]): string[];
|
|
23
|
+
/**
|
|
24
|
+
* 그 식별자의 항목을 버린다 — **아무도 가리키지 않게 된 뒤**에만 부른다.
|
|
25
|
+
*
|
|
26
|
+
* 로트는 계속 새로 생기므로 이 표는 스스로 줄지 않는다. 하루 수백 로트면 1년에 수십만 항목이고,
|
|
27
|
+
* 그것을 아무도 지우지 않으면 재기동으로만 줄어든다(그리고 중간 저장본이 그만큼 커진다).
|
|
28
|
+
*/
|
|
29
|
+
forget(id: string): boolean;
|
|
30
|
+
attributesOf(id: string | undefined): Record<string, unknown> | undefined;
|
|
31
|
+
get size(): number;
|
|
32
|
+
serialize(): Record<string, Record<string, unknown>>;
|
|
33
|
+
restore(saved: unknown): void;
|
|
34
|
+
clear(): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** 계약의 판정과 같은 것 — 이 파일 안에서만 쓴다(계약이 내보내는 것이 아니다). */
|
|
2
|
+
function isPlainObject(v) {
|
|
3
|
+
return !!v && typeof v === 'object' && !Array.isArray(v);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* 클래스 단위 마스터 표 — 관측 리듀서가 든다.
|
|
7
|
+
*
|
|
8
|
+
* 물품은 자리마다 따로 서지만(`클래스@자리`) 이 속성은 **클래스의 것**이다. 그래서 물품마다 복사해
|
|
9
|
+
* 두지 않고 클래스로 한 번 들고, 물품을 세울 때 본다. 마스터가 관측보다 늦게 와도 값이 서는 이유다.
|
|
10
|
+
*/
|
|
11
|
+
export class ClassMasterTable {
|
|
12
|
+
byId = new Map();
|
|
13
|
+
/**
|
|
14
|
+
* 속성을 **합친다** — 덮지 않는다(한 번에 일부만 오는 원본이 있다). 바뀐 식별자를 돌려준다.
|
|
15
|
+
*
|
|
16
|
+
* ── 지우는 법 ───────────────────────────────────────────────────────────────
|
|
17
|
+
* 값에 `null` 을 실으면 **그 속성을 지운다**(「모름으로 되돌린다」). 합치기만 하면 원본에서 지운 값이
|
|
18
|
+
* 트윈에 영원히 남고, 그것을 표현할 방법이 없으면 「지웠다」와 「이번엔 말하지 않았다」가 같아진다.
|
|
19
|
+
*
|
|
20
|
+
* `undefined` 는 지우지 않는다 — 그것은 「이 진술에 그 속성이 없다」이고, 원본이 일부만 보내는
|
|
21
|
+
* 정상이다. 두 뜻을 갈라 둔다.
|
|
22
|
+
*
|
|
23
|
+
* 속성이 하나도 남지 않으면 그 요소를 표에서 버린다(빈 껍데기를 들고 있지 않는다).
|
|
24
|
+
*/
|
|
25
|
+
merge(elements) {
|
|
26
|
+
const touched = [];
|
|
27
|
+
for (const e of elements) {
|
|
28
|
+
const next = { ...(this.byId.get(e.id) ?? {}) };
|
|
29
|
+
for (const [name, value] of Object.entries(e.attributes)) {
|
|
30
|
+
if (value === null)
|
|
31
|
+
delete next[name];
|
|
32
|
+
else if (value !== undefined)
|
|
33
|
+
next[name] = value;
|
|
34
|
+
}
|
|
35
|
+
if (Object.keys(next).length)
|
|
36
|
+
this.byId.set(e.id, next);
|
|
37
|
+
else
|
|
38
|
+
this.byId.delete(e.id);
|
|
39
|
+
touched.push(e.id);
|
|
40
|
+
}
|
|
41
|
+
return touched;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 그 식별자의 항목을 버린다 — **아무도 가리키지 않게 된 뒤**에만 부른다.
|
|
45
|
+
*
|
|
46
|
+
* 로트는 계속 새로 생기므로 이 표는 스스로 줄지 않는다. 하루 수백 로트면 1년에 수십만 항목이고,
|
|
47
|
+
* 그것을 아무도 지우지 않으면 재기동으로만 줄어든다(그리고 중간 저장본이 그만큼 커진다).
|
|
48
|
+
*/
|
|
49
|
+
forget(id) {
|
|
50
|
+
return this.byId.delete(id);
|
|
51
|
+
}
|
|
52
|
+
attributesOf(id) {
|
|
53
|
+
return id ? this.byId.get(id) : undefined;
|
|
54
|
+
}
|
|
55
|
+
get size() {
|
|
56
|
+
return this.byId.size;
|
|
57
|
+
}
|
|
58
|
+
serialize() {
|
|
59
|
+
return Object.fromEntries(this.byId);
|
|
60
|
+
}
|
|
61
|
+
restore(saved) {
|
|
62
|
+
this.byId.clear();
|
|
63
|
+
if (!isPlainObject(saved))
|
|
64
|
+
return;
|
|
65
|
+
for (const [id, attrs] of Object.entries(saved))
|
|
66
|
+
if (isPlainObject(attrs))
|
|
67
|
+
this.byId.set(id, { ...attrs });
|
|
68
|
+
}
|
|
69
|
+
clear() {
|
|
70
|
+
this.byId.clear();
|
|
71
|
+
}
|
|
72
|
+
}
|
package/dist/contract.d.ts
CHANGED
|
@@ -671,7 +671,27 @@ export type Effectivity = 'not-yet' | 'expired';
|
|
|
671
671
|
* `at` 를 주지 않으면 **판단하지 않는다**(`undefined`). 모르는 시각으로 폐기를 단정하면, 시각을 안 넘긴
|
|
672
672
|
* 소비처 전부가 자원을 잃는다. 파싱 불가한 시각도 같다 — 짐작해 고치지 않는다.
|
|
673
673
|
*/
|
|
674
|
-
|
|
674
|
+
/**
|
|
675
|
+
* 끝나는 시각을 **포함하는가** — 축마다 다르다. 규칙은 한 벌이고 규약만 밝힌다.
|
|
676
|
+
*
|
|
677
|
+
* ── 왜 이 칸이 생겼나 (2026-08-30) ────────────────────────────────────────
|
|
678
|
+
* 처음에는 이 판정이 한 곳뿐이었고 끝을 포함했다. 자원에는 그것이 맞다 — 폐기 일자가 있는 지게차는
|
|
679
|
+
* 띄엄띄엄 있고, 두 자원의 기간이 한 순간을 함께 갖는 일이 문제가 되지 않는다.
|
|
680
|
+
*
|
|
681
|
+
* 그런데 **선언은 빈틈없이 이어진다.** 8월 요금 주기가 끝나는 순간이 9월 주기가 시작하는 순간이다.
|
|
682
|
+
* 끝을 포함하면 그 한 순간에 두 단가가 동시에 유효해지고, 어느 것으로 계산했는지 말할 수 없다.
|
|
683
|
+
*
|
|
684
|
+
* 그때 같은 판정을 하는 함수를 하나 더 만들었다. 규칙이 두 벌이 되면 한쪽만 고쳐지는 날이 온다 —
|
|
685
|
+
* 이 저장소가 오늘 하루 그 부류를 여러 번 고쳤다. 그래서 함수는 하나로 두고 **규약을 인자로** 받는다.
|
|
686
|
+
*/
|
|
687
|
+
export interface EffectivityOptions {
|
|
688
|
+
/**
|
|
689
|
+
* `'inclusive'`(기본) — 끝나는 시각까지 유효하다. 자원의 유효 기간이 이쪽이다.
|
|
690
|
+
* `'exclusive'` — 끝나는 시각은 다음 구간의 것이다. 이어지는 주기(요금·단가)가 이쪽이다.
|
|
691
|
+
*/
|
|
692
|
+
end?: 'inclusive' | 'exclusive';
|
|
693
|
+
}
|
|
694
|
+
export declare function effectivityAt(p: EffectivePeriod | undefined, at?: ISOTime, opts?: EffectivityOptions): Effectivity | undefined;
|
|
675
695
|
/**
|
|
676
696
|
* 자원 **등급 정의** — ISA-95 가 세 자원에 똑같이 정의한 한 모양.
|
|
677
697
|
*
|
package/dist/contract.js
CHANGED
|
@@ -376,17 +376,7 @@ export function judgeAgainstSpec(spec, result) {
|
|
|
376
376
|
}
|
|
377
377
|
return allJudged ? 'pass' : undefined;
|
|
378
378
|
}
|
|
379
|
-
|
|
380
|
-
* 이 시각에 유효 기간 밖인가 — **한 규칙**으로 개체·등급·설비↔자산 매핑을 모두 판정한다.
|
|
381
|
-
*
|
|
382
|
-
* **표준은 날짜만 정하고 "밖이면 어떻게 되는가" 는 정하지 않는다.** 그 판단은 우리 것이므로 여기 밝힌다:
|
|
383
|
-
* 기간 밖이면 **그 자원은 그 시각의 모델에 참여하지 않는다**(배정되지 않고, 가용 분모에 들지 않는다).
|
|
384
|
-
* 지우지는 않는다 — 이유를 달아 남긴다. 조용히 사라지면 "왜 없어졌나" 를 아무도 답할 수 없다.
|
|
385
|
-
*
|
|
386
|
-
* `at` 를 주지 않으면 **판단하지 않는다**(`undefined`). 모르는 시각으로 폐기를 단정하면, 시각을 안 넘긴
|
|
387
|
-
* 소비처 전부가 자원을 잃는다. 파싱 불가한 시각도 같다 — 짐작해 고치지 않는다.
|
|
388
|
-
*/
|
|
389
|
-
export function effectivityAt(p, at) {
|
|
379
|
+
export function effectivityAt(p, at, opts) {
|
|
390
380
|
if (!p || !at)
|
|
391
381
|
return undefined;
|
|
392
382
|
const atMs = parsedMs(at);
|
|
@@ -396,7 +386,7 @@ export function effectivityAt(p, at) {
|
|
|
396
386
|
if (Number.isFinite(from) && atMs < from)
|
|
397
387
|
return 'not-yet';
|
|
398
388
|
const to = p.effectiveEnd ? parsedMs(p.effectiveEnd) : NaN;
|
|
399
|
-
if (Number.isFinite(to) && atMs > to)
|
|
389
|
+
if (Number.isFinite(to) && (opts?.end === 'exclusive' ? atMs >= to : atMs > to))
|
|
400
390
|
return 'expired';
|
|
401
391
|
return undefined;
|
|
402
392
|
}
|
package/dist/counterfactual.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Command, CommandAck, ScenarioControl, StateSnapshot } from '
|
|
1
|
+
import type { Command, CommandAck, ScenarioControl, StateSnapshot } from '@operato/operations-contract';
|
|
2
2
|
import { type StateDivergence } from './divergence.ts';
|
|
3
3
|
/** fork·구동·행위 가능한 트윈(FlowEngine 이 만족). */
|
|
4
4
|
export interface CounterfactualTwin {
|
package/dist/divergence.d.ts
CHANGED
package/dist/divergence.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* 상태를 같은 시점에 비교해 **드리프트(모델과 현실의 이탈)** 를 탐지한다. 발산 = 이상/개입 신호.
|
|
6
6
|
* (fork 로 예측 → 관측으로 실제 → 여기서 대조. execution-model.md 시뮬↔모니터링 커플링.)
|
|
7
7
|
*/
|
|
8
|
-
import { itemKeyOf } from
|
|
8
|
+
import { itemKeyOf } from '@operato/operations-contract';
|
|
9
9
|
function diffBy(predicted, actual, idOf, valOf) {
|
|
10
10
|
const p = new Map(predicted.map(e => [idOf(e), valOf(e)]));
|
|
11
11
|
const a = new Map(actual.map(e => [idOf(e), valOf(e)]));
|
package/dist/ems-kernel.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FlowEngine } from './flow-engine.ts';
|
|
2
2
|
import { type AllocationPolicy } from './allocation-policy.ts';
|
|
3
|
-
import { type CanonicalEnvelope, type DemandWindowState, type EnergyState, type StateSnapshot, type Attention, type StructureShift, type TwinModelDef } from '
|
|
3
|
+
import { type CanonicalEnvelope, type DemandWindowState, type EnergyState, type StateSnapshot, type Attention, type StructureShift, type TwinModelDef } from '@operato/operations-contract';
|
|
4
4
|
/** 수요 구간 — 요금의 알갱이다. 15분은 한국·다수 요금제의 최대수요 산정 단위다. */
|
|
5
5
|
export declare const DEMAND_WINDOW_MS: number;
|
|
6
6
|
/** 그 시각이 속한 구간의 시작 — 벽시계 경계(00·15·30·45분)에 맞춘다. */
|
package/dist/ems-kernel.js
CHANGED
|
@@ -27,10 +27,12 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import { FlowEngine } from "./flow-engine.js";
|
|
29
29
|
/* 기간 사실의 이름은 유입 문과 한 규칙이다(§`periodFactId`). */
|
|
30
|
-
import { periodFactId } from
|
|
30
|
+
import { periodFactId } from '@operato/operations-contract';
|
|
31
|
+
/* 「이 시각에 유효한가」는 커널에 규칙이 한 벌이다 — 선언 축도 그것을 쓴다. */
|
|
32
|
+
import { effectivityAt } from '@operato/operations-contract';
|
|
31
33
|
import { firstFitPolicy } from "./allocation-policy.js";
|
|
32
|
-
import { CMD, ENERGY_EVENT, minuteOfDayAt, localDayIndexAt, localDayStartMs } from
|
|
33
|
-
import { EMS_PROPERTY, METER_DIRECTION, electricalUpstreamOf, generationFractionAt } from
|
|
34
|
+
import { CMD, ENERGY_EVENT, minuteOfDayAt, localDayIndexAt, localDayStartMs } from '@operato/operations-contract';
|
|
35
|
+
import { EMS_PROPERTY, METER_DIRECTION, electricalUpstreamOf, generationFractionAt } from '@operato/operations-contract';
|
|
34
36
|
/** 수요 구간 — 요금의 알갱이다. 15분은 한국·다수 요금제의 최대수요 산정 단위다. */
|
|
35
37
|
export const DEMAND_WINDOW_MS = 15 * 60 * 1000;
|
|
36
38
|
/** 그 시각이 속한 구간의 시작 — 벽시계 경계(00·15·30·45분)에 맞춘다. */
|
|
@@ -1749,22 +1751,30 @@ function putDeclaration(list, d) {
|
|
|
1749
1751
|
return next.length > 24 ? next.slice(next.length - 24) : next;
|
|
1750
1752
|
}
|
|
1751
1753
|
/**
|
|
1752
|
-
* **이 시각에 유효한 선언** —
|
|
1754
|
+
* **이 시각에 유효한 선언** — 판정은 커널의 한 규칙이 한다(§`effectivityAt`).
|
|
1755
|
+
*
|
|
1756
|
+
* 여기서 하는 일은 **고르는 것**뿐이다. 「유효한가」를 여기서 다시 판정하면 규칙이 두 벌이 되고,
|
|
1757
|
+
* 한쪽만 고쳐지는 날이 온다. 실제로 이 함수는 처음에 자기 판정을 들고 있었다.
|
|
1758
|
+
*
|
|
1759
|
+
* 선언은 **빈틈없이 이어진다** — 8월 주기가 끝나는 순간이 9월 주기가 시작하는 순간이다. 그래서 끝을
|
|
1760
|
+
* 포함하지 않는다(`end: 'exclusive'`). 포함하면 그 한 순간에 두 단가가 동시에 유효해진다.
|
|
1753
1761
|
*
|
|
1754
1762
|
* 유효한 것이 없으면 답하지 않는다. 가장 가까운 것을 골라 주지 않는다 — 아직 시작하지 않은 단가로
|
|
1755
|
-
* 오늘을
|
|
1763
|
+
* 오늘을 계산하거나 이미 끝난 단가를 지금 것인 양 쓰게 된다. 둘 다 오류 없이 틀린 값을 만든다.
|
|
1756
1764
|
*
|
|
1757
1765
|
* 구간이 겹치면 **나중에 시작한 것**이 이긴다(더 좁게 정한 선언이 앞선다).
|
|
1758
1766
|
*/
|
|
1759
1767
|
function inEffectAt(list, atMs) {
|
|
1768
|
+
if (!list?.length)
|
|
1769
|
+
return undefined;
|
|
1770
|
+
const at = new Date(atMs).toISOString();
|
|
1760
1771
|
let best;
|
|
1761
1772
|
let bestFrom = -Infinity;
|
|
1762
|
-
for (const d of list
|
|
1763
|
-
|
|
1764
|
-
const to = Date.parse(String(d.to));
|
|
1765
|
-
if (!Number.isFinite(from) || !Number.isFinite(to))
|
|
1773
|
+
for (const d of list) {
|
|
1774
|
+
if (effectivityAt({ effectiveStart: d.from, effectiveEnd: d.to }, at, { end: 'exclusive' }) !== undefined)
|
|
1766
1775
|
continue;
|
|
1767
|
-
|
|
1776
|
+
const from = Date.parse(String(d.from));
|
|
1777
|
+
if (!Number.isFinite(from))
|
|
1768
1778
|
continue;
|
|
1769
1779
|
if (from > bestFrom) {
|
|
1770
1780
|
best = d;
|
package/dist/event-journal.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TwinModelDef, CanonicalEnvelope, StructureShift } from '
|
|
1
|
+
import type { TwinModelDef, CanonicalEnvelope, StructureShift } from '@operato/operations-contract';
|
|
2
2
|
import { type ProjectedState, type ReducerCheckpoint } from './state-projector.ts';
|
|
3
3
|
/** 저장된 기록을 처리할 것 — 도메인 커널 또는 `StateProjector`. 계약은 넷뿐이다. */
|
|
4
4
|
export interface JournalProjector {
|
package/dist/flow-engine.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { TestResult, ISOTime, MaterialQuantity, WorkCalendarEntry, EffectivePeriod, Effectivity, OffCalendarReason, ResourceProperty, ResourceClassDef, MaterialDefinition, Attention, TwinModelDef, CanonicalEnvelope, Command, CommandAck, EventHandler, EquipmentMotion, OeeMetrics, AssetState, GeneratorSpec, InterventionOutcome, OrderState, PersonState, ScenarioControl, ScenarioOverride, StateSnapshot, TwinKernel, Unsubscribe, LocationState, ItemState, EquipmentState, OrderStatusDelta, TaskState, TaskStatus, StructureShift, IdentityGroundingView, IdentityDeclaration, TestSpecificationCriterion, LocationObservation } from '
|
|
2
|
-
import type { VocabularyElement } from '
|
|
1
|
+
import type { TestResult, ISOTime, MaterialQuantity, WorkCalendarEntry, EffectivePeriod, Effectivity, OffCalendarReason, ResourceProperty, ResourceClassDef, MaterialDefinition, Attention, TwinModelDef, CanonicalEnvelope, Command, CommandAck, EventHandler, EquipmentMotion, OeeMetrics, AssetState, GeneratorSpec, InterventionOutcome, OrderState, PersonState, ScenarioControl, ScenarioOverride, StateSnapshot, TwinKernel, Unsubscribe, LocationState, ItemState, EquipmentState, OrderStatusDelta, TaskState, TaskStatus, StructureShift, IdentityGroundingView, IdentityDeclaration, TestSpecificationCriterion, LocationObservation } from '@operato/operations-contract';
|
|
2
|
+
import type { VocabularyElement } from '@operato/operations-contract';
|
|
3
3
|
import type { ReducerCheckpoint } from './observed-reducer.ts';
|
|
4
|
-
import type { EpcisEvent, BizTransactionElement } from '
|
|
4
|
+
import type { EpcisEvent, BizTransactionElement } from '@operato/operations-contract';
|
|
5
5
|
import type { AllocationPolicy, SlotView } from './allocation-policy.ts';
|
|
6
6
|
import type { DurationEstimator, DurationContext } from './duration-estimator.ts';
|
|
7
|
-
import type { OperationDef, IsoDuration, OpMaterialSpecification } from '
|
|
8
|
-
import { type CapacityAnalysis } from '
|
|
9
|
-
import { type CommittedDemand, type OperationsCapabilityReport } from '
|
|
7
|
+
import type { OperationDef, IsoDuration, OpMaterialSpecification } from '@operato/operations-contract';
|
|
8
|
+
import { type CapacityAnalysis } from '@operato/operations-contract';
|
|
9
|
+
import { type CommittedDemand, type OperationsCapabilityReport } from '@operato/operations-contract';
|
|
10
10
|
export interface FlowLocation {
|
|
11
11
|
id: string;
|
|
12
12
|
type: string;
|
package/dist/flow-engine.js
CHANGED
|
@@ -9,17 +9,17 @@
|
|
|
9
9
|
* 통합 타입은 도메인 필드를 옵셔널로 넓혀(FlowItem.gtin?, FlowOrder.shipmentEpc? 등) 두 도메인을 담는다.
|
|
10
10
|
* (roadmap Phase5 발견 → 추출. [[project_flow_single_base_vision]] FlowLocation 단일 base 방향과 정합.)
|
|
11
11
|
*/
|
|
12
|
-
import { OP_EVENT, CMD, locationStatusOf, readBoardEquipment, readBoardLocations, readBoardAssets, classClosure, capabilityOf, requiredTestsFor, priorityRank, dueStatusOf, isOrderTerminal, effectivityAt, offCalendarAt, offCalendarReasonAt, minuteOfDayAt, activeShiftAt, subLotIdOf, itemKeyOf, identityGroundingOf, outsideLimit } from
|
|
12
|
+
import { OP_EVENT, CMD, locationStatusOf, readBoardEquipment, readBoardLocations, readBoardAssets, classClosure, capabilityOf, requiredTestsFor, priorityRank, dueStatusOf, isOrderTerminal, effectivityAt, offCalendarAt, offCalendarReasonAt, minuteOfDayAt, activeShiftAt, subLotIdOf, itemKeyOf, identityGroundingOf, outsideLimit } from '@operato/operations-contract';
|
|
13
13
|
import { ObservedReducer } from "./observed-reducer.js";
|
|
14
14
|
/* 주체를 정하는 규칙은 유입 문과 한 벌이다 — 두 곳에 적으면 한쪽만 고쳐진다. */
|
|
15
|
-
import { resolveSubject } from
|
|
16
|
-
import { transformationEvent, aggregationEvent, objectEvent, parseEpc, DISP, ILMD_ATTR, CBV_BIZSTEP, objectUri, bizTransactionUri, gdtiUri } from
|
|
17
|
-
import { OP_PARAM } from
|
|
18
|
-
import { parseIsoDuration } from
|
|
19
|
-
import { analyzeCapacity } from
|
|
20
|
-
import { operationsCapabilityOf } from
|
|
15
|
+
import { resolveSubject } from '@operato/operations-contract';
|
|
16
|
+
import { transformationEvent, aggregationEvent, objectEvent, parseEpc, DISP, ILMD_ATTR, CBV_BIZSTEP, objectUri, bizTransactionUri, gdtiUri } from '@operato/operations-contract';
|
|
17
|
+
import { OP_PARAM } from '@operato/operations-contract';
|
|
18
|
+
import { parseIsoDuration } from '@operato/operations-contract';
|
|
19
|
+
import { analyzeCapacity } from '@operato/operations-contract';
|
|
20
|
+
import { operationsCapabilityOf } from '@operato/operations-contract';
|
|
21
21
|
/* 에너지 상태 필드는 **능력 선언에서 뽑는다** — 손으로 적으면 능력에 필드를 더한 날 스냅샷이 빠진다. */
|
|
22
|
-
import { stateFieldsOf } from
|
|
22
|
+
import { stateFieldsOf } from '@operato/operations-contract';
|
|
23
23
|
const BASE_EPOCH = Date.parse('2026-01-01T00:00:00Z');
|
|
24
24
|
/**
|
|
25
25
|
* 선언한 유효 기간만 뽑는다 — 마스터가 말하지 않으면 필드를 만들지 않는다.
|
package/dist/forecast.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ScenarioControl, ScenarioDef, StateSnapshot } from '
|
|
1
|
+
import type { ScenarioControl, ScenarioDef, StateSnapshot } from '@operato/operations-contract';
|
|
2
2
|
/** fork·시나리오 구동 가능한 트윈(FlowEngine 이 만족). */
|
|
3
3
|
export interface ForecastTwin {
|
|
4
4
|
getSnapshot(): StateSnapshot;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
|
-
export * from '
|
|
2
|
-
export * from '
|
|
3
|
-
export * from '
|
|
1
|
+
export * from '@operato/operations-contract';
|
|
2
|
+
export * from '@operato/operations-contract';
|
|
3
|
+
export * from '@operato/operations-contract';
|
|
4
4
|
export * from './counterfactual.ts';
|
|
5
5
|
export * from './forecast.ts';
|
|
6
6
|
export * from './twin-observer.ts';
|
|
7
7
|
export * from './event-journal.ts';
|
|
8
|
-
export * from '
|
|
8
|
+
export * from '@operato/operations-contract';
|
|
9
9
|
export * from './divergence.ts';
|
|
10
|
-
export * from '
|
|
11
|
-
export * from '
|
|
12
|
-
export * from '
|
|
13
|
-
export * from '
|
|
14
|
-
export * from '
|
|
10
|
+
export * from '@operato/operations-contract';
|
|
11
|
+
export * from '@operato/operations-contract';
|
|
12
|
+
export * from '@operato/operations-contract';
|
|
13
|
+
export * from '@operato/operations-contract';
|
|
14
|
+
export * from '@operato/operations-contract';
|
|
15
15
|
export * from './allocation-policy.ts';
|
|
16
16
|
export * from './duration-estimator.ts';
|
|
17
|
-
export * from '
|
|
17
|
+
export * from '@operato/operations-contract';
|
|
18
18
|
export * from './observed-reducer.ts';
|
|
19
19
|
export * from './state-projector.ts';
|
|
20
20
|
export * from './task-fold.ts';
|
|
21
21
|
export * from './job-response.ts';
|
|
22
|
-
export * from '
|
|
22
|
+
export * from '@operato/operations-contract';
|
|
23
23
|
export * from './runtime.ts';
|
|
24
|
-
export * from '
|
|
25
|
-
export * from '
|
|
24
|
+
export * from '@operato/operations-contract';
|
|
25
|
+
export * from '@operato/operations-contract';
|
|
26
26
|
export * from './flow-engine.ts';
|
|
27
|
-
export * from '
|
|
28
|
-
export * from '
|
|
27
|
+
export * from '@operato/operations-contract';
|
|
28
|
+
export * from '@operato/operations-contract';
|
|
29
29
|
export { WmsKernel } from './kernel.ts';
|
|
30
30
|
export { YmsKernel } from './yms-kernel.ts';
|
|
31
31
|
export { MesKernel } from './mes-kernel.ts';
|
|
32
32
|
export { EmsKernel, DEMAND_WINDOW_MS, demandWindowStart } from './ems-kernel.ts';
|
|
33
|
-
export { ingestEnergyRecords, isEnergyRecord, ingestEnergyEquipmentRecords, isEnergyEquipmentRecord, ingestEnergyGenerationRecords, isEnergyGenerationRecord, ingestEnergyUsagePeriodRecords, isEnergyUsagePeriodRecord, ingestEnergyBillRecords, isEnergyBillRecord, ingestEnergyTariffBasisRecords, isEnergyTariffBasisRecord, ingestEnergyGenerationPriceRecords, isEnergyGenerationPriceRecord, ingestEnergyGenerationPeriodRecords, isEnergyGenerationPeriodRecord, resolveSubject, periodFactId } from '
|
|
34
|
-
export { ingestOperationalRecords, isOperationalRecord, operationalKindOf } from '
|
|
35
|
-
export type { OperationalKind, OperationalRecord, OperationalIngestOptions } from '
|
|
33
|
+
export { ingestEnergyRecords, isEnergyRecord, ingestEnergyEquipmentRecords, isEnergyEquipmentRecord, ingestEnergyGenerationRecords, isEnergyGenerationRecord, ingestEnergyUsagePeriodRecords, isEnergyUsagePeriodRecord, ingestEnergyBillRecords, isEnergyBillRecord, ingestEnergyTariffBasisRecords, isEnergyTariffBasisRecord, ingestEnergyGenerationPriceRecords, isEnergyGenerationPriceRecord, ingestEnergyGenerationPeriodRecords, isEnergyGenerationPeriodRecord, resolveSubject, periodFactId } from '@operato/operations-contract';
|
|
34
|
+
export { ingestOperationalRecords, isOperationalRecord, operationalKindOf } from '@operato/operations-contract';
|
|
35
|
+
export type { OperationalKind, OperationalRecord, OperationalIngestOptions } from '@operato/operations-contract';
|
|
36
36
|
export { attributeEnergy, electricityCost, energyIntensity, energyOfWindows } from './energy-attribution.ts';
|
|
37
37
|
export type { AttributionBasis, AttributionResult, ElectricityCost, EnergyConsumer, EnergyPool, EnergyShare, IntensityInput, IntensityResult, IntensityDenominator, TariffDeclaration, WeightKind, WindowedEnergy } from './energy-attribution.ts';
|
|
38
|
-
export type { EnergyRecord, EnergyEquipmentRecord, EnergyGenerationRecord, EnergyUsagePeriodRecord, EnergyBillRecord, EnergyTariffBasisRecord, EnergyGenerationPriceRecord, EnergyGenerationPeriodRecord, EnergyIngestOptions, EnergyIngestResult } from '
|
|
39
|
-
export * from '
|
|
38
|
+
export type { EnergyRecord, EnergyEquipmentRecord, EnergyGenerationRecord, EnergyUsagePeriodRecord, EnergyBillRecord, EnergyTariffBasisRecord, EnergyGenerationPriceRecord, EnergyGenerationPeriodRecord, EnergyIngestOptions, EnergyIngestResult } from '@operato/operations-contract';
|
|
39
|
+
export * from '@operato/operations-contract';
|
|
40
|
+
export { ClassMasterTable } from './class-master-table.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from '@operato/operations-contract';
|
|
2
|
+
export * from '@operato/operations-contract';
|
|
3
|
+
export * from '@operato/operations-contract';
|
|
4
4
|
export * from "./counterfactual.js";
|
|
5
5
|
export * from "./forecast.js";
|
|
6
6
|
export * from "./twin-observer.js";
|
|
7
7
|
export * from "./event-journal.js";
|
|
8
|
-
export * from
|
|
8
|
+
export * from '@operato/operations-contract';
|
|
9
9
|
export * from "./divergence.js";
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
12
|
-
export * from
|
|
13
|
-
export * from
|
|
14
|
-
export * from
|
|
10
|
+
export * from '@operato/operations-contract';
|
|
11
|
+
export * from '@operato/operations-contract';
|
|
12
|
+
export * from '@operato/operations-contract';
|
|
13
|
+
export * from '@operato/operations-contract';
|
|
14
|
+
export * from '@operato/operations-contract';
|
|
15
15
|
export * from "./allocation-policy.js";
|
|
16
16
|
export * from "./duration-estimator.js";
|
|
17
|
-
export * from
|
|
17
|
+
export * from '@operato/operations-contract';
|
|
18
18
|
export * from "./observed-reducer.js";
|
|
19
19
|
export * from "./state-projector.js";
|
|
20
20
|
export * from "./task-fold.js";
|
|
21
21
|
export * from "./job-response.js";
|
|
22
|
-
export * from
|
|
22
|
+
export * from '@operato/operations-contract';
|
|
23
23
|
export * from "./runtime.js";
|
|
24
|
-
export * from
|
|
25
|
-
export * from
|
|
24
|
+
export * from '@operato/operations-contract';
|
|
25
|
+
export * from '@operato/operations-contract';
|
|
26
26
|
export * from "./flow-engine.js";
|
|
27
|
-
export * from
|
|
28
|
-
export * from
|
|
27
|
+
export * from '@operato/operations-contract';
|
|
28
|
+
export * from '@operato/operations-contract';
|
|
29
29
|
export { WmsKernel } from "./kernel.js";
|
|
30
30
|
export { YmsKernel } from "./yms-kernel.js";
|
|
31
31
|
export { MesKernel } from "./mes-kernel.js";
|
|
32
32
|
export { EmsKernel, DEMAND_WINDOW_MS, demandWindowStart } from "./ems-kernel.js";
|
|
33
|
-
export { ingestEnergyRecords, isEnergyRecord, ingestEnergyEquipmentRecords, isEnergyEquipmentRecord, ingestEnergyGenerationRecords, isEnergyGenerationRecord, ingestEnergyUsagePeriodRecords, isEnergyUsagePeriodRecord, ingestEnergyBillRecords, isEnergyBillRecord, ingestEnergyTariffBasisRecords, isEnergyTariffBasisRecord, ingestEnergyGenerationPriceRecords, isEnergyGenerationPriceRecord, ingestEnergyGenerationPeriodRecords, isEnergyGenerationPeriodRecord, resolveSubject, periodFactId } from
|
|
33
|
+
export { ingestEnergyRecords, isEnergyRecord, ingestEnergyEquipmentRecords, isEnergyEquipmentRecord, ingestEnergyGenerationRecords, isEnergyGenerationRecord, ingestEnergyUsagePeriodRecords, isEnergyUsagePeriodRecord, ingestEnergyBillRecords, isEnergyBillRecord, ingestEnergyTariffBasisRecords, isEnergyTariffBasisRecord, ingestEnergyGenerationPriceRecords, isEnergyGenerationPriceRecord, ingestEnergyGenerationPeriodRecords, isEnergyGenerationPeriodRecord, resolveSubject, periodFactId } from '@operato/operations-contract';
|
|
34
34
|
/* 운영 사실의 문 — 리듀서가 다루는 여섯이 들어오는 자리(미러가 시뮬보다 가난하지 않게). */
|
|
35
|
-
export { ingestOperationalRecords, isOperationalRecord, operationalKindOf } from
|
|
35
|
+
export { ingestOperationalRecords, isOperationalRecord, operationalKindOf } from '@operato/operations-contract';
|
|
36
36
|
export { attributeEnergy, electricityCost, energyIntensity, energyOfWindows } from "./energy-attribution.js";
|
|
37
37
|
/* 에너지 상태 타입은 **계약**에 있다(상태의 모양은 계약이다) — contract 의 `export *` 가 이미 낸다. */
|
|
38
|
-
export * from
|
|
38
|
+
export * from '@operato/operations-contract';
|
|
39
|
+
export { ClassMasterTable } from "./class-master-table.js";
|
package/dist/job-response.d.ts
CHANGED
package/dist/kernel.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Command, CommandAck, GeneratorSpec } from '
|
|
1
|
+
import type { Command, CommandAck, GeneratorSpec } from '@operato/operations-contract';
|
|
2
2
|
import type { AllocationPolicy } from './allocation-policy.ts';
|
|
3
3
|
import { FlowEngine } from './flow-engine.ts';
|
|
4
4
|
import type { FlowOrder, FlowTask } from './flow-engine.ts';
|
package/dist/kernel.js
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* 입고: 도착 → receiving(Txn PO + Agg 팔레트←케이스 + Object) → putaway → storing.
|
|
6
6
|
* 출고: SO 오더 → 할당(Txn SO) → pick(bin→staging) → picking → packing(Agg 화물←팔레트) → staging → shipping(DELETE).
|
|
7
7
|
*/
|
|
8
|
-
import { CMD } from
|
|
8
|
+
import { CMD } from '@operato/operations-contract';
|
|
9
9
|
import { firstFitPolicy } from "./allocation-policy.js";
|
|
10
10
|
import { FlowEngine } from "./flow-engine.js";
|
|
11
11
|
import { planMakeToOrder } from "./make-to-order.js";
|
|
12
|
-
import { BIZSTEP, BTT } from
|
|
13
|
-
import { DISP, ILMD_ATTR, aggregationEvent, objectEvent, transactionEvent } from
|
|
14
|
-
import { subLotIdOf, itemKeyOf } from
|
|
12
|
+
import { BIZSTEP, BTT } from '@operato/operations-contract';
|
|
13
|
+
import { DISP, ILMD_ATTR, aggregationEvent, objectEvent, transactionEvent } from '@operato/operations-contract';
|
|
14
|
+
import { subLotIdOf, itemKeyOf } from '@operato/operations-contract';
|
|
15
15
|
const TRAVEL_MS = 30_000;
|
|
16
16
|
const SHELF_MS = 30 * 24 * 3_600_000; // 기본 유통기한(30일)
|
|
17
17
|
const SHELF_JITTER_MS = 5 * 24 * 3_600_000; // 로트별 만료 편차(FEFO 가 FIFO 와 갈리게)
|
package/dist/make-to-order.d.ts
CHANGED
package/dist/mes-kernel.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { GeneratorSpec, Command, CommandAck, ProductionSpec, TwinModelDef, IdentityGroundingView, Attention } from '
|
|
1
|
+
import type { GeneratorSpec, Command, CommandAck, ProductionSpec, TwinModelDef, IdentityGroundingView, Attention } from '@operato/operations-contract';
|
|
2
2
|
import type { AllocationPolicy } from './allocation-policy.ts';
|
|
3
3
|
import { FlowEngine } from './flow-engine.ts';
|
|
4
4
|
import type { FlowOrder, FlowTask } from './flow-engine.ts';
|
|
5
|
-
import { type OpMaterialSpecification } from '
|
|
5
|
+
import { type OpMaterialSpecification } from '@operato/operations-contract';
|
|
6
6
|
export declare class MesKernel extends FlowEngine {
|
|
7
7
|
private wipSeq;
|
|
8
8
|
private prodSeq;
|
|
@@ -60,7 +60,7 @@ export declare class MesKernel extends FlowEngine {
|
|
|
60
60
|
* 모델 자리(§`TwinModelDef.identity`)로 옮기면 이 override 는 사라진다. 두 자리를 동시에 읽는 것이
|
|
61
61
|
* 아니라 **하나를 고르는** 것이므로 규칙이 갈리지 않는다.
|
|
62
62
|
*/
|
|
63
|
-
protected identityDeclaration(): import("
|
|
63
|
+
protected identityDeclaration(): import("@operato/operations-contract").IdentityDeclaration | undefined;
|
|
64
64
|
protected identityGroundingView(): IdentityGroundingView;
|
|
65
65
|
/**
|
|
66
66
|
* 선언이 말하는 자리 타입이 **이 트윈에 있나** — 로드 시점에 한 번, 모아서 말한다 (2026-08-20).
|
package/dist/mes-kernel.js
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
* ③ 셋업/체인지오버 = work-center 가 제품 전환 시 셋업(changeoverKey=제품 gtin) → OEE Availability.
|
|
9
9
|
* ④ OEE = base 가 설비(설비)별 계측(가동/셋업/기아/품질). cut=cutter·weld=welder 이종 자원.
|
|
10
10
|
*/
|
|
11
|
-
import { identityGroundingOf } from
|
|
11
|
+
import { identityGroundingOf } from '@operato/operations-contract';
|
|
12
12
|
import { firstFitPolicy } from "./allocation-policy.js";
|
|
13
13
|
import { FlowEngine } from "./flow-engine.js";
|
|
14
|
-
import { DISP, objectEvent, transactionEvent, gdtiUri, sgtinClass, bizTransactionUri } from
|
|
15
|
-
import { MES_BIZSTEP, BTT_PRODORDER, sgtinUri } from
|
|
16
|
-
import { OP_PARAM } from
|
|
14
|
+
import { DISP, objectEvent, transactionEvent, gdtiUri, sgtinClass, bizTransactionUri } from '@operato/operations-contract';
|
|
15
|
+
import { MES_BIZSTEP, BTT_PRODORDER, sgtinUri } from '@operato/operations-contract';
|
|
16
|
+
import { OP_PARAM } from '@operato/operations-contract';
|
|
17
17
|
/* 아래 셋은 **기본값**이다 — 명세(OperationDef.duration·parameters)가 있으면 그 값이 이긴다.
|
|
18
18
|
* 이름에 DEFAULT 를 붙인 이유: 예전에는 이것이 유일한 값이어서 "현장 명세" 와 구별되지 않았고,
|
|
19
19
|
* 그 상수가 수율 판단(주목 신호)까지 만들어 냈다. 무엇을 기본값으로 굴렸는지는 specCoverage() 가 밝힌다. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AssetState, TestResult, MaterialQuantity, TwinModelDef, CanonicalEnvelope, LocationState, ItemState, LocationObservation, EquipmentState, PersonState, TaskState, OrderState, StructureShift } from '
|
|
2
|
-
import { type VocabularyElement } from '
|
|
1
|
+
import type { AssetState, TestResult, MaterialQuantity, TwinModelDef, CanonicalEnvelope, LocationState, ItemState, LocationObservation, EquipmentState, PersonState, TaskState, OrderState, StructureShift } from '@operato/operations-contract';
|
|
2
|
+
import { type VocabularyElement } from '@operato/operations-contract';
|
|
3
3
|
interface ProjItem {
|
|
4
4
|
epc: string;
|
|
5
5
|
/** 로트의 부분(표준 MaterialSubLot.ID) — 비직렬 로트가 자리마다 갈릴 때만. */
|
package/dist/observed-reducer.js
CHANGED
|
@@ -19,9 +19,11 @@
|
|
|
19
19
|
* - 운영 델타(task/equipment/order.status) → tasks·equipment·orders (EPCIS 로 재구성 불가한 절반)
|
|
20
20
|
* 마스터(로케이션)는 board 초기화 + applyMaster 로 갱신(마스터 동기).
|
|
21
21
|
*/
|
|
22
|
-
import { OP_EVENT, capabilityOf, itemKeyOf, judgeAgainstSpec, requiredTestsFor, locationStatusOf, readBoardEquipment, readBoardLocations, readBoardAssets, effectivityAt, offCalendarAt, offCalendarReasonAt, activeShiftAt } from
|
|
23
|
-
import { ILMD_ATTR, parseEpc } from
|
|
24
|
-
import {
|
|
22
|
+
import { OP_EVENT, capabilityOf, itemKeyOf, judgeAgainstSpec, requiredTestsFor, locationStatusOf, readBoardEquipment, readBoardLocations, readBoardAssets, effectivityAt, offCalendarAt, offCalendarReasonAt, activeShiftAt } from '@operato/operations-contract';
|
|
23
|
+
import { ILMD_ATTR, parseEpc } from '@operato/operations-contract';
|
|
24
|
+
import { expiryFromAttributes, lotFromAttributes } from '@operato/operations-contract';
|
|
25
|
+
/* 클래스 마스터 표는 상태를 들므로 커널에 있다(§`class-master-table`). */
|
|
26
|
+
import { ClassMasterTable } from "./class-master-table.js";
|
|
25
27
|
/**
|
|
26
28
|
* 투영이 들고 있는 물품 — **계약(ItemState)을 축소하지 않는다.**
|
|
27
29
|
*
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CanonicalEnvelope, Command, CommandAck, ScenarioControl, StateSnapshot, TwinKernel } from '
|
|
1
|
+
import type { CanonicalEnvelope, Command, CommandAck, ScenarioControl, StateSnapshot, TwinKernel } from '@operato/operations-contract';
|
|
2
2
|
export type SubscriptionMessage = {
|
|
3
3
|
kind: 'snapshot';
|
|
4
4
|
revision: number;
|
package/dist/task-fold.d.ts
CHANGED
package/dist/twin-observer.d.ts
CHANGED
package/dist/yms-kernel.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GeneratorSpec } from '
|
|
1
|
+
import type { GeneratorSpec } from '@operato/operations-contract';
|
|
2
2
|
import type { AllocationPolicy } from './allocation-policy.ts';
|
|
3
3
|
import { FlowEngine } from './flow-engine.ts';
|
|
4
4
|
import type { FlowOrder, FlowTask } from './flow-engine.ts';
|
package/dist/yms-kernel.js
CHANGED
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
* - drop(기본): 트레일러를 야드 슬롯에 내려놓고(주차) 창 도래 시 호슬러가 도크로 pull. 야드 버퍼 사용.
|
|
16
16
|
* - live: 게이트에서 대기하다 창 도래 시 도크로 직행(야드 미경유). 게이트/도크를 더 오래 점유.
|
|
17
17
|
*/
|
|
18
|
-
import { itemKeyOf } from
|
|
18
|
+
import { itemKeyOf } from '@operato/operations-contract';
|
|
19
19
|
import { firstFitPolicy } from "./allocation-policy.js";
|
|
20
20
|
import { FlowEngine } from "./flow-engine.js";
|
|
21
|
-
import { DISP, objectEvent, transactionEvent } from
|
|
22
|
-
import { YARD_BIZSTEP, BTT_DELIVERY } from
|
|
21
|
+
import { DISP, objectEvent, transactionEvent } from '@operato/operations-contract';
|
|
22
|
+
import { YARD_BIZSTEP, BTT_DELIVERY } from '@operato/operations-contract';
|
|
23
23
|
const TRAVEL_MS = 20_000; // 야드 이동
|
|
24
24
|
const DWELL_MS = 30_000; // 도크 체류(상·하차) — depart 이동에 folded
|
|
25
25
|
const WINDOW_DELAY_MS = 40_000; // 도착 후 어포인트먼트 창까지(early arrival → 대기)
|