@g1cloud/entity-modeler-next 5.0.0-beta.41 → 5.0.0-beta.43

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.
@@ -0,0 +1,18 @@
1
+ import { DbColumn, LogicalModel, ModelId } from './types';
2
+ /** owner 표시 속성 한 건의 슬롯 보충 계획 — 컨트롤러가 `updateAttribute { dbAttrs }`로 커밋한다. */
3
+ export interface EmbedSlotFill {
4
+ /** 표시 속성을 보유한 소유자 엔티티. */
5
+ entityId: ModelId;
6
+ /** `EMBED_OWN` 표시 속성. */
7
+ attributeId: ModelId;
8
+ /** 보충 후 전체 슬롯 목록(기존 슬롯 그대로 + 꼬리 빈 슬롯). */
9
+ dbAttrs: DbColumn[];
10
+ /** 보충한 슬롯 수(로그·테스트 가독용). */
11
+ added: number;
12
+ }
13
+ /**
14
+ * `embeddableRef`를 사용하는 모든 owner의 슬롯을 선언 컬럼 수까지 채우는 계획.
15
+ * 대상이 없거나 이미 맞으면 빈 배열(무변경). 컬렉션 EMBED(@ElementCollection)는 컬럼이 임베더블에
16
+ * 남고 owner 슬롯을 비우는 것이 정상이라 제외한다(`controller.setEmbedCardinality`가 `dbAttrs: []`).
17
+ */
18
+ export declare function planEmbedSlotFill(model: LogicalModel, embeddableRef: ModelId, genId?: () => ModelId): EmbedSlotFill[];
@@ -0,0 +1,23 @@
1
+ import { ComputedRef, Ref } from 'vue';
2
+ import { Command, EditorState } from '../command/types';
3
+ import { ClipboardContent, EditorController, Selection } from './controller';
4
+ import { ModelId } from '../core/types';
5
+ /** 이 축이 팩토리 클로저에서 쓰는 것 전부 — 늘어나면 여기 선언이 먼저 늘어난다(의존 표면 = 이 타입). */
6
+ export interface ClipboardImportContext {
7
+ /** 편집 대상 reactive 상태(속성 교체만 일어나므로 참조 안정). */
8
+ state: EditorState;
9
+ clipboard: Ref<ClipboardContent | null>;
10
+ /** paste·importEntities가 붙여넣은 대상으로 선택을 옮긴다(쓰기). */
11
+ selection: Ref<Selection>;
12
+ inspectedEntityId: ComputedRef<ModelId | null>;
13
+ /** 조회 모드 판정 — run()의 백스톱과 별개로 selection 부수효과를 막기 위해 진입에서 직접 본다. */
14
+ editable: Ref<boolean>;
15
+ /** 모델 변경의 단일 실행점(조회 모드 no-op + 안내). */
16
+ run: (c: Command) => void;
17
+ }
18
+ /**
19
+ * 클립보드·임포트 인텐트 3종을 조립한다. 컨트롤러는 반환된 메서드를 `EditorController`에 **명시 위임**한다
20
+ * (스프레드가 아니라 한 줄씩) — 스프레드는 이 모듈에 export가 늘면 컨트롤러 런타임 표면이 **무심사로**
21
+ * 증식하는 배럴과 같은 실패 모드다(TI-4 `export *` 금지와 같은 논거: 최소 저항 경로가 곧 올바른 행동).
22
+ */
23
+ export declare function createClipboardImportApi(ctx: ClipboardImportContext): Pick<EditorController, 'copy' | 'paste' | 'importEntities'>;
@@ -0,0 +1,67 @@
1
+ import { Command } from '../command/types';
2
+ import { ReconcilePlan } from '../core/propagation';
3
+ import { Attribute, DbColumn, Entity, LogicalModel, ModelId } from '../core/types';
4
+ /**
5
+ * 식별자 전파 reconcile 계획을 자식 엔터티 대상 서브명령 배열로 변환.
6
+ * 1차 변경(관계 생성/삭제 등)과 함께 composite로 묶으면 전파 FK 동기화가 하나의 undo/redo
7
+ * 원자 단위가 된다 — 부분 undo로 고아 FK가 남지 않는다.
8
+ * 순서(remove→update→add)는 각기 다른 속성을 대상으로 해 상호 간섭이 없다.
9
+ *
10
+ * ★**owner 앵커 와이어링(CC-3)** — 계획이 관계의 FK를 새로 만들면 `end2.attributeRef`를 그 FK로 맞춘다.
11
+ * 종전에는 속성 CRUD만 방출해 앵커가 죽은 id를 계속 가리켰고, 코드젠 `relByAttr`(scaffoldJava:454)이
12
+ * 해소에 실패해 **관계가 산출에서 사라졌다**. 두 형상을 함께 덮는다:
13
+ * - **교체**: 부모 PK가 바뀌어 구 FK remove + 신 FK add가 같이 나는데 앵커가 구 FK를 가리킴
14
+ * → 모델은 완전한데 산출만 소실되는 최악 형상.
15
+ * - **재획득**: 부모가 PK를 얻어 FK가 add되는데 앵커가 미설정/죽은 상태 → cascade add 경로엔
16
+ * 앵커 배선이 없었다(생성 경로 `addAssociation:1947`·임베더블 전환 `:749`에만 있었다).
17
+ * 살아남는 속성을 가리키는 앵커는 건드리지 않는다(멱등 + 사용자/기존 상태 존중).
18
+ *
19
+ * ⚠️ **예방 전용 — 기존 dangling은 복구하지 않는다.** 이 함수는 전파 계획이 있을 때만 호출되므로,
20
+ * 이미 앵커가 죽은 문서는 그 자식에 계획이 발동하는 편집(부모 식별자 변경 등)이 있어야 정정된다.
21
+ * 엔티티명 변경 같은 비-식별자 편집은 계획이 비어 도달하지 않는다(실측: 실 데이터 유일 사례
22
+ * `Cart` self-assoc은 부모 rename으로 정정되지 않음). 기존 분의 복구는 로드-타임 파생 + 통합 스윕
23
+ * (`planHealBackfillOps`가 이미 `end1.attributeRef`를 diff하므로 end2 대칭 확장) 소관 — 별 결정.
24
+ *
25
+ * ⚠️ 순수 제거(부모가 PK를 잃음·임베더블 전환)로 **가리킬 FK가 아예 없는 경우는 해제하지 않는다** —
26
+ * 그 상태는 전파 산출이 0이라 방출할 관계도 없어 무해하고, `CHK-JPA-19`도 같은 근거로 면제한다(관계가
27
+ * 아니라 부모 PK 부재가 고칠 자리 = `CHK-JPA-1`). 호스트 검출기 규칙 5(`owner-fk-attr`)에는 남으므로
28
+ * 축적 위반 정리(B축) 소관.
29
+ * ※ 종전 이 자리에 적힌 "undefined가 wire에서 탈락해(CC-8) clear를 표현할 수 없다"는 **해소됐다** —
30
+ * `toWirePatch`(op.ts)가 update patch의 undefined를 null로 정규화하므로 `{attributeRef: undefined}`도
31
+ * 서버에 clear로 도달한다. 즉 위 판단은 이제 **전송 제약이 아니라 도메인 판단**으로만 서 있다(해제해도
32
+ * 무해하지만 얻는 것이 없다). 해제로 전환하려면 CC-3 복구 트랙에서 함께 결정할 것.
33
+ */
34
+ export declare function reconcilePlanToCommands(logical: LogicalModel, childId: ModelId, plan: ReconcilePlan): Command[];
35
+ /** logical을 얕게 복제하되 한 엔터티의 attributes만 transform 결과로 교체(읽기 전용 전파 계획 입력용). */
36
+ export declare function withEntityAttributes(logical: LogicalModel, entityId: ModelId, transform: (attrs: Attribute[]) => Attribute[]): LogicalModel;
37
+ /**
38
+ * 부모(parentId) 식별자 변경이 자식·후손으로 번지는 연쇄 reconcile 서브명령.
39
+ * futureLogical은 변경이 이미 반영된 상태여야 한다(construction 시점 계획 고정 → 결정적 redo).
40
+ * 영향 없는 변경(비식별 속성 등)이면 빈 배열을 돌려준다(planPropagation이 빈 계획만 산출).
41
+ *
42
+ * **임베드 슬롯 보충도 여기서 함께 방출**한다 — 편집된 엔티티가 임베더블이면 사용처(owner)의
43
+ * `EMBED_OWN` 표시 속성 슬롯을 선언 컬럼 수까지 채운다(FK 전파의 임베드 짝, `core/embedSlots`).
44
+ * 이 seam을 고른 이유: 속성 추가·수정·삭제·임베더블 전환의 모든 진입점이 이미 여기를 지나므로
45
+ * 트리거를 한 곳에만 두면 되고, 서브명령이 같은 composite에 실려 **undo가 원자적**이다.
46
+ */
47
+ export declare function cascadeCommands(futureLogical: LogicalModel, parentId: ModelId): Command[];
48
+ /**
49
+ * "자식의 FK 집합이 직접 바뀌는" 트리거(관계 삭제·identifying 토글)용 연쇄 서브명령.
50
+ * 1) seed 자식을 직접 reconcile(FK 증감/플립), 2) 그 변화를 적용한 상태로 후손 cascade.
51
+ * (부모 식별자 자체가 바뀌는 트리거는 부모 자신 reconcile이 불필요해 cascadeCommands를 직접 쓴다.)
52
+ * futureLogical은 트리거 변경이 이미 반영된 상태여야 한다(construction 시점 계획 고정).
53
+ */
54
+ export declare function childReconcileWithCascade(futureLogical: LogicalModel, childId: ModelId): Command[];
55
+ export declare function flattenEmbeddableColumns(embeddable: Entity): DbColumn[];
56
+ /**
57
+ * 임베더블 → 일반 엔터티 역전환의 부수 명령(stereotype update 명령에 합성).
58
+ * 임베더블이 1급 엔터티가 되면 자체 테이블·PK를 가지므로:
59
+ * 1) PK 자동 부여 — 식별자가 하나도 없으면 기본 PK(id/Long/BIGINT, addEntity 기본형과 동일)를 신설.
60
+ * 2) 이 임베더블(id)을 임베드하던 EMBED 관계를 일반 관계로 전환 — owner가 보유한 EMBED_OWN 표시속성
61
+ * (embedded.embeddableRef === id)을 제거하고, 관계 ends를 owner=end1(부모)/X=end2(자식)로 정규화한다.
62
+ * composition·embed attributeRef·legacyEmbedRaw를 버려야 저장 분기(assocToEmbed·legacyEmbedRaw)가
63
+ * 더는 EMBED로 환원하지 않는다. owner를 부모로 유지해 X(end2 자식)가 owner PK를 FK로 받는다(전파).
64
+ * plan은 construction 시점 고정(결정적 redo) — childReconcileWithCascade와 동일 산식을 인라인한다.
65
+ */
66
+ export declare function leavingEmbeddableCommands(logical: LogicalModel, id: ModelId): Command[];
67
+ export declare function enteringEmbeddableCommands(logical: LogicalModel, id: ModelId): Command[];
@@ -0,0 +1,30 @@
1
+ import { ComputedRef, Ref } from 'vue';
2
+ import { EditorState } from '../command/types';
3
+ import { CommandStack } from '../command/stack';
4
+ import { DiagramMeta } from '../adapter/diagramAdapter';
5
+ import { OpConflict } from '../command/op';
6
+ import { OpSyncTransport } from '../command/opSync';
7
+ import { EditorController, HistoryTransport, RestoreTransport } from './controller';
8
+ /** 이 축이 팩토리 클로저에서 쓰는 것 전부(주입 옵션 4 + 상태 4). 늘어나면 여기 선언이 먼저 늘어난다. */
9
+ export interface HostSyncContext {
10
+ state: EditorState;
11
+ /** op-mode 게이트(schemaVersion>=2 && opWriteEnabled) — attach·가용성 판정 공용. */
12
+ opMode: ComputedRef<boolean>;
13
+ /** 프리즈 시 편집 잠금(쓰기) + 복원 가용성 판정(읽기). */
14
+ editable: Ref<boolean>;
15
+ /** 하드 프리즈 충돌 노출(쓰기). */
16
+ opConflict: Ref<OpConflict | null>;
17
+ opTransport?: OpSyncTransport;
18
+ onOpError?: (err: unknown) => void;
19
+ historyTransport?: HistoryTransport;
20
+ restoreTransport?: RestoreTransport;
21
+ }
22
+ export interface HostSyncBinding extends Pick<EditorController, 'historyTransport' | 'historyAvailable' | 'restoreTransport' | 'restoreAvailable' | 'restoreToSeq' | 'reloadRequest' | 'flush' | 'whenOpsSettled'> {
23
+ /**
24
+ * op 어댑터 (재)구성 — 최초 생성과 `loadDiagram` 양쪽에서 호출한다.
25
+ * `stack`·`meta`를 **캡처하지 않고 이 시점에 받는 것**이 이 분리의 핵심이다(reload가 둘 다 교체한다).
26
+ */
27
+ setupOpAdapter(stack: CommandStack, meta: DiagramMeta | undefined): void;
28
+ teardownOpAdapter(): void;
29
+ }
30
+ export declare function createHostSync(ctx: HostSyncContext): HostSyncBinding;
@@ -0,0 +1,27 @@
1
+ import { Ref } from 'vue';
2
+ import { Command, EditorState } from '../command/types';
3
+ import { EditorController, Selection } from './controller';
4
+ import { ModelId, Point } from '../core/types';
5
+ /** 이 축이 팩토리 클로저에서 쓰는 것 전부. 늘어나면 여기 선언이 먼저 늘어난다(= 의존 인벤토리). */
6
+ export interface SelectionContext {
7
+ state: EditorState;
8
+ selection: Ref<Selection>;
9
+ /** 캔버스 센터링 요청 신호(requestFocus가 nonce를 올려 발화). */
10
+ focusRequest: Ref<{
11
+ id: ModelId;
12
+ nonce: number;
13
+ } | null>;
14
+ /** 모델 변경의 단일 실행점(조회 모드 no-op + 안내). */
15
+ run: (c: Command) => void;
16
+ /** 잠금 게이트 — 차단 시 true + 안내 emit. */
17
+ gateEntityLocked: (id: ModelId) => boolean;
18
+ /** 순수 잠금 조회(다중 이동에서 잠긴 대상만 건너뛴다 — 안내는 내지 않는다). */
19
+ isEntityLockedFn: (id: ModelId) => boolean;
20
+ isGroupLockedFn: (id: ModelId) => boolean;
21
+ /** 그룹 박스 + 멤버 + 내부 waypoint를 같은 delta로 옮기는 명령 집합(dragGroup과 공유). */
22
+ groupMoveCommands: (groupId: ModelId, location: Point, members: {
23
+ id: ModelId;
24
+ location: Point;
25
+ }[]) => Command[];
26
+ }
27
+ export declare function createSelectionApi(ctx: SelectionContext): Pick<EditorController, 'selectAttribute' | 'moveAttributeFocus' | 'nudgeSelectedAttributes' | 'nudgeNodes' | 'requestFocus'>;