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

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/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var q=Object.defineProperty;var z=s=>{throw TypeError(s)};var D=(s,t,e)=>t in s?q(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var F=(s,t,e)=>D(s,typeof t!="symbol"?t+"":t,e),x=(s,t,e)=>t.has(s)||z("Cannot "+e);var i=(s,t,e)=>(x(s,t,"read from private field"),e?e.call(s):t.get(s)),g=(s,t,e)=>t.has(s)?z("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(s):t.set(s,e),l=(s,t,e,n)=>(x(s,t,"write to private field"),n?n.call(s,e):t.set(s,e),e),u=(s,t,e)=>(x(s,t,"access private method"),e);var L=(s,t,e,n)=>({set _(o){l(s,t,o,e)},get _(){return i(s,t,n)}});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class M extends Error{constructor(e){super(`[jogak] Unknown entry id: ${e}`);F(this,"id");this.name="UnknownEntryError",this.id=e}}var a,T,j,k,v,E,w,h,y,N;class U{constructor(){g(this,h);g(this,a,new Map);g(this,T);g(this,j,new Set);g(this,k);g(this,v);g(this,E,!1);g(this,w,!1)}register(t){const e=B(t);u(this,h,N).call(this,()=>{this.registerMeta(e),this.hydrateEntry(t.id,t.jogaks,t.meta.component)})}unregister(t){const e=i(this,a).get(t);e!==void 0&&(e.kind==="pending"&&e.reject(new M(t)),i(this,a).delete(t),u(this,h,y).call(this))}get(t){const e=i(this,a).get(t);return(e==null?void 0:e.kind)==="hydrated"?e.entry:void 0}getAll(){const t=[];for(const e of i(this,a).values())e.kind==="hydrated"&&t.push(e.entry);return t}search(t){const e=t.toLowerCase();return this.getAll().filter(n=>n.title.toLowerCase().includes(e))}getTree(){const t={};for(const e of this.getAll()){const n=e.title.split("/");let o=t;for(let d=0;d<n.length-1;d++){const c=n[d];if(c===void 0)continue;const f=o[c];(f===void 0||"id"in f)&&(o[c]={}),o=o[c]}const r=n[n.length-1];r!==void 0&&(o[r]=e)}return t}clear(){if(i(this,a).size!==0){for(const t of i(this,a).values())t.kind==="pending"&&t.reject(new Error("[jogak] registry cleared"));i(this,a).clear(),u(this,h,y).call(this)}}get size(){let t=0;for(const e of i(this,a).values())e.kind==="hydrated"&&t++;return t}registerMeta(t){const e=i(this,a).get(t.id);if(e===void 0){i(this,a).set(t.id,{kind:"meta",meta:t}),u(this,h,y).call(this);return}if(e.kind==="meta"){i(this,a).set(t.id,{kind:"meta",meta:t}),u(this,h,y).call(this);return}if(e.kind==="pending"){i(this,a).set(t.id,{kind:"pending",meta:t,promise:e.promise,resolve:e.resolve,reject:e.reject}),u(this,h,y).call(this);return}const n={...e.entry,title:t.title,filePath:t.filePath,source:t.source,meta:R(t,e.entry.meta.component)};i(this,a).set(t.id,{kind:"hydrated",meta:t,entry:n}),u(this,h,y).call(this)}hydrateEntry(t,e,n){const o=i(this,a).get(t);let r;o===void 0?(console.warn(`[jogak] hydrateEntry called for unknown id "${t}" — synthesizing minimal meta`),r={id:t,title:t,jogakNames:e.map(c=>c.name),autoArgTypes:{},userArgTypes:{},source:"",filePath:"",metaExtras:{}}):r=o.meta;const d={id:r.id,title:r.title,jogaks:e,meta:R(r,n),...r.filePath?{filePath:r.filePath}:{},...r.source?{source:r.source}:{}};if((o==null?void 0:o.kind)==="pending"){i(this,a).set(t,{kind:"hydrated",meta:r,entry:d}),u(this,h,y).call(this),o.resolve(d);return}i(this,a).set(t,{kind:"hydrated",meta:r,entry:d}),u(this,h,y).call(this)}invalidateEntry(t){const e=i(this,a).get(t);e===void 0||e.kind!=="hydrated"||(i(this,a).set(t,{kind:"meta",meta:e.meta}),u(this,h,y).call(this))}requestEntry(t){const e=i(this,a).get(t);if(e===void 0)return Promise.reject(new M(t));if(e.kind==="hydrated")return Promise.resolve(e.entry);if(e.kind==="pending")return e.promise;const n=i(this,T);if(n===void 0)return Promise.reject(new Error("[jogak] entry loader not set — virtual:jogak index module did not load"));let o,r;const d=new Promise((c,f)=>{o=c,r=f});return i(this,a).set(t,{kind:"pending",meta:e.meta,promise:d,resolve:o,reject:r}),n(t).then(()=>{const c=i(this,a).get(t);(c==null?void 0:c.kind)!=="hydrated"&&r(new Error(`[jogak] entry module loaded but did not hydrate: ${t}`))},c=>{const f=c instanceof Error?c:new Error(String(c)),p=i(this,a).get(t);(p==null?void 0:p.kind)==="pending"&&p.promise===d&&i(this,a).set(t,{kind:"meta",meta:e.meta}),r(f)}),d}getAllMeta(){if(i(this,k)!==void 0)return i(this,k);const t=[];for(const n of i(this,a).values())t.push(n.meta);const e=t;return l(this,k,e),e}getMetaTree(){if(i(this,v)!==void 0)return i(this,v);const t={};for(const e of i(this,a).values()){const n=e.meta,o=n.title.split("/");let r=t;for(let c=0;c<o.length-1;c++){const f=o[c];if(f===void 0)continue;const p=r[f];(p===void 0||"id"in p)&&(r[f]={}),r=r[f]}const d=o[o.length-1];d!==void 0&&(r[d]=n)}return l(this,v,t),t}getEntryState(t){const e=i(this,a).get(t);return e===void 0?"unknown":e.kind}setEntryLoader(t){l(this,T,t)}subscribe(t){i(this,j).add(t);let e=!0;return()=>{e&&(e=!1,i(this,j).delete(t))}}}a=new WeakMap,T=new WeakMap,j=new WeakMap,k=new WeakMap,v=new WeakMap,E=new WeakMap,w=new WeakMap,h=new WeakSet,y=function(){if(l(this,k,void 0),l(this,v,void 0),i(this,E)){l(this,w,!0);return}const t=Array.from(i(this,j));for(const e of t)try{e()}catch(n){console.error("[jogak] subscribe listener threw:",n)}},N=function(t){if(i(this,E)){t();return}l(this,E,!0),l(this,w,!1);try{t()}finally{l(this,E,!1),i(this,w)&&(l(this,w,!1),u(this,h,y).call(this))}};function B(s){const t=s.meta.argTypes??{};return{id:s.id,title:s.title,jogakNames:s.jogaks.map(e=>e.name),autoArgTypes:{},userArgTypes:t,source:s.source??"",filePath:s.filePath??"",metaExtras:{...s.meta.tags!==void 0?{tags:s.meta.tags}:{},...s.meta.parameters!==void 0?{parameters:s.meta.parameters}:{}}}}function R(s,t){const e={...s.autoArgTypes};for(const n of Object.keys(s.userArgTypes)){const o=s.userArgTypes[n];o!==void 0&&(e[n]={...e[n],...o})}return{title:s.title,component:t,argTypes:e,...s.metaExtras.tags!==void 0?{tags:s.metaExtras.tags}:{},...s.metaExtras.parameters!==void 0?{parameters:s.metaExtras.parameters}:{}}}const I=new U;var m,A,P,b,C;class O{constructor(){g(this,b);g(this,m,[]);g(this,A,new Set);g(this,P,1)}emit(t,e){const n={id:L(this,P)._++,name:t,args:e,timestamp:Date.now()};l(this,m,[...i(this,m),n]),u(this,b,C).call(this)}subscribe(t){return i(this,A).add(t),t(i(this,m)),()=>{i(this,A).delete(t)}}clear(){i(this,m).length!==0&&(l(this,m,[]),u(this,b,C).call(this))}getLogs(){return i(this,m)}}m=new WeakMap,A=new WeakMap,P=new WeakMap,b=new WeakSet,C=function(){for(const t of i(this,A))t(i(this,m))};const S=new O;function $(s,t=S){return(...e)=>{t.emit(s,e)}}function J(s,t,e=S){const n={...s};for(const o of Object.keys(t)){const r=t[o];if(r===void 0)continue;const d=r.action!==void 0&&r.action!==!1,c=r.type==="function";if(!d&&!c||typeof n[o]=="function")continue;const f=typeof r.action=="string"?r.action:o;n[o]=$(f,e)}return n}exports.ActionChannel=O;exports.ComponentRegistry=U;exports.UnknownEntryError=M;exports.action=$;exports.defaultActionChannel=S;exports.defaultRegistry=I;exports.injectActions=J;
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;
package/dist/index.mjs CHANGED
@@ -1,39 +1,48 @@
1
- var $ = Object.defineProperty;
2
- var C = (s) => {
3
- throw TypeError(s);
1
+ var R = Object.defineProperty;
2
+ var I = (i) => {
3
+ throw TypeError(i);
4
4
  };
5
- var q = (s, t, e) => t in s ? $(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
6
- var z = (s, t, e) => q(s, typeof t != "symbol" ? t + "" : t, e), b = (s, t, e) => t.has(s) || C("Cannot " + e);
7
- var i = (s, t, e) => (b(s, t, "read from private field"), e ? e.call(s) : t.get(s)), g = (s, t, e) => t.has(s) ? C("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(s) : t.set(s, e), l = (s, t, e, n) => (b(s, t, "write to private field"), n ? n.call(s, e) : t.set(s, e), e), u = (s, t, e) => (b(s, t, "access private method"), e);
8
- var F = (s, t, e, n) => ({
9
- set _(o) {
10
- l(s, t, o, e);
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);
8
+ var O = (i, t, e, n) => ({
9
+ set _(r) {
10
+ c(i, t, r, e);
11
11
  },
12
12
  get _() {
13
- return i(s, t, n);
13
+ return s(i, t, n);
14
14
  }
15
15
  });
16
- class L extends Error {
16
+ class U extends Error {
17
17
  constructor(e) {
18
18
  super(`[jogak] Unknown entry id: ${e}`);
19
- z(this, "id");
19
+ N(this, "id");
20
20
  this.name = "UnknownEntryError", this.id = e;
21
21
  }
22
22
  }
23
- var a, T, j, k, v, E, w, d, m, N;
24
- class D {
23
+ var a, P, b, v, k, E, w, j, A, T, l, m, C, q;
24
+ class J {
25
25
  constructor() {
26
- g(this, d);
27
- g(this, a, /* @__PURE__ */ new Map());
28
- g(this, T);
26
+ f(this, l);
27
+ f(this, a, /* @__PURE__ */ new Map());
28
+ f(this, P);
29
29
  // ── F2: subscribe + 내부 캐시 ────────────────────────────────────────
30
- g(this, j, /* @__PURE__ */ new Set());
31
- g(this, k);
32
- g(this, v);
30
+ f(this, b, /* @__PURE__ */ new Set());
31
+ f(this, v);
32
+ f(this, k);
33
+ // 결정성 fix: hydrated entry list / tree 도 캐시. mutation 시 invalidate.
34
+ f(this, E);
35
+ f(this, w);
36
+ /**
37
+ * 정렬된 id 순서. mutation 시 invalidate, 다음 호출에서 한 번만 재계산.
38
+ * getAll / getTree / getAllMeta / getMetaTree 모두 이 순서를 따른다.
39
+ * 결과: 모든 외부 노출 collection 이 동일 ordering 을 가진다.
40
+ */
41
+ f(this, j);
33
42
  /** register()가 registerMeta + hydrateEntry를 합쳐 호출할 때 중간 notify를 억제한다. */
34
- g(this, E, !1);
43
+ f(this, A, !1);
35
44
  /** batch 도중에 mutation이 한 번이라도 일어났는지 — false면 batch 종료 시 notify 안 한다. */
36
- g(this, w, !1);
45
+ f(this, T, !1);
37
46
  }
38
47
  // ── 기존 외부 API: 시그니처 변경 없음. 시맨틱은 hydrated만 표면. ───────────
39
48
  /**
@@ -44,26 +53,30 @@ class D {
44
53
  * 두 mutation은 batch로 묶여 단일 notify만 발생한다.
45
54
  */
46
55
  register(t) {
47
- const e = O(t);
48
- u(this, d, N).call(this, () => {
56
+ const e = V(t);
57
+ u(this, l, q).call(this, () => {
49
58
  this.registerMeta(e), this.hydrateEntry(t.id, t.jogaks, t.meta.component);
50
59
  });
51
60
  }
52
61
  unregister(t) {
53
- const e = i(this, a).get(t);
54
- e !== void 0 && (e.kind === "pending" && e.reject(new L(t)), i(this, a).delete(t), u(this, d, m).call(this));
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));
55
64
  }
56
65
  /** hydrated일 때만 RegistryEntry를 반환한다. meta-only/pending이면 undefined. */
57
66
  get(t) {
58
- const e = i(this, a).get(t);
67
+ const e = s(this, a).get(t);
59
68
  return (e == null ? void 0 : e.kind) === "hydrated" ? e.entry : void 0;
60
69
  }
61
70
  /** hydrated 항목만 반환. meta-only는 `getAllMeta()` 사용. */
62
71
  getAll() {
72
+ if (s(this, E) !== void 0) return s(this, E);
63
73
  const t = [];
64
- for (const e of i(this, a).values())
65
- e.kind === "hydrated" && t.push(e.entry);
66
- return t;
74
+ for (const n of u(this, l, C).call(this)) {
75
+ const r = s(this, a).get(n);
76
+ (r == null ? void 0 : r.kind) === "hydrated" && t.push(r.entry);
77
+ }
78
+ const e = t;
79
+ return c(this, E, e), e;
67
80
  }
68
81
  search(t) {
69
82
  const e = t.toLowerCase();
@@ -71,34 +84,38 @@ class D {
71
84
  }
72
85
  /**
73
86
  * title의 '/' 구분자로 hydrated entry만의 계층 트리를 구성한다.
87
+ *
88
+ * `getAll()`이 정렬된 순서를 반환하므로 트리 객체의 키 iteration order
89
+ * (ECMA-262 §OrdinaryOwnPropertyKeys: insertion order for string keys)도 결정적이다.
74
90
  */
75
91
  getTree() {
92
+ if (s(this, w) !== void 0) return s(this, w);
76
93
  const t = {};
77
94
  for (const e of this.getAll()) {
78
95
  const n = e.title.split("/");
79
- let o = t;
96
+ let r = t;
80
97
  for (let h = 0; h < n.length - 1; h++) {
81
- const c = n[h];
82
- if (c === void 0) continue;
83
- const f = o[c];
84
- (f === void 0 || "id" in f) && (o[c] = {}), o = o[c];
98
+ const d = n[h];
99
+ if (d === void 0) continue;
100
+ const g = r[d];
101
+ (g === void 0 || "id" in g) && (r[d] = {}), r = r[d];
85
102
  }
86
- const r = n[n.length - 1];
87
- r !== void 0 && (o[r] = e);
103
+ const o = n[n.length - 1];
104
+ o !== void 0 && (r[o] = e);
88
105
  }
89
- return t;
106
+ return c(this, w, t), t;
90
107
  }
91
108
  clear() {
92
- if (i(this, a).size !== 0) {
93
- for (const t of i(this, a).values())
109
+ if (s(this, a).size !== 0) {
110
+ for (const t of s(this, a).values())
94
111
  t.kind === "pending" && t.reject(new Error("[jogak] registry cleared"));
95
- i(this, a).clear(), u(this, d, m).call(this);
112
+ s(this, a).clear(), u(this, l, m).call(this);
96
113
  }
97
114
  }
98
115
  /** hydrated 개수. */
99
116
  get size() {
100
117
  let t = 0;
101
- for (const e of i(this, a).values())
118
+ for (const e of s(this, a).values())
102
119
  e.kind === "hydrated" && t++;
103
120
  return t;
104
121
  }
@@ -108,23 +125,23 @@ class D {
108
125
  * meta 등록만으로는 `getAll()` 결과에 안 들어간다.
109
126
  */
110
127
  registerMeta(t) {
111
- const e = i(this, a).get(t.id);
128
+ const e = s(this, a).get(t.id);
112
129
  if (e === void 0) {
113
- i(this, a).set(t.id, { kind: "meta", meta: t }), u(this, d, m).call(this);
130
+ s(this, a).set(t.id, { kind: "meta", meta: t }), u(this, l, m).call(this);
114
131
  return;
115
132
  }
116
133
  if (e.kind === "meta") {
117
- i(this, a).set(t.id, { kind: "meta", meta: t }), u(this, d, m).call(this);
134
+ s(this, a).set(t.id, { kind: "meta", meta: t }), u(this, l, m).call(this);
118
135
  return;
119
136
  }
120
137
  if (e.kind === "pending") {
121
- i(this, a).set(t.id, {
138
+ s(this, a).set(t.id, {
122
139
  kind: "pending",
123
140
  meta: t,
124
141
  promise: e.promise,
125
142
  resolve: e.resolve,
126
143
  reject: e.reject
127
- }), u(this, d, m).call(this);
144
+ }), u(this, l, m).call(this);
128
145
  return;
129
146
  }
130
147
  const n = {
@@ -132,42 +149,42 @@ class D {
132
149
  title: t.title,
133
150
  filePath: t.filePath,
134
151
  source: t.source,
135
- meta: S(t, e.entry.meta.component)
152
+ meta: $(t, e.entry.meta.component)
136
153
  };
137
- i(this, a).set(t.id, { kind: "hydrated", meta: t, entry: n }), u(this, d, m).call(this);
154
+ s(this, a).set(t.id, { kind: "hydrated", meta: t, entry: n }), u(this, l, m).call(this);
138
155
  }
139
156
  /**
140
157
  * entry 가상모듈이 호출. pending Promise들을 resolve.
141
158
  * meta가 없는 상태에서 호출되면(=직접 import) 임시 meta를 합성한다 (defensive).
142
159
  */
143
160
  hydrateEntry(t, e, n) {
144
- const o = i(this, a).get(t);
145
- let r;
146
- o === void 0 ? (console.warn(
161
+ const r = s(this, a).get(t);
162
+ let o;
163
+ r === void 0 ? (console.warn(
147
164
  `[jogak] hydrateEntry called for unknown id "${t}" — synthesizing minimal meta`
148
- ), r = {
165
+ ), o = {
149
166
  id: t,
150
167
  title: t,
151
- jogakNames: e.map((c) => c.name),
168
+ jogakNames: e.map((d) => d.name),
152
169
  autoArgTypes: {},
153
170
  userArgTypes: {},
154
171
  source: "",
155
172
  filePath: "",
156
173
  metaExtras: {}
157
- }) : r = o.meta;
174
+ }) : o = r.meta;
158
175
  const h = {
159
- id: r.id,
160
- title: r.title,
176
+ id: o.id,
177
+ title: o.title,
161
178
  jogaks: e,
162
- meta: S(r, n),
163
- ...r.filePath ? { filePath: r.filePath } : {},
164
- ...r.source ? { source: r.source } : {}
179
+ meta: $(o, n),
180
+ ...o.filePath ? { filePath: o.filePath } : {},
181
+ ...o.source ? { source: o.source } : {}
165
182
  };
166
- if ((o == null ? void 0 : o.kind) === "pending") {
167
- i(this, a).set(t, { kind: "hydrated", meta: r, entry: h }), u(this, d, m).call(this), o.resolve(h);
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);
168
185
  return;
169
186
  }
170
- i(this, a).set(t, { kind: "hydrated", meta: r, entry: h }), u(this, d, m).call(this);
187
+ s(this, a).set(t, { kind: "hydrated", meta: o, entry: h }), u(this, l, m).call(this);
171
188
  }
172
189
  /**
173
190
  * 어댑터가 호출. hydrated였던 entry를 meta 상태로 되돌린다.
@@ -175,8 +192,8 @@ class D {
175
192
  * unknown / meta / pending 상태에는 영향 없음.
176
193
  */
177
194
  invalidateEntry(t) {
178
- const e = i(this, a).get(t);
179
- e === void 0 || e.kind !== "hydrated" || (i(this, a).set(t, { kind: "meta", meta: e.meta }), u(this, d, m).call(this));
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));
180
197
  }
181
198
  /**
182
199
  * UI/어댑터가 호출. entry id로 완전한 RegistryEntry를 비동기 획득.
@@ -187,40 +204,40 @@ class D {
187
204
  * - unknown → 즉시 reject (UnknownEntryError)
188
205
  */
189
206
  requestEntry(t) {
190
- const e = i(this, a).get(t);
207
+ const e = s(this, a).get(t);
191
208
  if (e === void 0)
192
- return Promise.reject(new L(t));
209
+ return Promise.reject(new U(t));
193
210
  if (e.kind === "hydrated")
194
211
  return Promise.resolve(e.entry);
195
212
  if (e.kind === "pending")
196
213
  return e.promise;
197
- const n = i(this, T);
214
+ const n = s(this, P);
198
215
  if (n === void 0)
199
216
  return Promise.reject(
200
217
  new Error(
201
218
  "[jogak] entry loader not set — virtual:jogak index module did not load"
202
219
  )
203
220
  );
204
- let o, r;
205
- const h = new Promise((c, f) => {
206
- o = c, r = f;
221
+ let r, o;
222
+ const h = new Promise((d, g) => {
223
+ r = d, o = g;
207
224
  });
208
- return i(this, a).set(t, {
225
+ return s(this, a).set(t, {
209
226
  kind: "pending",
210
227
  meta: e.meta,
211
228
  promise: h,
212
- resolve: o,
213
- reject: r
229
+ resolve: r,
230
+ reject: o
214
231
  }), n(t).then(
215
232
  () => {
216
- const c = i(this, a).get(t);
217
- (c == null ? void 0 : c.kind) !== "hydrated" && r(
233
+ const d = s(this, a).get(t);
234
+ (d == null ? void 0 : d.kind) !== "hydrated" && o(
218
235
  new Error(`[jogak] entry module loaded but did not hydrate: ${t}`)
219
236
  );
220
237
  },
221
- (c) => {
222
- const f = c instanceof Error ? c : new Error(String(c)), p = i(this, a).get(t);
223
- (p == null ? void 0 : p.kind) === "pending" && p.promise === h && i(this, a).set(t, { kind: "meta", meta: e.meta }), r(f);
238
+ (d) => {
239
+ const g = d instanceof Error ? d : new Error(String(d)), y = s(this, a).get(t);
240
+ (y == null ? void 0 : y.kind) === "pending" && y.promise === h && s(this, a).set(t, { kind: "meta", meta: e.meta }), o(g);
224
241
  }
225
242
  ), h;
226
243
  }
@@ -231,37 +248,41 @@ class D {
231
248
  * useSyncExternalStore의 referential identity 요구를 만족시키기 위함.
232
249
  */
233
250
  getAllMeta() {
234
- if (i(this, k) !== void 0) return i(this, k);
251
+ if (s(this, v) !== void 0) return s(this, v);
235
252
  const t = [];
236
- for (const n of i(this, a).values())
237
- t.push(n.meta);
253
+ for (const n of u(this, l, C).call(this)) {
254
+ const r = s(this, a).get(n);
255
+ r !== void 0 && t.push(r.meta);
256
+ }
238
257
  const e = t;
239
- return l(this, k, e), e;
258
+ return c(this, v, e), e;
240
259
  }
241
260
  /**
242
261
  * 사이드바 트리 전용 — 모든 상태의 meta를 트리화.
243
262
  * F2: getAllMeta와 동일한 캐시 정책.
244
263
  */
245
264
  getMetaTree() {
246
- if (i(this, v) !== void 0) return i(this, v);
265
+ if (s(this, k) !== void 0) return s(this, k);
247
266
  const t = {};
248
- for (const e of i(this, a).values()) {
249
- const n = e.meta, o = n.title.split("/");
250
- let r = t;
251
- for (let c = 0; c < o.length - 1; c++) {
252
- const f = o[c];
253
- if (f === void 0) continue;
254
- const p = r[f];
255
- (p === void 0 || "id" in p) && (r[f] = {}), r = r[f];
267
+ for (const e of u(this, l, C).call(this)) {
268
+ const n = s(this, a).get(e);
269
+ if (n === void 0) continue;
270
+ const r = n.meta, o = r.title.split("/");
271
+ let h = t;
272
+ for (let g = 0; g < o.length - 1; g++) {
273
+ const y = o[g];
274
+ if (y === void 0) continue;
275
+ const L = h[y];
276
+ (L === void 0 || "id" in L) && (h[y] = {}), h = h[y];
256
277
  }
257
- const h = o[o.length - 1];
258
- h !== void 0 && (r[h] = n);
278
+ const d = o[o.length - 1];
279
+ d !== void 0 && (h[d] = r);
259
280
  }
260
- return l(this, v, t), t;
281
+ return c(this, k, t), t;
261
282
  }
262
283
  /** 진단 — 상태 머신 노출. */
263
284
  getEntryState(t) {
264
- const e = i(this, a).get(t);
285
+ const e = s(this, a).get(t);
265
286
  return e === void 0 ? "unknown" : e.kind;
266
287
  }
267
288
  /**
@@ -269,7 +290,7 @@ class D {
269
290
  * 빌드/SSR에서 정적 import 매핑으로 교체할 때도 사용.
270
291
  */
271
292
  setEntryLoader(t) {
272
- l(this, T, t);
293
+ c(this, P, t);
273
294
  }
274
295
  // ── F2: subscribe API ────────────────────────────────────────────────
275
296
  /**
@@ -283,135 +304,156 @@ class D {
283
304
  * - 반환값은 unsubscribe 함수 (멱등 — 두 번 호출해도 안전).
284
305
  */
285
306
  subscribe(t) {
286
- i(this, j).add(t);
307
+ s(this, b).add(t);
287
308
  let e = !0;
288
309
  return () => {
289
- e && (e = !1, i(this, j).delete(t));
310
+ e && (e = !1, s(this, b).delete(t));
290
311
  };
291
312
  }
292
313
  }
293
- a = new WeakMap(), T = new WeakMap(), j = new WeakMap(), k = new WeakMap(), v = new WeakMap(), E = new WeakMap(), w = new WeakMap(), d = new WeakSet(), // ── 내부 헬퍼 ─────────────────────────────────────────────────────────
314
+ a = new WeakMap(), P = 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(), // ── 내부 헬퍼 ─────────────────────────────────────────────────────────
294
315
  /**
295
316
  * 캐시 invalidate + listener 통지를 단일 헬퍼로.
296
317
  * batch 모드에서는 dirty 플래그만 켜고 실제 통지는 batch 종료 시점에 한다.
297
318
  */
298
319
  m = function() {
299
- if (l(this, k, void 0), l(this, v, void 0), i(this, E)) {
300
- l(this, w, !0);
320
+ if (c(this, v, void 0), c(this, k, void 0), c(this, E, void 0), c(this, w, void 0), c(this, j, void 0), s(this, A)) {
321
+ c(this, T, !0);
301
322
  return;
302
323
  }
303
- const t = Array.from(i(this, j));
324
+ const t = Array.from(s(this, b));
304
325
  for (const e of t)
305
326
  try {
306
327
  e();
307
328
  } catch (n) {
308
329
  console.error("[jogak] subscribe listener threw:", n);
309
330
  }
331
+ }, /**
332
+ * 모든 외부 노출 collection 이 공유하는 정렬된 id 순서.
333
+ * mutation 시 #cachedSortedIds 가 undefined 로 invalidate, 다음 호출에서 한 번만 재계산.
334
+ *
335
+ * 정렬 정책은 module-private `compareMetaForOrdering` 단일 source.
336
+ */
337
+ C = function() {
338
+ if (s(this, j) !== void 0) return s(this, j);
339
+ const t = [];
340
+ for (const [n, r] of s(this, a))
341
+ t.push({ id: n, title: r.meta.title });
342
+ t.sort(G);
343
+ const e = t.map((n) => n.id);
344
+ return c(this, j, e), e;
310
345
  }, /**
311
346
  * register() 처럼 여러 mutation을 묶어 단일 notify로 처리.
312
347
  * 내부 전용 — public API 아님.
313
348
  */
314
- N = function(t) {
315
- if (i(this, E)) {
349
+ q = function(t) {
350
+ if (s(this, A)) {
316
351
  t();
317
352
  return;
318
353
  }
319
- l(this, E, !0), l(this, w, !1);
354
+ c(this, A, !0), c(this, T, !1);
320
355
  try {
321
356
  t();
322
357
  } finally {
323
- l(this, E, !1), i(this, w) && (l(this, w, !1), u(this, d, m).call(this));
358
+ c(this, A, !1), s(this, T) && (c(this, T, !1), u(this, l, m).call(this));
324
359
  }
325
360
  };
326
- function O(s) {
327
- const t = s.meta.argTypes ?? {};
361
+ function V(i) {
362
+ const t = i.meta.argTypes ?? {};
328
363
  return {
329
- id: s.id,
330
- title: s.title,
331
- jogakNames: s.jogaks.map((e) => e.name),
364
+ id: i.id,
365
+ title: i.title,
366
+ jogakNames: i.jogaks.map((e) => e.name),
332
367
  autoArgTypes: {},
333
368
  userArgTypes: t,
334
- source: s.source ?? "",
335
- filePath: s.filePath ?? "",
369
+ source: i.source ?? "",
370
+ filePath: i.filePath ?? "",
336
371
  metaExtras: {
337
- ...s.meta.tags !== void 0 ? { tags: s.meta.tags } : {},
338
- ...s.meta.parameters !== void 0 ? { parameters: s.meta.parameters } : {}
372
+ ...i.meta.tags !== void 0 ? { tags: i.meta.tags } : {},
373
+ ...i.meta.parameters !== void 0 ? { parameters: i.meta.parameters } : {}
339
374
  }
340
375
  };
341
376
  }
342
- function S(s, t) {
377
+ function $(i, t) {
343
378
  const e = {
344
- ...s.autoArgTypes
379
+ ...i.autoArgTypes
345
380
  };
346
- for (const n of Object.keys(s.userArgTypes)) {
347
- const o = s.userArgTypes[n];
348
- o !== void 0 && (e[n] = { ...e[n], ...o });
381
+ for (const n of Object.keys(i.userArgTypes)) {
382
+ const r = i.userArgTypes[n];
383
+ r !== void 0 && (e[n] = { ...e[n], ...r });
349
384
  }
350
385
  return {
351
- title: s.title,
386
+ title: i.title,
352
387
  component: t,
353
388
  argTypes: e,
354
- ...s.metaExtras.tags !== void 0 ? { tags: s.metaExtras.tags } : {},
355
- ...s.metaExtras.parameters !== void 0 ? { parameters: s.metaExtras.parameters } : {}
389
+ ...i.metaExtras.tags !== void 0 ? { tags: i.metaExtras.tags } : {},
390
+ ...i.metaExtras.parameters !== void 0 ? { parameters: i.metaExtras.parameters } : {}
356
391
  };
357
392
  }
358
- const J = new D();
359
- var y, A, P, x, M;
360
- class R {
393
+ function G(i, t) {
394
+ const e = i.title.localeCompare(t.title, "en", {
395
+ sensitivity: "base",
396
+ numeric: !0
397
+ });
398
+ return e !== 0 ? e : i.id.localeCompare(t.id, "en", { sensitivity: "base", numeric: !0 });
399
+ }
400
+ const W = new J();
401
+ var p, x, S, M, F;
402
+ class H {
361
403
  constructor() {
362
- g(this, x);
363
- g(this, y, []);
364
- g(this, A, /* @__PURE__ */ new Set());
365
- g(this, P, 1);
404
+ f(this, M);
405
+ f(this, p, []);
406
+ f(this, x, /* @__PURE__ */ new Set());
407
+ f(this, S, 1);
366
408
  }
367
409
  emit(t, e) {
368
410
  const n = {
369
- id: F(this, P)._++,
411
+ id: O(this, S)._++,
370
412
  name: t,
371
413
  args: e,
372
414
  timestamp: Date.now()
373
415
  };
374
- l(this, y, [...i(this, y), n]), u(this, x, M).call(this);
416
+ c(this, p, [...s(this, p), n]), u(this, M, F).call(this);
375
417
  }
376
418
  subscribe(t) {
377
- return i(this, A).add(t), t(i(this, y)), () => {
378
- i(this, A).delete(t);
419
+ return s(this, x).add(t), t(s(this, p)), () => {
420
+ s(this, x).delete(t);
379
421
  };
380
422
  }
381
423
  clear() {
382
- i(this, y).length !== 0 && (l(this, y, []), u(this, x, M).call(this));
424
+ s(this, p).length !== 0 && (c(this, p, []), u(this, M, F).call(this));
383
425
  }
384
426
  getLogs() {
385
- return i(this, y);
427
+ return s(this, p);
386
428
  }
387
429
  }
388
- y = new WeakMap(), A = new WeakMap(), P = new WeakMap(), x = new WeakSet(), M = function() {
389
- for (const t of i(this, A)) t(i(this, y));
430
+ p = new WeakMap(), x = new WeakMap(), S = new WeakMap(), M = new WeakSet(), F = function() {
431
+ for (const t of s(this, x)) t(s(this, p));
390
432
  };
391
- const U = new R();
392
- function B(s, t = U) {
433
+ const D = new H();
434
+ function K(i, t = D) {
393
435
  return (...e) => {
394
- t.emit(s, e);
436
+ t.emit(i, e);
395
437
  };
396
438
  }
397
- function V(s, t, e = U) {
398
- const n = { ...s };
399
- for (const o of Object.keys(t)) {
400
- const r = t[o];
401
- if (r === void 0) continue;
402
- const h = r.action !== void 0 && r.action !== !1, c = r.type === "function";
403
- if (!h && !c || typeof n[o] == "function") continue;
404
- const f = typeof r.action == "string" ? r.action : o;
405
- n[o] = B(f, e);
439
+ function X(i, t, e = D) {
440
+ const n = { ...i };
441
+ for (const r of Object.keys(t)) {
442
+ const o = t[r];
443
+ if (o === void 0) continue;
444
+ const h = o.action !== void 0 && o.action !== !1, d = o.type === "function";
445
+ if (!h && !d || typeof n[r] == "function") continue;
446
+ const g = typeof o.action == "string" ? o.action : r;
447
+ n[r] = K(g, e);
406
448
  }
407
449
  return n;
408
450
  }
409
451
  export {
410
- R as ActionChannel,
411
- D as ComponentRegistry,
412
- L as UnknownEntryError,
413
- B as action,
414
- U as defaultActionChannel,
415
- J as defaultRegistry,
416
- V as injectActions
452
+ H as ActionChannel,
453
+ J as ComponentRegistry,
454
+ U as UnknownEntryError,
455
+ K as action,
456
+ D as defaultActionChannel,
457
+ W as defaultRegistry,
458
+ X as injectActions
417
459
  };
@@ -22,6 +22,9 @@ export declare class ComponentRegistry {
22
22
  search(query: string): readonly RegistryEntry[];
23
23
  /**
24
24
  * title의 '/' 구분자로 hydrated entry만의 계층 트리를 구성한다.
25
+ *
26
+ * `getAll()`이 정렬된 순서를 반환하므로 트리 객체의 키 iteration order
27
+ * (ECMA-262 §OrdinaryOwnPropertyKeys: insertion order for string keys)도 결정적이다.
25
28
  */
26
29
  getTree(): CategoryTree;
27
30
  clear(): void;
@@ -1,4 +1,4 @@
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}),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 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'
2
2
 
3
3
  const _entryLoader = (slug) =>
4
4
  import(/* @vite-ignore */ '/@id/__x00__virtual:jogak/entry/' + slug)
@@ -141,7 +141,7 @@ function it(t = {}) {
141
141
  let r, i, k;
142
142
  const w = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), T = /* @__PURE__ */ new Map();
143
143
  async function M() {
144
- const { glob: e } = await import("glob"), d = k ?? process.cwd(), a = await e(o, { cwd: d, absolute: !0 }), u = [];
144
+ const { glob: e } = await import("glob"), d = k ?? process.cwd(), a = (await e(o, { cwd: d, absolute: !0 })).sort(), u = [];
145
145
  w.clear(), _.clear();
146
146
  for (const s of a) {
147
147
  let y = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jogak/core",
3
- "version": "0.1.0-alpha.3",
3
+ "version": "0.1.0-alpha.5",
4
4
  "description": "Core types, registry, and Vite plugin for Jogak — a lightweight Storybook alternative.",
5
5
  "keywords": [
6
6
  "jogak",
@@ -63,6 +63,7 @@
63
63
  "devDependencies": {
64
64
  "vite": "^6.0.0",
65
65
  "vite-plugin-dts": "^4.0.0",
66
+ "vitest": "^2.0.0",
66
67
  "typescript": "^5.5.0",
67
68
  "@types/node": "^20.14.0"
68
69
  },
@@ -77,6 +78,8 @@
77
78
  "scripts": {
78
79
  "build": "vite build",
79
80
  "dev": "vite build --watch",
80
- "typecheck": "tsc --noEmit"
81
+ "typecheck": "tsc --noEmit",
82
+ "test": "vitest run",
83
+ "test:watch": "vitest"
81
84
  }
82
85
  }