@jogak/core 0.1.0-alpha.5 → 0.1.0-alpha.7

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.
@@ -0,0 +1,45 @@
1
+ import { JogakPluginOptions } from './types.js';
2
+ /**
3
+ * `jogak.config.{ts,mts,mjs,js,json}`의 default export 타입.
4
+ *
5
+ * `JogakPluginOptions`의 모든 필드 + 사용자가 자주 변경하는 dev/build 옵션을
6
+ * 통합한다. 모든 필드 optional — 미지정 시 jogak 기본값 또는 CLI 플래그가 적용.
7
+ *
8
+ * **CLI 플래그 우선순위**: CLI 플래그가 본 config의 값을 override한다 (Vite 패턴).
9
+ * 예: `jogak.config.ts`에 `port: 3000`, CLI에 `--port 4000` → 4000 적용.
10
+ *
11
+ * 미노출 필드(예: `cwd`, `framework`, `disableCacheValidation`, `noGenerate`,
12
+ * `emitRegistry`)는 CLI 플래그 전용 또는 자동 감지로만 처리 — 사용자가 config
13
+ * 파일에서 자주 만지지 않는 옵션이라 표면을 줄였다.
14
+ */
15
+ export interface JogakConfig extends JogakPluginOptions {
16
+ /** dev server 포트. 기본 5173. CLI `--port`로 override. */
17
+ readonly port?: number;
18
+ /** dev server bind host. 기본 'localhost'. CLI `--host`로 override. */
19
+ readonly host?: string | boolean;
20
+ /** dev 시작 시 브라우저 자동 오픈. 기본 false. CLI `--open`로 override. */
21
+ readonly open?: boolean | string;
22
+ /** 정적 빌드 출력 디렉토리. 기본 'jogak-static'. CLI `--out-dir`로 override. */
23
+ readonly outDir?: string;
24
+ /** 정적 빌드 base public path. 기본 './'. CLI `--base`로 override. */
25
+ readonly base?: string;
26
+ /** 빌드 minify 모드. 기본 'esbuild'. CLI `--minify`로 override. */
27
+ readonly minify?: boolean | 'esbuild' | 'terser';
28
+ /** 빌드 소스맵. 기본 false. CLI `--sourcemap`로 override. */
29
+ readonly sourcemap?: boolean;
30
+ }
31
+ /**
32
+ * `jogak.config.ts`에서 사용자가 호출하는 identity helper.
33
+ *
34
+ * TypeScript 타입 추론을 위해서만 존재 — 런타임에는 입력 그대로 반환.
35
+ *
36
+ * @example
37
+ * import { defineJogakConfig } from '@jogak/core'
38
+ *
39
+ * export default defineJogakConfig({
40
+ * globalCss: true,
41
+ * previewIsolation: 'none',
42
+ * port: 3000,
43
+ * })
44
+ */
45
+ export declare function defineJogakConfig<T extends JogakConfig>(config: T): T;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export type { ArgType, JogakMeta, Jogak, RegistryEntry, RegistryEntryMeta, CategoryTree, CategoryMetaTree, JogakAdapter, JogakPluginOptions, } 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
+ export { defineJogakConfig, type JogakConfig } from './config.js';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var V=Object.defineProperty;var U=i=>{throw TypeError(i)};var G=(i,t,e)=>t in i?V(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var I=(i,t,e)=>G(i,typeof t!="symbol"?t+"":t,e),z=(i,t,e)=>t.has(i)||U("Cannot "+e);var s=(i,t,e)=>(z(i,t,"read from private field"),e?e.call(i):t.get(i)),f=(i,t,e)=>t.has(i)?U("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(i):t.set(i,e),d=(i,t,e,n)=>(z(i,t,"write to private field"),n?n.call(i,e):t.set(i,e),e),u=(i,t,e)=>(z(i,t,"access private method"),e);var N=(i,t,e,n)=>({set _(r){d(i,t,r,e)},get _(){return s(i,t,n)}});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class F extends Error{constructor(e){super(`[jogak] Unknown entry id: ${e}`);I(this,"id");this.name="UnknownEntryError",this.id=e}}var a,x,b,v,k,E,w,j,A,T,l,m,C,D;class q{constructor(){f(this,l);f(this,a,new Map);f(this,x);f(this,b,new Set);f(this,v);f(this,k);f(this,E);f(this,w);f(this,j);f(this,A,!1);f(this,T,!1)}register(t){const e=H(t);u(this,l,D).call(this,()=>{this.registerMeta(e),this.hydrateEntry(t.id,t.jogaks,t.meta.component)})}unregister(t){const e=s(this,a).get(t);e!==void 0&&(e.kind==="pending"&&e.reject(new F(t)),s(this,a).delete(t),u(this,l,m).call(this))}get(t){const e=s(this,a).get(t);return(e==null?void 0:e.kind)==="hydrated"?e.entry:void 0}getAll(){if(s(this,E)!==void 0)return s(this,E);const t=[];for(const n of u(this,l,C).call(this)){const r=s(this,a).get(n);(r==null?void 0:r.kind)==="hydrated"&&t.push(r.entry)}const e=t;return d(this,E,e),e}search(t){const e=t.toLowerCase();return this.getAll().filter(n=>n.title.toLowerCase().includes(e))}getTree(){if(s(this,w)!==void 0)return s(this,w);const t={};for(const e of this.getAll()){const n=e.title.split("/");let r=t;for(let h=0;h<n.length-1;h++){const c=n[h];if(c===void 0)continue;const g=r[c];(g===void 0||"id"in g)&&(r[c]={}),r=r[c]}const o=n[n.length-1];o!==void 0&&(r[o]=e)}return d(this,w,t),t}clear(){if(s(this,a).size!==0){for(const t of s(this,a).values())t.kind==="pending"&&t.reject(new Error("[jogak] registry cleared"));s(this,a).clear(),u(this,l,m).call(this)}}get size(){let t=0;for(const e of s(this,a).values())e.kind==="hydrated"&&t++;return t}registerMeta(t){const e=s(this,a).get(t.id);if(e===void 0){s(this,a).set(t.id,{kind:"meta",meta:t}),u(this,l,m).call(this);return}if(e.kind==="meta"){s(this,a).set(t.id,{kind:"meta",meta:t}),u(this,l,m).call(this);return}if(e.kind==="pending"){s(this,a).set(t.id,{kind:"pending",meta:t,promise:e.promise,resolve:e.resolve,reject:e.reject}),u(this,l,m).call(this);return}const n={...e.entry,title:t.title,filePath:t.filePath,source:t.source,meta:$(t,e.entry.meta.component)};s(this,a).set(t.id,{kind:"hydrated",meta:t,entry:n}),u(this,l,m).call(this)}hydrateEntry(t,e,n){const r=s(this,a).get(t);let o;r===void 0?(console.warn(`[jogak] hydrateEntry called for unknown id "${t}" — synthesizing minimal meta`),o={id:t,title:t,jogakNames:e.map(c=>c.name),autoArgTypes:{},userArgTypes:{},source:"",filePath:"",metaExtras:{}}):o=r.meta;const h={id:o.id,title:o.title,jogaks:e,meta:$(o,n),...o.filePath?{filePath:o.filePath}:{},...o.source?{source:o.source}:{}};if((r==null?void 0:r.kind)==="pending"){s(this,a).set(t,{kind:"hydrated",meta:o,entry:h}),u(this,l,m).call(this),r.resolve(h);return}s(this,a).set(t,{kind:"hydrated",meta:o,entry:h}),u(this,l,m).call(this)}invalidateEntry(t){const e=s(this,a).get(t);e===void 0||e.kind!=="hydrated"||(s(this,a).set(t,{kind:"meta",meta:e.meta}),u(this,l,m).call(this))}requestEntry(t){const e=s(this,a).get(t);if(e===void 0)return Promise.reject(new F(t));if(e.kind==="hydrated")return Promise.resolve(e.entry);if(e.kind==="pending")return e.promise;const n=s(this,x);if(n===void 0)return Promise.reject(new Error("[jogak] entry loader not set — virtual:jogak index module did not load"));let r,o;const h=new Promise((c,g)=>{r=c,o=g});return s(this,a).set(t,{kind:"pending",meta:e.meta,promise:h,resolve:r,reject:o}),n(t).then(()=>{const c=s(this,a).get(t);(c==null?void 0:c.kind)!=="hydrated"&&o(new Error(`[jogak] entry module loaded but did not hydrate: ${t}`))},c=>{const g=c instanceof Error?c:new Error(String(c)),p=s(this,a).get(t);(p==null?void 0:p.kind)==="pending"&&p.promise===h&&s(this,a).set(t,{kind:"meta",meta:e.meta}),o(g)}),h}getAllMeta(){if(s(this,v)!==void 0)return s(this,v);const t=[];for(const n of u(this,l,C).call(this)){const r=s(this,a).get(n);r!==void 0&&t.push(r.meta)}const e=t;return d(this,v,e),e}getMetaTree(){if(s(this,k)!==void 0)return s(this,k);const t={};for(const e of u(this,l,C).call(this)){const n=s(this,a).get(e);if(n===void 0)continue;const r=n.meta,o=r.title.split("/");let h=t;for(let g=0;g<o.length-1;g++){const p=o[g];if(p===void 0)continue;const R=h[p];(R===void 0||"id"in R)&&(h[p]={}),h=h[p]}const c=o[o.length-1];c!==void 0&&(h[c]=r)}return d(this,k,t),t}getEntryState(t){const e=s(this,a).get(t);return e===void 0?"unknown":e.kind}setEntryLoader(t){d(this,x,t)}subscribe(t){s(this,b).add(t);let e=!0;return()=>{e&&(e=!1,s(this,b).delete(t))}}}a=new WeakMap,x=new WeakMap,b=new WeakMap,v=new WeakMap,k=new WeakMap,E=new WeakMap,w=new WeakMap,j=new WeakMap,A=new WeakMap,T=new WeakMap,l=new WeakSet,m=function(){if(d(this,v,void 0),d(this,k,void 0),d(this,E,void 0),d(this,w,void 0),d(this,j,void 0),s(this,A)){d(this,T,!0);return}const t=Array.from(s(this,b));for(const e of t)try{e()}catch(n){console.error("[jogak] subscribe listener threw:",n)}},C=function(){if(s(this,j)!==void 0)return s(this,j);const t=[];for(const[n,r]of s(this,a))t.push({id:n,title:r.meta.title});t.sort(K);const e=t.map(n=>n.id);return d(this,j,e),e},D=function(t){if(s(this,A)){t();return}d(this,A,!0),d(this,T,!1);try{t()}finally{d(this,A,!1),s(this,T)&&(d(this,T,!1),u(this,l,m).call(this))}};function H(i){const t=i.meta.argTypes??{};return{id:i.id,title:i.title,jogakNames:i.jogaks.map(e=>e.name),autoArgTypes:{},userArgTypes:t,source:i.source??"",filePath:i.filePath??"",metaExtras:{...i.meta.tags!==void 0?{tags:i.meta.tags}:{},...i.meta.parameters!==void 0?{parameters:i.meta.parameters}:{}}}}function $(i,t){const e={...i.autoArgTypes};for(const n of Object.keys(i.userArgTypes)){const r=i.userArgTypes[n];r!==void 0&&(e[n]={...e[n],...r})}return{title:i.title,component:t,argTypes:e,...i.metaExtras.tags!==void 0?{tags:i.metaExtras.tags}:{},...i.metaExtras.parameters!==void 0?{parameters:i.metaExtras.parameters}:{}}}function K(i,t){const e=i.title.localeCompare(t.title,"en",{sensitivity:"base",numeric:!0});return e!==0?e:i.id.localeCompare(t.id,"en",{sensitivity:"base",numeric:!0})}const Q=new q;var y,P,S,M,L;class B{constructor(){f(this,M);f(this,y,[]);f(this,P,new Set);f(this,S,1)}emit(t,e){const n={id:N(this,S)._++,name:t,args:e,timestamp:Date.now()};d(this,y,[...s(this,y),n]),u(this,M,L).call(this)}subscribe(t){return s(this,P).add(t),t(s(this,y)),()=>{s(this,P).delete(t)}}clear(){s(this,y).length!==0&&(d(this,y,[]),u(this,M,L).call(this))}getLogs(){return s(this,y)}}y=new WeakMap,P=new WeakMap,S=new WeakMap,M=new WeakSet,L=function(){for(const t of s(this,P))t(s(this,y))};const O=new B;function J(i,t=O){return(...e)=>{t.emit(i,e)}}function W(i,t,e=O){const n={...i};for(const r of Object.keys(t)){const o=t[r];if(o===void 0)continue;const h=o.action!==void 0&&o.action!==!1,c=o.type==="function";if(!h&&!c||typeof n[r]=="function")continue;const g=typeof o.action=="string"?o.action:r;n[r]=J(g,e)}return n}exports.ActionChannel=B;exports.ComponentRegistry=q;exports.UnknownEntryError=F;exports.action=J;exports.defaultActionChannel=O;exports.defaultRegistry=Q;exports.injectActions=W;
1
+ "use strict";var V=Object.defineProperty;var U=i=>{throw TypeError(i)};var G=(i,t,e)=>t in i?V(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var I=(i,t,e)=>G(i,typeof t!="symbol"?t+"":t,e),z=(i,t,e)=>t.has(i)||U("Cannot "+e);var s=(i,t,e)=>(z(i,t,"read from private field"),e?e.call(i):t.get(i)),u=(i,t,e)=>t.has(i)?U("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(i):t.set(i,e),d=(i,t,e,n)=>(z(i,t,"write to private field"),n?n.call(i,e):t.set(i,e),e),f=(i,t,e)=>(z(i,t,"access private method"),e);var J=(i,t,e,n)=>({set _(r){d(i,t,r,e)},get _(){return s(i,t,n)}});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class F extends Error{constructor(e){super(`[jogak] Unknown entry id: ${e}`);I(this,"id");this.name="UnknownEntryError",this.id=e}}var a,C,b,v,k,E,w,j,A,T,l,m,M,q;class ${constructor(){u(this,l);u(this,a,new Map);u(this,C);u(this,b,new Set);u(this,v);u(this,k);u(this,E);u(this,w);u(this,j);u(this,A,!1);u(this,T,!1)}register(t){const e=H(t);f(this,l,q).call(this,()=>{this.registerMeta(e),this.hydrateEntry(t.id,t.jogaks,t.meta.component)})}unregister(t){const e=s(this,a).get(t);e!==void 0&&(e.kind==="pending"&&e.reject(new F(t)),s(this,a).delete(t),f(this,l,m).call(this))}get(t){const e=s(this,a).get(t);return(e==null?void 0:e.kind)==="hydrated"?e.entry:void 0}getAll(){if(s(this,E)!==void 0)return s(this,E);const t=[];for(const n of f(this,l,M).call(this)){const r=s(this,a).get(n);(r==null?void 0:r.kind)==="hydrated"&&t.push(r.entry)}const e=t;return d(this,E,e),e}search(t){const e=t.toLowerCase();return this.getAll().filter(n=>n.title.toLowerCase().includes(e))}getTree(){if(s(this,w)!==void 0)return s(this,w);const t={};for(const e of this.getAll()){const n=e.title.split("/");let r=t;for(let h=0;h<n.length-1;h++){const c=n[h];if(c===void 0)continue;const g=r[c];(g===void 0||"id"in g)&&(r[c]={}),r=r[c]}const o=n[n.length-1];o!==void 0&&(r[o]=e)}return d(this,w,t),t}clear(){if(s(this,a).size!==0){for(const t of s(this,a).values())t.kind==="pending"&&t.reject(new Error("[jogak] registry cleared"));s(this,a).clear(),f(this,l,m).call(this)}}get size(){let t=0;for(const e of s(this,a).values())e.kind==="hydrated"&&t++;return t}registerMeta(t){const e=s(this,a).get(t.id);if(e===void 0){s(this,a).set(t.id,{kind:"meta",meta:t}),f(this,l,m).call(this);return}if(e.kind==="meta"){s(this,a).set(t.id,{kind:"meta",meta:t}),f(this,l,m).call(this);return}if(e.kind==="pending"){s(this,a).set(t.id,{kind:"pending",meta:t,promise:e.promise,resolve:e.resolve,reject:e.reject}),f(this,l,m).call(this);return}const n={...e.entry,title:t.title,filePath:t.filePath,source:t.source,meta:N(t,e.entry.meta.component)};s(this,a).set(t.id,{kind:"hydrated",meta:t,entry:n}),f(this,l,m).call(this)}hydrateEntry(t,e,n){const r=s(this,a).get(t);let o;r===void 0?(console.warn(`[jogak] hydrateEntry called for unknown id "${t}" — synthesizing minimal meta`),o={id:t,title:t,jogakNames:e.map(c=>c.name),autoArgTypes:{},userArgTypes:{},source:"",filePath:"",metaExtras:{}}):o=r.meta;const h={id:o.id,title:o.title,jogaks:e,meta:N(o,n),...o.filePath?{filePath:o.filePath}:{},...o.source?{source:o.source}:{}};if((r==null?void 0:r.kind)==="pending"){s(this,a).set(t,{kind:"hydrated",meta:o,entry:h}),f(this,l,m).call(this),r.resolve(h);return}s(this,a).set(t,{kind:"hydrated",meta:o,entry:h}),f(this,l,m).call(this)}invalidateEntry(t){const e=s(this,a).get(t);e===void 0||e.kind!=="hydrated"||(s(this,a).set(t,{kind:"meta",meta:e.meta}),f(this,l,m).call(this))}requestEntry(t){const e=s(this,a).get(t);if(e===void 0)return Promise.reject(new F(t));if(e.kind==="hydrated")return Promise.resolve(e.entry);if(e.kind==="pending")return e.promise;const n=s(this,C);if(n===void 0)return Promise.reject(new Error("[jogak] entry loader not set — virtual:jogak index module did not load"));let r,o;const h=new Promise((c,g)=>{r=c,o=g});return s(this,a).set(t,{kind:"pending",meta:e.meta,promise:h,resolve:r,reject:o}),n(t).then(()=>{const c=s(this,a).get(t);(c==null?void 0:c.kind)!=="hydrated"&&o(new Error(`[jogak] entry module loaded but did not hydrate: ${t}`))},c=>{const g=c instanceof Error?c:new Error(String(c)),p=s(this,a).get(t);(p==null?void 0:p.kind)==="pending"&&p.promise===h&&s(this,a).set(t,{kind:"meta",meta:e.meta}),o(g)}),h}getAllMeta(){if(s(this,v)!==void 0)return s(this,v);const t=[];for(const n of f(this,l,M).call(this)){const r=s(this,a).get(n);r!==void 0&&t.push(r.meta)}const e=t;return d(this,v,e),e}getMetaTree(){if(s(this,k)!==void 0)return s(this,k);const t={};for(const e of f(this,l,M).call(this)){const n=s(this,a).get(e);if(n===void 0)continue;const r=n.meta,o=r.title.split("/");let h=t;for(let g=0;g<o.length-1;g++){const p=o[g];if(p===void 0)continue;const R=h[p];(R===void 0||"id"in R)&&(h[p]={}),h=h[p]}const c=o[o.length-1];c!==void 0&&(h[c]=r)}return d(this,k,t),t}getEntryState(t){const e=s(this,a).get(t);return e===void 0?"unknown":e.kind}setEntryLoader(t){d(this,C,t)}subscribe(t){s(this,b).add(t);let e=!0;return()=>{e&&(e=!1,s(this,b).delete(t))}}}a=new WeakMap,C=new WeakMap,b=new WeakMap,v=new WeakMap,k=new WeakMap,E=new WeakMap,w=new WeakMap,j=new WeakMap,A=new WeakMap,T=new WeakMap,l=new WeakSet,m=function(){if(d(this,v,void 0),d(this,k,void 0),d(this,E,void 0),d(this,w,void 0),d(this,j,void 0),s(this,A)){d(this,T,!0);return}const t=Array.from(s(this,b));for(const e of t)try{e()}catch(n){console.error("[jogak] subscribe listener threw:",n)}},M=function(){if(s(this,j)!==void 0)return s(this,j);const t=[];for(const[n,r]of s(this,a))t.push({id:n,title:r.meta.title});t.sort(K);const e=t.map(n=>n.id);return d(this,j,e),e},q=function(t){if(s(this,A)){t();return}d(this,A,!0),d(this,T,!1);try{t()}finally{d(this,A,!1),s(this,T)&&(d(this,T,!1),f(this,l,m).call(this))}};function H(i){const t=i.meta.argTypes??{};return{id:i.id,title:i.title,jogakNames:i.jogaks.map(e=>e.name),autoArgTypes:{},userArgTypes:t,source:i.source??"",filePath:i.filePath??"",metaExtras:{...i.meta.tags!==void 0?{tags:i.meta.tags}:{},...i.meta.parameters!==void 0?{parameters:i.meta.parameters}:{}}}}function N(i,t){const e={...i.autoArgTypes};for(const n of Object.keys(i.userArgTypes)){const r=i.userArgTypes[n];r!==void 0&&(e[n]={...e[n],...r})}return{title:i.title,component:t,argTypes:e,...i.metaExtras.tags!==void 0?{tags:i.metaExtras.tags}:{},...i.metaExtras.parameters!==void 0?{parameters:i.metaExtras.parameters}:{}}}function K(i,t){const e=i.title.localeCompare(t.title,"en",{sensitivity:"base",numeric:!0});return e!==0?e:i.id.localeCompare(t.id,"en",{sensitivity:"base",numeric:!0})}const Q=new $;var y,P,S,x,L;class D{constructor(){u(this,x);u(this,y,[]);u(this,P,new Set);u(this,S,1)}emit(t,e){const n={id:J(this,S)._++,name:t,args:e,timestamp:Date.now()};d(this,y,[...s(this,y),n]),f(this,x,L).call(this)}subscribe(t){return s(this,P).add(t),t(s(this,y)),()=>{s(this,P).delete(t)}}clear(){s(this,y).length!==0&&(d(this,y,[]),f(this,x,L).call(this))}getLogs(){return s(this,y)}}y=new WeakMap,P=new WeakMap,S=new WeakMap,x=new WeakSet,L=function(){for(const t of s(this,P))t(s(this,y))};const O=new D;function B(i,t=O){return(...e)=>{t.emit(i,e)}}function W(i,t,e=O){const n={...i};for(const r of Object.keys(t)){const o=t[r];if(o===void 0)continue;const h=o.action!==void 0&&o.action!==!1,c=o.type==="function";if(!h&&!c||typeof n[r]=="function")continue;const g=typeof o.action=="string"?o.action:r;n[r]=B(g,e)}return n}function X(i){return i}exports.ActionChannel=D;exports.ComponentRegistry=$;exports.UnknownEntryError=F;exports.action=B;exports.defaultActionChannel=O;exports.defaultRegistry=Q;exports.defineJogakConfig=X;exports.injectActions=W;
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- var R = Object.defineProperty;
1
+ var J = Object.defineProperty;
2
2
  var I = (i) => {
3
3
  throw TypeError(i);
4
4
  };
5
- var B = (i, t, e) => t in i ? R(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
6
- var N = (i, t, e) => B(i, typeof t != "symbol" ? t + "" : t, e), z = (i, t, e) => t.has(i) || I("Cannot " + e);
7
- var s = (i, t, e) => (z(i, t, "read from private field"), e ? e.call(i) : t.get(i)), f = (i, t, e) => t.has(i) ? I("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e), c = (i, t, e, n) => (z(i, t, "write to private field"), n ? n.call(i, e) : t.set(i, e), e), u = (i, t, e) => (z(i, t, "access private method"), e);
5
+ var R = (i, t, e) => t in i ? J(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
6
+ var N = (i, t, e) => R(i, typeof t != "symbol" ? t + "" : t, e), z = (i, t, e) => t.has(i) || I("Cannot " + e);
7
+ var s = (i, t, e) => (z(i, t, "read from private field"), e ? e.call(i) : t.get(i)), u = (i, t, e) => t.has(i) ? I("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e), c = (i, t, e, n) => (z(i, t, "write to private field"), n ? n.call(i, e) : t.set(i, e), e), f = (i, t, e) => (z(i, t, "access private method"), e);
8
8
  var O = (i, t, e, n) => ({
9
9
  set _(r) {
10
10
  c(i, t, r, e);
@@ -21,28 +21,28 @@ class U extends Error {
21
21
  }
22
22
  }
23
23
  var a, P, b, v, k, E, w, j, A, T, l, m, C, q;
24
- class J {
24
+ class B {
25
25
  constructor() {
26
- f(this, l);
27
- f(this, a, /* @__PURE__ */ new Map());
28
- f(this, P);
26
+ u(this, l);
27
+ u(this, a, /* @__PURE__ */ new Map());
28
+ u(this, P);
29
29
  // ── F2: subscribe + 내부 캐시 ────────────────────────────────────────
30
- f(this, b, /* @__PURE__ */ new Set());
31
- f(this, v);
32
- f(this, k);
30
+ u(this, b, /* @__PURE__ */ new Set());
31
+ u(this, v);
32
+ u(this, k);
33
33
  // 결정성 fix: hydrated entry list / tree 도 캐시. mutation 시 invalidate.
34
- f(this, E);
35
- f(this, w);
34
+ u(this, E);
35
+ u(this, w);
36
36
  /**
37
37
  * 정렬된 id 순서. mutation 시 invalidate, 다음 호출에서 한 번만 재계산.
38
38
  * getAll / getTree / getAllMeta / getMetaTree 모두 이 순서를 따른다.
39
39
  * 결과: 모든 외부 노출 collection 이 동일 ordering 을 가진다.
40
40
  */
41
- f(this, j);
41
+ u(this, j);
42
42
  /** register()가 registerMeta + hydrateEntry를 합쳐 호출할 때 중간 notify를 억제한다. */
43
- f(this, A, !1);
43
+ u(this, A, !1);
44
44
  /** batch 도중에 mutation이 한 번이라도 일어났는지 — false면 batch 종료 시 notify 안 한다. */
45
- f(this, T, !1);
45
+ u(this, T, !1);
46
46
  }
47
47
  // ── 기존 외부 API: 시그니처 변경 없음. 시맨틱은 hydrated만 표면. ───────────
48
48
  /**
@@ -54,13 +54,13 @@ class J {
54
54
  */
55
55
  register(t) {
56
56
  const e = V(t);
57
- u(this, l, q).call(this, () => {
57
+ f(this, l, q).call(this, () => {
58
58
  this.registerMeta(e), this.hydrateEntry(t.id, t.jogaks, t.meta.component);
59
59
  });
60
60
  }
61
61
  unregister(t) {
62
62
  const e = s(this, a).get(t);
63
- e !== void 0 && (e.kind === "pending" && e.reject(new U(t)), s(this, a).delete(t), u(this, l, m).call(this));
63
+ e !== void 0 && (e.kind === "pending" && e.reject(new U(t)), s(this, a).delete(t), f(this, l, m).call(this));
64
64
  }
65
65
  /** hydrated일 때만 RegistryEntry를 반환한다. meta-only/pending이면 undefined. */
66
66
  get(t) {
@@ -71,7 +71,7 @@ class J {
71
71
  getAll() {
72
72
  if (s(this, E) !== void 0) return s(this, E);
73
73
  const t = [];
74
- for (const n of u(this, l, C).call(this)) {
74
+ for (const n of f(this, l, C).call(this)) {
75
75
  const r = s(this, a).get(n);
76
76
  (r == null ? void 0 : r.kind) === "hydrated" && t.push(r.entry);
77
77
  }
@@ -109,7 +109,7 @@ class J {
109
109
  if (s(this, a).size !== 0) {
110
110
  for (const t of s(this, a).values())
111
111
  t.kind === "pending" && t.reject(new Error("[jogak] registry cleared"));
112
- s(this, a).clear(), u(this, l, m).call(this);
112
+ s(this, a).clear(), f(this, l, m).call(this);
113
113
  }
114
114
  }
115
115
  /** hydrated 개수. */
@@ -127,11 +127,11 @@ class J {
127
127
  registerMeta(t) {
128
128
  const e = s(this, a).get(t.id);
129
129
  if (e === void 0) {
130
- s(this, a).set(t.id, { kind: "meta", meta: t }), u(this, l, m).call(this);
130
+ s(this, a).set(t.id, { kind: "meta", meta: t }), f(this, l, m).call(this);
131
131
  return;
132
132
  }
133
133
  if (e.kind === "meta") {
134
- s(this, a).set(t.id, { kind: "meta", meta: t }), u(this, l, m).call(this);
134
+ s(this, a).set(t.id, { kind: "meta", meta: t }), f(this, l, m).call(this);
135
135
  return;
136
136
  }
137
137
  if (e.kind === "pending") {
@@ -141,7 +141,7 @@ class J {
141
141
  promise: e.promise,
142
142
  resolve: e.resolve,
143
143
  reject: e.reject
144
- }), u(this, l, m).call(this);
144
+ }), f(this, l, m).call(this);
145
145
  return;
146
146
  }
147
147
  const n = {
@@ -151,7 +151,7 @@ class J {
151
151
  source: t.source,
152
152
  meta: $(t, e.entry.meta.component)
153
153
  };
154
- s(this, a).set(t.id, { kind: "hydrated", meta: t, entry: n }), u(this, l, m).call(this);
154
+ s(this, a).set(t.id, { kind: "hydrated", meta: t, entry: n }), f(this, l, m).call(this);
155
155
  }
156
156
  /**
157
157
  * entry 가상모듈이 호출. pending Promise들을 resolve.
@@ -181,10 +181,10 @@ class J {
181
181
  ...o.source ? { source: o.source } : {}
182
182
  };
183
183
  if ((r == null ? void 0 : r.kind) === "pending") {
184
- s(this, a).set(t, { kind: "hydrated", meta: o, entry: h }), u(this, l, m).call(this), r.resolve(h);
184
+ s(this, a).set(t, { kind: "hydrated", meta: o, entry: h }), f(this, l, m).call(this), r.resolve(h);
185
185
  return;
186
186
  }
187
- s(this, a).set(t, { kind: "hydrated", meta: o, entry: h }), u(this, l, m).call(this);
187
+ s(this, a).set(t, { kind: "hydrated", meta: o, entry: h }), f(this, l, m).call(this);
188
188
  }
189
189
  /**
190
190
  * 어댑터가 호출. hydrated였던 entry를 meta 상태로 되돌린다.
@@ -193,7 +193,7 @@ class J {
193
193
  */
194
194
  invalidateEntry(t) {
195
195
  const e = s(this, a).get(t);
196
- e === void 0 || e.kind !== "hydrated" || (s(this, a).set(t, { kind: "meta", meta: e.meta }), u(this, l, m).call(this));
196
+ e === void 0 || e.kind !== "hydrated" || (s(this, a).set(t, { kind: "meta", meta: e.meta }), f(this, l, m).call(this));
197
197
  }
198
198
  /**
199
199
  * UI/어댑터가 호출. entry id로 완전한 RegistryEntry를 비동기 획득.
@@ -250,7 +250,7 @@ class J {
250
250
  getAllMeta() {
251
251
  if (s(this, v) !== void 0) return s(this, v);
252
252
  const t = [];
253
- for (const n of u(this, l, C).call(this)) {
253
+ for (const n of f(this, l, C).call(this)) {
254
254
  const r = s(this, a).get(n);
255
255
  r !== void 0 && t.push(r.meta);
256
256
  }
@@ -264,7 +264,7 @@ class J {
264
264
  getMetaTree() {
265
265
  if (s(this, k) !== void 0) return s(this, k);
266
266
  const t = {};
267
- for (const e of u(this, l, C).call(this)) {
267
+ for (const e of f(this, l, C).call(this)) {
268
268
  const n = s(this, a).get(e);
269
269
  if (n === void 0) continue;
270
270
  const r = n.meta, o = r.title.split("/");
@@ -355,7 +355,7 @@ q = function(t) {
355
355
  try {
356
356
  t();
357
357
  } finally {
358
- c(this, A, !1), s(this, T) && (c(this, T, !1), u(this, l, m).call(this));
358
+ c(this, A, !1), s(this, T) && (c(this, T, !1), f(this, l, m).call(this));
359
359
  }
360
360
  };
361
361
  function V(i) {
@@ -397,14 +397,14 @@ function G(i, t) {
397
397
  });
398
398
  return e !== 0 ? e : i.id.localeCompare(t.id, "en", { sensitivity: "base", numeric: !0 });
399
399
  }
400
- const W = new J();
400
+ const W = new B();
401
401
  var p, x, S, M, F;
402
402
  class H {
403
403
  constructor() {
404
- f(this, M);
405
- f(this, p, []);
406
- f(this, x, /* @__PURE__ */ new Set());
407
- f(this, S, 1);
404
+ u(this, M);
405
+ u(this, p, []);
406
+ u(this, x, /* @__PURE__ */ new Set());
407
+ u(this, S, 1);
408
408
  }
409
409
  emit(t, e) {
410
410
  const n = {
@@ -413,7 +413,7 @@ class H {
413
413
  args: e,
414
414
  timestamp: Date.now()
415
415
  };
416
- c(this, p, [...s(this, p), n]), u(this, M, F).call(this);
416
+ c(this, p, [...s(this, p), n]), f(this, M, F).call(this);
417
417
  }
418
418
  subscribe(t) {
419
419
  return s(this, x).add(t), t(s(this, p)), () => {
@@ -421,7 +421,7 @@ class H {
421
421
  };
422
422
  }
423
423
  clear() {
424
- s(this, p).length !== 0 && (c(this, p, []), u(this, M, F).call(this));
424
+ s(this, p).length !== 0 && (c(this, p, []), f(this, M, F).call(this));
425
425
  }
426
426
  getLogs() {
427
427
  return s(this, p);
@@ -448,12 +448,16 @@ function X(i, t, e = D) {
448
448
  }
449
449
  return n;
450
450
  }
451
+ function Y(i) {
452
+ return i;
453
+ }
451
454
  export {
452
455
  H as ActionChannel,
453
- J as ComponentRegistry,
456
+ B as ComponentRegistry,
454
457
  U as UnknownEntryError,
455
458
  K as action,
456
459
  D as defaultActionChannel,
457
460
  W as defaultRegistry,
461
+ Y as defineJogakConfig,
458
462
  X as injectActions
459
463
  };
package/dist/types.d.ts CHANGED
@@ -154,4 +154,89 @@ export interface JogakPluginOptions {
154
154
  * jogak({ resolveAlias: { '@': './src', '@components': './src/components' } })
155
155
  */
156
156
  readonly resolveAlias?: Readonly<Record<string, string>>;
157
+ /**
158
+ * 사용자 globalCss를 jogak SPA에 import한다 (알파.6 opt-in).
159
+ *
160
+ * 동기:
161
+ * - `runHost`는 vite root를 `@jogak/ui` 패키지로 두고 사용자 `vite.config.ts`/
162
+ * `main.tsx`를 무시하므로(`configFile: false`), 사용자 `index.css`(Tailwind/
163
+ * shadcn 디자인 토큰)가 jogak SPA에 자동 적용되지 않는다.
164
+ * - 본 옵션이 `true`이거나 명시 경로면 plugin이 사용자 css를 가상 모듈로
165
+ * 주입해 jogak SPA가 import한다.
166
+ *
167
+ * 의미:
168
+ * - `false` (default): 미주입. jogak chrome 기본 스타일만 사용 (알파.4~5 동작 그대로).
169
+ * - `true`: `<userRoot>/src/{index,main,styles,global,app,globals}.css` 후보를
170
+ * 순차 검사해 **첫 발견 1개**만 import. 미발견 시 빈 모듈 (no-op).
171
+ * - `string`: 사용자 root 기준 상대 경로 또는 절대 경로 1개. 자동 감지 비활성화.
172
+ * - `string[]`: 명시 경로 N개를 배열 순서대로 모두 import. 자동 감지 비활성화.
173
+ *
174
+ * 자동 감지 후보 (우선순위 순):
175
+ * 1. `src/index.css` (shadcn/ui Vite)
176
+ * 2. `src/main.css`
177
+ * 3. `src/styles.css`
178
+ * 4. `src/styles/globals.css` (Next.js shadcn)
179
+ * 5. `src/styles/index.css`
180
+ * 6. `src/app/globals.css` (Next.js App Router shadcn)
181
+ * 7. `src/global.css`
182
+ * 8. `src/app.css`
183
+ *
184
+ * 격리:
185
+ * - jogak UI는 알파.4~5에서 Tailwind v4 + `prefix=jogak`로 마이그레이션되어
186
+ * 사용자 utility class와 충돌 zero (예: 사용자 `.bg-primary` ≠ jogak `.jogak\:bg-...`).
187
+ * - jogak CSS variable은 `--jogak-*` prefix → 사용자 `:root { --primary }` 같은
188
+ * 토큰과 namespace 충돌 zero.
189
+ * - 단, 사용자 css의 `*` selector / `body` selector / reset 류는 jogak chrome에
190
+ * 영향 가능. README의 "scope 가이드" 패턴 참조.
191
+ *
192
+ * 한계 (알파.7+ 로드맵):
193
+ * - 사용자 css를 preview 영역으로만 한정하는 Shadow DOM/iframe 격리는 미지원.
194
+ * - `previewIsolation` 옵션은 알파.7+에서 별도 도입.
195
+ * - `globalCss: true` 자동 감지는 dev 시작 시점에 한 번만 수행 — 후보 css 파일이
196
+ * dev 시작 후에 새로 추가되면 dev 서버 재시작이 필요하다. 명시 경로
197
+ * (`globalCss: './src/index.css'`)는 파일이 나중에 생성되어도 정상 hot reload된다.
198
+ *
199
+ * @default false
200
+ *
201
+ * @example 자동 감지
202
+ * jogak({ globalCss: true })
203
+ *
204
+ * @example 명시 경로
205
+ * jogak({ globalCss: './src/index.css' })
206
+ *
207
+ * @example 다중 import (디자인 토큰 + reset 분리)
208
+ * jogak({ globalCss: ['./src/tokens.css', './src/index.css'] })
209
+ */
210
+ readonly globalCss?: boolean | string | readonly string[];
211
+ /**
212
+ * Preview 영역의 격리 모드 (알파.7 도입, opt-in).
213
+ *
214
+ * 사용자 globalCss(알파.6의 `globalCss` 옵션)가 jogak chrome에까지 전역 영향을
215
+ * 주는 것을 막고 싶을 때 사용한다. default `'none'`은 알파.6 동작 그대로.
216
+ *
217
+ * 모드:
218
+ * - `'none'` (default): Preview는 jogak SPA와 동일 document에 마운트.
219
+ * 알파.6 chrome 보호 rule(`[data-jogak-shell] :where(button,...)`)만으로
220
+ * 격리. 사용자 globalCss는 chrome + preview 모두 영향.
221
+ * - `'shadow'`: Preview의 `[data-jogak-content]` 영역만 ShadowRoot에 마운트.
222
+ * 사용자 globalCss를 `adoptedStyleSheets`로 ShadowRoot에 주입해 preview에서
223
+ * 디자인 토큰이 작동. **한계**: Radix UI(shadcn dialog/popover/tooltip 등)는
224
+ * `Portal`을 `document.body`로 띄우므로 포털 내용은 ShadowRoot 외부로 빠져
225
+ * utility class가 적용되지 않을 수 있다 (사용자 컴포넌트가 Portal `container`
226
+ * prop으로 ShadowRoot 내부 element를 지정하면 회피 가능). 자세한 한계는
227
+ * README 참조.
228
+ * - `'iframe'`: Preview를 별도 `<iframe>`에 로드. 완벽 격리. **한계**: jogak의
229
+ * "single Vite, no iframe" 차별점과 상충하므로 명시적 opt-in 한정. HMR은
230
+ * iframe도 Vite dev server module이라 작동하지만, args/이벤트 전달이
231
+ * postMessage 또는 `contentWindow` 직접 접근 한 단계 추가됨.
232
+ *
233
+ * @default 'none'
234
+ *
235
+ * @example shadcn/ui dialog가 preview에서 사용자 토큰을 받게 하려면
236
+ * jogak({ globalCss: true, previewIsolation: 'none' }) // 기본 — 충분
237
+ *
238
+ * @example chrome 까지 사용자 reset이 침범하는 게 싫다면
239
+ * jogak({ globalCss: true, previewIsolation: 'shadow' })
240
+ */
241
+ readonly previewIsolation?: 'none' | 'shadow' | 'iframe';
157
242
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 사용자 globalCss 자동 감지 + 옵션 정규화 (알파.6, opt-in).
3
+ *
4
+ * 본 모듈은 `JogakPluginOptions.globalCss` 옵션 값을 절대 경로 배열로 변환한다.
5
+ * 자동 감지(`true`)는 첫 발견 1개만 반환 — 다중 import는 명시 배열로 사용자가 선언.
6
+ *
7
+ * 자동 감지 후보(우선순위 순)는 spec `_workspace/01_arch/api-contracts.md` §4.1을 따른다.
8
+ */
9
+ /**
10
+ * 사용자 globalCss 자동 감지.
11
+ *
12
+ * `<userRoot>/src/...` 후보를 우선순위 순으로 검사해 **첫 발견 1개**만 반환.
13
+ * 미발견 시 빈 배열.
14
+ *
15
+ * 첫 발견 stop 정책:
16
+ * - 사용자가 다중 import를 원하면 명시 배열(`globalCss: ['...', '...']`)을 쓰게 한다.
17
+ * - 자동 감지에서 모든 후보를 import하면 의도치 않은 css 중복(예: index.css와
18
+ * styles.css 둘 다 존재 시)이 발생할 수 있다.
19
+ */
20
+ export declare function detectUserGlobalCss(userRoot: string): readonly string[];
21
+ /**
22
+ * 옵션 값 → 절대 경로 배열로 정규화.
23
+ *
24
+ * - `false`/`undefined`: `[]`
25
+ * - `true`: `detectUserGlobalCss(userRoot)`
26
+ * - `string`: `[resolve(userRoot, string)]`. 빈 문자열은 `[]`.
27
+ * - `string[]`: 각 요소 resolve, 빈 요소 무시 (배열 순서 보존)
28
+ *
29
+ * `existsSync` 검증은 명시 경로(string/string[])에서는 하지 않는다 — 사용자가
30
+ * 의도적으로 빈 파일 또는 동적 css generator를 쓸 수 있고, 미존재 시 Vite가
31
+ * 자체 에러로 알려주는 게 더 명확하다 (silent skip은 디버깅 어려움).
32
+ */
33
+ export declare function resolveGlobalCssPaths(option: boolean | string | readonly string[] | undefined, userRoot: string): readonly string[];
@@ -1,21 +1,27 @@
1
- "use strict";var V=Object.create;var N=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,K=Object.prototype.hasOwnProperty;var q=(e,o,a,c)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of J(o))!K.call(e,s)&&s!==a&&N(e,s,{get:()=>o[s],enumerable:!(c=G(o,s))||c.enumerable});return e};var W=(e,o,a)=>(a=e!=null?V(B(e)):{},q(o||!e||!e.__esModule?N(a,"default",{value:e,enumerable:!0}):a,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("node:path"),_=require("node:fs"),w=require("node:fs/promises"),O=require("../extractor-client-CiWszHel.cjs"),X=["@jogak/core","@jogak/react","@jogak/web-components","@jogak/next"];async function P(e){try{const c=await w.stat(e);if(!c.isDirectory())return c.mtimeMs}catch{return 0}let o=0,a;try{a=await w.readdir(e)}catch{return 0}for(const c of a){const s=p.join(e,c);try{const u=await w.stat(s);if(u.isDirectory()){const y=await P(s);y>o&&(o=y)}else u.mtimeMs>o&&(o=u.mtimeMs)}catch{continue}}return o}async function Y(e){const o=p.resolve(e.root,"node_modules/.vite/deps");if(!_.existsSync(o))return{purged:!1};const a=p.join(o,"_metadata.json");if(!_.existsSync(a))return{purged:!1};let c;try{c=(await w.stat(a)).mtimeMs}catch(u){return e.logger.warn(`[jogak] cache validation: failed to stat _metadata.json (${u.message})`),{purged:!1}}const s=e.packages??X;for(const u of s){const y=p.resolve(e.root,"node_modules",u,"dist");if(!_.existsSync(y))continue;let n;try{n=await P(y)}catch(l){e.logger.warn(`[jogak] cache validation: failed to walk ${u}/dist (${l.message})`);continue}if(n>c+1e3)try{return await w.rm(o,{recursive:!0,force:!0}),e.logger.info(`[jogak] vite deps cache invalidated (stale): ${u} dist newer than cache`),{purged:!0,reason:u}}catch(l){return e.logger.warn(`[jogak] cache validation: failed to purge ${o} (${l.message})`),{purged:!1}}}return{purged:!1}}function H(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,"")}function z(e){if(_.existsSync(e))try{const o=_.readFileSync(e,"utf8");return JSON.parse(H(o))}catch{return}}function Q(e,o,a){if(!e.endsWith("/*")||!o.endsWith("/*"))return;const c=e.slice(0,-2),s=p.resolve(a,o.slice(0,-2));return[c,s]}function Z(e,o){var s,u;const a={},c=new Set([e,p.resolve(o,"tsconfig.app.json")]);for(const y of c){const n=z(y);if(n===void 0)continue;const l=(s=n.compilerOptions)==null?void 0:s.paths;if(l===void 0)continue;const S=((u=n.compilerOptions)==null?void 0:u.baseUrl)??".",j=p.resolve(p.dirname(y),S);for(const[x,T]of Object.entries(l)){const M=T[0];if(M===void 0)continue;const t=Q(x,M,j);if(t===void 0)continue;const[f,r]=t;a[f]===void 0&&(a[f]=r)}}return a}const $="virtual:jogak",C="\0"+$,F="virtual:jogak/entry/",A="\0"+F;function ee(e){return Buffer.from(e,"utf8").toString("base64url")}function te(e){return Buffer.from(e,"base64url").toString("utf8")}function R(e){return{title:e.title,jogakNamesKey:[...e.jogakNames].sort().join("|")}}function oe(e,o){return e!==void 0&&e.title===o.title&&e.jogakNamesKey===o.jogakNamesKey}function re(e={}){const{patterns:o=["src/**/*.jogak.ts","src/**/*.jogak.tsx"],codeTheme:a="vsDark"}=e,c=e.cwd,s=e.tsConfigFilePath,u=e.disableCacheValidation===!0,y=e.resolveAlias;let n,l,S;const j=new Map,x=new Map,T=new Map;async function M(){const{glob:t}=await import("glob"),f=S??process.cwd(),r=(await t(o,{cwd:f,absolute:!0})).sort(),g=[];j.clear(),x.clear();for(const d of r){let v="";try{v=await w.readFile(d,"utf8")}catch{continue}let h={},i=null;if(l!==void 0){try{h=await l.extract(d)}catch{h={}}try{i=await l.extractMeta(d)}catch{i=null}}if(i===null)continue;const m=i.title;j.set(m,d),x.set(d,m);const k={id:m,title:i.title,jogakNames:i.jogakNames,autoArgTypes:h,userArgTypes:i.userArgTypes,source:v,filePath:d,metaExtras:i.metaExtras};T.set(d,R(k)),g.push({id:m,filePath:d,meta:k})}return g}return{name:"vite-plugin-jogak",config(){const t=c??process.cwd(),f=s??p.resolve(t,"tsconfig.json"),r=Z(f,t),g={};if(y!==void 0)for(const[v,h]of Object.entries(y))g[v]=p.resolve(t,h);const d={...r,...g};if(Object.keys(d).length!==0)return{resolve:{alias:d}}},async configResolved(t){S=c??t.root,t.command==="serve"&&!u&&await Y({root:t.root,logger:{info:r=>t.logger.info(r),warn:r=>t.logger.warn(r)}});const f=s??p.resolve(S,"tsconfig.json");l=_.existsSync(f)?O.createPropsExtractor({tsConfigFilePath:f}):O.createPropsExtractor()},configureServer(t){n=t},buildEnd(){l==null||l.releaseCache()},resolveId(t){if(t===$)return C;if(t.startsWith(F))return"\0"+t},async load(t){if(t===C){const r=(await M()).map(g=>g.meta);return`import { defaultRegistry } from '@jogak/core'
1
+ "use strict";var K=Object.create;var L=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var X=Object.getPrototypeOf,Y=Object.prototype.hasOwnProperty;var H=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of W(t))!Y.call(e,a)&&a!==s&&L(e,a,{get:()=>t[a],enumerable:!(o=q(t,a))||o.enumerable});return e};var z=(e,t,s)=>(s=e!=null?K(X(e)):{},H(t||!e||!e.__esModule?L(s,"default",{value:e,enumerable:!0}):s,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("node:path"),_=require("node:fs"),k=require("node:fs/promises"),R=require("../extractor-client-CiWszHel.cjs"),Q=["@jogak/core","@jogak/react","@jogak/web-components","@jogak/next"];async function P(e){try{const o=await k.stat(e);if(!o.isDirectory())return o.mtimeMs}catch{return 0}let t=0,s;try{s=await k.readdir(e)}catch{return 0}for(const o of s){const a=f.join(e,o);try{const l=await k.stat(a);if(l.isDirectory()){const y=await P(a);y>t&&(t=y)}else l.mtimeMs>t&&(t=l.mtimeMs)}catch{continue}}return t}async function Z(e){const t=f.resolve(e.root,"node_modules/.vite/deps");if(!_.existsSync(t))return{purged:!1};const s=f.join(t,"_metadata.json");if(!_.existsSync(s))return{purged:!1};let o;try{o=(await k.stat(s)).mtimeMs}catch(l){return e.logger.warn(`[jogak] cache validation: failed to stat _metadata.json (${l.message})`),{purged:!1}}const a=e.packages??Q;for(const l of a){const y=f.resolve(e.root,"node_modules",l,"dist");if(!_.existsSync(y))continue;let h;try{h=await P(y)}catch(w){e.logger.warn(`[jogak] cache validation: failed to walk ${l}/dist (${w.message})`);continue}if(h>o+1e3)try{return await k.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 ee=["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 te(e){for(const t of ee){const s=f.resolve(e,t);if(_.existsSync(s))return[s]}return[]}function re(e,t){if(e===void 0||e===!1)return[];if(e===!0)return te(t);if(typeof e=="string")return e.length>0?[f.resolve(t,e)]:[];const s=[];for(const o of e)typeof o=="string"&&o.length>0&&s.push(f.resolve(t,o));return s}function se(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,"")}function oe(e){if(_.existsSync(e))try{const t=_.readFileSync(e,"utf8");return JSON.parse(se(t))}catch{return}}function ne(e,t,s){if(!e.endsWith("/*")||!t.endsWith("/*"))return;const o=e.slice(0,-2),a=f.resolve(s,t.slice(0,-2));return[o,a]}function ae(e,t){var a,l;const s={},o=new Set([e,f.resolve(t,"tsconfig.app.json")]);for(const y of o){const h=oe(y);if(h===void 0)continue;const w=(a=h.compilerOptions)==null?void 0:a.paths;if(w===void 0)continue;const d=((l=h.compilerOptions)==null?void 0:l.baseUrl)??".",p=f.resolve(f.dirname(y),d);for(const[S,b]of Object.entries(w)){const x=b[0];if(x===void 0)continue;const C=ne(S,x,p);if(C===void 0)continue;const[A,r]=C;s[A]===void 0&&(s[A]=r)}}return s}const F="virtual:jogak",M="\0"+F,G="virtual:jogak/entry/",O="\0"+G,U="virtual:jogak/global-css",$="\0"+U;function ie(e){return Buffer.from(e,"utf8").toString("base64url")}function ce(e){return Buffer.from(e,"base64url").toString("utf8")}function D(e){return{title:e.title,jogakNamesKey:[...e.jogakNames].sort().join("|")}}function le(e,t){return e!==void 0&&e.title===t.title&&e.jogakNamesKey===t.jogakNamesKey}function ue(e={}){const{patterns:t=["src/**/*.jogak.ts","src/**/*.jogak.tsx"],codeTheme:s="vsDark"}=e,o=e.cwd,a=e.tsConfigFilePath,l=e.disableCacheValidation===!0,y=e.resolveAlias,h=e.globalCss,w=e.previewIsolation??"none";let d,p,S;const b=new Map,x=new Map,C=new Map;async function A(){const{glob:r}=await import("glob"),g=S??process.cwd(),n=(await r(t,{cwd:g,absolute:!0})).sort(),u=[];b.clear(),x.clear();for(const i of n){let v="";try{v=await k.readFile(i,"utf8")}catch{continue}let j={},c=null;if(p!==void 0){try{j=await p.extract(i)}catch{j={}}try{c=await p.extractMeta(i)}catch{c=null}}if(c===null)continue;const m=c.title;b.set(m,i),x.set(i,m);const T={id:m,title:c.title,jogakNames:c.jogakNames,autoArgTypes:j,userArgTypes:c.userArgTypes,source:v,filePath:i,metaExtras:c.metaExtras};C.set(i,D(T)),u.push({id:m,filePath:i,meta:T})}return u}return{name:"vite-plugin-jogak",config(){const r=o??process.cwd(),g=a??f.resolve(r,"tsconfig.json"),n=ae(g,r),u={};if(y!==void 0)for(const[v,j]of Object.entries(y))u[v]=f.resolve(r,j);const i={...n,...u};if(Object.keys(i).length!==0)return{resolve:{alias:i}}},async configResolved(r){S=o??r.root,r.command==="serve"&&!l&&await Z({root:r.root,logger:{info:n=>r.logger.info(n),warn:n=>r.logger.warn(n)}});const g=a??f.resolve(S,"tsconfig.json");p=_.existsSync(g)?R.createPropsExtractor({tsConfigFilePath:g}):R.createPropsExtractor()},configureServer(r){d=r},buildEnd(){p==null||p.releaseCache()},resolveId(r){if(r===F)return M;if(r===U)return $;if(r.startsWith(G))return"\0"+r},async load(r){if(r===$){const g=S??process.cwd(),n=re(h,g);return n.length===0?`// [jogak] globalCss not configured or no candidates found.
2
+ export {}
3
+ `:`${n.map(i=>`import ${JSON.stringify(i)}`).join(`
4
+ `)}
5
+ export {}
6
+ `}if(r===M){const n=(await A()).map(u=>u.meta);return`import { defaultRegistry } from '@jogak/core'
2
7
 
3
8
  const _entryLoader = (slug) =>
4
9
  import(/* @vite-ignore */ '/@id/__x00__virtual:jogak/entry/' + slug)
5
10
  defaultRegistry.setEntryLoader((id) => {
6
- const slug = ${ae()}
11
+ const slug = ${de()}
7
12
  return _entryLoader(slug(id))
8
13
  })
9
14
 
10
- const _metas = ${JSON.stringify(r)}
15
+ const _metas = ${JSON.stringify(n)}
11
16
 
12
17
  for (const m of _metas) defaultRegistry.registerMeta(m)
13
18
 
14
- export const _jogakCodeTheme = ${JSON.stringify(a)}
19
+ export const _jogakCodeTheme = ${JSON.stringify(s)}
20
+ export const _jogakPreviewIsolation = ${JSON.stringify(w)}
15
21
  export const _jogakMetas = _metas
16
- `}if(t.startsWith(A)){const f=t.slice(A.length),r=te(f);let g=j.get(r);return g===void 0&&(await M(),g=j.get(r)),g===void 0?`// [jogak] unknown entry id: ${JSON.stringify(r)}
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)}
17
23
  export {}
18
- `:`import * as _user from ${JSON.stringify(g)}
24
+ `:`import * as _user from ${JSON.stringify(u)}
19
25
  import { defaultRegistry } from '@jogak/core'
20
26
 
21
27
  const _meta = _user.default
@@ -24,18 +30,18 @@ delete _named.default
24
30
  const _jogaks = Object.values(_named).filter(
25
31
  (v) => v !== null && typeof v === 'object' && typeof v.name === 'string'
26
32
  )
27
- defaultRegistry.hydrateEntry(${JSON.stringify(r)}, _jogaks, _meta?.component)
33
+ defaultRegistry.hydrateEntry(${JSON.stringify(n)}, _jogaks, _meta?.component)
28
34
 
29
35
  if (import.meta.hot) {
30
36
  import.meta.hot.accept()
31
37
  }
32
38
 
33
39
  export {}
34
- `}},async handleHotUpdate({file:t,modules:f}){const r=/\.jogak\.(tsx?|jsx?)$/.test(t),g=/\.(tsx?|jsx?)$/.test(t)&&!r;if(!r&&!g||n===void 0||!r)return;const d=n.moduleGraph.getModuleById(C),v=x.get(t),h=v!==void 0?A+ee(v):void 0,i=h!==void 0?n.moduleGraph.getModuleById(h):void 0;let m=null,k={},E="";if(l!==void 0){try{m=await l.extractMeta(t)}catch{m=null}try{k=await l.extract(t)}catch{k={}}try{E=await w.readFile(t,"utf8")}catch{E=""}}if(m===null){d!==void 0&&n.moduleGraph.invalidateModule(d),i!==void 0&&n.moduleGraph.invalidateModule(i),n.ws.send({type:"full-reload"});return}const I=R(m),D=T.get(t),L=oe(D,I);if(T.set(t,I),!L||v===void 0){d!==void 0&&n.moduleGraph.invalidateModule(d),i!==void 0&&n.moduleGraph.invalidateModule(i),n.ws.send({type:"full-reload"});return}const U={id:v,title:m.title,jogakNames:m.jogakNames,autoArgTypes:k,userArgTypes:m.userArgTypes,source:E,filePath:t,metaExtras:m.metaExtras};i!==void 0&&n.moduleGraph.invalidateModule(i),n.ws.send({type:"custom",event:"jogak:meta-update",data:{id:v,meta:U}});const b=[...f];return i!==void 0&&!b.includes(i)&&b.push(i),b}}}function ae(){return`(rawId) => {
40
+ `}},async handleHotUpdate({file:r,modules:g}){const n=/\.jogak\.(tsx?|jsx?)$/.test(r),u=/\.(tsx?|jsx?)$/.test(r)&&!n;if(!n&&!u||d===void 0||!n)return;const i=d.moduleGraph.getModuleById(M),v=x.get(r),j=v!==void 0?O+ie(v):void 0,c=j!==void 0?d.moduleGraph.getModuleById(j):void 0;let m=null,T={},E="";if(p!==void 0){try{m=await p.extractMeta(r)}catch{m=null}try{T=await p.extract(r)}catch{T={}}try{E=await k.readFile(r,"utf8")}catch{E=""}}if(m===null){i!==void 0&&d.moduleGraph.invalidateModule(i),c!==void 0&&d.moduleGraph.invalidateModule(c),d.ws.send({type:"full-reload"});return}const N=D(m),V=C.get(r),J=le(V,N);if(C.set(r,N),!J||v===void 0){i!==void 0&&d.moduleGraph.invalidateModule(i),c!==void 0&&d.moduleGraph.invalidateModule(c),d.ws.send({type:"full-reload"});return}const B={id:v,title:m.title,jogakNames:m.jogakNames,autoArgTypes:T,userArgTypes:m.userArgTypes,source:E,filePath:r,metaExtras:m.metaExtras};c!==void 0&&d.moduleGraph.invalidateModule(c),d.ws.send({type:"custom",event:"jogak:meta-update",data:{id:v,meta:B}});const I=[...g];return c!==void 0&&!I.includes(c)&&I.push(c),I}}}function de(){return`(rawId) => {
35
41
  if (typeof Buffer !== 'undefined') return Buffer.from(rawId, 'utf8').toString('base64url')
36
42
  // 브라우저 폴백: btoa는 binary string 기준이라 UTF-8을 한번 인코딩해야 한다.
37
43
  const enc = new TextEncoder().encode(rawId)
38
44
  let bin = ''
39
45
  for (let i = 0; i < enc.length; i++) bin += String.fromCharCode(enc[i])
40
46
  return btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')
41
- }`}exports.jogak=re;
47
+ }`}exports.jogak=ue;
@@ -1,33 +1,33 @@
1
- import { resolve as h, join as $, dirname as G } from "node:path";
2
- import { existsSync as S, readFileSync as J } from "node:fs";
3
- import { stat as C, rm as B, readdir as K, readFile as N } from "node:fs/promises";
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
4
  import { c as R } from "../extractor-client-CReBed7x.js";
5
- const W = [
5
+ const H = [
6
6
  "@jogak/core",
7
7
  "@jogak/react",
8
8
  "@jogak/web-components",
9
9
  "@jogak/next"
10
10
  ];
11
- async function P(t) {
11
+ async function F(t) {
12
12
  try {
13
- const l = await C(t);
14
- if (!l.isDirectory())
15
- return l.mtimeMs;
13
+ const a = await O(t);
14
+ if (!a.isDirectory())
15
+ return a.mtimeMs;
16
16
  } catch {
17
17
  return 0;
18
18
  }
19
- let o = 0, f;
19
+ let o = 0, s;
20
20
  try {
21
- f = await K(t);
21
+ s = await q(t);
22
22
  } catch {
23
23
  return 0;
24
24
  }
25
- for (const l of f) {
26
- const m = $(t, l);
25
+ for (const a of s) {
26
+ const g = P(t, a);
27
27
  try {
28
- const c = await C(m);
28
+ const c = await O(g);
29
29
  if (c.isDirectory()) {
30
- const p = await P(m);
30
+ const p = await F(g);
31
31
  p > o && (o = p);
32
32
  } else c.mtimeMs > o && (o = c.mtimeMs);
33
33
  } catch {
@@ -36,149 +36,176 @@ async function P(t) {
36
36
  }
37
37
  return o;
38
38
  }
39
- async function X(t) {
40
- const o = h(t.root, "node_modules/.vite/deps");
41
- if (!S(o))
39
+ async function z(t) {
40
+ const o = y(t.root, "node_modules/.vite/deps");
41
+ if (!T(o))
42
42
  return { purged: !1 };
43
- const f = $(o, "_metadata.json");
44
- if (!S(f))
43
+ const s = P(o, "_metadata.json");
44
+ if (!T(s))
45
45
  return { purged: !1 };
46
- let l;
46
+ let a;
47
47
  try {
48
- l = (await C(f)).mtimeMs;
48
+ a = (await O(s)).mtimeMs;
49
49
  } catch (c) {
50
50
  return t.logger.warn(
51
51
  `[jogak] cache validation: failed to stat _metadata.json (${c.message})`
52
52
  ), { purged: !1 };
53
53
  }
54
- const m = t.packages ?? W;
55
- for (const c of m) {
56
- const p = h(t.root, "node_modules", c, "dist");
57
- if (!S(p)) continue;
58
- let r;
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;
59
59
  try {
60
- r = await P(p);
61
- } catch (i) {
60
+ h = await F(p);
61
+ } catch (w) {
62
62
  t.logger.warn(
63
- `[jogak] cache validation: failed to walk ${c}/dist (${i.message})`
63
+ `[jogak] cache validation: failed to walk ${c}/dist (${w.message})`
64
64
  );
65
65
  continue;
66
66
  }
67
- if (r > l + 1e3)
67
+ if (h > a + 1e3)
68
68
  try {
69
- return await B(o, { recursive: !0, force: !0 }), t.logger.info(
69
+ return await Y(o, { recursive: !0, force: !0 }), t.logger.info(
70
70
  `[jogak] vite deps cache invalidated (stale): ${c} dist newer than cache`
71
71
  ), { purged: !0, reason: c };
72
- } catch (i) {
72
+ } catch (w) {
73
73
  return t.logger.warn(
74
- `[jogak] cache validation: failed to purge ${o} (${i.message})`
74
+ `[jogak] cache validation: failed to purge ${o} (${w.message})`
75
75
  ), { purged: !1 };
76
76
  }
77
77
  }
78
78
  return { purged: !1 };
79
79
  }
80
- function Y(t) {
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
108
  return t.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
82
109
  }
83
- function q(t) {
84
- if (S(t))
110
+ function ot(t) {
111
+ if (T(t))
85
112
  try {
86
- const o = J(t, "utf8");
87
- return JSON.parse(Y(o));
113
+ const o = X(t, "utf8");
114
+ return JSON.parse(et(o));
88
115
  } catch {
89
116
  return;
90
117
  }
91
118
  }
92
- function H(t, o, f) {
119
+ function rt(t, o, s) {
93
120
  if (!t.endsWith("/*") || !o.endsWith("/*")) return;
94
- const l = t.slice(0, -2), m = h(f, o.slice(0, -2));
95
- return [l, m];
121
+ const a = t.slice(0, -2), g = y(s, o.slice(0, -2));
122
+ return [a, g];
96
123
  }
97
- function z(t, o) {
98
- var m, c;
99
- const f = {}, l = /* @__PURE__ */ new Set([
124
+ function st(t, o) {
125
+ var g, c;
126
+ const s = {}, a = /* @__PURE__ */ new Set([
100
127
  t,
101
- h(o, "tsconfig.app.json")
128
+ y(o, "tsconfig.app.json")
102
129
  ]);
103
- for (const p of l) {
104
- const r = q(p);
105
- if (r === void 0) continue;
106
- const i = (m = r.compilerOptions) == null ? void 0 : m.paths;
107
- if (i === void 0) continue;
108
- const k = ((c = r.compilerOptions) == null ? void 0 : c.baseUrl) ?? ".", w = h(G(p), k);
109
- for (const [_, T] of Object.entries(i)) {
110
- const M = T[0];
111
- if (M === void 0) continue;
112
- const e = H(_, M, w);
113
- if (e === void 0) continue;
114
- const [d, a] = e;
115
- f[d] === void 0 && (f[d] = a);
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;
134
+ 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);
116
143
  }
117
144
  }
118
- return f;
145
+ return s;
119
146
  }
120
- const D = "virtual:jogak", x = "\0" + D, F = "virtual:jogak/entry/", A = "\0" + F;
121
- function Q(t) {
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) {
122
149
  return Buffer.from(t, "utf8").toString("base64url");
123
150
  }
124
- function Z(t) {
151
+ function nt(t) {
125
152
  return Buffer.from(t, "base64url").toString("utf8");
126
153
  }
127
- function O(t) {
154
+ function D(t) {
128
155
  return {
129
156
  title: t.title,
130
157
  jogakNamesKey: [...t.jogakNames].sort().join("|")
131
158
  };
132
159
  }
133
- function tt(t, o) {
160
+ function it(t, o) {
134
161
  return t !== void 0 && t.title === o.title && t.jogakNamesKey === o.jogakNamesKey;
135
162
  }
136
- function it(t = {}) {
163
+ function gt(t = {}) {
137
164
  const {
138
165
  patterns: o = ["src/**/*.jogak.ts", "src/**/*.jogak.tsx"],
139
- codeTheme: f = "vsDark"
140
- } = t, l = t.cwd, m = t.tsConfigFilePath, c = t.disableCacheValidation === !0, p = t.resolveAlias;
141
- let r, i, k;
142
- const w = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), T = /* @__PURE__ */ new Map();
143
- async function M() {
144
- const { glob: e } = await import("glob"), d = k ?? process.cwd(), a = (await e(o, { cwd: d, absolute: !0 })).sort(), u = [];
145
- w.clear(), _.clear();
146
- for (const s of a) {
147
- let y = "";
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 ?? "none";
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) {
174
+ let v = "";
148
175
  try {
149
- y = await N(s, "utf8");
176
+ v = await L(n, "utf8");
150
177
  } catch {
151
178
  continue;
152
179
  }
153
- let v = {}, n = null;
154
- if (i !== void 0) {
180
+ let j = {}, i = null;
181
+ if (m !== void 0) {
155
182
  try {
156
- v = await i.extract(s);
183
+ j = await m.extract(n);
157
184
  } catch {
158
- v = {};
185
+ j = {};
159
186
  }
160
187
  try {
161
- n = await i.extractMeta(s);
188
+ i = await m.extractMeta(n);
162
189
  } catch {
163
- n = null;
190
+ i = null;
164
191
  }
165
192
  }
166
- if (n === null) continue;
167
- const g = n.title;
168
- w.set(g, s), _.set(s, g);
169
- const j = {
170
- id: g,
171
- title: n.title,
172
- jogakNames: n.jogakNames,
173
- autoArgTypes: v,
174
- userArgTypes: n.userArgTypes,
175
- source: y,
176
- filePath: s,
177
- metaExtras: n.metaExtras
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,
202
+ source: v,
203
+ filePath: n,
204
+ metaExtras: i.metaExtras
178
205
  };
179
- T.set(s, O(j)), u.push({ id: g, filePath: s, meta: j });
206
+ b.set(n, D(C)), l.push({ id: f, filePath: n, meta: C });
180
207
  }
181
- return u;
208
+ return l;
182
209
  }
183
210
  return {
184
211
  name: "vite-plugin-jogak",
@@ -193,65 +220,77 @@ function it(t = {}) {
193
220
  * 우선순위: `options.resolveAlias` (명시) > tsconfig 자동 추출.
194
221
  */
195
222
  config() {
196
- const e = l ?? process.cwd(), d = m ?? h(e, "tsconfig.json"), a = z(d, e), u = {};
223
+ const e = a ?? process.cwd(), d = g ?? y(e, "tsconfig.json"), r = st(d, e), l = {};
197
224
  if (p !== void 0)
198
- for (const [y, v] of Object.entries(p))
199
- u[y] = h(e, v);
200
- const s = { ...a, ...u };
201
- if (Object.keys(s).length !== 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)
202
229
  return {
203
- resolve: { alias: s }
230
+ resolve: { alias: n }
204
231
  };
205
232
  },
206
233
  async configResolved(e) {
207
- k = l ?? e.root, e.command === "serve" && !c && await X({
234
+ _ = a ?? e.root, e.command === "serve" && !c && await z({
208
235
  root: e.root,
209
236
  logger: {
210
- info: (a) => e.logger.info(a),
211
- warn: (a) => e.logger.warn(a)
237
+ info: (r) => e.logger.info(r),
238
+ warn: (r) => e.logger.warn(r)
212
239
  }
213
240
  });
214
- const d = m ?? h(k, "tsconfig.json");
215
- i = S(d) ? R({ tsConfigFilePath: d }) : R();
241
+ const d = g ?? y(_, "tsconfig.json");
242
+ m = T(d) ? R({ tsConfigFilePath: d }) : R();
216
243
  },
217
244
  configureServer(e) {
218
- r = e;
245
+ u = e;
219
246
  },
220
247
  buildEnd() {
221
- i == null || i.releaseCache();
248
+ m == null || m.releaseCache();
222
249
  },
223
250
  resolveId(e) {
224
- if (e === D)
225
- return x;
226
- if (e.startsWith(F))
251
+ if (e === G)
252
+ return E;
253
+ if (e === V)
254
+ return $;
255
+ if (e.startsWith(U))
227
256
  return "\0" + e;
228
257
  },
229
258
  async load(e) {
230
- if (e === x) {
231
- const a = (await M()).map((u) => u.meta);
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.
262
+ export {}
263
+ ` : `${r.map((n) => `import ${JSON.stringify(n)}`).join(`
264
+ `)}
265
+ export {}
266
+ `;
267
+ }
268
+ if (e === E) {
269
+ const r = (await A()).map((l) => l.meta);
232
270
  return `import { defaultRegistry } from '@jogak/core'
233
271
 
234
272
  const _entryLoader = (slug) =>
235
273
  import(/* @vite-ignore */ '/@id/__x00__virtual:jogak/entry/' + slug)
236
274
  defaultRegistry.setEntryLoader((id) => {
237
- const slug = ${et()}
275
+ const slug = ${ct()}
238
276
  return _entryLoader(slug(id))
239
277
  })
240
278
 
241
- const _metas = ${JSON.stringify(a)}
279
+ const _metas = ${JSON.stringify(r)}
242
280
 
243
281
  for (const m of _metas) defaultRegistry.registerMeta(m)
244
282
 
245
- export const _jogakCodeTheme = ${JSON.stringify(f)}
283
+ export const _jogakCodeTheme = ${JSON.stringify(s)}
284
+ export const _jogakPreviewIsolation = ${JSON.stringify(w)}
246
285
  export const _jogakMetas = _metas
247
286
  `;
248
287
  }
249
- if (e.startsWith(A)) {
250
- const d = e.slice(A.length), a = Z(d);
251
- let u = w.get(a);
252
- return u === void 0 && (await M(), u = w.get(a)), u === void 0 ? `// [jogak] unknown entry id: ${JSON.stringify(a)}
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)}
253
292
  export {}
254
- ` : `import * as _user from ${JSON.stringify(u)}
293
+ ` : `import * as _user from ${JSON.stringify(l)}
255
294
  import { defaultRegistry } from '@jogak/core'
256
295
 
257
296
  const _meta = _user.default
@@ -260,7 +299,7 @@ delete _named.default
260
299
  const _jogaks = Object.values(_named).filter(
261
300
  (v) => v !== null && typeof v === 'object' && typeof v.name === 'string'
262
301
  )
263
- defaultRegistry.hydrateEntry(${JSON.stringify(a)}, _jogaks, _meta?.component)
302
+ defaultRegistry.hydrateEntry(${JSON.stringify(r)}, _jogaks, _meta?.component)
264
303
 
265
304
  if (import.meta.hot) {
266
305
  import.meta.hot.accept()
@@ -271,59 +310,59 @@ export {}
271
310
  }
272
311
  },
273
312
  async handleHotUpdate({ file: e, modules: d }) {
274
- const a = /\.jogak\.(tsx?|jsx?)$/.test(e), u = /\.(tsx?|jsx?)$/.test(e) && !a;
275
- if (!a && !u || r === void 0 || !a) return;
276
- const s = r.moduleGraph.getModuleById(
277
- x
278
- ), y = _.get(e), v = y !== void 0 ? A + Q(y) : void 0, n = v !== void 0 ? r.moduleGraph.getModuleById(v) : void 0;
279
- let g = null, j = {}, E = "";
280
- if (i !== void 0) {
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) {
281
320
  try {
282
- g = await i.extractMeta(e);
321
+ f = await m.extractMeta(e);
283
322
  } catch {
284
- g = null;
323
+ f = null;
285
324
  }
286
325
  try {
287
- j = await i.extract(e);
326
+ C = await m.extract(e);
288
327
  } catch {
289
- j = {};
328
+ C = {};
290
329
  }
291
330
  try {
292
- E = await N(e, "utf8");
331
+ I = await L(e, "utf8");
293
332
  } catch {
294
- E = "";
333
+ I = "";
295
334
  }
296
335
  }
297
- if (g === null) {
298
- s !== void 0 && r.moduleGraph.invalidateModule(s), n !== void 0 && r.moduleGraph.invalidateModule(n), r.ws.send({ type: "full-reload" });
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" });
299
338
  return;
300
339
  }
301
- const I = O(g), L = T.get(e), U = tt(L, I);
302
- if (T.set(e, I), !U || y === void 0) {
303
- s !== void 0 && r.moduleGraph.invalidateModule(s), n !== void 0 && r.moduleGraph.invalidateModule(n), r.ws.send({ type: "full-reload" });
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" });
304
343
  return;
305
344
  }
306
- const V = {
307
- id: y,
308
- title: g.title,
309
- jogakNames: g.jogakNames,
310
- autoArgTypes: j,
311
- userArgTypes: g.userArgTypes,
312
- source: E,
345
+ const K = {
346
+ id: v,
347
+ title: f.title,
348
+ jogakNames: f.jogakNames,
349
+ autoArgTypes: C,
350
+ userArgTypes: f.userArgTypes,
351
+ source: I,
313
352
  filePath: e,
314
- metaExtras: g.metaExtras
353
+ metaExtras: f.metaExtras
315
354
  };
316
- n !== void 0 && r.moduleGraph.invalidateModule(n), r.ws.send({
355
+ i !== void 0 && u.moduleGraph.invalidateModule(i), u.ws.send({
317
356
  type: "custom",
318
357
  event: "jogak:meta-update",
319
- data: { id: y, meta: V }
358
+ data: { id: v, meta: K }
320
359
  });
321
- const b = [...d];
322
- return n !== void 0 && !b.includes(n) && b.push(n), b;
360
+ const x = [...d];
361
+ return i !== void 0 && !x.includes(i) && x.push(i), x;
323
362
  }
324
363
  };
325
364
  }
326
- function et() {
365
+ function ct() {
327
366
  return `(rawId) => {
328
367
  if (typeof Buffer !== 'undefined') return Buffer.from(rawId, 'utf8').toString('base64url')
329
368
  // 브라우저 폴백: btoa는 binary string 기준이라 UTF-8을 한번 인코딩해야 한다.
@@ -334,5 +373,5 @@ function et() {
334
373
  }`;
335
374
  }
336
375
  export {
337
- it as jogak
376
+ gt as jogak
338
377
  };
@@ -15,5 +15,8 @@ export declare const RESOLVED_VIRTUAL_INDEX_ID: string;
15
15
  /** Entry 모듈 prefix — 뒤에 base64url(id)이 붙는다. */
16
16
  export declare const VIRTUAL_ENTRY_PREFIX = "virtual:jogak/entry/";
17
17
  export declare const RESOLVED_VIRTUAL_ENTRY_PREFIX: string;
18
+ /** Global css 모듈 — 사용자 globalCss를 import한다 (알파.6, opt-in). */
19
+ export declare const VIRTUAL_GLOBAL_CSS_ID = "virtual:jogak/global-css";
20
+ export declare const RESOLVED_VIRTUAL_GLOBAL_CSS_ID: string;
18
21
  export declare function idToSlug(id: string): string;
19
22
  export declare function slugToId(slug: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jogak/core",
3
- "version": "0.1.0-alpha.5",
3
+ "version": "0.1.0-alpha.7",
4
4
  "description": "Core types, registry, and Vite plugin for Jogak — a lightweight Storybook alternative.",
5
5
  "keywords": [
6
6
  "jogak",