@g1cloud/entity-modeler-next 5.0.0-beta.48 → 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/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>;
@@ -22,11 +22,34 @@ import { Attribute, DbColumn, EmbeddableCatalog, LogicalModel, ModelId } from '.
22
22
  * 번째 사본이 되는데, 참조 안정화가 이미 성능 목표(하한)를 달성했으므로 그 최적화는 드리프트 위험만
23
23
  * 남기고 얻는 게 없었다(실측 차이 없음 — 헤더 하단 수치).
24
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
+ *
25
44
  * ── 계약 ─────────────────────────────────────────────────────────────────────
26
45
  * 순수 함수다(모델을 변형하지 않고 표시용 파생값만 만든다). 값 시맨틱은 종전 `EntityNode`의 세 함수
27
46
  * (`effectiveAttr`·`embedCols`·`typeCell`의 collectionType)와 **동일**해야 한다 — 이 모듈은 성능 리팩터이고
28
- * 표시 결과를 바꾸지 않는다. 해소가 불필요한 속성은 **맵에 넣지 않는다**(호출자가 원본을 쓴다)
29
- * 인덱스 미주입(read-only 임베드)이면 종전 `!editor` 폴백과 같은 원형 표시가 된다.
47
+ * 표시 결과를 바꾸지 않는다(`redundantSlots`는 뒤에 얹힌 **표시 힌트**이고, 소비는 뷰가 결정한다).
48
+ * 해소가 불필요한 속성은 **맵에 넣지 않는다**(호출자가 원본을 쓴다) ⇒ 인덱스 미주입(read-only 임베드)이면
49
+ * 종전 `!editor` 폴백과 같은 원형 표시가 된다.
50
+ *
51
+ * 판정은 **엔티티 로컬**이다(다른 엔티티를 읽지 않는다) — 위 「참조 안정화」가 좁혀 둔 무효화 범위를
52
+ * 넓히지 않기 위해서다.
30
53
  */
31
54
  export interface EntityColumnResolution {
32
55
  /** attr modelId → FK 상속 해소된 표시용 속성. 해소가 일어난 속성만 포함. */
@@ -35,6 +58,12 @@ export interface EntityColumnResolution {
35
58
  embedCols: ReadonlyMap<ModelId, DbColumn[]>;
36
59
  /** attr modelId → 컬렉션 임베드 래핑 타입. 단일 임베드(undefined)는 포함하지 않는다. */
37
60
  collectionTypes: ReadonlyMap<ModelId, 'LIST' | 'SET'>;
61
+ /**
62
+ * attr modelId → **반복 서브컬럼** 슬롯 인덱스. 같은 `(임베더블 타입, 슬롯 위치)` 자리의 실효 물리명이
63
+ * 그 엔티티 안에서 **전부 같을 때**(그리고 그런 자리가 2개 이상일 때) 그 슬롯들을 담는다 — 아래 「반복
64
+ * 서브컬럼」 참조. 반복이 없는 속성은 포함하지 않는다.
65
+ */
66
+ redundantSlots: ReadonlyMap<ModelId, ReadonlySet<number>>;
38
67
  }
39
68
  /** 엔티티 modelId → 그 엔티티 행들의 해소 결과. */
40
69
  export type ColumnResolutionIndex = ReadonlyMap<ModelId, EntityColumnResolution>;
@@ -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.48",
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
  }