@nine-lab/nine-mu 0.1.290 → 0.1.291

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nine-lab/nine-mu",
3
- "version": "0.1.290",
3
+ "version": "0.1.291",
4
4
  "description": "AI-Driven Full-Stack Code Fabrication Engine",
5
5
  "type": "module",
6
6
  "main": "./dist/nine-mu.umd.js",
@@ -5,7 +5,7 @@ import '@nine-lab/nine-util';
5
5
  export class NineDiffPopup extends HTMLElement {
6
6
  #dialog = null;
7
7
  #tabContainer = null;
8
- #fileList = []; // 최종 일괄 저장을 위한 데이터 버퍼
8
+ #fileList = []; // 최종 [모두 저장]을 위한 차분 명세 데이터 버퍼
9
9
  #host;
10
10
 
11
11
  constructor() {
@@ -19,8 +19,7 @@ export class NineDiffPopup extends HTMLElement {
19
19
  }
20
20
 
21
21
  /**
22
- * 💡 [기존 방식 복구] 스타일 전량 제거하고,
23
- * 기존 소스처럼 nine-tab 내부에 nine-tab-page 2개를 정적으로 미리 박아 놓습니다.
22
+ * 💡 페이지 외곽 틀은 오리지널 정적 구조로 안전하게 확보 (내부 에디터 슬롯은 비워둠)
24
23
  */
25
24
  #renderScaffolding() {
26
25
  const customImport = this.getAttribute("css-path") ? `@import "${this.getAttribute("css-path")}";` : "";
@@ -34,12 +33,10 @@ export class NineDiffPopup extends HTMLElement {
34
33
 
35
34
  <nine-dialog>
36
35
  <nine-tab theme="theme-3">
37
- <nine-tab-page caption="MYBATIS">
38
- <nine-diff class="MyBatis"></nine-diff>
39
- </nine-tab-page>
40
- <nine-tab-page caption="JAVASCRIPT">
41
- <nine-diff class="JavaScript"></nine-diff>
42
- </nine-tab-page>
36
+ <nine-tab-page caption="MYBATIS" id="layer_MyBatis"></nine-tab-page>
37
+ <nine-tab-page caption="SERVICE" id="layer_Service"></nine-tab-page>
38
+ <nine-tab-page caption="CONTROLLER" id="layer_Controller"></nine-tab-page>
39
+ <nine-tab-page caption="JAVASCRIPT" id="layer_JavaScript"></nine-tab-page>
43
40
  </nine-tab>
44
41
 
45
42
  <div class="footer">
@@ -62,8 +59,7 @@ export class NineDiffPopup extends HTMLElement {
62
59
  }
63
60
 
64
61
  /**
65
- * 💡 [기존 정적 매핑 방식]
66
- * 동적 생성 없이, 이미 조립되어 들어간 nine-tab 내부의 에디터를 정밀 타격하여 데이터만 꽂습니다.
62
+ * 💡 [ 고정 + 에디터 동적 인스턴싱 엔진]
67
63
  */
68
64
  async data(fileList) {
69
65
  if (!Array.isArray(fileList) || fileList.length === 0) return this;
@@ -77,40 +73,59 @@ export class NineDiffPopup extends HTMLElement {
77
73
  return 'javascript';
78
74
  };
79
75
 
80
- // 💡 중요: nine-tab #renderTabs() #init()이 끝난
81
- // 섀도우 돔 내부(.tab-pages)로 이사 간 에디터 인스턴스들을 정확하게 추적합니다.
76
+ // 1. nine-tab 컴포넌트의 오리지널 정적 파싱(#renderTabs) 연산이 완료될 때까지 미세한 마진 확보
82
77
  setTimeout(() => {
83
- fileList.forEach((file) => {
84
- const { layer, full_path, asis_source, source } = file;
78
+ const activeLayers = fileList.map(f => f.layer);
85
79
 
86
- // 🎯 렌더링이 완료된 실제 단말 장치는 nine-tab의 shadowRoot 안에 박혀 있습니다.
87
- const diff = this.#tabContainer.shadowRoot.querySelector(`nine-diff.${layer}`);
80
+ // 컴포넌트 내부 섀도우 돔으로 이사 간 실제 페이지 버튼과 컨텐츠 컨테이너 영역 확보
81
+ const tabButtons = this.#tabContainer.shadowRoot.querySelectorAll('.tab-button');
88
82
 
89
- if (diff) {
90
- const lang = detectLanguage(full_path);
83
+ // 4대 고정 레이어 명세 정의
84
+ const targetLayers = ["MyBatis", "Service", "Controller", "JavaScript"];
91
85
 
92
- // 탭 버튼의 상단 텍스트(캡션) 실제 파일명에 맞춰 동기화 시켜줍니다.
93
- const fileName = full_path.split('/').pop() || "Unknown";
94
- const tabButtons = this.#tabContainer.shadowRoot.querySelectorAll('.tab-button');
86
+ targetLayers.forEach((layerName, index) => {
87
+ const currentBtn = tabButtons[index];
88
+ // nine-tab 내부 섀도우 돔에 조립되어 대기 중인 실제 페이지 몸체 본문 div
89
+ const pageBody = this.#tabContainer.shadowRoot.getElementById(`content${index}`);
95
90
 
96
- tabButtons.forEach(btn => {
97
- if (btn.textContent.trim() === layer.toUpperCase()) {
98
- btn.textContent = `${layer.toUpperCase()} (${fileName})`;
99
- }
100
- });
91
+ if (!pageBody) return;
101
92
 
102
- // 날것의 소스 데이터 바인딩 초기화 실행
103
- diff.initialize(asis_source || "", source || "", lang);
93
+ // 이번 백엔드 완료 시그널에 해당 레이어 수정 명세가 포함되어 있다면?
94
+ if (activeLayers.includes(layerName)) {
95
+ const fileData = fileList.find(f => f.layer === layerName);
96
+ const fileName = fileData.full_path.split('/').pop() || "Unknown";
97
+
98
+ // A. 상단 탭 버튼 텍스트를 실제 파일명으로 동적 업데이트 및 노출
99
+ if (currentBtn) {
100
+ currentBtn.textContent = `${layerName.toUpperCase()} (${fileName})`;
101
+ currentBtn.style.display = "unset";
102
+ }
103
+
104
+ // B. 🔥 [핵심 수정]: 내부 에디터 슬롯만 런타임에 싱싱하게 완전히 새로 구워서 주입 (지연 차단)
105
+ pageBody.innerHTML = `<nine-diff class="${layerName}"></nine-diff>`;
106
+
107
+ // C. 새로 태어난 동적 에디터 단말 장치 즉시 인터페이스 초기화
108
+ const freshDiff = pageBody.querySelector(`nine-diff.${layerName}`);
109
+ if (freshDiff) {
110
+ const lang = detectLanguage(fileData.full_path);
111
+ freshDiff.initialize(fileData.asis_source || "", fileData.source || "", lang);
112
+ }
104
113
  } else {
105
- trace.error(`❌ 에디터 인스턴스를 찾을 없습니다: nine-diff.${layer}`);
114
+ // 이번 태스크에서 수정되지 않은 제외 영역은 상단 버튼을 hide 처리하여 깔끔하게 마스킹
115
+ if (currentBtn) {
116
+ currentBtn.style.display = "none";
117
+ currentBtn.classList.remove("active");
118
+ }
119
+ pageBody.innerHTML = ""; // 컨텐츠 본문 초기화
106
120
  }
107
121
  });
108
122
 
109
- // 데이터 세팅 완료 nine-tab 초기 포커싱 가동
123
+ // 2. 동적 에디터 갱신 및 마스킹 완료 후, 번째 활성화(Visible)된 탭으로 자동 클릭 이동
110
124
  if (this.#tabContainer && typeof this.#tabContainer.initialize === 'function') {
111
125
  this.#tabContainer.initialize();
112
126
  }
113
- }, 100);
127
+
128
+ }, 120);
114
129
 
115
130
  return this;
116
131
  }
@@ -124,7 +139,7 @@ export class NineDiffPopup extends HTMLElement {
124
139
  for (const file of this.#fileList) {
125
140
  const { layer, full_path, asis_source } = file;
126
141
 
127
- // 저장 시점에도 nine-tab shadowRoot를 관통하여 데이터를 스캔합니다.
142
+ // nine-tab 내부 섀도우 영역 안에서 동적 가동 중인 에디터 컨텐츠 타겟팅 캡처
128
143
  const diff = this.#tabContainer.shadowRoot.querySelector(`nine-diff.${layer}`);
129
144
  const currentContent = diff ? diff.getContents() : asis_source;
130
145