@g1cloud/entity-modeler-next 5.0.0-beta.47 → 5.0.0-beta.49
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 +6 -0
- package/dist/editor/association.d.ts +18 -0
- package/dist/editor/attribute.d.ts +25 -0
- package/dist/editor/commandPlans.d.ts +22 -2
- package/dist/editor/entity.d.ts +19 -0
- package/dist/editor/group.d.ts +22 -0
- package/dist/editor/note.d.ts +11 -0
- package/dist/editor/selection.d.ts +1 -6
- package/dist/entity-modeler-next.css +1 -1
- package/dist/entity-modeler.js +12625 -12259
- package/dist/entity-modeler.umd.cjs +24 -24
- package/dist/i18n/ko.d.ts +7 -0
- package/dist/view/DiagramCanvas.vue.d.ts +5 -0
- package/dist/view/columnResolution.d.ts +85 -0
- package/dist/view/embedSlotCollapse.d.ts +36 -0
- package/package.json +2 -1
package/dist/i18n/ko.d.ts
CHANGED
|
@@ -307,6 +307,13 @@ export declare const ko: {
|
|
|
307
307
|
readonly 'em.node.logicalMissing': "(논리명)";
|
|
308
308
|
readonly 'em.node.editLock': "편집 잠금";
|
|
309
309
|
readonly 'em.node.connectHint': "드래그해 다른 엔티티와 관계 연결";
|
|
310
|
+
readonly 'em.node.embedRepeatedShow': "이 엔티티에서 값이 같아 접힌 컬럼 {count}개 보기";
|
|
311
|
+
readonly 'em.node.embedRepeatedHide': "값이 같아 반복되는 컬럼 접기";
|
|
312
|
+
readonly 'em.node.embedAttrHide': "이 임베드 컬럼 접기";
|
|
313
|
+
readonly 'em.node.embedAttrShow': "접힌 임베드 컬럼 {count}개 보기";
|
|
314
|
+
readonly 'em.node.embedAllHide': "이 엔티티의 임베드 컬럼 모두 접기";
|
|
315
|
+
readonly 'em.node.embedAllShow': "접힌 임베드 컬럼 모두 펼치기";
|
|
316
|
+
readonly 'em.node.embedAllSummary': "임베드 컬럼 {n}개 숨김";
|
|
310
317
|
readonly 'em.node.opsSummaryTitle': "오퍼레이션 {n}개 — 클래스 표시 모드에서 펼쳐 보입니다";
|
|
311
318
|
readonly 'em.node.opsSummary': "오퍼레이션 {n}개";
|
|
312
319
|
readonly 'em.node.addAttr': "+ 속성";
|
|
@@ -4,6 +4,11 @@ import { ModelId } from '../core/types';
|
|
|
4
4
|
type __VLS_Props = {
|
|
5
5
|
controller: EditorController;
|
|
6
6
|
diffMarks?: Map<ModelId, DiffMark> | null;
|
|
7
|
+
/**
|
|
8
|
+
* 임베드 반복 서브컬럼 접힘의 sessionStorage 보존 키. 생략 시 미보존(`useResizableWidth`·탐색기와
|
|
9
|
+
* 같은 opt-in 규약 — 호스트 전역 키 충돌 방지 + read-only 다중 임베드가 서로 덮지 않게).
|
|
10
|
+
*/
|
|
11
|
+
embedCollapseStorageKey?: string;
|
|
7
12
|
};
|
|
8
13
|
declare function exportSvg(): Promise<void>;
|
|
9
14
|
declare function exportPng(): Promise<void>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ComputedRef, InjectionKey } from 'vue';
|
|
2
|
+
import { Attribute, DbColumn, EmbeddableCatalog, LogicalModel, ModelId } from '../core/types';
|
|
3
|
+
/**
|
|
4
|
+
* 캔버스 행 표시에 필요한 **상속·공유 해소를 노드 밖에서 한 번에** 계산한 인덱스 (VE-7 ②).
|
|
5
|
+
*
|
|
6
|
+
* ── 왜 노드 밖으로 뺐나 ────────────────────────────────────────────────────────
|
|
7
|
+
* `EntityNode`가 자기 행을 그리려면 **다른 엔티티를 읽어야 한다**(FK 물리명·타입은 부모 PK에서,
|
|
8
|
+
* 임베드 슬롯은 임베더블 소스에서, 공유 통화 컬럼은 owner 컬럼에서 상속). 그 읽기가 렌더 이펙트
|
|
9
|
+
* 안에 있으면 Vue가 `logical.entities`와 **각 엔티티의 `attributes`까지** 노드의 의존으로 추적하므로,
|
|
10
|
+
* 무관한 엔티티 1개를 추가해도 이 경로를 타는 노드가 전부 무효화된다 — VE-1이 좁혀 둔 스코프가
|
|
11
|
+
* 되돌아간다. 실측(module-order 미러 시드 188노드): 엔티티 추가 1회에 EntityNode patch **124**,
|
|
12
|
+
* 해소 두 축을 끄면 **4**(각 축 단독으로도 발동 · 이 경로를 타는 노드 169/188).
|
|
13
|
+
*
|
|
14
|
+
* ── 무엇을 dedup 하는가 ───────────────────────────────────────────────────────
|
|
15
|
+
* 노드별 해소는 각자 자기 속성만 처리하므로 **중복이 아니다**(총 작업량은 같다). 실제 중복은
|
|
16
|
+
* `indexColumnsByModelId(collectSharedColumns(...))`를 **임베드 속성마다** 다시 만들던 것 하나이고
|
|
17
|
+
* (그 안의 owner 역참조는 embeddable 노드에서 전 엔티티 스캔이다) → **엔티티별 1회**로 접었다.
|
|
18
|
+
* 상속·스코프 계산 자체는 core 헬퍼(`collectSharedColumns`·`resolveEffectiveColumn`·
|
|
19
|
+
* `resolveFkOriginColumn`·`embedCollectionType`)를 **그대로 호출한다** — 시맨틱을 여기 옮겨 적으면 이
|
|
20
|
+
* 리포가 반복해서 싸운 미러 드리프트(VE-4 축)를 뷰 계층에 새로 만드는 셈이다. ★초안에서 owner 역참조
|
|
21
|
+
* 맵을 직접 만들어 `sharedColumnScopeEntities`의 규칙을 재구현했다가 **되돌렸다**: 그것이 그 규칙의 네
|
|
22
|
+
* 번째 사본이 되는데, 참조 안정화가 이미 성능 목표(하한)를 달성했으므로 그 최적화는 드리프트 위험만
|
|
23
|
+
* 남기고 얻는 게 없었다(실측 차이 없음 — 헤더 하단 수치).
|
|
24
|
+
*
|
|
25
|
+
* ── 반복 서브컬럼(redundantSlots) ─────────────────────────────────────────────
|
|
26
|
+
* 임베드 서브행은 캔버스 렌더 행의 큰 몫인데(실측 BNKR_SALES v2 576엔티티: 속성 6,214 + 서브행 2,683 =
|
|
27
|
+
* **30.2%**), 그중 상당수가 **엔티티 안에서 같은 값을 반복**한다. 지배적 형상은 Money의 currency 슬롯이다:
|
|
28
|
+
* - 미지정(빈 슬롯) 656건 → 카탈로그 기본명 `'currency'`로 해소되어 전부 같은 이름
|
|
29
|
+
* (그중 613건은 한 엔티티에 2개 이상이라 `CHK-NAME-2` 컬럼 충돌까지 유발한다 — OrderItem 59/59)
|
|
30
|
+
* - 공유 지정(SHARED_REF) 43건 → `Claim.order_local_currency` **하나를 43개가 함께 가리킨다**
|
|
31
|
+
* 즉 **정상 지정된 경우에도 반복**이고(오히려 더 완전한 반복이다), 그 43행이 주는 정보는 "이 엔티티의
|
|
32
|
+
* Money는 저 통화 컬럼을 공유한다" 한 줄이다. 반대로 amount 슬롯은 704건 전부 고유 물리명을 가져
|
|
33
|
+
* 같은 규칙에서 자동으로 빠진다 — 판정 축은 "상속이냐"가 아니라 **"엔티티 안에서 새 정보를 주느냐"**다.
|
|
34
|
+
*
|
|
35
|
+
* 판정: 같은 `(attrType, 임베더블 타입, 슬롯 인덱스)` 자리를 묶어 실효 물리명이 **전부 같고** 그 자리가
|
|
36
|
+
* **2개 이상**이면 그 슬롯 전체를 반복으로 본다. 하나만 있으면 반복이 아니므로 제외하고, Money 하드코딩
|
|
37
|
+
* 없이 Tel·Name·Address는 사용처마다 물리명을 오버라이드하고 있어 자동으로 걸러진다(실측: Tel #0·#1은
|
|
38
|
+
* 상속 0/고유 37).
|
|
39
|
+
*
|
|
40
|
+
* ★뷰는 이것을 **기본 접힘**으로만 쓴다(행을 지우지 않는다) — 접힌 자리에 숨긴 개수를 표시하고 캐럿으로
|
|
41
|
+
* 펼치면 전부 보인다. 위 613건처럼 `CHK-NAME-2`가 걸린 슬롯도 여기 포함되지만, 그 신호의 소유자는
|
|
42
|
+
* 검증 패널이고 이 모듈은 **표시 반복만** 접는다(미완성 상태를 지우지 않는다).
|
|
43
|
+
*
|
|
44
|
+
* ── 계약 ─────────────────────────────────────────────────────────────────────
|
|
45
|
+
* 순수 함수다(모델을 변형하지 않고 표시용 파생값만 만든다). 값 시맨틱은 종전 `EntityNode`의 세 함수
|
|
46
|
+
* (`effectiveAttr`·`embedCols`·`typeCell`의 collectionType)와 **동일**해야 한다 — 이 모듈은 성능 리팩터이고
|
|
47
|
+
* 표시 결과를 바꾸지 않는다(`redundantSlots`는 그 뒤에 얹힌 **표시 힌트**이고, 소비는 뷰가 결정한다).
|
|
48
|
+
* 해소가 불필요한 속성은 **맵에 넣지 않는다**(호출자가 원본을 쓴다) ⇒ 인덱스 미주입(read-only 임베드)이면
|
|
49
|
+
* 종전 `!editor` 폴백과 같은 원형 표시가 된다.
|
|
50
|
+
*
|
|
51
|
+
* 판정은 **엔티티 로컬**이다(다른 엔티티를 읽지 않는다) — 위 「참조 안정화」가 좁혀 둔 무효화 범위를
|
|
52
|
+
* 넓히지 않기 위해서다.
|
|
53
|
+
*/
|
|
54
|
+
export interface EntityColumnResolution {
|
|
55
|
+
/** attr modelId → FK 상속 해소된 표시용 속성. 해소가 일어난 속성만 포함. */
|
|
56
|
+
effectiveAttrs: ReadonlyMap<ModelId, Attribute>;
|
|
57
|
+
/** attr modelId → 임베드 펼침 컬럼(상속·공유 해소 적용). EMBED 속성만 포함. */
|
|
58
|
+
embedCols: ReadonlyMap<ModelId, DbColumn[]>;
|
|
59
|
+
/** attr modelId → 컬렉션 임베드 래핑 타입. 단일 임베드(undefined)는 포함하지 않는다. */
|
|
60
|
+
collectionTypes: ReadonlyMap<ModelId, 'LIST' | 'SET'>;
|
|
61
|
+
/**
|
|
62
|
+
* attr modelId → **반복 서브컬럼** 슬롯 인덱스. 같은 `(임베더블 타입, 슬롯 위치)` 자리의 실효 물리명이
|
|
63
|
+
* 그 엔티티 안에서 **전부 같을 때**(그리고 그런 자리가 2개 이상일 때) 그 슬롯들을 담는다 — 아래 「반복
|
|
64
|
+
* 서브컬럼」 참조. 반복이 없는 속성은 포함하지 않는다.
|
|
65
|
+
*/
|
|
66
|
+
redundantSlots: ReadonlyMap<ModelId, ReadonlySet<number>>;
|
|
67
|
+
}
|
|
68
|
+
/** 엔티티 modelId → 그 엔티티 행들의 해소 결과. */
|
|
69
|
+
export type ColumnResolutionIndex = ReadonlyMap<ModelId, EntityColumnResolution>;
|
|
70
|
+
/**
|
|
71
|
+
* 캔버스가 provide, `EntityNode`가 inject. 미주입 시 노드는 원형(raw) 표시로 graceful degrade한다
|
|
72
|
+
* (종전 `!editor` 분기와 동일한 폴백) — 독립 렌더·테스트에서 캔버스 없이 노드를 쓸 수 있게 유지.
|
|
73
|
+
*/
|
|
74
|
+
export declare const COLUMN_RESOLUTION: InjectionKey<ComputedRef<ColumnResolutionIndex>>;
|
|
75
|
+
/**
|
|
76
|
+
* 참조 안정 인덱서 — 직전 인덱스를 기억해 **내용이 같은 엔티티는 이전 결과 객체를 재사용**한다.
|
|
77
|
+
* 캔버스가 computed 안에서 호출한다(모델 변경당 1회). 상태를 갖는 이유는 위 「참조 안정화」 참조.
|
|
78
|
+
*/
|
|
79
|
+
export declare function createColumnResolutionIndexer(): (model: LogicalModel, catalog?: EmbeddableCatalog) => ColumnResolutionIndex;
|
|
80
|
+
/**
|
|
81
|
+
* 모델 전체의 표시 해소 인덱스를 만든다. `catalog`는 EMBED_PREDEF 서브컬럼의 선언값 출처(호스트 주입) —
|
|
82
|
+
* 미주입이면 그 축만 원형으로 degrade한다(종전 `editor?.embeddableCatalog` 분기 동형).
|
|
83
|
+
* `prev`를 주면 내용이 같은 엔티티의 결과 **객체 참조를 재사용**한다(무효화 범위 축소 — 위 문단).
|
|
84
|
+
*/
|
|
85
|
+
export declare function buildColumnResolutionIndex(model: LogicalModel, catalog?: EmbeddableCatalog, prev?: ColumnResolutionIndex): ColumnResolutionIndex;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { InjectionKey } from 'vue';
|
|
2
|
+
export interface EmbedSlotCollapseApi {
|
|
3
|
+
/** 이 키가 지금 접혀 있는가. 기본값은 축마다 다르다(헤더 표 참조). */
|
|
4
|
+
isCollapsed: (key: string) => boolean;
|
|
5
|
+
/** 접힘 토글 — 조회 모드에서도 허용된다(읽기 편의이지 편집이 아니다). */
|
|
6
|
+
toggle: (key: string) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 미주입이면 노드는 **전부 펼친 원형 표시**로 degrade 한다(`COLUMN_RESOLUTION` 폴백과 같은 방향) —
|
|
10
|
+
* 캔버스 없이 노드를 독립 렌더·테스트할 수 있게 유지한다.
|
|
11
|
+
*/
|
|
12
|
+
export declare const EMBED_SLOT_COLLAPSE: InjectionKey<EmbedSlotCollapseApi>;
|
|
13
|
+
/**
|
|
14
|
+
* 반복 슬롯 축의 키. 속성 modelId 단독이 아니라 엔티티를 접두로 붙인다 — 레거시 유래 데이터에
|
|
15
|
+
* **속성 modelId 중복**이 실재하기 때문이다(CC-V 실측: 같은 중복 id 가 v1·v2 양쪽에 존재).
|
|
16
|
+
*/
|
|
17
|
+
export declare const embedSlotKey: (entityId: string, attrId: string) => string;
|
|
18
|
+
/** 엔티티 일괄 축 키의 접두 — 기본값 분기(`defaultCollapsed`)가 이것으로 축을 가른다. */
|
|
19
|
+
export declare const ENTITY_FOLD_PREFIX = "all:";
|
|
20
|
+
/** 속성 통째 축 키의 접두. */
|
|
21
|
+
export declare const ATTR_FOLD_PREFIX = "one:";
|
|
22
|
+
/**
|
|
23
|
+
* 엔티티 일괄 축의 키. `modelId`는 UUID 라 `:` 를 담지 않으므로 접두 있는 키는 반복 축 키와
|
|
24
|
+
* 절대 겹치지 않는다(반복 축 키의 접두는 항상 엔티티 UUID 다).
|
|
25
|
+
*/
|
|
26
|
+
export declare const embedAllKey: (entityId: string) => string;
|
|
27
|
+
/**
|
|
28
|
+
* 속성 통째 축의 키. 반복 축과 **같은 (엔티티, 속성) 쌍을 가리키되 다른 축**이라 접두로만 갈린다 —
|
|
29
|
+
* 둘은 동시에 상태를 가질 수 있고(통째를 풀면 반복 접힘이 그대로 살아난다) 그것이 의도다.
|
|
30
|
+
*/
|
|
31
|
+
export declare const embedAttrKey: (entityId: string, attrId: string) => string;
|
|
32
|
+
/**
|
|
33
|
+
* 이 키의 기본 접힘 여부 — 캔버스가 `useTreeCollapse`에 그대로 넘긴다. **키의 순수 함수**여야 하며
|
|
34
|
+
* (그 헤더 ①·②), 축별 기본값 근거는 이 모듈 헤더의 표에 있다. 접두가 없는 키(=반복 축)만 접힘이다.
|
|
35
|
+
*/
|
|
36
|
+
export declare const embedDefaultCollapsed: (key: string) => boolean;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@g1cloud/entity-modeler-next",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "5.0.0-beta.
|
|
4
|
+
"version": "5.0.0-beta.49",
|
|
5
5
|
"description": "Vue 3 visual entity-modeling / class-diagram editor",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"test:watch": "vitest",
|
|
58
58
|
"test:coverage": "vitest run --coverage",
|
|
59
59
|
"verify": "node scripts/verify-all.mjs",
|
|
60
|
+
"verify:floor": "node scripts/verify-all.mjs --update-floor",
|
|
60
61
|
"typecheck": "vue-tsc --noEmit",
|
|
61
62
|
"check": "pnpm run test && pnpm run build"
|
|
62
63
|
}
|