@jogak/core 0.1.0-alpha.7.1 → 0.1.0-alpha.8
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/config.d.ts +14 -1
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +73 -28
- package/dist/vite/index.js +82 -13
- package/dist/vite/index.mjs +287 -185
- package/dist/vite/plugin.d.ts +1 -0
- package/dist/vite/preview-frame-plugin.d.ts +21 -0
- package/dist/vite/virtual-ids.d.ts +14 -0
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JogakPluginOptions } from './types.js';
|
|
1
|
+
import { JogakPluginOptions, UserViteOptions } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* `jogak.config.{ts,mts,mjs,js,json}`의 default export 타입.
|
|
4
4
|
*
|
|
@@ -27,6 +27,19 @@ export interface JogakConfig extends JogakPluginOptions {
|
|
|
27
27
|
readonly minify?: boolean | 'esbuild' | 'terser';
|
|
28
28
|
/** 빌드 소스맵. 기본 false. CLI `--sourcemap`로 override. */
|
|
29
29
|
readonly sourcemap?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* 사용자 vite 인스턴스 spawn 옵션 (알파.8). 미지정 시 cwd의 `vite.config.{ts,mts,js,mjs,cjs}`를
|
|
32
|
+
* 자동 탐지해 별도 vite dev server를 띄워 iframe src로 사용한다.
|
|
33
|
+
*
|
|
34
|
+
* `previewIsolation: 'iframe'` (default)에서만 사용된다.
|
|
35
|
+
*
|
|
36
|
+
* @example 사용자 vite 명시 비활성화 (알파.7.1 동등 fallback)
|
|
37
|
+
* defineJogakConfig({ userVite: { disabled: true } })
|
|
38
|
+
*
|
|
39
|
+
* @example 사용자 vite 포트 명시
|
|
40
|
+
* defineJogakConfig({ userVite: { port: 5174 } })
|
|
41
|
+
*/
|
|
42
|
+
readonly userVite?: UserViteOptions;
|
|
30
43
|
}
|
|
31
44
|
/**
|
|
32
45
|
* `jogak.config.ts`에서 사용자가 호출하는 identity helper.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { ArgType, JogakMeta, Jogak, RegistryEntry, RegistryEntryMeta, CategoryTree, CategoryMetaTree, JogakAdapter, JogakPluginOptions, } from './types.js';
|
|
1
|
+
export type { ArgType, JogakMeta, Jogak, RegistryEntry, RegistryEntryMeta, CategoryTree, CategoryMetaTree, JogakAdapter, JogakPluginOptions, UserViteOptions, } from './types.js';
|
|
2
2
|
export { ComponentRegistry, defaultRegistry, UnknownEntryError } from './registry.js';
|
|
3
3
|
export { ActionChannel, defaultActionChannel, action, injectActions, type ActionLog, type ActionListener, } from './actions.js';
|
|
4
4
|
export { defineJogakConfig, type JogakConfig } from './config.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -209,38 +209,83 @@ export interface JogakPluginOptions {
|
|
|
209
209
|
*/
|
|
210
210
|
readonly globalCss?: boolean | string | readonly string[];
|
|
211
211
|
/**
|
|
212
|
-
* Preview 영역의 격리 모드 (알파.7 도입, 알파.
|
|
212
|
+
* Preview 영역의 격리 모드 (알파.7 도입, 알파.8에서 default `'iframe'`로 변경).
|
|
213
213
|
*
|
|
214
|
-
* 사용자
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
214
|
+
* 알파.8의 default `'iframe'`은 사용자 vite 인스턴스를 spawn하여 그 vite의 정상 client에
|
|
215
|
+
* iframe document를 마운트한다. 사용자 plugins(@tailwindcss/vite 등)이 그대로 작동하므로
|
|
216
|
+
* **사용자 컴포넌트가 사용자 디자인 시스템 그대로 보인다**. 동시에 outer document의
|
|
217
|
+
* jogak chrome은 iframe 외부라 사용자 css 영향 zero (양방향 격리).
|
|
218
218
|
*
|
|
219
219
|
* 모드:
|
|
220
|
-
* - `'
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* @default 'shadow'
|
|
235
|
-
*
|
|
236
|
-
* @example 양방향 격리 (default — 미지정 시 적용)
|
|
237
|
-
* jogak({ globalCss: true }) // previewIsolation 'shadow' 자동 적용
|
|
238
|
-
*
|
|
239
|
-
* @example 사용자 reset이 chrome에도 영향을 주길 원하는 경우
|
|
240
|
-
* jogak({ globalCss: true, previewIsolation: 'none' })
|
|
220
|
+
* - `'iframe'` (default, 알파.8): Preview를 사용자 vite의 정상 client(iframe)에 마운트.
|
|
221
|
+
* 사용자 utility 정상 컴파일 + 사용자 globalCss 적용 + Radix Portal 정상 (iframe document.body).
|
|
222
|
+
* chrome 침범 zero. cross-origin postMessage로 entry/args 전달.
|
|
223
|
+
* `userVite` 옵션으로 spawn 동작 제어.
|
|
224
|
+
* - `'shadow'` (deprecated, 알파.9 부활 검토): Preview를 ShadowRoot에 마운트. 알파.8 v1에서는
|
|
225
|
+
* 사용자 vite 산출물을 shadow에 inject하는 통로가 미구현 — 사용자 utility 미적용 한계.
|
|
226
|
+
* chrome 침범은 zero지만 사용자 컴포넌트 시각이 raw에 가까움.
|
|
227
|
+
* - `'none'` (deprecated, 알파.10 제거 검토): 사용자 globalCss를 outer document에 inject.
|
|
228
|
+
* jogak chrome이 사용자 reset/preflight 영향을 받음 (back-compat).
|
|
229
|
+
*
|
|
230
|
+
* @default 'iframe'
|
|
231
|
+
*
|
|
232
|
+
* @example 사용자 vite 자동 spawn + iframe 모드 (default — 미지정 시 적용)
|
|
233
|
+
* jogak({ globalCss: true }) // previewIsolation 'iframe', 사용자 vite 자동 탐지
|
|
241
234
|
*
|
|
242
|
-
* @example
|
|
243
|
-
* jogak({ globalCss: true, previewIsolation: '
|
|
235
|
+
* @example 사용자 vite 스폰 비활성 + 사용자 reset이 chrome에도 영향 (back-compat)
|
|
236
|
+
* jogak({ globalCss: true, previewIsolation: 'none' })
|
|
244
237
|
*/
|
|
245
238
|
readonly previewIsolation?: 'none' | 'shadow' | 'iframe';
|
|
239
|
+
/**
|
|
240
|
+
* 알파.8 internal: 본 jogak() plugin이 사용자 vite scope의 preview-frame entry용으로
|
|
241
|
+
* 동작하는지. CLI의 spawnUserVite가 사용자 vite에 jogak()을 mergeConfig로 inject할 때
|
|
242
|
+
* `previewFrame: true`를 함께 설정한다.
|
|
243
|
+
*
|
|
244
|
+
* `previewFrame: true`일 때:
|
|
245
|
+
* - jogak SPA chrome 가상 모듈(`_jogakCodeTheme`/`_jogakPreviewIsolation`/`_jogakUserViteUrl`/
|
|
246
|
+
* `_jogakMetas`) emit 비활성화
|
|
247
|
+
* - entry 가상 모듈(`virtual:jogak/entry/<slug>`)은 그대로 emit (preview-entry가 사용)
|
|
248
|
+
* - 사용자 측 vite plugins(@tailwindcss/vite 등)와 공존
|
|
249
|
+
*
|
|
250
|
+
* 사용자가 직접 설정하는 옵션이 아니다.
|
|
251
|
+
*/
|
|
252
|
+
readonly previewFrame?: boolean;
|
|
253
|
+
/**
|
|
254
|
+
* 알파.8 internal: jogak SPA가 iframe src로 사용할 사용자 vite의 base URL
|
|
255
|
+
* (예: `http://localhost:5174`). CLI가 spawnUserVite 결과를 `runHost` 통해
|
|
256
|
+
* jogak() plugin에 전달한다.
|
|
257
|
+
*
|
|
258
|
+
* 빈 문자열 또는 미지정 시 기존 fallback (jogak SPA Vite scope의 preview-frame.tsx).
|
|
259
|
+
*
|
|
260
|
+
* 사용자가 직접 설정하는 옵션이 아니다.
|
|
261
|
+
*/
|
|
262
|
+
readonly userViteUrl?: string;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* 알파.8: 사용자 vite 인스턴스 spawn 옵션.
|
|
266
|
+
*
|
|
267
|
+
* jogak CLI는 사용자 cwd의 `vite.config.{ts,mts,js,mjs,cjs}`를 자동 탐지해 별도
|
|
268
|
+
* vite dev server를 spawn한다. iframe 모드의 src로 사용되어 사용자 컴포넌트가
|
|
269
|
+
* 사용자 vite plugins(@tailwindcss/vite, custom alias 등)의 정상 client에서
|
|
270
|
+
* 평가된다.
|
|
271
|
+
*/
|
|
272
|
+
export interface UserViteOptions {
|
|
273
|
+
/**
|
|
274
|
+
* 사용자 vite.config.ts 절대/상대 경로. 미지정 시 cwd에서 자동 탐지
|
|
275
|
+
* (`vite.config.ts` > `vite.config.mts` > `vite.config.js` > `vite.config.mjs` > `vite.config.cjs`).
|
|
276
|
+
*/
|
|
277
|
+
readonly configFile?: string;
|
|
278
|
+
/**
|
|
279
|
+
* 사용자 vite dev server 포트. 미지정 시 0(free port).
|
|
280
|
+
*/
|
|
281
|
+
readonly port?: number;
|
|
282
|
+
/**
|
|
283
|
+
* 사용자 vite dev server host. 미지정 시 'localhost'.
|
|
284
|
+
*/
|
|
285
|
+
readonly host?: string | boolean;
|
|
286
|
+
/**
|
|
287
|
+
* 사용자 vite spawn을 비활성화. 알파.7.1 동등 fallback 동작
|
|
288
|
+
* (사용자 utility 미컴파일).
|
|
289
|
+
*/
|
|
290
|
+
readonly disabled?: boolean;
|
|
246
291
|
}
|
package/dist/vite/index.js
CHANGED
|
@@ -1,25 +1,94 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var Q=Object.create;var N=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var ee=Object.getOwnPropertyNames;var te=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty;var ne=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ee(t))!re.call(e,a)&&a!==r&&N(e,a,{get:()=>t[a],enumerable:!(o=Z(t,a))||o.enumerable});return e};var oe=(e,t,r)=>(r=e!=null?Q(te(e)):{},ne(t||!e||!e.__esModule?N(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("node:path"),E=require("node:fs"),I=require("node:fs/promises"),D=require("../extractor-client-CiWszHel.cjs"),ae=["@jogak/core","@jogak/react","@jogak/web-components","@jogak/next"];async function B(e){try{const o=await I.stat(e);if(!o.isDirectory())return o.mtimeMs}catch{return 0}let t=0,r;try{r=await I.readdir(e)}catch{return 0}for(const o of r){const a=g.join(e,o);try{const l=await I.stat(a);if(l.isDirectory()){const f=await B(a);f>t&&(t=f)}else l.mtimeMs>t&&(t=l.mtimeMs)}catch{continue}}return t}async function se(e){const t=g.resolve(e.root,"node_modules/.vite/deps");if(!E.existsSync(t))return{purged:!1};const r=g.join(t,"_metadata.json");if(!E.existsSync(r))return{purged:!1};let o;try{o=(await I.stat(r)).mtimeMs}catch(l){return e.logger.warn(`[jogak] cache validation: failed to stat _metadata.json (${l.message})`),{purged:!1}}const a=e.packages??ae;for(const l of a){const f=g.resolve(e.root,"node_modules",l,"dist");if(!E.existsSync(f))continue;let v;try{v=await B(f)}catch(w){e.logger.warn(`[jogak] cache validation: failed to walk ${l}/dist (${w.message})`);continue}if(v>o+1e3)try{return await I.rm(t,{recursive:!0,force:!0}),e.logger.info(`[jogak] vite deps cache invalidated (stale): ${l} dist newer than cache`),{purged:!0,reason:l}}catch(w){return e.logger.warn(`[jogak] cache validation: failed to purge ${t} (${w.message})`),{purged:!1}}}return{purged:!1}}const ie=["src/index.css","src/main.css","src/styles.css","src/styles/globals.css","src/styles/index.css","src/app/globals.css","src/global.css","src/app.css"];function ce(e){for(const t of ie){const r=g.resolve(e,t);if(E.existsSync(r))return[r]}return[]}function J(e,t){if(e===void 0||e===!1)return[];if(e===!0)return ce(t);if(typeof e=="string")return e.length>0?[g.resolve(t,e)]:[];const r=[];for(const o of e)typeof o=="string"&&o.length>0&&r.push(g.resolve(t,o));return r}function le(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,"")}function ue(e){if(E.existsSync(e))try{const t=E.readFileSync(e,"utf8");return JSON.parse(le(t))}catch{return}}function de(e,t,r){if(!e.endsWith("/*")||!t.endsWith("/*"))return;const o=e.slice(0,-2),a=g.resolve(r,t.slice(0,-2));return[o,a]}function ge(e,t){var a,l;const r={},o=new Set([e,g.resolve(t,"tsconfig.app.json")]);for(const f of o){const v=ue(f);if(v===void 0)continue;const w=(a=v.compilerOptions)==null?void 0:a.paths;if(w===void 0)continue;const T=((l=v.compilerOptions)==null?void 0:l.baseUrl)??".",R=g.resolve(g.dirname(f),T);for(const[d,y]of Object.entries(w)){const _=y[0];if(_===void 0)continue;const k=de(d,_,R);if(k===void 0)continue;const[S,b]=k;r[S]===void 0&&(r[S]=b)}}return r}const W="virtual:jogak",O="\0"+W,K="virtual:jogak/entry/",L="\0"+K,H="virtual:jogak/global-css",U="\0"+H,M="virtual:jogak/preview-entry",$="\0"+M,Y="virtual:jogak/preview-global-css",F="\0"+Y;function fe(e){return Buffer.from(e,"utf8").toString("base64url")}function me(e){return Buffer.from(e,"base64url").toString("utf8")}const pe="/__jogak_preview__/index.html";function ye(e){return{name:"vite-plugin-jogak-preview-frame",enforce:"pre",configureServer(t){t.middlewares.use((r,o,a)=>{if(r.url===void 0||r.url.split("?")[0]!==pe||r.method!=="GET")return a();const f=ve();t.transformIndexHtml(r.url,f).then(v=>{o.statusCode=200,o.setHeader("Content-Type","text/html; charset=utf-8"),o.end(v)}).catch(a)})},resolveId(t){if(t===M)return $;if(t===Y)return F},load(t){if(t===F){const r=J(e.globalCss,e.userRoot);return r.length===0?`// [jogak] preview-global-css: no candidates
|
|
2
2
|
export {}
|
|
3
|
-
|
|
3
|
+
`:r.map(o=>`import ${JSON.stringify(o)}`).join(`
|
|
4
|
+
`)+`
|
|
5
|
+
export {}
|
|
6
|
+
`}if(t===$)return he}}}function ve(){return`<!doctype html>
|
|
7
|
+
<html lang="en">
|
|
8
|
+
<head>
|
|
9
|
+
<meta charset="UTF-8" />
|
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
11
|
+
<title>jogak preview</title>
|
|
12
|
+
<style>
|
|
13
|
+
html, body { margin: 0; padding: 0; }
|
|
14
|
+
#jogak-preview-root { display: block; }
|
|
15
|
+
</style>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<div id="jogak-preview-root"></div>
|
|
19
|
+
<script type="module" src="/@id/${M}"><\/script>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
22
|
+
`}const he=`
|
|
23
|
+
import { reactAdapter } from '@jogak/react'
|
|
24
|
+
import { defaultRegistry } from '@jogak/core'
|
|
25
|
+
import 'virtual:jogak'
|
|
26
|
+
import 'virtual:jogak/preview-global-css'
|
|
27
|
+
|
|
28
|
+
const rootEl = document.getElementById('jogak-preview-root')
|
|
29
|
+
if (rootEl === null) throw new Error('[jogak] #jogak-preview-root not found')
|
|
30
|
+
|
|
31
|
+
let currentContainer = null
|
|
32
|
+
let currentArgs = {}
|
|
33
|
+
let currentEntryId = null
|
|
34
|
+
|
|
35
|
+
async function renderEntry(entryId, args) {
|
|
36
|
+
currentEntryId = entryId
|
|
37
|
+
currentArgs = args
|
|
38
|
+
const entry = await defaultRegistry.requestEntry(entryId)
|
|
39
|
+
if (currentContainer === null) {
|
|
40
|
+
currentContainer = document.createElement('div')
|
|
41
|
+
rootEl.replaceChildren(currentContainer)
|
|
42
|
+
}
|
|
43
|
+
reactAdapter.render(entry, args, currentContainer)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function unmount() {
|
|
47
|
+
if (currentContainer !== null) {
|
|
48
|
+
reactAdapter.unmount(currentContainer)
|
|
49
|
+
currentContainer = null
|
|
50
|
+
currentEntryId = null
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
window.addEventListener('message', (event) => {
|
|
55
|
+
const data = event.data
|
|
56
|
+
if (data == null || typeof data !== 'object') return
|
|
57
|
+
if (data.type === 'jogak:setProps') {
|
|
58
|
+
void renderEntry(data.entryId, data.args ?? {}).then(() => {
|
|
59
|
+
window.parent.postMessage({ type: 'jogak:rendered', entryId: data.entryId }, '*')
|
|
60
|
+
}).catch((err) => {
|
|
61
|
+
window.parent.postMessage({ type: 'jogak:error', message: String(err?.message ?? err) }, '*')
|
|
62
|
+
})
|
|
63
|
+
} else if (data.type === 'jogak:unmount') {
|
|
64
|
+
unmount()
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
window.parent.postMessage({ type: 'jogak:ready' }, '*')
|
|
69
|
+
`;function G(e){return{title:e.title,jogakNamesKey:[...e.jogakNames].sort().join("|")}}function we(e,t){return e!==void 0&&e.title===t.title&&e.jogakNamesKey===t.jogakNamesKey}function je(e={}){const{patterns:t=["src/**/*.jogak.ts","src/**/*.jogak.tsx"],codeTheme:r="vsDark"}=e,o=e.cwd,a=e.tsConfigFilePath,l=e.disableCacheValidation===!0,f=e.resolveAlias,v=e.globalCss,w=e.previewIsolation??"iframe",T=e.previewFrame===!0,R=e.userViteUrl??"";let d,y,_;const k=new Map,S=new Map,b=new Map;async function P(){const{glob:n}=await import("glob"),m=_??process.cwd(),s=(await n(t,{cwd:m,absolute:!0})).sort(),u=[];k.clear(),S.clear();for(const i of s){let h="";try{h=await I.readFile(i,"utf8")}catch{continue}let j={},c=null;if(y!==void 0){try{j=await y.extract(i)}catch{j={}}try{c=await y.extractMeta(i)}catch{c=null}}if(c===null)continue;const p=c.title;k.set(p,i),S.set(i,p);const C={id:p,title:c.title,jogakNames:c.jogakNames,autoArgTypes:j,userArgTypes:c.userArgTypes,source:h,filePath:i,metaExtras:c.metaExtras};b.set(i,G(C)),u.push({id:p,filePath:i,meta:C})}return u}return{name:"vite-plugin-jogak",config(){const n=o??process.cwd(),m=a??g.resolve(n,"tsconfig.json"),s=ge(m,n),u={};if(f!==void 0)for(const[h,j]of Object.entries(f))u[h]=g.resolve(n,j);const i={...s,...u};if(Object.keys(i).length!==0)return{resolve:{alias:i}}},async configResolved(n){_=o??n.root,n.command==="serve"&&!l&&await se({root:n.root,logger:{info:s=>n.logger.info(s),warn:s=>n.logger.warn(s)}});const m=a??g.resolve(_,"tsconfig.json");y=E.existsSync(m)?D.createPropsExtractor({tsConfigFilePath:m}):D.createPropsExtractor()},configureServer(n){d=n},buildEnd(){y==null||y.releaseCache()},resolveId(n){if(n===W)return O;if(n===H)return U;if(n.startsWith(K))return"\0"+n},async load(n){if(n===U){const m=_??process.cwd(),s=J(v,m);return s.length===0?`// [jogak] globalCss not configured or no candidates found.
|
|
70
|
+
export {}
|
|
71
|
+
`:`${s.map(i=>`import ${JSON.stringify(i)}`).join(`
|
|
4
72
|
`)}
|
|
5
73
|
export {}
|
|
6
|
-
`}if(
|
|
74
|
+
`}if(n===O){const s=(await P()).map(i=>i.meta),u=T?"":`
|
|
75
|
+
export const _jogakCodeTheme = ${JSON.stringify(r)}
|
|
76
|
+
export const _jogakPreviewIsolation = ${JSON.stringify(w)}
|
|
77
|
+
export const _jogakUserViteUrl = ${JSON.stringify(R)}
|
|
78
|
+
export const _jogakMetas = _metas
|
|
79
|
+
`;return`import { defaultRegistry } from '@jogak/core'
|
|
7
80
|
|
|
8
81
|
const _entryLoader = (slug) =>
|
|
9
82
|
import(/* @vite-ignore */ '/@id/__x00__virtual:jogak/entry/' + slug)
|
|
10
83
|
defaultRegistry.setEntryLoader((id) => {
|
|
11
|
-
const slug = ${
|
|
84
|
+
const slug = ${_e()}
|
|
12
85
|
return _entryLoader(slug(id))
|
|
13
86
|
})
|
|
14
87
|
|
|
15
|
-
const _metas = ${JSON.stringify(
|
|
88
|
+
const _metas = ${JSON.stringify(s)}
|
|
16
89
|
|
|
17
90
|
for (const m of _metas) defaultRegistry.registerMeta(m)
|
|
18
|
-
|
|
19
|
-
export const _jogakCodeTheme = ${JSON.stringify(s)}
|
|
20
|
-
export const _jogakPreviewIsolation = ${JSON.stringify(w)}
|
|
21
|
-
export const _jogakMetas = _metas
|
|
22
|
-
`}if(r.startsWith(O)){const g=r.slice(O.length),n=ce(g);let u=b.get(n);return u===void 0&&(await A(),u=b.get(n)),u===void 0?`// [jogak] unknown entry id: ${JSON.stringify(n)}
|
|
91
|
+
${u}`}if(n.startsWith(L)){const m=n.slice(L.length),s=me(m);let u=k.get(s);return u===void 0&&(await P(),u=k.get(s)),u===void 0?`// [jogak] unknown entry id: ${JSON.stringify(s)}
|
|
23
92
|
export {}
|
|
24
93
|
`:`import * as _user from ${JSON.stringify(u)}
|
|
25
94
|
import { defaultRegistry } from '@jogak/core'
|
|
@@ -30,18 +99,18 @@ delete _named.default
|
|
|
30
99
|
const _jogaks = Object.values(_named).filter(
|
|
31
100
|
(v) => v !== null && typeof v === 'object' && typeof v.name === 'string'
|
|
32
101
|
)
|
|
33
|
-
defaultRegistry.hydrateEntry(${JSON.stringify(
|
|
102
|
+
defaultRegistry.hydrateEntry(${JSON.stringify(s)}, _jogaks, _meta?.component)
|
|
34
103
|
|
|
35
104
|
if (import.meta.hot) {
|
|
36
105
|
import.meta.hot.accept()
|
|
37
106
|
}
|
|
38
107
|
|
|
39
108
|
export {}
|
|
40
|
-
`}},async handleHotUpdate({file:
|
|
109
|
+
`}},async handleHotUpdate({file:n,modules:m}){const s=/\.jogak\.(tsx?|jsx?)$/.test(n),u=/\.(tsx?|jsx?)$/.test(n)&&!s;if(!s&&!u||d===void 0||!s)return;const i=d.moduleGraph.getModuleById(O),h=S.get(n),j=h!==void 0?L+fe(h):void 0,c=j!==void 0?d.moduleGraph.getModuleById(j):void 0;let p=null,C={},A="";if(y!==void 0){try{p=await y.extractMeta(n)}catch{p=null}try{C=await y.extract(n)}catch{C={}}try{A=await I.readFile(n,"utf8")}catch{A=""}}if(p===null){i!==void 0&&d.moduleGraph.invalidateModule(i),c!==void 0&&d.moduleGraph.invalidateModule(c),d.ws.send({type:"full-reload"});return}const V=G(p),X=b.get(n),q=we(X,V);if(b.set(n,V),!q||h===void 0){i!==void 0&&d.moduleGraph.invalidateModule(i),c!==void 0&&d.moduleGraph.invalidateModule(c),d.ws.send({type:"full-reload"});return}const z={id:h,title:p.title,jogakNames:p.jogakNames,autoArgTypes:C,userArgTypes:p.userArgTypes,source:A,filePath:n,metaExtras:p.metaExtras};c!==void 0&&d.moduleGraph.invalidateModule(c),d.ws.send({type:"custom",event:"jogak:meta-update",data:{id:h,meta:z}});const x=[...m];return c!==void 0&&!x.includes(c)&&x.push(c),x}}}function _e(){return`(rawId) => {
|
|
41
110
|
if (typeof Buffer !== 'undefined') return Buffer.from(rawId, 'utf8').toString('base64url')
|
|
42
111
|
// 브라우저 폴백: btoa는 binary string 기준이라 UTF-8을 한번 인코딩해야 한다.
|
|
43
112
|
const enc = new TextEncoder().encode(rawId)
|
|
44
113
|
let bin = ''
|
|
45
114
|
for (let i = 0; i < enc.length; i++) bin += String.fromCharCode(enc[i])
|
|
46
115
|
return btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')
|
|
47
|
-
}`}exports.jogak=
|
|
116
|
+
}`}exports.jogak=je;exports.jogakPreviewFramePlugin=ye;
|
package/dist/vite/index.mjs
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
import { resolve as y, join as
|
|
2
|
-
import { existsSync as
|
|
3
|
-
import { stat as
|
|
4
|
-
import { c as
|
|
5
|
-
const
|
|
1
|
+
import { resolve as y, join as B, dirname as q } from "node:path";
|
|
2
|
+
import { existsSync as S, readFileSync as tt } from "node:fs";
|
|
3
|
+
import { stat as x, rm as et, readdir as rt, readFile as P } from "node:fs/promises";
|
|
4
|
+
import { c as D } from "../extractor-client-CReBed7x.js";
|
|
5
|
+
const nt = [
|
|
6
6
|
"@jogak/core",
|
|
7
7
|
"@jogak/react",
|
|
8
8
|
"@jogak/web-components",
|
|
9
9
|
"@jogak/next"
|
|
10
10
|
];
|
|
11
|
-
async function
|
|
11
|
+
async function J(t) {
|
|
12
12
|
try {
|
|
13
|
-
const
|
|
14
|
-
if (!
|
|
15
|
-
return
|
|
13
|
+
const o = await x(t);
|
|
14
|
+
if (!o.isDirectory())
|
|
15
|
+
return o.mtimeMs;
|
|
16
16
|
} catch {
|
|
17
17
|
return 0;
|
|
18
18
|
}
|
|
19
|
-
let
|
|
19
|
+
let e = 0, n;
|
|
20
20
|
try {
|
|
21
|
-
|
|
21
|
+
n = await rt(t);
|
|
22
22
|
} catch {
|
|
23
23
|
return 0;
|
|
24
24
|
}
|
|
25
|
-
for (const
|
|
26
|
-
const
|
|
25
|
+
for (const o of n) {
|
|
26
|
+
const c = B(t, o);
|
|
27
27
|
try {
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
} else
|
|
28
|
+
const l = await x(c);
|
|
29
|
+
if (l.isDirectory()) {
|
|
30
|
+
const g = await J(c);
|
|
31
|
+
g > e && (e = g);
|
|
32
|
+
} else l.mtimeMs > e && (e = l.mtimeMs);
|
|
33
33
|
} catch {
|
|
34
34
|
continue;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
return
|
|
37
|
+
return e;
|
|
38
38
|
}
|
|
39
|
-
async function
|
|
40
|
-
const
|
|
41
|
-
if (!
|
|
39
|
+
async function ot(t) {
|
|
40
|
+
const e = y(t.root, "node_modules/.vite/deps");
|
|
41
|
+
if (!S(e))
|
|
42
42
|
return { purged: !1 };
|
|
43
|
-
const
|
|
44
|
-
if (!
|
|
43
|
+
const n = B(e, "_metadata.json");
|
|
44
|
+
if (!S(n))
|
|
45
45
|
return { purged: !1 };
|
|
46
|
-
let
|
|
46
|
+
let o;
|
|
47
47
|
try {
|
|
48
|
-
|
|
49
|
-
} catch (
|
|
48
|
+
o = (await x(n)).mtimeMs;
|
|
49
|
+
} catch (l) {
|
|
50
50
|
return t.logger.warn(
|
|
51
|
-
`[jogak] cache validation: failed to stat _metadata.json (${
|
|
51
|
+
`[jogak] cache validation: failed to stat _metadata.json (${l.message})`
|
|
52
52
|
), { purged: !1 };
|
|
53
53
|
}
|
|
54
|
-
const
|
|
55
|
-
for (const
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
58
|
-
let
|
|
54
|
+
const c = t.packages ?? nt;
|
|
55
|
+
for (const l of c) {
|
|
56
|
+
const g = y(t.root, "node_modules", l, "dist");
|
|
57
|
+
if (!S(g)) continue;
|
|
58
|
+
let v;
|
|
59
59
|
try {
|
|
60
|
-
|
|
60
|
+
v = await J(g);
|
|
61
61
|
} catch (w) {
|
|
62
62
|
t.logger.warn(
|
|
63
|
-
`[jogak] cache validation: failed to walk ${
|
|
63
|
+
`[jogak] cache validation: failed to walk ${l}/dist (${w.message})`
|
|
64
64
|
);
|
|
65
65
|
continue;
|
|
66
66
|
}
|
|
67
|
-
if (
|
|
67
|
+
if (v > o + 1e3)
|
|
68
68
|
try {
|
|
69
|
-
return await
|
|
70
|
-
`[jogak] vite deps cache invalidated (stale): ${
|
|
71
|
-
), { purged: !0, reason:
|
|
69
|
+
return await et(e, { recursive: !0, force: !0 }), t.logger.info(
|
|
70
|
+
`[jogak] vite deps cache invalidated (stale): ${l} dist newer than cache`
|
|
71
|
+
), { purged: !0, reason: l };
|
|
72
72
|
} catch (w) {
|
|
73
73
|
return t.logger.warn(
|
|
74
|
-
`[jogak] cache validation: failed to purge ${
|
|
74
|
+
`[jogak] cache validation: failed to purge ${e} (${w.message})`
|
|
75
75
|
), { purged: !1 };
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
return { purged: !1 };
|
|
79
79
|
}
|
|
80
|
-
const
|
|
80
|
+
const at = [
|
|
81
81
|
"src/index.css",
|
|
82
82
|
"src/main.css",
|
|
83
83
|
"src/styles.css",
|
|
@@ -87,125 +87,225 @@ const Q = [
|
|
|
87
87
|
"src/global.css",
|
|
88
88
|
"src/app.css"
|
|
89
89
|
];
|
|
90
|
-
function
|
|
91
|
-
for (const
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
90
|
+
function st(t) {
|
|
91
|
+
for (const e of at) {
|
|
92
|
+
const n = y(t, e);
|
|
93
|
+
if (S(n)) return [n];
|
|
94
94
|
}
|
|
95
95
|
return [];
|
|
96
96
|
}
|
|
97
|
-
function
|
|
97
|
+
function W(t, e) {
|
|
98
98
|
if (t === void 0 || t === !1) return [];
|
|
99
|
-
if (t === !0) return
|
|
99
|
+
if (t === !0) return st(e);
|
|
100
100
|
if (typeof t == "string")
|
|
101
|
-
return t.length > 0 ? [y(
|
|
102
|
-
const
|
|
103
|
-
for (const
|
|
104
|
-
typeof
|
|
105
|
-
return
|
|
101
|
+
return t.length > 0 ? [y(e, t)] : [];
|
|
102
|
+
const n = [];
|
|
103
|
+
for (const o of t)
|
|
104
|
+
typeof o == "string" && o.length > 0 && n.push(y(e, o));
|
|
105
|
+
return n;
|
|
106
106
|
}
|
|
107
|
-
function
|
|
107
|
+
function it(t) {
|
|
108
108
|
return t.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
|
|
109
109
|
}
|
|
110
|
-
function
|
|
111
|
-
if (
|
|
110
|
+
function ct(t) {
|
|
111
|
+
if (S(t))
|
|
112
112
|
try {
|
|
113
|
-
const
|
|
114
|
-
return JSON.parse(
|
|
113
|
+
const e = tt(t, "utf8");
|
|
114
|
+
return JSON.parse(it(e));
|
|
115
115
|
} catch {
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
function
|
|
120
|
-
if (!t.endsWith("/*") || !
|
|
121
|
-
const
|
|
122
|
-
return [
|
|
119
|
+
function lt(t, e, n) {
|
|
120
|
+
if (!t.endsWith("/*") || !e.endsWith("/*")) return;
|
|
121
|
+
const o = t.slice(0, -2), c = y(n, e.slice(0, -2));
|
|
122
|
+
return [o, c];
|
|
123
123
|
}
|
|
124
|
-
function
|
|
125
|
-
var
|
|
126
|
-
const
|
|
124
|
+
function ut(t, e) {
|
|
125
|
+
var c, l;
|
|
126
|
+
const n = {}, o = /* @__PURE__ */ new Set([
|
|
127
127
|
t,
|
|
128
|
-
y(
|
|
128
|
+
y(e, "tsconfig.app.json")
|
|
129
129
|
]);
|
|
130
|
-
for (const
|
|
131
|
-
const
|
|
132
|
-
if (
|
|
133
|
-
const w = (
|
|
130
|
+
for (const g of o) {
|
|
131
|
+
const v = ct(g);
|
|
132
|
+
if (v === void 0) continue;
|
|
133
|
+
const w = (c = v.compilerOptions) == null ? void 0 : c.paths;
|
|
134
134
|
if (w === void 0) continue;
|
|
135
|
-
const
|
|
136
|
-
for (const [
|
|
137
|
-
const
|
|
138
|
-
if (
|
|
139
|
-
const
|
|
140
|
-
if (
|
|
141
|
-
const [
|
|
142
|
-
|
|
135
|
+
const b = ((l = v.compilerOptions) == null ? void 0 : l.baseUrl) ?? ".", T = y(q(g), b);
|
|
136
|
+
for (const [d, p] of Object.entries(w)) {
|
|
137
|
+
const _ = p[0];
|
|
138
|
+
if (_ === void 0) continue;
|
|
139
|
+
const k = lt(d, _, T);
|
|
140
|
+
if (k === void 0) continue;
|
|
141
|
+
const [E, C] = k;
|
|
142
|
+
n[E] === void 0 && (n[E] = C);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
-
return
|
|
145
|
+
return n;
|
|
146
146
|
}
|
|
147
|
-
const
|
|
148
|
-
function
|
|
147
|
+
const K = "virtual:jogak", L = "\0" + K, H = "virtual:jogak/entry/", O = "\0" + H, Y = "virtual:jogak/global-css", U = "\0" + Y, M = "virtual:jogak/preview-entry", $ = "\0" + M, X = "virtual:jogak/preview-global-css", F = "\0" + X;
|
|
148
|
+
function dt(t) {
|
|
149
149
|
return Buffer.from(t, "utf8").toString("base64url");
|
|
150
150
|
}
|
|
151
|
-
function
|
|
151
|
+
function gt(t) {
|
|
152
152
|
return Buffer.from(t, "base64url").toString("utf8");
|
|
153
153
|
}
|
|
154
|
-
|
|
154
|
+
const ft = "/__jogak_preview__/index.html";
|
|
155
|
+
function kt(t) {
|
|
156
|
+
return {
|
|
157
|
+
name: "vite-plugin-jogak-preview-frame",
|
|
158
|
+
enforce: "pre",
|
|
159
|
+
configureServer(e) {
|
|
160
|
+
e.middlewares.use((n, o, c) => {
|
|
161
|
+
if (n.url === void 0 || n.url.split("?")[0] !== ft || n.method !== "GET") return c();
|
|
162
|
+
const g = mt();
|
|
163
|
+
e.transformIndexHtml(n.url, g).then((v) => {
|
|
164
|
+
o.statusCode = 200, o.setHeader("Content-Type", "text/html; charset=utf-8"), o.end(v);
|
|
165
|
+
}).catch(c);
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
resolveId(e) {
|
|
169
|
+
if (e === M) return $;
|
|
170
|
+
if (e === X) return F;
|
|
171
|
+
},
|
|
172
|
+
load(e) {
|
|
173
|
+
if (e === F) {
|
|
174
|
+
const n = W(t.globalCss, t.userRoot);
|
|
175
|
+
return n.length === 0 ? `// [jogak] preview-global-css: no candidates
|
|
176
|
+
export {}
|
|
177
|
+
` : n.map((o) => `import ${JSON.stringify(o)}`).join(`
|
|
178
|
+
`) + `
|
|
179
|
+
export {}
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
if (e === $)
|
|
183
|
+
return pt;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function mt() {
|
|
188
|
+
return `<!doctype html>
|
|
189
|
+
<html lang="en">
|
|
190
|
+
<head>
|
|
191
|
+
<meta charset="UTF-8" />
|
|
192
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
193
|
+
<title>jogak preview</title>
|
|
194
|
+
<style>
|
|
195
|
+
html, body { margin: 0; padding: 0; }
|
|
196
|
+
#jogak-preview-root { display: block; }
|
|
197
|
+
</style>
|
|
198
|
+
</head>
|
|
199
|
+
<body>
|
|
200
|
+
<div id="jogak-preview-root"></div>
|
|
201
|
+
<script type="module" src="/@id/${M}"><\/script>
|
|
202
|
+
</body>
|
|
203
|
+
</html>
|
|
204
|
+
`;
|
|
205
|
+
}
|
|
206
|
+
const pt = `
|
|
207
|
+
import { reactAdapter } from '@jogak/react'
|
|
208
|
+
import { defaultRegistry } from '@jogak/core'
|
|
209
|
+
import 'virtual:jogak'
|
|
210
|
+
import 'virtual:jogak/preview-global-css'
|
|
211
|
+
|
|
212
|
+
const rootEl = document.getElementById('jogak-preview-root')
|
|
213
|
+
if (rootEl === null) throw new Error('[jogak] #jogak-preview-root not found')
|
|
214
|
+
|
|
215
|
+
let currentContainer = null
|
|
216
|
+
let currentArgs = {}
|
|
217
|
+
let currentEntryId = null
|
|
218
|
+
|
|
219
|
+
async function renderEntry(entryId, args) {
|
|
220
|
+
currentEntryId = entryId
|
|
221
|
+
currentArgs = args
|
|
222
|
+
const entry = await defaultRegistry.requestEntry(entryId)
|
|
223
|
+
if (currentContainer === null) {
|
|
224
|
+
currentContainer = document.createElement('div')
|
|
225
|
+
rootEl.replaceChildren(currentContainer)
|
|
226
|
+
}
|
|
227
|
+
reactAdapter.render(entry, args, currentContainer)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function unmount() {
|
|
231
|
+
if (currentContainer !== null) {
|
|
232
|
+
reactAdapter.unmount(currentContainer)
|
|
233
|
+
currentContainer = null
|
|
234
|
+
currentEntryId = null
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
window.addEventListener('message', (event) => {
|
|
239
|
+
const data = event.data
|
|
240
|
+
if (data == null || typeof data !== 'object') return
|
|
241
|
+
if (data.type === 'jogak:setProps') {
|
|
242
|
+
void renderEntry(data.entryId, data.args ?? {}).then(() => {
|
|
243
|
+
window.parent.postMessage({ type: 'jogak:rendered', entryId: data.entryId }, '*')
|
|
244
|
+
}).catch((err) => {
|
|
245
|
+
window.parent.postMessage({ type: 'jogak:error', message: String(err?.message ?? err) }, '*')
|
|
246
|
+
})
|
|
247
|
+
} else if (data.type === 'jogak:unmount') {
|
|
248
|
+
unmount()
|
|
249
|
+
}
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
window.parent.postMessage({ type: 'jogak:ready' }, '*')
|
|
253
|
+
`;
|
|
254
|
+
function G(t) {
|
|
155
255
|
return {
|
|
156
256
|
title: t.title,
|
|
157
257
|
jogakNamesKey: [...t.jogakNames].sort().join("|")
|
|
158
258
|
};
|
|
159
259
|
}
|
|
160
|
-
function
|
|
161
|
-
return t !== void 0 && t.title ===
|
|
260
|
+
function yt(t, e) {
|
|
261
|
+
return t !== void 0 && t.title === e.title && t.jogakNamesKey === e.jogakNamesKey;
|
|
162
262
|
}
|
|
163
|
-
function
|
|
263
|
+
function Et(t = {}) {
|
|
164
264
|
const {
|
|
165
|
-
patterns:
|
|
166
|
-
codeTheme:
|
|
167
|
-
} = t,
|
|
168
|
-
let
|
|
169
|
-
const k = /* @__PURE__ */ new Map(),
|
|
170
|
-
async function
|
|
171
|
-
const { glob:
|
|
172
|
-
k.clear(),
|
|
173
|
-
for (const
|
|
174
|
-
let
|
|
265
|
+
patterns: e = ["src/**/*.jogak.ts", "src/**/*.jogak.tsx"],
|
|
266
|
+
codeTheme: n = "vsDark"
|
|
267
|
+
} = t, o = t.cwd, c = t.tsConfigFilePath, l = t.disableCacheValidation === !0, g = t.resolveAlias, v = t.globalCss, w = t.previewIsolation ?? "iframe", b = t.previewFrame === !0, T = t.userViteUrl ?? "";
|
|
268
|
+
let d, p, _;
|
|
269
|
+
const k = /* @__PURE__ */ new Map(), E = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Map();
|
|
270
|
+
async function V() {
|
|
271
|
+
const { glob: r } = await import("glob"), f = _ ?? process.cwd(), a = (await r(e, { cwd: f, absolute: !0 })).sort(), u = [];
|
|
272
|
+
k.clear(), E.clear();
|
|
273
|
+
for (const s of a) {
|
|
274
|
+
let h = "";
|
|
175
275
|
try {
|
|
176
|
-
|
|
276
|
+
h = await P(s, "utf8");
|
|
177
277
|
} catch {
|
|
178
278
|
continue;
|
|
179
279
|
}
|
|
180
280
|
let j = {}, i = null;
|
|
181
|
-
if (
|
|
281
|
+
if (p !== void 0) {
|
|
182
282
|
try {
|
|
183
|
-
j = await
|
|
283
|
+
j = await p.extract(s);
|
|
184
284
|
} catch {
|
|
185
285
|
j = {};
|
|
186
286
|
}
|
|
187
287
|
try {
|
|
188
|
-
i = await
|
|
288
|
+
i = await p.extractMeta(s);
|
|
189
289
|
} catch {
|
|
190
290
|
i = null;
|
|
191
291
|
}
|
|
192
292
|
}
|
|
193
293
|
if (i === null) continue;
|
|
194
|
-
const
|
|
195
|
-
k.set(
|
|
196
|
-
const
|
|
197
|
-
id:
|
|
294
|
+
const m = i.title;
|
|
295
|
+
k.set(m, s), E.set(s, m);
|
|
296
|
+
const I = {
|
|
297
|
+
id: m,
|
|
198
298
|
title: i.title,
|
|
199
299
|
jogakNames: i.jogakNames,
|
|
200
300
|
autoArgTypes: j,
|
|
201
301
|
userArgTypes: i.userArgTypes,
|
|
202
|
-
source:
|
|
203
|
-
filePath:
|
|
302
|
+
source: h,
|
|
303
|
+
filePath: s,
|
|
204
304
|
metaExtras: i.metaExtras
|
|
205
305
|
};
|
|
206
|
-
|
|
306
|
+
C.set(s, G(I)), u.push({ id: m, filePath: s, meta: I });
|
|
207
307
|
}
|
|
208
|
-
return
|
|
308
|
+
return u;
|
|
209
309
|
}
|
|
210
310
|
return {
|
|
211
311
|
name: "vite-plugin-jogak",
|
|
@@ -220,77 +320,78 @@ function gt(t = {}) {
|
|
|
220
320
|
* 우선순위: `options.resolveAlias` (명시) > tsconfig 자동 추출.
|
|
221
321
|
*/
|
|
222
322
|
config() {
|
|
223
|
-
const
|
|
224
|
-
if (
|
|
225
|
-
for (const [
|
|
226
|
-
|
|
227
|
-
const
|
|
228
|
-
if (Object.keys(
|
|
323
|
+
const r = o ?? process.cwd(), f = c ?? y(r, "tsconfig.json"), a = ut(f, r), u = {};
|
|
324
|
+
if (g !== void 0)
|
|
325
|
+
for (const [h, j] of Object.entries(g))
|
|
326
|
+
u[h] = y(r, j);
|
|
327
|
+
const s = { ...a, ...u };
|
|
328
|
+
if (Object.keys(s).length !== 0)
|
|
229
329
|
return {
|
|
230
|
-
resolve: { alias:
|
|
330
|
+
resolve: { alias: s }
|
|
231
331
|
};
|
|
232
332
|
},
|
|
233
|
-
async configResolved(
|
|
234
|
-
_ =
|
|
235
|
-
root:
|
|
333
|
+
async configResolved(r) {
|
|
334
|
+
_ = o ?? r.root, r.command === "serve" && !l && await ot({
|
|
335
|
+
root: r.root,
|
|
236
336
|
logger: {
|
|
237
|
-
info: (
|
|
238
|
-
warn: (
|
|
337
|
+
info: (a) => r.logger.info(a),
|
|
338
|
+
warn: (a) => r.logger.warn(a)
|
|
239
339
|
}
|
|
240
340
|
});
|
|
241
|
-
const
|
|
242
|
-
|
|
341
|
+
const f = c ?? y(_, "tsconfig.json");
|
|
342
|
+
p = S(f) ? D({ tsConfigFilePath: f }) : D();
|
|
243
343
|
},
|
|
244
|
-
configureServer(
|
|
245
|
-
|
|
344
|
+
configureServer(r) {
|
|
345
|
+
d = r;
|
|
246
346
|
},
|
|
247
347
|
buildEnd() {
|
|
248
|
-
|
|
348
|
+
p == null || p.releaseCache();
|
|
249
349
|
},
|
|
250
|
-
resolveId(
|
|
251
|
-
if (
|
|
252
|
-
return
|
|
253
|
-
if (
|
|
254
|
-
return
|
|
255
|
-
if (
|
|
256
|
-
return "\0" +
|
|
350
|
+
resolveId(r) {
|
|
351
|
+
if (r === K)
|
|
352
|
+
return L;
|
|
353
|
+
if (r === Y)
|
|
354
|
+
return U;
|
|
355
|
+
if (r.startsWith(H))
|
|
356
|
+
return "\0" + r;
|
|
257
357
|
},
|
|
258
|
-
async load(
|
|
259
|
-
if (
|
|
260
|
-
const
|
|
261
|
-
return
|
|
358
|
+
async load(r) {
|
|
359
|
+
if (r === U) {
|
|
360
|
+
const f = _ ?? process.cwd(), a = W(v, f);
|
|
361
|
+
return a.length === 0 ? `// [jogak] globalCss not configured or no candidates found.
|
|
262
362
|
export {}
|
|
263
|
-
` : `${
|
|
363
|
+
` : `${a.map((s) => `import ${JSON.stringify(s)}`).join(`
|
|
264
364
|
`)}
|
|
265
365
|
export {}
|
|
266
366
|
`;
|
|
267
367
|
}
|
|
268
|
-
if (
|
|
269
|
-
const
|
|
368
|
+
if (r === L) {
|
|
369
|
+
const a = (await V()).map((s) => s.meta), u = b ? "" : `
|
|
370
|
+
export const _jogakCodeTheme = ${JSON.stringify(n)}
|
|
371
|
+
export const _jogakPreviewIsolation = ${JSON.stringify(w)}
|
|
372
|
+
export const _jogakUserViteUrl = ${JSON.stringify(T)}
|
|
373
|
+
export const _jogakMetas = _metas
|
|
374
|
+
`;
|
|
270
375
|
return `import { defaultRegistry } from '@jogak/core'
|
|
271
376
|
|
|
272
377
|
const _entryLoader = (slug) =>
|
|
273
378
|
import(/* @vite-ignore */ '/@id/__x00__virtual:jogak/entry/' + slug)
|
|
274
379
|
defaultRegistry.setEntryLoader((id) => {
|
|
275
|
-
const slug = ${
|
|
380
|
+
const slug = ${vt()}
|
|
276
381
|
return _entryLoader(slug(id))
|
|
277
382
|
})
|
|
278
383
|
|
|
279
|
-
const _metas = ${JSON.stringify(
|
|
384
|
+
const _metas = ${JSON.stringify(a)}
|
|
280
385
|
|
|
281
386
|
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
|
-
`;
|
|
387
|
+
${u}`;
|
|
287
388
|
}
|
|
288
|
-
if (
|
|
289
|
-
const
|
|
290
|
-
let
|
|
291
|
-
return
|
|
389
|
+
if (r.startsWith(O)) {
|
|
390
|
+
const f = r.slice(O.length), a = gt(f);
|
|
391
|
+
let u = k.get(a);
|
|
392
|
+
return u === void 0 && (await V(), u = k.get(a)), u === void 0 ? `// [jogak] unknown entry id: ${JSON.stringify(a)}
|
|
292
393
|
export {}
|
|
293
|
-
` : `import * as _user from ${JSON.stringify(
|
|
394
|
+
` : `import * as _user from ${JSON.stringify(u)}
|
|
294
395
|
import { defaultRegistry } from '@jogak/core'
|
|
295
396
|
|
|
296
397
|
const _meta = _user.default
|
|
@@ -299,7 +400,7 @@ delete _named.default
|
|
|
299
400
|
const _jogaks = Object.values(_named).filter(
|
|
300
401
|
(v) => v !== null && typeof v === 'object' && typeof v.name === 'string'
|
|
301
402
|
)
|
|
302
|
-
defaultRegistry.hydrateEntry(${JSON.stringify(
|
|
403
|
+
defaultRegistry.hydrateEntry(${JSON.stringify(a)}, _jogaks, _meta?.component)
|
|
303
404
|
|
|
304
405
|
if (import.meta.hot) {
|
|
305
406
|
import.meta.hot.accept()
|
|
@@ -309,60 +410,60 @@ export {}
|
|
|
309
410
|
`;
|
|
310
411
|
}
|
|
311
412
|
},
|
|
312
|
-
async handleHotUpdate({ file:
|
|
313
|
-
const
|
|
314
|
-
if (!
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
),
|
|
318
|
-
let
|
|
319
|
-
if (
|
|
413
|
+
async handleHotUpdate({ file: r, modules: f }) {
|
|
414
|
+
const a = /\.jogak\.(tsx?|jsx?)$/.test(r), u = /\.(tsx?|jsx?)$/.test(r) && !a;
|
|
415
|
+
if (!a && !u || d === void 0 || !a) return;
|
|
416
|
+
const s = d.moduleGraph.getModuleById(
|
|
417
|
+
L
|
|
418
|
+
), h = E.get(r), j = h !== void 0 ? O + dt(h) : void 0, i = j !== void 0 ? d.moduleGraph.getModuleById(j) : void 0;
|
|
419
|
+
let m = null, I = {}, R = "";
|
|
420
|
+
if (p !== void 0) {
|
|
320
421
|
try {
|
|
321
|
-
|
|
422
|
+
m = await p.extractMeta(r);
|
|
322
423
|
} catch {
|
|
323
|
-
|
|
424
|
+
m = null;
|
|
324
425
|
}
|
|
325
426
|
try {
|
|
326
|
-
|
|
427
|
+
I = await p.extract(r);
|
|
327
428
|
} catch {
|
|
328
|
-
|
|
429
|
+
I = {};
|
|
329
430
|
}
|
|
330
431
|
try {
|
|
331
|
-
|
|
432
|
+
R = await P(r, "utf8");
|
|
332
433
|
} catch {
|
|
333
|
-
|
|
434
|
+
R = "";
|
|
334
435
|
}
|
|
335
436
|
}
|
|
336
|
-
if (
|
|
337
|
-
|
|
437
|
+
if (m === null) {
|
|
438
|
+
s !== void 0 && d.moduleGraph.invalidateModule(s), i !== void 0 && d.moduleGraph.invalidateModule(i), d.ws.send({ type: "full-reload" });
|
|
338
439
|
return;
|
|
339
440
|
}
|
|
340
|
-
const N =
|
|
341
|
-
if (
|
|
342
|
-
|
|
441
|
+
const N = G(m), z = C.get(r), Q = yt(z, N);
|
|
442
|
+
if (C.set(r, N), !Q || h === void 0) {
|
|
443
|
+
s !== void 0 && d.moduleGraph.invalidateModule(s), i !== void 0 && d.moduleGraph.invalidateModule(i), d.ws.send({ type: "full-reload" });
|
|
343
444
|
return;
|
|
344
445
|
}
|
|
345
|
-
const
|
|
346
|
-
id:
|
|
347
|
-
title:
|
|
348
|
-
jogakNames:
|
|
349
|
-
autoArgTypes:
|
|
350
|
-
userArgTypes:
|
|
351
|
-
source:
|
|
352
|
-
filePath:
|
|
353
|
-
metaExtras:
|
|
446
|
+
const Z = {
|
|
447
|
+
id: h,
|
|
448
|
+
title: m.title,
|
|
449
|
+
jogakNames: m.jogakNames,
|
|
450
|
+
autoArgTypes: I,
|
|
451
|
+
userArgTypes: m.userArgTypes,
|
|
452
|
+
source: R,
|
|
453
|
+
filePath: r,
|
|
454
|
+
metaExtras: m.metaExtras
|
|
354
455
|
};
|
|
355
|
-
i !== void 0 &&
|
|
456
|
+
i !== void 0 && d.moduleGraph.invalidateModule(i), d.ws.send({
|
|
356
457
|
type: "custom",
|
|
357
458
|
event: "jogak:meta-update",
|
|
358
|
-
data: { id:
|
|
459
|
+
data: { id: h, meta: Z }
|
|
359
460
|
});
|
|
360
|
-
const
|
|
361
|
-
return i !== void 0 && !
|
|
461
|
+
const A = [...f];
|
|
462
|
+
return i !== void 0 && !A.includes(i) && A.push(i), A;
|
|
362
463
|
}
|
|
363
464
|
};
|
|
364
465
|
}
|
|
365
|
-
function
|
|
466
|
+
function vt() {
|
|
366
467
|
return `(rawId) => {
|
|
367
468
|
if (typeof Buffer !== 'undefined') return Buffer.from(rawId, 'utf8').toString('base64url')
|
|
368
469
|
// 브라우저 폴백: btoa는 binary string 기준이라 UTF-8을 한번 인코딩해야 한다.
|
|
@@ -373,5 +474,6 @@ function ct() {
|
|
|
373
474
|
}`;
|
|
374
475
|
}
|
|
375
476
|
export {
|
|
376
|
-
|
|
477
|
+
Et as jogak,
|
|
478
|
+
kt as jogakPreviewFramePlugin
|
|
377
479
|
};
|
package/dist/vite/plugin.d.ts
CHANGED
|
@@ -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;
|
|
@@ -18,5 +18,19 @@ export declare const RESOLVED_VIRTUAL_ENTRY_PREFIX: string;
|
|
|
18
18
|
/** Global css 모듈 — 사용자 globalCss를 import한다 (알파.6, opt-in). */
|
|
19
19
|
export declare const VIRTUAL_GLOBAL_CSS_ID = "virtual:jogak/global-css";
|
|
20
20
|
export declare const RESOLVED_VIRTUAL_GLOBAL_CSS_ID: string;
|
|
21
|
+
/**
|
|
22
|
+
* Preview frame entry (알파.8) — 사용자 vite scope의 iframe entry.
|
|
23
|
+
* jogakPreviewFramePlugin이 emit. 사용자 vite의 module graph에 포함되어
|
|
24
|
+
* 사용자 plugins(@tailwindcss/vite 등)가 정상 처리.
|
|
25
|
+
*/
|
|
26
|
+
export declare const VIRTUAL_PREVIEW_ENTRY_ID = "virtual:jogak/preview-entry";
|
|
27
|
+
export declare const RESOLVED_VIRTUAL_PREVIEW_ENTRY_ID: string;
|
|
28
|
+
/**
|
|
29
|
+
* Preview-scope의 사용자 globalCss (알파.8) — 알파.6의 `virtual:jogak/global-css`는
|
|
30
|
+
* jogak SPA scope. 본 모듈은 사용자 vite scope의 preview-frame entry용.
|
|
31
|
+
* jogakPreviewFramePlugin이 emit.
|
|
32
|
+
*/
|
|
33
|
+
export declare const VIRTUAL_PREVIEW_GLOBAL_CSS_ID = "virtual:jogak/preview-global-css";
|
|
34
|
+
export declare const RESOLVED_VIRTUAL_PREVIEW_GLOBAL_CSS_ID: string;
|
|
21
35
|
export declare function idToSlug(id: string): string;
|
|
22
36
|
export declare function slugToId(slug: string): string;
|