@nine-lab/nine-mu 0.1.381 โ†’ 0.1.383

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.381",
3
+ "version": "0.1.383",
4
4
  "description": "AI-Driven Full-Stack Code Fabrication Engine",
5
5
  "type": "module",
6
6
  "main": "./dist/nine-mu.umd.js",
@@ -1,4 +1,4 @@
1
- import React, { createContext, useState, useContext, lazy, Suspense } from 'react';
1
+ import React, { createContext, useEffect, useState, useContext, lazy, Suspense } from 'react';
2
2
  import { Route, Routes } from 'react-router-dom';
3
3
 
4
4
  // ==========================================
@@ -208,29 +208,47 @@ class NineExceptionHook extends React.Component {
208
208
  export function NineHook({ menuUrl, views, error404, onCatch, fallback, styles, containerStyle }) {
209
209
  const [menuData, setMenuData] = useState([]);
210
210
 
211
- // ๐ŸŽฏ AI๊ฐ€ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๋ฉด ๋Ÿฐํƒ€์ž„์— ์‹ค์‹œ๊ฐ„ ๋ฐ˜์˜๋˜๋„๋ก ๋™์  fetch ์ฒ˜๋ฆฌ
212
- useEffect(() => {
211
+ // ๐ŸŽฏ 1. ๋Ÿฐํƒ€์ž„ ๋™์  fetch ํ•จ์ˆ˜ ๋ถ„๋ฆฌ
212
+ const fetchRoutes = async () => {
213
213
  if (!menuUrl) return;
214
+ try {
215
+ // ํƒ€์ž„์Šคํƒฌํ”„(?t=...)๋ฅผ ์ฃผ์–ด ๋ธŒ๋ผ์šฐ์ € ์บ์‹œ๋ฅผ ๋ฌด์กฐ๊ฑด ํŒŒ๊ดดํ•˜๊ณ  ํ•˜๋“œ๋””์Šคํฌ์˜ ๋‚ ๊ฒƒ ํŒŒ์ผ ๋‚ด์šฉ์„ ๊ฐ€์ ธ์˜ด
216
+ const response = await fetch(`${menuUrl}?t=${Date.now()}`);
217
+ if (response.ok) {
218
+ const data = await response.json();
214
219
 
215
- const fetchRoutes = async () => {
216
- try {
217
- // ์บ์‹œ ๋ฒ„์ŠคํŒ…(?t=...)์„ ์ถ”๊ฐ€ํ•˜๋ฉด AI๊ฐ€ ์ˆ˜์ •ํ–ˆ์„ ๋•Œ ๋ธŒ๋ผ์šฐ์ € ์บ์‹œ๋ฅผ ํƒ€์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค.
218
- const response = await fetch(`${menuUrl}?t=${Date.now()}`);
219
- if (response.ok) {
220
- const data = await response.json();
221
- setMenuData(data);
222
- }
223
- } catch (e) {
224
- console.error("[Nine-Library] ๋Ÿฐํƒ€์ž„ ๋ฉ”๋‰ด ๋™๊ธฐํ™” ์‹คํŒจ:", e);
220
+ // ๐Ÿ’ก ๊ธฐ์กด ๋ฐ์ดํ„ฐ์™€ ์ƒˆ๋กœ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค๋ฅผ ๋•Œ๋งŒ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ๋ฌดํ•œ ๋ฃจํ”„ ๋ฐฉ์ง€
221
+ setMenuData((prev) => {
222
+ if (JSON.stringify(prev) === JSON.stringify(data)) return prev;
223
+ console.log("๐Ÿ”ฅ [Nine-Library] AI์— ์˜ํ•œ routes.json ๋ณ€๊ฒฝ ๊ฐ์ง€ -> ๋ฉ”๋‰ด ๋ฐ ๋ผ์šฐํ„ฐ ์‹ค์‹œ๊ฐ„ ๋™๊ธฐํ™” ์™„๋ฃŒ");
224
+ return data;
225
+ });
225
226
  }
226
- };
227
+ } catch (e) {
228
+ console.error("[Nine-Library] ๋Ÿฐํƒ€์ž„ ๋ฉ”๋‰ด ๋™๊ธฐํ™” ์‹คํŒจ:", e);
229
+ }
230
+ };
227
231
 
232
+ // ๐ŸŽฏ 2. ์‹ค์‹œ๊ฐ„ ๋ฐ˜์‘ํ˜• ํŠธ๋ฆฌ๊ฑฐ ์—”์ง„ ์ฒด์ธ
233
+ useEffect(() => {
234
+ // ์ตœ์ดˆ ๋กœ๋“œ ์‹œ ์‹คํ–‰
228
235
  fetchRoutes();
229
236
 
230
- // ํ•„์š”์‹œ: ์ฃผ์†Œ์ฐฝ popstate๋‚˜ ํŠน์ • ๋ณต๊ตฌ ์ด๋ฒคํŠธ ์‹œ์ ์— ์žฌํ˜ธ์ถœํ•˜๋„๋ก ํŠธ๋ฆฌ๊ฑฐ ์—ฐ๋™ ๊ฐ€๋Šฅ
231
- }, [menuUrl]);
237
+ // ๐Ÿ’ก ํŠธ๋ฆฌ๊ฑฐ A: AI๊ฐ€ ์ฝ”๋“œ๋ฅผ ๊ณ ์น˜๊ณ  ์ฃผ์†Œ๋ฅผ ๋ฐ”๊ฟจ์„ ๋•Œ(popstate/click) ์ฆ‰์‹œ ๋™๊ธฐํ™”
238
+ window.addEventListener('popstate', fetchRoutes);
239
+ document.addEventListener('click', fetchRoutes, true);
240
+
241
+ // ๐Ÿ’ก ํŠธ๋ฆฌ๊ฑฐ B: ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ€๋งŒํžˆ ์žˆ์–ด๋„ AI๊ฐ€ ๋ฐฑ์—”๋“œ์—์„œ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๋ฉด 3์ดˆ๋งˆ๋‹ค ์ž๋™ ์ฒดํฌ (ํด๋ง)
242
+ const intervalId = setInterval(fetchRoutes, 3000);
243
+
244
+ return () => {
245
+ window.removeEventListener('popstate', fetchRoutes);
246
+ document.removeEventListener('click', fetchRoutes, true);
247
+ clearInterval(intervalId);
248
+ };
249
+ }, [menuUrl]); // menuUrl์ด ์ฃผ์ž…๋˜๋ฉด ์ด๋ฒคํŠธ์™€ ํƒ€์ด๋จธ๊ฐ€ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ”์ธ๋”ฉ๋ฉ๋‹ˆ๋‹ค.
232
250
 
233
- // ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์—๋Š” ๊ฐ€๋ณ๊ฒŒ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , ์™„๋ฃŒ๋˜๋ฉด ๋ผ์šฐํ„ฐ ๊ตฌ์ถ•
251
+ // ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋˜๊ณ  ์ •์ œ๋˜๋ฉด ๋™์  ๋ผ์šฐํŠธ ๋งคํŠธ๋ฆญ์Šค ์ƒ์„ฑ
234
252
  const dynamicRoutes = createDynamicRoutes(menuData, views, error404);
235
253
 
236
254
  return React.createElement(