@operato/twin-kernel 0.5.0 → 0.6.0
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/contract.d.ts +8 -8
- package/dist/domain-catalog.d.ts +1 -1
- package/dist/domain-definition.js +1 -1
- package/dist/event-journal.d.ts +3 -3
- package/dist/flow-engine.d.ts +4 -4
- package/dist/flow-engine.js +2 -2
- package/dist/observed-reducer.d.ts +3 -3
- package/dist-cjs/index.cjs +2 -2
- package/package.json +1 -1
package/dist/contract.d.ts
CHANGED
|
@@ -362,7 +362,7 @@ export declare function conversionFactorOf(def: MaterialDefinition | undefined,
|
|
|
362
362
|
* 되풀이를 간단히 적기 위한 선택이고, 그러면 **어느 기준의 06:00 인가**가 반드시 필요하다 —
|
|
363
363
|
* Rosarito(UTC−7)의 06:00 을 UTC 로 읽으면 7시간이 틀린다.
|
|
364
364
|
*
|
|
365
|
-
* 그래서 `
|
|
365
|
+
* 그래서 `TwinModelDef.utcOffsetMinutes` 가 그 기준이다. **선언하지 않으면 UTC 로 읽고, 그 사실을 여기
|
|
366
366
|
* 밝힌다**(조용히 가정하지 않기 위해). 프레임워크에는 이미 테넌트 시간대(`Domain.timezone`)와
|
|
367
367
|
* 교대→절대구간 변환(`@things-factory/work-shift` `work-shift-range`, moment-timezone)이 있으므로,
|
|
368
368
|
* **기준을 푸는 일은 호스트의 몫**이다(커널은 zero-dep — 시간대 데이터를 들 수 없다).
|
|
@@ -1267,14 +1267,14 @@ export type Unsubscribe = () => void;
|
|
|
1267
1267
|
* 이 함수를 거치지 않고 `def.locations` 를 직접 읽는 코드를 두지 않는다 — 하나라도 남으면 그 경로에서만
|
|
1268
1268
|
* 옛 보드의 자리가 조용히 사라진다(빈 배열 = 자리 없는 트윈 = 아무 일도 일어나지 않는다).
|
|
1269
1269
|
*/
|
|
1270
|
-
export declare function readBoardLocations(def:
|
|
1270
|
+
export declare function readBoardLocations(def: TwinModelDef | (Record<string, unknown> & {
|
|
1271
1271
|
locations?: unknown;
|
|
1272
1272
|
nodes?: unknown;
|
|
1273
|
-
})):
|
|
1274
|
-
export declare function readBoardEquipment(def:
|
|
1273
|
+
})): TwinModelDef['locations'];
|
|
1274
|
+
export declare function readBoardEquipment(def: TwinModelDef | Record<string, unknown>): TwinModelDef['equipment'];
|
|
1275
1275
|
/** 저장된 보드의 반복사용 자산 — 설비와 같은 정규화를 거친다. */
|
|
1276
|
-
export declare function readBoardAssets(def:
|
|
1277
|
-
export interface
|
|
1276
|
+
export declare function readBoardAssets(def: TwinModelDef | Record<string, unknown>): NonNullable<TwinModelDef['assets']>;
|
|
1277
|
+
export interface TwinModelDef {
|
|
1278
1278
|
/** parallelism = 동시 처리 수(LocationState.parallelism 참조). capacity 는 저장 용량. */
|
|
1279
1279
|
locations: {
|
|
1280
1280
|
id: string;
|
|
@@ -1396,7 +1396,7 @@ export interface BoardDef {
|
|
|
1396
1396
|
*
|
|
1397
1397
|
* ── 왜 이제야 선언하나 (2026-08-08) ──────────────────────────────────────────
|
|
1398
1398
|
* 이 자리는 **이미 쓰이고 있었다.** 마스터 인제스트가 `board.operations` 로 통과시키고 호스트가
|
|
1399
|
-
* `applyOperations` 로 커널에 싣는다. 그런데 `
|
|
1399
|
+
* `applyOperations` 로 커널에 싣는다. 그런데 `TwinModelDef` 는 그것을 말한 적이 없다.
|
|
1400
1400
|
*
|
|
1401
1401
|
* 바로 위 `productionSpec` 이 겪은 것과 **같은 일**이다 — "계약에 없으니 아무도 이 자리를 발견할
|
|
1402
1402
|
* 수 없었다. 타입이 말해 주지 않는 필드는 없는 필드다." 그때 배운 것을 여기 적용한다.
|
|
@@ -1422,7 +1422,7 @@ export interface ProductionSpec {
|
|
|
1422
1422
|
recipeKey?: string;
|
|
1423
1423
|
}
|
|
1424
1424
|
export interface TwinKernel {
|
|
1425
|
-
|
|
1425
|
+
loadTwinModel(def: TwinModelDef): void;
|
|
1426
1426
|
getSnapshot(): StateSnapshot;
|
|
1427
1427
|
onEvent(handler: EventHandler): Unsubscribe;
|
|
1428
1428
|
dispatch(cmd: Command): CommandAck;
|
package/dist/domain-catalog.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface DomainProfileInfo {
|
|
|
30
30
|
export declare const DOMAIN_CATALOG: Record<DomainSystem, DomainProfileInfo>;
|
|
31
31
|
export interface TwinAxisInfo {
|
|
32
32
|
/**
|
|
33
|
-
* 축의 이름 — 화면·관계 선언이 쓰는 키. 최상위 축은 `
|
|
33
|
+
* 축의 이름 — 화면·관계 선언이 쓰는 키. 최상위 축은 `TwinModelDef` 의 키 **그대로**다
|
|
34
34
|
* (저장·계약의 이름과 갈라지면 그 순간 방언이 생긴다).
|
|
35
35
|
*/
|
|
36
36
|
axis: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* 도메인 정의(DomainDefinition) — 커널의 선언적 도메인 계약. `
|
|
2
|
+
* 도메인 정의(DomainDefinition) — 커널의 선언적 도메인 계약. `TwinModelDef`(토폴로지 입력)의 확장 격.
|
|
3
3
|
* 커널이 "무엇이 있고 어떻게 흐르나"(타입 + 공정 route/BOM)를 **데이터로** 받는 형식. zero-dep(자기 타입).
|
|
4
4
|
*
|
|
5
5
|
* 특정 공정이 커널 코드에 하드코딩되던 것을 이 데이터 계약으로 대체한다(design/plans/domain-catalog-layering.md).
|
package/dist/event-journal.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TwinModelDef, CanonicalEnvelope } from './contract.ts';
|
|
2
2
|
import { type ProjectedState } from './state-projector.ts';
|
|
3
3
|
export declare class EventJournal {
|
|
4
4
|
private events;
|
|
@@ -14,10 +14,10 @@ export declare class EventJournal {
|
|
|
14
14
|
untilSimTime(iso: string): CanonicalEnvelope[];
|
|
15
15
|
}
|
|
16
16
|
/** 이벤트열 → 상태 재구성(시간여행). board = 마스터(토폴로지·설비). */
|
|
17
|
-
export declare function replay(board:
|
|
17
|
+
export declare function replay(board: TwinModelDef, events: readonly CanonicalEnvelope[]): ProjectedState;
|
|
18
18
|
/** 한 구조 아래에서 일어난 이벤트들 — 재생의 한 마디. */
|
|
19
19
|
export interface StructureSegment {
|
|
20
|
-
board:
|
|
20
|
+
board: TwinModelDef;
|
|
21
21
|
events: readonly CanonicalEnvelope[];
|
|
22
22
|
}
|
|
23
23
|
/** 구조가 바뀐 지점마다 무엇이 사라졌는지. 조용히 넘어가지 않는다. */
|
package/dist/flow-engine.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ISOTime, MaterialQuantity, WorkCalendarEntry, EffectivePeriod, Effectivity, OffCalendarReason, ResourceProperty, ResourceClassDef, MaterialDefinition, Attention,
|
|
1
|
+
import type { ISOTime, MaterialQuantity, WorkCalendarEntry, EffectivePeriod, Effectivity, OffCalendarReason, ResourceProperty, ResourceClassDef, MaterialDefinition, Attention, TwinModelDef, CanonicalEnvelope, Command, CommandAck, EventHandler, EquipmentMotion, OeeMetrics, AssetState, GeneratorSpec, OrderState, PersonState, ScenarioControl, StateSnapshot, TwinKernel, Unsubscribe, LocationState, ItemState, EquipmentState, OrderStatusDelta, TaskState } from './contract.ts';
|
|
2
2
|
import type { EpcisEvent, BizTransactionElement } from './epcis.ts';
|
|
3
3
|
import type { AllocationPolicy, SlotView } from './allocation-policy.ts';
|
|
4
4
|
import type { DurationEstimator, DurationContext } from './duration-estimator.ts';
|
|
@@ -283,7 +283,7 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
283
283
|
private observedDirty;
|
|
284
284
|
private observeMode;
|
|
285
285
|
/** 관측 구동이 투영기를 세울 때 필요한 원본 보드(구조는 이벤트가 아니라 마스터에서 온다). */
|
|
286
|
-
protected boardDef?:
|
|
286
|
+
protected boardDef?: TwinModelDef;
|
|
287
287
|
/** 명세 소비 기록 — 무엇을 선언값으로, 무엇을 기본값으로 계산했나(정직한 자기보고). */
|
|
288
288
|
private specUse;
|
|
289
289
|
protected epcSeq: number;
|
|
@@ -310,9 +310,9 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
310
310
|
* 이동(WMS/YMS: from→to 이동) 이든 변환(MES: 소비→생산) 이든 여기서 결정 → base 가 이동-중립.
|
|
311
311
|
*/
|
|
312
312
|
protected abstract onTaskComplete(task: FlowTask): void;
|
|
313
|
-
|
|
313
|
+
loadTwinModel(def: TwinModelDef): void;
|
|
314
314
|
/**
|
|
315
|
-
* what-if 구성 변주 — fork(또는 실행 중) 엔진에 설비 추가.
|
|
315
|
+
* what-if 구성 변주 — fork(또는 실행 중) 엔진에 설비 추가. loadTwinModel 설비 삽입과 동일 규약.
|
|
316
316
|
* 기본은 mtbf 미지정(고장 없는 신뢰 자원) → sampleExp(rng) 무소비라 baseline fork 와 깨끗이 비교 가능.
|
|
317
317
|
*/
|
|
318
318
|
addEquipment(m: {
|
package/dist/flow-engine.js
CHANGED
|
@@ -253,7 +253,7 @@ export class FlowEngine {
|
|
|
253
253
|
this.policy = policy;
|
|
254
254
|
}
|
|
255
255
|
// ── TwinKernel (mechanics, 도메인 무관) ───────────────────────────────────
|
|
256
|
-
|
|
256
|
+
loadTwinModel(def) {
|
|
257
257
|
this.boardDef = def;
|
|
258
258
|
/*
|
|
259
259
|
* **생산 선언은 어느 커널이든 싣는다.** 예전에는 MES 커널만 생성자에서 이것을 실었고(그 시절
|
|
@@ -283,7 +283,7 @@ export class FlowEngine {
|
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
/**
|
|
286
|
-
* what-if 구성 변주 — fork(또는 실행 중) 엔진에 설비 추가.
|
|
286
|
+
* what-if 구성 변주 — fork(또는 실행 중) 엔진에 설비 추가. loadTwinModel 설비 삽입과 동일 규약.
|
|
287
287
|
* 기본은 mtbf 미지정(고장 없는 신뢰 자원) → sampleExp(rng) 무소비라 baseline fork 와 깨끗이 비교 가능.
|
|
288
288
|
*/
|
|
289
289
|
addEquipment(m) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AssetState,
|
|
1
|
+
import type { AssetState, TwinModelDef, CanonicalEnvelope, LocationState, ItemState, EquipmentState, PersonState, TaskState, OrderState } from './contract.ts';
|
|
2
2
|
/**
|
|
3
3
|
* 마스터 동기 — 선언적 로케이션 upsert/remove.
|
|
4
4
|
*
|
|
@@ -72,7 +72,7 @@ export declare class ObservedReducer {
|
|
|
72
72
|
private shifts;
|
|
73
73
|
/** 시각 해석 기준(보드 선언) — 없으면 UTC. 캘린더의 `HH:MM` 이 어느 기준인지 정한다. */
|
|
74
74
|
private utcOffsetMinutes?;
|
|
75
|
-
constructor(board:
|
|
75
|
+
constructor(board: TwinModelDef);
|
|
76
76
|
/**
|
|
77
77
|
* **구조를 갈아탄다** — 관측된 사실은 지키고 토폴로지만 새 선언으로 바꾼다.
|
|
78
78
|
*
|
|
@@ -91,7 +91,7 @@ export declare class ObservedReducer {
|
|
|
91
91
|
* 관측으로 알게 된 자리(`origin: 'observed'`)는 **새 마스터에 없어도 남긴다** — 마스터가 모르는
|
|
92
92
|
* 자리에서 물건이 실제로 보였다는 사실은 구조를 바꾼다고 사라지지 않는다.
|
|
93
93
|
*/
|
|
94
|
-
adoptStructure(board:
|
|
94
|
+
adoptStructure(board: TwinModelDef): {
|
|
95
95
|
locationsAdded: number;
|
|
96
96
|
locationsDropped: number;
|
|
97
97
|
equipmentDropped: number;
|
package/dist-cjs/index.cjs
CHANGED
|
@@ -2280,7 +2280,7 @@ var FlowEngine = class {
|
|
|
2280
2280
|
this.policy = policy;
|
|
2281
2281
|
}
|
|
2282
2282
|
// ── TwinKernel (mechanics, 도메인 무관) ───────────────────────────────────
|
|
2283
|
-
|
|
2283
|
+
loadTwinModel(def) {
|
|
2284
2284
|
this.boardDef = def;
|
|
2285
2285
|
if (def.productionSpec?.definition?.operations?.length) this.loadOperations(def.productionSpec.definition.operations);
|
|
2286
2286
|
for (const n of readBoardLocations(def)) this.locations.set(n.id, { id: n.id, type: n.type, capacity: n.capacity, parallelism: n.parallelism, occupancy: 0, status: "idle", parentId: n.parentId });
|
|
@@ -2299,7 +2299,7 @@ var FlowEngine = class {
|
|
|
2299
2299
|
}
|
|
2300
2300
|
}
|
|
2301
2301
|
/**
|
|
2302
|
-
* what-if 구성 변주 — fork(또는 실행 중) 엔진에 설비 추가.
|
|
2302
|
+
* what-if 구성 변주 — fork(또는 실행 중) 엔진에 설비 추가. loadTwinModel 설비 삽입과 동일 규약.
|
|
2303
2303
|
* 기본은 mtbf 미지정(고장 없는 신뢰 자원) → sampleExp(rng) 무소비라 baseline fork 와 깨끗이 비교 가능.
|
|
2304
2304
|
*/
|
|
2305
2305
|
addEquipment(m) {
|
package/package.json
CHANGED