@operato/twin-kernel 0.7.39 → 0.7.41
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 +176 -10
- package/dist/contract.js +46 -5
- package/dist/domain-catalog.d.ts +1 -1
- package/dist/domain-catalog.js +1 -1
- package/dist/domain-definition.d.ts +17 -0
- package/dist/domain-definition.js +7 -0
- package/dist/ems-kernel.js +13 -1
- package/dist/epcis.d.ts +22 -0
- package/dist/epcis.js +91 -2
- package/dist/face2-adapter.d.ts +21 -1
- package/dist/face2-adapter.js +12 -1
- package/dist/flow-engine.d.ts +156 -8
- package/dist/flow-engine.js +324 -21
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/kernel.d.ts +15 -0
- package/dist/kernel.js +50 -16
- package/dist/mes-kernel.d.ts +117 -27
- package/dist/mes-kernel.js +354 -170
- package/dist/observed-reducer.d.ts +1 -1
- package/dist/observed-reducer.js +7 -4
- package/dist/yms-kernel.js +12 -5
- package/dist-cjs/index.cjs +648 -187
- package/package.json +1 -1
package/dist/flow-engine.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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, StructureShift } from './contract.ts';
|
|
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, StructureShift, IdentityGroundingView } 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';
|
|
@@ -209,6 +209,30 @@ export interface FlowOrder {
|
|
|
209
209
|
held?: boolean;
|
|
210
210
|
dockDoor?: string;
|
|
211
211
|
windowStartMs?: number;
|
|
212
|
+
/**
|
|
213
|
+
* **이 오더가 만드는 레시피** — 표준 `OperationsRequest` → `SegmentRequirement`.
|
|
214
|
+
*
|
|
215
|
+
* ── 왜 오더가 드는가 (2026-08-20) ────────────────────────────────────────
|
|
216
|
+
* 예전에는 레시피가 **트윈 전체에 하나**였다(`ProductionSpec.recipeKey ?? recipes[0]`). 그래서 제품이
|
|
217
|
+
* 둘인 공장을 선언으로 표현할 수 없었고, 체인지오버(제품 전환)를 데모하려면 커널 상수에 제품 목록을
|
|
218
|
+
* 두어야 했다 — 그것이 `MES_PRODUCTS` 가 남아 있는 이유였다.
|
|
219
|
+
*
|
|
220
|
+
* 표준이 이미 이 자리를 정해 두었다: 일정 하나에 요구가 여럿 들리고, 요구가 `SegmentRequirement` 로
|
|
221
|
+
* 쪼개진다. 실 시스템도 그렇다(작업지시가 제품·라우팅·BOM 을 든다). **공장이 레시피를 갖는 것이
|
|
222
|
+
* 아니라 오더가 갖는다.**
|
|
223
|
+
*
|
|
224
|
+
* 비면 선언 수준의 기본(`ProductionSpec.recipeKey ?? recipes[0]`)으로 떨어진다 — 레시피가 하나인
|
|
225
|
+
* 트윈은 예전과 같이 돈다.
|
|
226
|
+
*/
|
|
227
|
+
recipeKey?: string;
|
|
228
|
+
/**
|
|
229
|
+
* **씨앗이 이 오더의 확보분을 다 심지 못했다** — 원본이 말한 물품이 스냅샷에 없었다.
|
|
230
|
+
*
|
|
231
|
+
* 그 오더는 원본에 실재하지만 이 트윈에는 그것을 완료할 자재가 없다. 그래서 완료 시점에 제품을
|
|
232
|
+
* 지어내지도 않고(계보가 거짓이 된다) 멈추지도 않는다(원본의 빈틈이 답 전체를 죽인다) — **막혔다고
|
|
233
|
+
* 말한다.** 이 표시가 없으면 그 상황과 「우리 계산의 결함」을 구별할 수 없다.
|
|
234
|
+
*/
|
|
235
|
+
seedIncomplete?: boolean;
|
|
212
236
|
/** 우선순위 — 표준 `OperationsRequest.Priority`(작은 값이 급하다). 할당 순서를 정한다. */
|
|
213
237
|
priority?: number;
|
|
214
238
|
/** 예정 창 — 표준 `StartTime`/`EndTime`. 납기가 있어야 "늦었나" 를 물을 수 있다. */
|
|
@@ -345,10 +369,67 @@ export interface OeeCounters {
|
|
|
345
369
|
* 이벤트 누적기(근사)로 별도 공급해야 한다. 공식만 공유되고 입력원은 live 데이터-생산 결정.
|
|
346
370
|
*/
|
|
347
371
|
export declare function computeOee(c: OeeCounters, nowMs: number): OeeMetrics;
|
|
372
|
+
/**
|
|
373
|
+
* 물품 저장소 — **맵과 「자리별 색인」을 함께 든다.**
|
|
374
|
+
*
|
|
375
|
+
* ── 왜 클래스인가 (2026-08-21) ──────────────────────────────────────────────
|
|
376
|
+
* 자재를 확보할 때(`claimMaterials`) 「그 자리에 있는 물품」만 필요한데, 요구 한 줄마다 **물품 전체를
|
|
377
|
+
* 순회**하고 있었다. 규모 기준선이 그 값을 보인다: 물품이 15배 늘 때 주문당 비용이 3~4배가 된다
|
|
378
|
+
* (`test/order-scale-baseline.test.ts`). 목표 규모는 물품 10만이다.
|
|
379
|
+
*
|
|
380
|
+
* 색인을 따로 들면 갱신하는 자리가 흩어지고, 한 자리라도 빠뜨리면 **재고가 조용히 사라진다**(그 자리에
|
|
381
|
+
* 있는데 색인에 없으면 작업이 영원히 자재를 기다린다). 그래서 맵과 색인을 **한 객체**에 담아, 물품을
|
|
382
|
+
* 바꾸는 길이 이 클래스뿐이게 한다. 자리를 옮기는 것도 여기 통로가 있다(`relocate`) — 물품 객체의
|
|
383
|
+
* `location` 을 직접 고치면 색인이 어긋나므로, 그 규율은 시험이 지킨다.
|
|
384
|
+
*
|
|
385
|
+
* Map 과 같은 이름들을 그대로 낸다(`get`·`set`·`delete`·`has`·`values`·`clear`·순회) — 소비처를 고치지
|
|
386
|
+
* 않고 색인을 얻기 위해서다.
|
|
387
|
+
*/
|
|
388
|
+
export declare class ItemStore {
|
|
389
|
+
private map;
|
|
390
|
+
private byLocation;
|
|
391
|
+
get size(): number;
|
|
392
|
+
get(key: string): FlowItem | undefined;
|
|
393
|
+
has(key: string): boolean;
|
|
394
|
+
values(): IterableIterator<FlowItem>;
|
|
395
|
+
keys(): IterableIterator<string>;
|
|
396
|
+
entries(): IterableIterator<[string, FlowItem]>;
|
|
397
|
+
[Symbol.iterator](): IterableIterator<[string, FlowItem]>;
|
|
398
|
+
forEach(fn: (item: FlowItem, key: string) => void): void;
|
|
399
|
+
set(key: string, item: FlowItem): this;
|
|
400
|
+
delete(key: string): boolean;
|
|
401
|
+
clear(): void;
|
|
402
|
+
/**
|
|
403
|
+
* 물품을 다른 자리로 옮긴다 — **색인이 함께 움직이는 유일한 통로.**
|
|
404
|
+
*
|
|
405
|
+
* 없는 물품을 옮기라는 요청은 조용히 넘기지 않는다: 그 요청을 낸 쪽의 계산이 이미 어긋난 것이고,
|
|
406
|
+
* 지나가면 그 뒤의 이동·처분이 엉뚱한 자리에 적힌다.
|
|
407
|
+
*/
|
|
408
|
+
relocate(key: string, to: string): FlowItem;
|
|
409
|
+
/**
|
|
410
|
+
* 사본 — **자기 복제 방법을 스스로 안다.**
|
|
411
|
+
*
|
|
412
|
+
* `fork()` 는 `Map` 만 알고 나머지는 `structuredClone` 으로 복제한다. 그 함수는 클래스의 메서드를
|
|
413
|
+
* 복제하지 못하므로(평범한 객체가 된다), 저장소가 복제를 맡지 않으면 사본의 물품 조회가 통째로
|
|
414
|
+
* 깨진다 — 실제로 그렇게 42건이 붉어졌다. 복제 방법을 아는 객체가 스스로 복제한다.
|
|
415
|
+
*/
|
|
416
|
+
clone(): ItemStore;
|
|
417
|
+
/** 그 자리에 있는 물품들 — 색인이 답한다(전체 순회가 아니다). */
|
|
418
|
+
at(location: string): FlowItem[];
|
|
419
|
+
/**
|
|
420
|
+
* 색인이 맵과 어긋난 자리 — **시험이 쓰는 확인 통로**(전체를 다시 세므로 비싸다).
|
|
421
|
+
*
|
|
422
|
+
* 어긋남은 조용한 결함이다(자재가 있는데 없다고 판정된다). 그래서 「어긋나지 않을 것이다」를 믿지 않고
|
|
423
|
+
* 시나리오를 돌린 뒤 이 값으로 확인한다.
|
|
424
|
+
*/
|
|
425
|
+
indexDrift(): string[];
|
|
426
|
+
private index;
|
|
427
|
+
private unindex;
|
|
428
|
+
}
|
|
348
429
|
export declare abstract class FlowEngine implements TwinKernel {
|
|
349
430
|
tenantId: string;
|
|
350
431
|
locations: Map<string, FlowLocation>;
|
|
351
|
-
items:
|
|
432
|
+
items: ItemStore;
|
|
352
433
|
equipment: Map<string, FlowEquipment>;
|
|
353
434
|
/** 등급 정의(표준 `<X>Class`) — 상속·유효기간 판정의 재료. 선언 안 하면 비어 있고, 소속 그대로 판정한다. */
|
|
354
435
|
protected classDefs: {
|
|
@@ -417,6 +498,21 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
417
498
|
/** 관측 구동(P0) — 이벤트를 접는 투영기와 그 사실. tick 과 섞이지 않게 명시적으로 들고 있다. */
|
|
418
499
|
private observer?;
|
|
419
500
|
/** 관측분이 아직 커널 상태로 옮겨지지 않았다 — 스냅샷·fork 직전에 한 번만 옮긴다. */
|
|
501
|
+
/**
|
|
502
|
+
* **관측 모드에서 원본과 어긋난 횟수** — 받아들였지만 사실이 맞지 않았다.
|
|
503
|
+
*
|
|
504
|
+
* 미러는 원본을 비추는 쪽이라 어긋남을 만나도 멈추지 않는다(멈추면 원본의 한 건이 트윈 전체를
|
|
505
|
+
* 세운다). 그래서 **세어 둔다** — 세지 않으면 그 결함이 아무 데도 드러나지 않고, 화면은 어긋난 적이
|
|
506
|
+
* 없는 트윈과 구별되지 않는다.
|
|
507
|
+
*/
|
|
508
|
+
/**
|
|
509
|
+
* **씨앗이 심지 못한 참조의 수** — 원본이 말했지만 그 물품이 스냅샷에 없었다.
|
|
510
|
+
*
|
|
511
|
+
* 0 이 아니면 이 트윈의 상태는 원본의 일부를 담지 못했다는 뜻이다. 예측·집계가 그 사실을 모르면
|
|
512
|
+
* 부족한 씨앗 위에서 낸 답을 완전한 답으로 읽는다.
|
|
513
|
+
*/
|
|
514
|
+
private seedDanglingRefs;
|
|
515
|
+
private transformInputsAbsent;
|
|
420
516
|
private observedDirty;
|
|
421
517
|
private observeMode;
|
|
422
518
|
/** 관측 구동이 투영기를 세울 때 필요한 원본 보드(구조는 이벤트가 아니라 마스터에서 온다). */
|
|
@@ -536,6 +632,17 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
536
632
|
since: string;
|
|
537
633
|
}[];
|
|
538
634
|
}): void;
|
|
635
|
+
/**
|
|
636
|
+
* 씨앗의 확보분 중 **이 트윈에 실제로 있는 것만** 남긴다 — 없는 것은 세고 버린다.
|
|
637
|
+
*
|
|
638
|
+
* 원본이 확보분을 말했는데 그 물품이 스냅샷에 없으면, 그 참조는 심는 순간 이미 사실이 아니다.
|
|
639
|
+
* 심어 두면 나중에 틱에서 드러나고(시뮬은 없는 것을 소비하지 않으므로 멈춘다) 그 판정이 예측
|
|
640
|
+
* 경로에서 터지면 원본의 빈틈 하나가 답 전체를 서버 오류로 죽인다.
|
|
641
|
+
*
|
|
642
|
+
* 그래서 심을 때 맞춘다. **없는 물품을 만들어 채우지 않는다** — 채우면 계보와 재고가 거짓 위에 선다.
|
|
643
|
+
* 대신 몇 건이 맞지 않았는지 남겨 씨앗이 불완전했다는 사실을 답에 실을 수 있게 한다.
|
|
644
|
+
*/
|
|
645
|
+
private resolvedAllocated;
|
|
539
646
|
hydrateObserved(snap: {
|
|
540
647
|
locations: LocationState[];
|
|
541
648
|
items: ItemState[];
|
|
@@ -757,7 +864,7 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
757
864
|
* 이긴다(원천 사본의 값이 낡았을 때 고칠 자리가 여기다). 무엇을 썼는지는 `specCoverage()` 가 밝힌다.
|
|
758
865
|
*
|
|
759
866
|
* ── 조용히 버리지 않는다 ────────────────────────────────────────────────────
|
|
760
|
-
* 읽을 수 없는 값은
|
|
867
|
+
* 읽을 수 없는 값은 오류를 낸다. 받아 두고 무시하면 화면은 「넣었습니다」라고 말하고 시뮬은 상수로 도는데,
|
|
761
868
|
* 그 어긋남을 아무도 볼 수 없다(이 시스템에서 가장 비싼 종류의 침묵이다).
|
|
762
869
|
*/
|
|
763
870
|
declareDurations(durations: Record<string, IsoDuration> | undefined | null): void;
|
|
@@ -775,7 +882,7 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
775
882
|
* · **현장 선언이 원천 명세를 이긴다**(ADR-0034) — 원천 사본이 낡았을 때 고칠 자리가 그것뿐이다.
|
|
776
883
|
* · 명세 행이 없는 종류에도 얹힌다 — 행을 지어 만들면 지어낸 `intent` 가 능력 계산을 오염시킨다.
|
|
777
884
|
* · 무엇을 썼는지는 `specCoverage()` 의 `parameters` 가 그대로 밝힌다.
|
|
778
|
-
* · 빈 이름·빈 값은
|
|
885
|
+
* · 빈 이름·빈 값은 **오류를 낸다**: 받아 두고 무시하면 화면은 「넣었습니다」라고 말하고 시뮬은 상수로 돈다.
|
|
779
886
|
*/
|
|
780
887
|
declareParameters(params: Record<string, Record<string, string | number>> | undefined | null): void;
|
|
781
888
|
/**
|
|
@@ -783,6 +890,14 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
783
890
|
* 생산 정의를 가진 커널이 override 해서 자기 라우트를 답한다.
|
|
784
891
|
*/
|
|
785
892
|
protected routeKeys(): string[] | undefined;
|
|
893
|
+
/**
|
|
894
|
+
* **이 트윈이 굴리는 서로 다른 라우트들** — 용량이 답할 수 있는지를 가른다.
|
|
895
|
+
*
|
|
896
|
+
* 하나면 `routeKeys()` 가 그 순서를 답한다. 둘 이상이면 「하루 몇 대」의 답이 **제품 구성에 따라
|
|
897
|
+
* 달라지므로**, 하나를 골라 답하지 않고 서로 다르다는 사실을 `capacity()` 가 함께 낸다. 조용히 고르면
|
|
898
|
+
* 능력 숫자가 거짓이 되고, 그 위에 선 모든 계획이 거짓 위에 선다.
|
|
899
|
+
*/
|
|
900
|
+
protected distinctRouteKeys(): string[];
|
|
786
901
|
/**
|
|
787
902
|
* **이 공장이 하루 몇 대를 낼 수 있는가** — 실행해 보지 않고 답한다.
|
|
788
903
|
*
|
|
@@ -799,6 +914,7 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
799
914
|
sampleWeekStartMs: number;
|
|
800
915
|
}): CapacityAnalysis & {
|
|
801
916
|
mixedCalendars: boolean;
|
|
917
|
+
mixedRoutes: boolean;
|
|
802
918
|
};
|
|
803
919
|
/**
|
|
804
920
|
* **생산 능력 보고서** — ISA-95 Part 4 `OperationsCapability`(§operations-capability).
|
|
@@ -905,7 +1021,7 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
905
1021
|
* `skuMix` 에서 weight 로 gtin 선택(rng) — 도착·오더 자극의 품목 결정.
|
|
906
1022
|
*
|
|
907
1023
|
* **빈 목록이면 고르지 않는다**(`undefined`). 예전에는 `mix[mix.length - 1].gtin` 으로 떨어져
|
|
908
|
-
* `mix[-1]` 이 undefined 가 되고 거기서
|
|
1024
|
+
* `mix[-1]` 이 undefined 가 되고 거기서 오류가 났다 — 그 예외가 서버까지 올라가 **정확도 추세 전체를
|
|
909
1025
|
* 죽였다**(품목 구성을 선언하지 않은 자극 하나가 예측 전체를 껐다).
|
|
910
1026
|
*
|
|
911
1027
|
* 없는 품목을 지어내지 않는다: 무엇을 만들지 모르면 **만들지 않는 것**이 맞고, 부르는 쪽이
|
|
@@ -1099,6 +1215,30 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
1099
1215
|
* 같은 품목이 그 자리에 이미 있으면 **수량을 더한다** — 새 줄을 만들면 같은 자리의 같은 로트가
|
|
1100
1216
|
* 둘로 갈려 재고가 부푼다(§MaterialSubLot 에서 겪은 것과 반대 방향의 같은 오류).
|
|
1101
1217
|
*/
|
|
1218
|
+
/**
|
|
1219
|
+
* **이 공정의 산출을 도메인이 직접 만드는가** — 기본은 아니다(코어가 만든다).
|
|
1220
|
+
*
|
|
1221
|
+
* ── 왜 이 이음새가 있나 (2026-08-20) ──────────────────────────────────────
|
|
1222
|
+
* 코어의 산출은 **비직렬 클래스+수량**이다(일련번호를 지어내지 않으므로). 그런데 어떤 도메인은
|
|
1223
|
+
* 산출물에 **개체 정체성**이 필요하다: MES 의 레시피 생산은 개체마다 직렬번호를 갖고, 수율이
|
|
1224
|
+
* 개체별로 양품/불량을 가르고, 계보(`TransformationEvent`)가 오더의 단계들을 잇는다.
|
|
1225
|
+
*
|
|
1226
|
+
* 그 도메인이 산출을 만들 때 코어도 같은 선언을 보고 만들면 **같은 산출이 두 벌** 된다 — 재고가
|
|
1227
|
+
* 조용히 두 배가 되고, 그 위의 모든 계산이 거짓 위에 선다. 그래서 소유를 **한쪽으로 정한다.**
|
|
1228
|
+
*
|
|
1229
|
+
* 코어는 여기서 **도메인 명사를 하나도 알지 않는다**: 「누가 만드는가」만 묻는다. 무엇을 만드는지는
|
|
1230
|
+
* 여전히 선언이 정하고, 코어는 그 선언을 읽을 뿐이다.
|
|
1231
|
+
*/
|
|
1232
|
+
protected producesOwnOutputs(_opKey: string): boolean;
|
|
1233
|
+
/**
|
|
1234
|
+
* **이 트윈의 정체성 근거** — 스냅샷에 실린다(§`StateSnapshot.identityGrounding`).
|
|
1235
|
+
*
|
|
1236
|
+
* 코어는 선언을 갖고 있지 않다(생산 선언은 도메인의 것이다). 그래서 기본은 **선언 없음**이고,
|
|
1237
|
+
* 선언을 든 커널이 override 해서 자기 것을 답한다 — `routeKeys()` 와 같은 모양이다.
|
|
1238
|
+
*
|
|
1239
|
+
* 코어는 여기서 **정체성의 값을 정하지 않는다**: 「어디서 왔나」만 묻는다.
|
|
1240
|
+
*/
|
|
1241
|
+
protected identityGroundingView(): IdentityGroundingView;
|
|
1102
1242
|
private produceMaterials;
|
|
1103
1243
|
/**
|
|
1104
1244
|
* 이 작업이 **딛고 선 것**이 아직 있나 — 없으면 무엇이 없는지 답한다.
|
|
@@ -1106,7 +1246,7 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
1106
1246
|
* 작업은 혼자 서지 못한다: 옮길 **물품**과, (있다면) 그것을 시킨 **오더** 위에 선다. 진행 중에
|
|
1107
1247
|
* 둘 중 하나가 사라질 수 있다 — 물품은 포장·출하·소비로, 오더는 이미 이행돼 씨앗이 주입하지 않아서.
|
|
1108
1248
|
*
|
|
1109
|
-
* 그때 도메인 훅은 없는 것을 딛으려다
|
|
1249
|
+
* 그때 도메인 훅은 없는 것을 딛으려다 오류를 낸다(`order.gtin` · `item.location`). 그 예외 하나가
|
|
1110
1250
|
* **예측 전체를 죽였다** — 사용자에게는 기능이 통째로 사라진 것으로 보였다. 그래서 완료 **전에**
|
|
1111
1251
|
* 여기서 묻고, 없으면 그 작업만 접는다.
|
|
1112
1252
|
*/
|
|
@@ -1115,7 +1255,7 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
1115
1255
|
* 이 도메인이 이 작업을 **끝맺을 수 있나** — 코어가 모르는 조건은 도메인이 답한다.
|
|
1116
1256
|
*
|
|
1117
1257
|
* 코어는 물품과 오더까지만 안다. 그런데 도메인은 더 필요할 수 있다 — MES 는 완료 시점에 **오더와
|
|
1118
|
-
* 제품 정의**를 딛고 서고, 그 중 하나만 없어도
|
|
1258
|
+
* 제품 정의**를 딛고 서고, 그 중 하나만 없어도 오류를 낸다. 코어가 그 조건을 추측하면 도메인마다 다른
|
|
1119
1259
|
* 가정을 코어에 박게 되므로(방언), **묻는다.**
|
|
1120
1260
|
*
|
|
1121
1261
|
* 기본은 `true` — 대부분의 작업은 코어가 확인한 것으로 충분하다.
|
|
@@ -1126,13 +1266,21 @@ export declare abstract class FlowEngine implements TwinKernel {
|
|
|
1126
1266
|
*
|
|
1127
1267
|
* 물품 맵의 키는 `itemKeyOf`(직렬 물품은 `epc`, 로트의 부분은 `subLotId`)인데, 작업은 로트 식별자
|
|
1128
1268
|
* (`itemEpc`)로 가리킨다. 비직렬 로트에서는 둘이 **다르다** — 그래서 그냥 `get` 하면 못 찾는다.
|
|
1129
|
-
* 실제로 그 회귀를 냈다: 예측(씨앗) 경로에서 `item.location = …` 이 `undefined` 위에서
|
|
1269
|
+
* 실제로 그 회귀를 냈다: 예측(씨앗) 경로에서 `item.location = …` 이 `undefined` 위에서 오류를 내어
|
|
1130
1270
|
* **정확도 추세 전체가 서버 오류로 죽었다.**
|
|
1131
1271
|
*
|
|
1132
1272
|
* **부분이 여럿이면 풀지 않는다** — 어느 부분을 가리키는지 알 수 없고, 아무거나 고르면 그 뒤
|
|
1133
1273
|
* 이동·처분이 엉뚱한 자리에 적힌다. 그때는 참조가 부족한 것이고, 부르는 쪽이 그 사실을 말해야 한다.
|
|
1134
1274
|
*/
|
|
1135
1275
|
protected itemByRef(ref: string): FlowItem | undefined;
|
|
1276
|
+
/**
|
|
1277
|
+
* 참조가 키가 아니어서 전수 조회로 찾은 횟수 — **성능 판단의 근거**다.
|
|
1278
|
+
*
|
|
1279
|
+
* 규약대로면 0 이다. 0 이 아닌 것은 결함이 아니라 사실이다(원본이 준 참조는 우리 키를 모른다).
|
|
1280
|
+
* 다만 그 수가 규모와 함께 자라면 인덱스가 필요하다는 뜻이고, 그때 넣을 근거가 이 값이다.
|
|
1281
|
+
*/
|
|
1282
|
+
private refScans;
|
|
1283
|
+
refScanCount(): number;
|
|
1136
1284
|
/**
|
|
1137
1285
|
* 실제 자재 이동을 작업에 적어 둔다 — ISA-95 `JobResponse.MaterialActual`.
|
|
1138
1286
|
* 같은 품목·같은 쓰임은 **한 줄로 합친다**(줄을 늘리면 실적을 세는 쪽이 중복을 걷어내야 한다).
|