@jogak/core 0.1.0-alpha.7.1 → 0.1.0-alpha.9

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.
@@ -1,211 +1,285 @@
1
- import { resolve as y, join as P, dirname as W } from "node:path";
2
- import { existsSync as T, readFileSync as X } from "node:fs";
3
- import { stat as O, rm as Y, readdir as q, readFile as L } from "node:fs/promises";
4
- import { c as R } from "../extractor-client-CReBed7x.js";
5
- const H = [
1
+ import { resolve as _, join as B, dirname as tt } from "node:path";
2
+ import { existsSync as S, readFileSync as et } from "node:fs";
3
+ import { stat as L, rm as rt, readdir as ot, readFile as U } from "node:fs/promises";
4
+ import { r as W } from "../detect-global-css-CIVMmgzy.js";
5
+ import { c as $ } from "../extractor-client-CReBed7x.js";
6
+ const nt = [
6
7
  "@jogak/core",
7
8
  "@jogak/react",
8
9
  "@jogak/web-components",
9
10
  "@jogak/next"
10
11
  ];
11
- async function F(t) {
12
+ async function K(t) {
12
13
  try {
13
- const a = await O(t);
14
+ const a = await L(t);
14
15
  if (!a.isDirectory())
15
16
  return a.mtimeMs;
16
17
  } catch {
17
18
  return 0;
18
19
  }
19
- let o = 0, s;
20
+ let r = 0, o;
20
21
  try {
21
- s = await q(t);
22
+ o = await ot(t);
22
23
  } catch {
23
24
  return 0;
24
25
  }
25
- for (const a of s) {
26
- const g = P(t, a);
26
+ for (const a of o) {
27
+ const c = B(t, a);
27
28
  try {
28
- const c = await O(g);
29
- if (c.isDirectory()) {
30
- const p = await F(g);
31
- p > o && (o = p);
32
- } else c.mtimeMs > o && (o = c.mtimeMs);
29
+ const l = await L(c);
30
+ if (l.isDirectory()) {
31
+ const g = await K(c);
32
+ g > r && (r = g);
33
+ } else l.mtimeMs > r && (r = l.mtimeMs);
33
34
  } catch {
34
35
  continue;
35
36
  }
36
37
  }
37
- return o;
38
+ return r;
38
39
  }
39
- async function z(t) {
40
- const o = y(t.root, "node_modules/.vite/deps");
41
- if (!T(o))
40
+ async function at(t) {
41
+ const r = _(t.root, "node_modules/.vite/deps");
42
+ if (!S(r))
42
43
  return { purged: !1 };
43
- const s = P(o, "_metadata.json");
44
- if (!T(s))
44
+ const o = B(r, "_metadata.json");
45
+ if (!S(o))
45
46
  return { purged: !1 };
46
47
  let a;
47
48
  try {
48
- a = (await O(s)).mtimeMs;
49
- } catch (c) {
49
+ a = (await L(o)).mtimeMs;
50
+ } catch (l) {
50
51
  return t.logger.warn(
51
- `[jogak] cache validation: failed to stat _metadata.json (${c.message})`
52
+ `[jogak] cache validation: failed to stat _metadata.json (${l.message})`
52
53
  ), { purged: !1 };
53
54
  }
54
- const g = t.packages ?? H;
55
- for (const c of g) {
56
- const p = y(t.root, "node_modules", c, "dist");
57
- if (!T(p)) continue;
58
- let h;
55
+ const c = t.packages ?? nt;
56
+ for (const l of c) {
57
+ const g = _(t.root, "node_modules", l, "dist");
58
+ if (!S(g)) continue;
59
+ let y;
59
60
  try {
60
- h = await F(p);
61
+ y = await K(g);
61
62
  } catch (w) {
62
63
  t.logger.warn(
63
- `[jogak] cache validation: failed to walk ${c}/dist (${w.message})`
64
+ `[jogak] cache validation: failed to walk ${l}/dist (${w.message})`
64
65
  );
65
66
  continue;
66
67
  }
67
- if (h > a + 1e3)
68
+ if (y > a + 1e3)
68
69
  try {
69
- return await Y(o, { recursive: !0, force: !0 }), t.logger.info(
70
- `[jogak] vite deps cache invalidated (stale): ${c} dist newer than cache`
71
- ), { purged: !0, reason: c };
70
+ return await rt(r, { recursive: !0, force: !0 }), t.logger.info(
71
+ `[jogak] vite deps cache invalidated (stale): ${l} dist newer than cache`
72
+ ), { purged: !0, reason: l };
72
73
  } catch (w) {
73
74
  return t.logger.warn(
74
- `[jogak] cache validation: failed to purge ${o} (${w.message})`
75
+ `[jogak] cache validation: failed to purge ${r} (${w.message})`
75
76
  ), { purged: !1 };
76
77
  }
77
78
  }
78
79
  return { purged: !1 };
79
80
  }
80
- const Q = [
81
- "src/index.css",
82
- "src/main.css",
83
- "src/styles.css",
84
- "src/styles/globals.css",
85
- "src/styles/index.css",
86
- "src/app/globals.css",
87
- "src/global.css",
88
- "src/app.css"
89
- ];
90
- function Z(t) {
91
- for (const o of Q) {
92
- const s = y(t, o);
93
- if (T(s)) return [s];
94
- }
95
- return [];
96
- }
97
- function tt(t, o) {
98
- if (t === void 0 || t === !1) return [];
99
- if (t === !0) return Z(o);
100
- if (typeof t == "string")
101
- return t.length > 0 ? [y(o, t)] : [];
102
- const s = [];
103
- for (const a of t)
104
- typeof a == "string" && a.length > 0 && s.push(y(o, a));
105
- return s;
106
- }
107
- function et(t) {
81
+ function it(t) {
108
82
  return t.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
109
83
  }
110
- function ot(t) {
111
- if (T(t))
84
+ function st(t) {
85
+ if (S(t))
112
86
  try {
113
- const o = X(t, "utf8");
114
- return JSON.parse(et(o));
87
+ const r = et(t, "utf8");
88
+ return JSON.parse(it(r));
115
89
  } catch {
116
90
  return;
117
91
  }
118
92
  }
119
- function rt(t, o, s) {
120
- if (!t.endsWith("/*") || !o.endsWith("/*")) return;
121
- const a = t.slice(0, -2), g = y(s, o.slice(0, -2));
122
- return [a, g];
93
+ function ct(t, r, o) {
94
+ if (!t.endsWith("/*") || !r.endsWith("/*")) return;
95
+ const a = t.slice(0, -2), c = _(o, r.slice(0, -2));
96
+ return [a, c];
123
97
  }
124
- function st(t, o) {
125
- var g, c;
126
- const s = {}, a = /* @__PURE__ */ new Set([
98
+ function lt(t, r) {
99
+ var c, l;
100
+ const o = {}, a = /* @__PURE__ */ new Set([
127
101
  t,
128
- y(o, "tsconfig.app.json")
102
+ _(r, "tsconfig.app.json")
129
103
  ]);
130
- for (const p of a) {
131
- const h = ot(p);
132
- if (h === void 0) continue;
133
- const w = (g = h.compilerOptions) == null ? void 0 : g.paths;
104
+ for (const g of a) {
105
+ const y = st(g);
106
+ if (y === void 0) continue;
107
+ const w = (c = y.compilerOptions) == null ? void 0 : c.paths;
134
108
  if (w === void 0) continue;
135
- const u = ((c = h.compilerOptions) == null ? void 0 : c.baseUrl) ?? ".", m = y(W(p), u);
136
- for (const [_, k] of Object.entries(w)) {
137
- const S = k[0];
138
- if (S === void 0) continue;
139
- const b = rt(_, S, m);
140
- if (b === void 0) continue;
141
- const [A, e] = b;
142
- s[A] === void 0 && (s[A] = e);
109
+ const R = ((l = y.compilerOptions) == null ? void 0 : l.baseUrl) ?? ".", C = _(tt(g), R);
110
+ for (const [T, d] of Object.entries(w)) {
111
+ const f = d[0];
112
+ if (f === void 0) continue;
113
+ const j = ct(T, f, C);
114
+ if (j === void 0) continue;
115
+ const [k, I] = j;
116
+ o[k] === void 0 && (o[k] = I);
143
117
  }
144
118
  }
145
- return s;
119
+ return o;
146
120
  }
147
- const G = "virtual:jogak", E = "\0" + G, U = "virtual:jogak/entry/", M = "\0" + U, V = "virtual:jogak/global-css", $ = "\0" + V;
148
- function at(t) {
121
+ const H = "virtual:jogak", x = "\0" + H, Y = "virtual:jogak/entry/", P = "\0" + Y, X = "virtual:jogak/global-css", D = "\0" + X, M = "virtual:jogak/preview-entry", F = "\0" + M, z = "virtual:jogak/preview-global-css", G = "\0" + z;
122
+ function ut(t) {
149
123
  return Buffer.from(t, "utf8").toString("base64url");
150
124
  }
151
- function nt(t) {
125
+ function dt(t) {
152
126
  return Buffer.from(t, "base64url").toString("utf8");
153
127
  }
154
- function D(t) {
128
+ const gt = "/__jogak_preview__/index.html";
129
+ function kt(t) {
130
+ return {
131
+ name: "vite-plugin-jogak-preview-frame",
132
+ enforce: "pre",
133
+ configureServer(r) {
134
+ r.middlewares.use((o, a, c) => {
135
+ if (o.url === void 0 || o.url.split("?")[0] !== gt || o.method !== "GET") return c();
136
+ const g = ft();
137
+ r.transformIndexHtml(o.url, g).then((y) => {
138
+ a.statusCode = 200, a.setHeader("Content-Type", "text/html; charset=utf-8"), a.end(y);
139
+ }).catch(c);
140
+ });
141
+ },
142
+ resolveId(r) {
143
+ if (r === M) return F;
144
+ if (r === z) return G;
145
+ },
146
+ load(r) {
147
+ if (r === G) {
148
+ const o = W(t.globalCss, t.userRoot);
149
+ return o.length === 0 ? `// [jogak] preview-global-css: no candidates
150
+ export {}
151
+ ` : o.map((a) => `import ${JSON.stringify(a)}`).join(`
152
+ `) + `
153
+ export {}
154
+ `;
155
+ }
156
+ if (r === F)
157
+ return mt;
158
+ }
159
+ };
160
+ }
161
+ function ft() {
162
+ return `<!doctype html>
163
+ <html lang="en">
164
+ <head>
165
+ <meta charset="UTF-8" />
166
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
167
+ <title>jogak preview</title>
168
+ <style>
169
+ html, body { margin: 0; padding: 0; }
170
+ #jogak-preview-root { display: block; }
171
+ </style>
172
+ </head>
173
+ <body>
174
+ <div id="jogak-preview-root"></div>
175
+ <script type="module" src="/@id/${M}"><\/script>
176
+ </body>
177
+ </html>
178
+ `;
179
+ }
180
+ const mt = `
181
+ import { reactAdapter } from '@jogak/react'
182
+ import { defaultRegistry } from '@jogak/core'
183
+ import 'virtual:jogak'
184
+ import 'virtual:jogak/preview-global-css'
185
+
186
+ const rootEl = document.getElementById('jogak-preview-root')
187
+ if (rootEl === null) throw new Error('[jogak] #jogak-preview-root not found')
188
+
189
+ let currentContainer = null
190
+ let currentArgs = {}
191
+ let currentEntryId = null
192
+
193
+ async function renderEntry(entryId, args) {
194
+ currentEntryId = entryId
195
+ currentArgs = args
196
+ const entry = await defaultRegistry.requestEntry(entryId)
197
+ if (currentContainer === null) {
198
+ currentContainer = document.createElement('div')
199
+ rootEl.replaceChildren(currentContainer)
200
+ }
201
+ reactAdapter.render(entry, args, currentContainer)
202
+ }
203
+
204
+ function unmount() {
205
+ if (currentContainer !== null) {
206
+ reactAdapter.unmount(currentContainer)
207
+ currentContainer = null
208
+ currentEntryId = null
209
+ }
210
+ }
211
+
212
+ window.addEventListener('message', (event) => {
213
+ const data = event.data
214
+ if (data == null || typeof data !== 'object') return
215
+ if (data.type === 'jogak:setProps') {
216
+ void renderEntry(data.entryId, data.args ?? {}).then(() => {
217
+ window.parent.postMessage({ type: 'jogak:rendered', entryId: data.entryId }, '*')
218
+ }).catch((err) => {
219
+ window.parent.postMessage({ type: 'jogak:error', message: String(err?.message ?? err) }, '*')
220
+ })
221
+ } else if (data.type === 'jogak:unmount') {
222
+ unmount()
223
+ }
224
+ })
225
+
226
+ window.parent.postMessage({ type: 'jogak:ready' }, '*')
227
+ `;
228
+ function J(t) {
155
229
  return {
156
230
  title: t.title,
157
231
  jogakNamesKey: [...t.jogakNames].sort().join("|")
158
232
  };
159
233
  }
160
- function it(t, o) {
161
- return t !== void 0 && t.title === o.title && t.jogakNamesKey === o.jogakNamesKey;
234
+ function pt(t, r) {
235
+ return t !== void 0 && t.title === r.title && t.jogakNamesKey === r.jogakNamesKey;
162
236
  }
163
- function gt(t = {}) {
237
+ function Et(t = {}) {
164
238
  const {
165
- patterns: o = ["src/**/*.jogak.ts", "src/**/*.jogak.tsx"],
166
- codeTheme: s = "vsDark"
167
- } = t, a = t.cwd, g = t.tsConfigFilePath, c = t.disableCacheValidation === !0, p = t.resolveAlias, h = t.globalCss, w = t.previewIsolation ?? "shadow";
168
- let u, m, _;
169
- const k = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map();
170
- async function A() {
171
- const { glob: e } = await import("glob"), d = _ ?? process.cwd(), r = (await e(o, { cwd: d, absolute: !0 })).sort(), l = [];
172
- k.clear(), S.clear();
173
- for (const n of r) {
239
+ patterns: r = ["src/**/*.jogak.ts", "src/**/*.jogak.tsx"],
240
+ codeTheme: o = "vsDark"
241
+ } = t, a = t.cwd, c = t.tsConfigFilePath, l = t.disableCacheValidation === !0, g = t.resolveAlias, y = t.globalCss, w = t.previewIsolation ?? "iframe", R = t.previewFrame === !0, C = t.userPreviewUrl ?? t.userViteUrl ?? "", T = t.previewEntryPath ?? "/__jogak_preview__/index.html";
242
+ let d, f, j;
243
+ const k = /* @__PURE__ */ new Map(), I = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map();
244
+ async function N() {
245
+ const { glob: e } = await import("glob"), m = j ?? process.cwd(), n = (await e(r, { cwd: m, absolute: !0 })).sort(), u = [];
246
+ k.clear(), I.clear();
247
+ for (const i of n) {
174
248
  let v = "";
175
249
  try {
176
- v = await L(n, "utf8");
250
+ v = await U(i, "utf8");
177
251
  } catch {
178
252
  continue;
179
253
  }
180
- let j = {}, i = null;
181
- if (m !== void 0) {
254
+ let h = {}, s = null;
255
+ if (f !== void 0) {
182
256
  try {
183
- j = await m.extract(n);
257
+ h = await f.extract(i);
184
258
  } catch {
185
- j = {};
259
+ h = {};
186
260
  }
187
261
  try {
188
- i = await m.extractMeta(n);
262
+ s = await f.extractMeta(i);
189
263
  } catch {
190
- i = null;
264
+ s = null;
191
265
  }
192
266
  }
193
- if (i === null) continue;
194
- const f = i.title;
195
- k.set(f, n), S.set(n, f);
196
- const C = {
197
- id: f,
198
- title: i.title,
199
- jogakNames: i.jogakNames,
200
- autoArgTypes: j,
201
- userArgTypes: i.userArgTypes,
267
+ if (s === null) continue;
268
+ const p = s.title;
269
+ k.set(p, i), I.set(i, p);
270
+ const E = {
271
+ id: p,
272
+ title: s.title,
273
+ jogakNames: s.jogakNames,
274
+ autoArgTypes: h,
275
+ userArgTypes: s.userArgTypes,
202
276
  source: v,
203
- filePath: n,
204
- metaExtras: i.metaExtras
277
+ filePath: i,
278
+ metaExtras: s.metaExtras
205
279
  };
206
- b.set(n, D(C)), l.push({ id: f, filePath: n, meta: C });
280
+ b.set(i, J(E)), u.push({ id: p, filePath: i, meta: E });
207
281
  }
208
- return l;
282
+ return u;
209
283
  }
210
284
  return {
211
285
  name: "vite-plugin-jogak",
@@ -220,77 +294,80 @@ function gt(t = {}) {
220
294
  * 우선순위: `options.resolveAlias` (명시) > tsconfig 자동 추출.
221
295
  */
222
296
  config() {
223
- const e = a ?? process.cwd(), d = g ?? y(e, "tsconfig.json"), r = st(d, e), l = {};
224
- if (p !== void 0)
225
- for (const [v, j] of Object.entries(p))
226
- l[v] = y(e, j);
227
- const n = { ...r, ...l };
228
- if (Object.keys(n).length !== 0)
297
+ const e = a ?? process.cwd(), m = c ?? _(e, "tsconfig.json"), n = lt(m, e), u = {};
298
+ if (g !== void 0)
299
+ for (const [v, h] of Object.entries(g))
300
+ u[v] = _(e, h);
301
+ const i = { ...n, ...u };
302
+ if (Object.keys(i).length !== 0)
229
303
  return {
230
- resolve: { alias: n }
304
+ resolve: { alias: i }
231
305
  };
232
306
  },
233
307
  async configResolved(e) {
234
- _ = a ?? e.root, e.command === "serve" && !c && await z({
308
+ j = a ?? e.root, e.command === "serve" && !l && await at({
235
309
  root: e.root,
236
310
  logger: {
237
- info: (r) => e.logger.info(r),
238
- warn: (r) => e.logger.warn(r)
311
+ info: (n) => e.logger.info(n),
312
+ warn: (n) => e.logger.warn(n)
239
313
  }
240
314
  });
241
- const d = g ?? y(_, "tsconfig.json");
242
- m = T(d) ? R({ tsConfigFilePath: d }) : R();
315
+ const m = c ?? _(j, "tsconfig.json");
316
+ f = S(m) ? $({ tsConfigFilePath: m }) : $();
243
317
  },
244
318
  configureServer(e) {
245
- u = e;
319
+ d = e;
246
320
  },
247
321
  buildEnd() {
248
- m == null || m.releaseCache();
322
+ f == null || f.releaseCache();
249
323
  },
250
324
  resolveId(e) {
251
- if (e === G)
252
- return E;
253
- if (e === V)
254
- return $;
255
- if (e.startsWith(U))
325
+ if (e === H)
326
+ return x;
327
+ if (e === X)
328
+ return D;
329
+ if (e.startsWith(Y))
256
330
  return "\0" + e;
257
331
  },
258
332
  async load(e) {
259
- if (e === $) {
260
- const d = _ ?? process.cwd(), r = tt(h, d);
261
- return r.length === 0 ? `// [jogak] globalCss not configured or no candidates found.
333
+ if (e === D) {
334
+ const m = j ?? process.cwd(), n = W(y, m);
335
+ return n.length === 0 ? `// [jogak] globalCss not configured or no candidates found.
262
336
  export {}
263
- ` : `${r.map((n) => `import ${JSON.stringify(n)}`).join(`
337
+ ` : `${n.map((i) => `import ${JSON.stringify(i)}`).join(`
264
338
  `)}
265
339
  export {}
266
340
  `;
267
341
  }
268
- if (e === E) {
269
- const r = (await A()).map((l) => l.meta);
342
+ if (e === x) {
343
+ const n = (await N()).map((i) => i.meta), u = R ? "" : `
344
+ export const _jogakCodeTheme = ${JSON.stringify(o)}
345
+ export const _jogakPreviewIsolation = ${JSON.stringify(w)}
346
+ export const _jogakUserPreviewUrl = ${JSON.stringify(C)}
347
+ export const _jogakPreviewEntryPath = ${JSON.stringify(T)}
348
+ export const _jogakUserViteUrl = ${JSON.stringify(C)}
349
+ export const _jogakMetas = _metas
350
+ `;
270
351
  return `import { defaultRegistry } from '@jogak/core'
271
352
 
272
353
  const _entryLoader = (slug) =>
273
354
  import(/* @vite-ignore */ '/@id/__x00__virtual:jogak/entry/' + slug)
274
355
  defaultRegistry.setEntryLoader((id) => {
275
- const slug = ${ct()}
356
+ const slug = ${yt()}
276
357
  return _entryLoader(slug(id))
277
358
  })
278
359
 
279
- const _metas = ${JSON.stringify(r)}
360
+ const _metas = ${JSON.stringify(n)}
280
361
 
281
362
  for (const m of _metas) defaultRegistry.registerMeta(m)
282
-
283
- export const _jogakCodeTheme = ${JSON.stringify(s)}
284
- export const _jogakPreviewIsolation = ${JSON.stringify(w)}
285
- export const _jogakMetas = _metas
286
- `;
363
+ ${u}`;
287
364
  }
288
- if (e.startsWith(M)) {
289
- const d = e.slice(M.length), r = nt(d);
290
- let l = k.get(r);
291
- return l === void 0 && (await A(), l = k.get(r)), l === void 0 ? `// [jogak] unknown entry id: ${JSON.stringify(r)}
365
+ if (e.startsWith(P)) {
366
+ const m = e.slice(P.length), n = dt(m);
367
+ let u = k.get(n);
368
+ return u === void 0 && (await N(), u = k.get(n)), u === void 0 ? `// [jogak] unknown entry id: ${JSON.stringify(n)}
292
369
  export {}
293
- ` : `import * as _user from ${JSON.stringify(l)}
370
+ ` : `import * as _user from ${JSON.stringify(u)}
294
371
  import { defaultRegistry } from '@jogak/core'
295
372
 
296
373
  const _meta = _user.default
@@ -299,7 +376,7 @@ delete _named.default
299
376
  const _jogaks = Object.values(_named).filter(
300
377
  (v) => v !== null && typeof v === 'object' && typeof v.name === 'string'
301
378
  )
302
- defaultRegistry.hydrateEntry(${JSON.stringify(r)}, _jogaks, _meta?.component)
379
+ defaultRegistry.hydrateEntry(${JSON.stringify(n)}, _jogaks, _meta?.component)
303
380
 
304
381
  if (import.meta.hot) {
305
382
  import.meta.hot.accept()
@@ -309,60 +386,60 @@ export {}
309
386
  `;
310
387
  }
311
388
  },
312
- async handleHotUpdate({ file: e, modules: d }) {
313
- const r = /\.jogak\.(tsx?|jsx?)$/.test(e), l = /\.(tsx?|jsx?)$/.test(e) && !r;
314
- if (!r && !l || u === void 0 || !r) return;
315
- const n = u.moduleGraph.getModuleById(
316
- E
317
- ), v = S.get(e), j = v !== void 0 ? M + at(v) : void 0, i = j !== void 0 ? u.moduleGraph.getModuleById(j) : void 0;
318
- let f = null, C = {}, I = "";
319
- if (m !== void 0) {
389
+ async handleHotUpdate({ file: e, modules: m }) {
390
+ const n = /\.jogak\.(tsx?|jsx?)$/.test(e), u = /\.(tsx?|jsx?)$/.test(e) && !n;
391
+ if (!n && !u || d === void 0 || !n) return;
392
+ const i = d.moduleGraph.getModuleById(
393
+ x
394
+ ), v = I.get(e), h = v !== void 0 ? P + ut(v) : void 0, s = h !== void 0 ? d.moduleGraph.getModuleById(h) : void 0;
395
+ let p = null, E = {}, A = "";
396
+ if (f !== void 0) {
320
397
  try {
321
- f = await m.extractMeta(e);
398
+ p = await f.extractMeta(e);
322
399
  } catch {
323
- f = null;
400
+ p = null;
324
401
  }
325
402
  try {
326
- C = await m.extract(e);
403
+ E = await f.extract(e);
327
404
  } catch {
328
- C = {};
405
+ E = {};
329
406
  }
330
407
  try {
331
- I = await L(e, "utf8");
408
+ A = await U(e, "utf8");
332
409
  } catch {
333
- I = "";
410
+ A = "";
334
411
  }
335
412
  }
336
- if (f === null) {
337
- n !== void 0 && u.moduleGraph.invalidateModule(n), i !== void 0 && u.moduleGraph.invalidateModule(i), u.ws.send({ type: "full-reload" });
413
+ if (p === null) {
414
+ i !== void 0 && d.moduleGraph.invalidateModule(i), s !== void 0 && d.moduleGraph.invalidateModule(s), d.ws.send({ type: "full-reload" });
338
415
  return;
339
416
  }
340
- const N = D(f), J = b.get(e), B = it(J, N);
341
- if (b.set(e, N), !B || v === void 0) {
342
- n !== void 0 && u.moduleGraph.invalidateModule(n), i !== void 0 && u.moduleGraph.invalidateModule(i), u.ws.send({ type: "full-reload" });
417
+ const V = J(p), Q = b.get(e), Z = pt(Q, V);
418
+ if (b.set(e, V), !Z || v === void 0) {
419
+ i !== void 0 && d.moduleGraph.invalidateModule(i), s !== void 0 && d.moduleGraph.invalidateModule(s), d.ws.send({ type: "full-reload" });
343
420
  return;
344
421
  }
345
- const K = {
422
+ const q = {
346
423
  id: v,
347
- title: f.title,
348
- jogakNames: f.jogakNames,
349
- autoArgTypes: C,
350
- userArgTypes: f.userArgTypes,
351
- source: I,
424
+ title: p.title,
425
+ jogakNames: p.jogakNames,
426
+ autoArgTypes: E,
427
+ userArgTypes: p.userArgTypes,
428
+ source: A,
352
429
  filePath: e,
353
- metaExtras: f.metaExtras
430
+ metaExtras: p.metaExtras
354
431
  };
355
- i !== void 0 && u.moduleGraph.invalidateModule(i), u.ws.send({
432
+ s !== void 0 && d.moduleGraph.invalidateModule(s), d.ws.send({
356
433
  type: "custom",
357
434
  event: "jogak:meta-update",
358
- data: { id: v, meta: K }
435
+ data: { id: v, meta: q }
359
436
  });
360
- const x = [...d];
361
- return i !== void 0 && !x.includes(i) && x.push(i), x;
437
+ const O = [...m];
438
+ return s !== void 0 && !O.includes(s) && O.push(s), O;
362
439
  }
363
440
  };
364
441
  }
365
- function ct() {
442
+ function yt() {
366
443
  return `(rawId) => {
367
444
  if (typeof Buffer !== 'undefined') return Buffer.from(rawId, 'utf8').toString('base64url')
368
445
  // 브라우저 폴백: btoa는 binary string 기준이라 UTF-8을 한번 인코딩해야 한다.
@@ -373,5 +450,6 @@ function ct() {
373
450
  }`;
374
451
  }
375
452
  export {
376
- gt as jogak
453
+ Et as jogak,
454
+ kt as jogakPreviewFramePlugin
377
455
  };
@@ -1,3 +1,4 @@
1
1
  import { Plugin } from 'vite';
2
2
  import { JogakPluginOptions } from '../types.js';
3
3
  export declare function jogak(options?: JogakPluginOptions): Plugin;
4
+ export { jogakPreviewFramePlugin, type JogakPreviewFramePluginOptions, } from './preview-frame-plugin.js';
@@ -0,0 +1,21 @@
1
+ import { Plugin } from 'vite';
2
+ import { JogakPluginOptions } from '../types.js';
3
+ /**
4
+ * 알파.8: 사용자 vite scope에서 preview-frame iframe entry를 emit하는 plugin.
5
+ *
6
+ * jogak CLI의 `spawnUserVite`가 사용자 vite.config.ts에 `mergeConfig`로 자동 inject
7
+ * — 사용자가 직접 등록할 필요 없음.
8
+ *
9
+ * 책임:
10
+ * 1. `/__jogak_preview__/index.html` middleware: jogak preview-entry를 로드하는 HTML 응답
11
+ * 2. `virtual:jogak/preview-entry` 가상 모듈: postMessage 리스너 + reactAdapter.render
12
+ * 3. `virtual:jogak/preview-global-css` 가상 모듈: 사용자 globalCss를 사용자 vite의
13
+ * `@tailwindcss/vite` 등 정상 css 파이프라인을 통해 컴파일
14
+ */
15
+ export interface JogakPreviewFramePluginOptions {
16
+ /** 사용자 프로젝트 root (cwd). globalCss 자동 탐지 base. */
17
+ readonly userRoot: string;
18
+ /** 사용자 globalCss (jogak.config.ts의 globalCss와 동일 의미). */
19
+ readonly globalCss?: JogakPluginOptions['globalCss'];
20
+ }
21
+ export declare function jogakPreviewFramePlugin(options: JogakPreviewFramePluginOptions): Plugin;