@jogak/core 0.1.0-alpha.1 → 0.1.0-alpha.10.2
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/CHANGELOG.md +112 -0
- package/dist/actions-BvvUNlgo.js +69 -0
- package/dist/actions-D9bnuJ1b.cjs +1 -0
- package/dist/adapter.d.ts +80 -0
- package/dist/adapters/next/index.cjs +73 -0
- package/dist/adapters/next/index.d.ts +5 -0
- package/dist/adapters/next/index.mjs +222 -0
- package/dist/adapters/next/scaffold.d.ts +23 -0
- package/dist/adapters/next/spawn-dev.d.ts +2 -0
- package/dist/adapters/standalone/index.cjs +1 -0
- package/dist/adapters/standalone/index.d.ts +3 -0
- package/dist/adapters/standalone/index.mjs +21 -0
- package/dist/adapters/vite/build.d.ts +2 -0
- package/dist/adapters/vite/index.cjs +22 -0
- package/dist/adapters/vite/index.d.ts +5 -0
- package/dist/adapters/vite/index.mjs +134 -0
- package/dist/adapters/vite/preview-frame-plugin.d.ts +6 -0
- package/dist/adapters/vite/spawn-dev.d.ts +2 -0
- package/dist/adapters/webpack/index.cjs +74 -0
- package/dist/adapters/webpack/index.d.ts +5 -0
- package/dist/adapters/webpack/index.mjs +214 -0
- package/dist/adapters/webpack/scaffold.d.ts +18 -0
- package/dist/adapters/webpack/spawn-dev.d.ts +2 -0
- package/dist/builder-detect.d.ts +9 -0
- package/dist/config.d.ts +71 -0
- package/dist/detect-global-css-CDcuUAYE.cjs +1 -0
- package/dist/detect-global-css-CIVMmgzy.js +33 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.mjs +13 -413
- package/dist/plugin-DhT-PH1R.js +354 -0
- package/dist/plugin-Wtlz0hae.cjs +50 -0
- package/dist/preview-entry/protocol.d.ts +29 -0
- package/dist/preview-entry/source.d.ts +30 -0
- package/dist/registry-CnBX6XxF.js +397 -0
- package/dist/registry-DRRMxvoz.cjs +1 -0
- package/dist/registry.d.ts +3 -0
- package/dist/renderers/next/client/Preview.d.ts +27 -0
- package/dist/renderers/next/client/index.d.ts +2 -0
- package/dist/renderers/next/index.cjs +1 -0
- package/dist/renderers/next/index.d.ts +4 -0
- package/dist/renderers/next/index.mjs +53 -0
- package/dist/renderers/next/server/JogakLayout.d.ts +28 -0
- package/dist/renderers/next/server/index.d.ts +2 -0
- package/dist/renderers/react/JogakProvider.d.ts +8 -0
- package/dist/renderers/react/adapter.d.ts +2 -0
- package/dist/renderers/react/index.cjs +1 -0
- package/dist/renderers/react/index.d.ts +7 -0
- package/dist/renderers/react/index.mjs +101 -0
- package/dist/renderers/react/useEntry.d.ts +40 -0
- package/dist/renderers/react/useRegistryMeta.d.ts +27 -0
- package/dist/renderers/web-components/define.d.ts +11 -0
- package/dist/renderers/web-components/index.cjs +1 -0
- package/dist/renderers/web-components/index.d.ts +1 -0
- package/dist/renderers/web-components/index.mjs +48 -0
- package/dist/server.cjs +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.mjs +45 -0
- package/dist/source-9OiU8x_y.cjs +43 -0
- package/dist/source-D44KTQPu.js +50 -0
- package/dist/types.d.ts +161 -0
- package/dist/vite/index.cjs +1 -0
- package/dist/vite/index.mjs +2 -275
- package/dist/vite-plugin/detect-global-css.d.ts +33 -0
- package/dist/vite-plugin/index.cjs +1 -0
- package/dist/vite-plugin/index.d.ts +12 -0
- package/dist/vite-plugin/index.mjs +4 -0
- package/dist/vite-plugin/resolve-paths.d.ts +32 -0
- package/dist/{vite → vite-plugin}/virtual-ids.d.ts +17 -0
- package/package.json +101 -10
- package/dist/index.js +0 -1
- package/dist/vite/index.js +0 -41
- /package/dist/build/{index.js → index.cjs} +0 -0
- /package/dist/meta/{extractor-child.js → extractor-child.cjs} +0 -0
- /package/dist/{vite → vite-plugin}/cache-validate.d.ts +0 -0
- /package/dist/{vite → vite-plugin}/plugin.d.ts +0 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
var L = Object.defineProperty;
|
|
2
|
+
var C = (i) => {
|
|
3
|
+
throw TypeError(i);
|
|
4
|
+
};
|
|
5
|
+
var N = (i, t, e) => t in i ? L(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
|
|
6
|
+
var z = (i, t, e) => N(i, typeof t != "symbol" ? t + "" : t, e), M = (i, t, e) => t.has(i) || C("Cannot " + e);
|
|
7
|
+
var s = (i, t, e) => (M(i, t, "read from private field"), e ? e.call(i) : t.get(i)), f = (i, t, e) => t.has(i) ? C("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e), l = (i, t, e, r) => (M(i, t, "write to private field"), r ? r.call(i, e) : t.set(i, e), e), u = (i, t, e) => (M(i, t, "access private method"), e);
|
|
8
|
+
class S extends Error {
|
|
9
|
+
constructor(e) {
|
|
10
|
+
super(`[jogak] Unknown entry id: ${e}`);
|
|
11
|
+
z(this, "id");
|
|
12
|
+
this.name = "UnknownEntryError", this.id = e;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
var o, P, T, v, y, k, E, w, j, A, h, g, x, U;
|
|
16
|
+
class $ {
|
|
17
|
+
constructor() {
|
|
18
|
+
f(this, h);
|
|
19
|
+
f(this, o, /* @__PURE__ */ new Map());
|
|
20
|
+
f(this, P);
|
|
21
|
+
// ── F2: subscribe + 내부 캐시 ────────────────────────────────────────
|
|
22
|
+
f(this, T, /* @__PURE__ */ new Set());
|
|
23
|
+
f(this, v);
|
|
24
|
+
f(this, y);
|
|
25
|
+
// 결정성 fix: hydrated entry list / tree 도 캐시. mutation 시 invalidate.
|
|
26
|
+
f(this, k);
|
|
27
|
+
f(this, E);
|
|
28
|
+
/**
|
|
29
|
+
* 정렬된 id 순서. mutation 시 invalidate, 다음 호출에서 한 번만 재계산.
|
|
30
|
+
* getAll / getTree / getAllMeta / getMetaTree 모두 이 순서를 따른다.
|
|
31
|
+
* 결과: 모든 외부 노출 collection 이 동일 ordering 을 가진다.
|
|
32
|
+
*/
|
|
33
|
+
f(this, w);
|
|
34
|
+
/** register()가 registerMeta + hydrateEntry를 합쳐 호출할 때 중간 notify를 억제한다. */
|
|
35
|
+
f(this, j, !1);
|
|
36
|
+
/** batch 도중에 mutation이 한 번이라도 일어났는지 — false면 batch 종료 시 notify 안 한다. */
|
|
37
|
+
f(this, A, !1);
|
|
38
|
+
}
|
|
39
|
+
// ── 기존 외부 API: 시그니처 변경 없음. 시맨틱은 hydrated만 표면. ───────────
|
|
40
|
+
/**
|
|
41
|
+
* 즉시 hydrated 상태로 entry를 등록한다.
|
|
42
|
+
* 정적 빌드(`generateRegistryFile` 결과) / 테스트 / 기존 호출자 호환 경로.
|
|
43
|
+
*
|
|
44
|
+
* 내부 구현은 `registerMeta` + `hydrateEntry`의 compatibility shim.
|
|
45
|
+
* 두 mutation은 batch로 묶여 단일 notify만 발생한다.
|
|
46
|
+
*/
|
|
47
|
+
register(t) {
|
|
48
|
+
const e = q(t);
|
|
49
|
+
u(this, h, U).call(this, () => {
|
|
50
|
+
this.registerMeta(e), this.hydrateEntry(t.id, t.jogaks, t.meta.component);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
unregister(t) {
|
|
54
|
+
const e = s(this, o).get(t);
|
|
55
|
+
e !== void 0 && (e.kind === "pending" && e.reject(new S(t)), s(this, o).delete(t), u(this, h, g).call(this));
|
|
56
|
+
}
|
|
57
|
+
/** hydrated일 때만 RegistryEntry를 반환한다. meta-only/pending이면 undefined. */
|
|
58
|
+
get(t) {
|
|
59
|
+
const e = s(this, o).get(t);
|
|
60
|
+
return (e == null ? void 0 : e.kind) === "hydrated" ? e.entry : void 0;
|
|
61
|
+
}
|
|
62
|
+
/** hydrated 항목만 반환. meta-only는 `getAllMeta()` 사용. */
|
|
63
|
+
getAll() {
|
|
64
|
+
if (s(this, k) !== void 0) return s(this, k);
|
|
65
|
+
const t = [];
|
|
66
|
+
for (const r of u(this, h, x).call(this)) {
|
|
67
|
+
const n = s(this, o).get(r);
|
|
68
|
+
(n == null ? void 0 : n.kind) === "hydrated" && t.push(n.entry);
|
|
69
|
+
}
|
|
70
|
+
const e = t;
|
|
71
|
+
return l(this, k, e), e;
|
|
72
|
+
}
|
|
73
|
+
search(t) {
|
|
74
|
+
const e = t.toLowerCase();
|
|
75
|
+
return this.getAll().filter((r) => r.title.toLowerCase().includes(e));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* title의 '/' 구분자로 hydrated entry만의 계층 트리를 구성한다.
|
|
79
|
+
*
|
|
80
|
+
* `getAll()`이 정렬된 순서를 반환하므로 트리 객체의 키 iteration order
|
|
81
|
+
* (ECMA-262 §OrdinaryOwnPropertyKeys: insertion order for string keys)도 결정적이다.
|
|
82
|
+
*/
|
|
83
|
+
getTree() {
|
|
84
|
+
if (s(this, E) !== void 0) return s(this, E);
|
|
85
|
+
const t = {};
|
|
86
|
+
for (const e of this.getAll()) {
|
|
87
|
+
const r = e.title.split("/");
|
|
88
|
+
let n = t;
|
|
89
|
+
for (let c = 0; c < r.length - 1; c++) {
|
|
90
|
+
const d = r[c];
|
|
91
|
+
if (d === void 0) continue;
|
|
92
|
+
const m = n[d];
|
|
93
|
+
(m === void 0 || "id" in m) && (n[d] = {}), n = n[d];
|
|
94
|
+
}
|
|
95
|
+
const a = r[r.length - 1];
|
|
96
|
+
a !== void 0 && (n[a] = e);
|
|
97
|
+
}
|
|
98
|
+
return l(this, E, t), t;
|
|
99
|
+
}
|
|
100
|
+
clear() {
|
|
101
|
+
if (s(this, o).size !== 0) {
|
|
102
|
+
for (const t of s(this, o).values())
|
|
103
|
+
t.kind === "pending" && t.reject(new Error("[jogak] registry cleared"));
|
|
104
|
+
s(this, o).clear(), u(this, h, g).call(this);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** hydrated 개수. */
|
|
108
|
+
get size() {
|
|
109
|
+
let t = 0;
|
|
110
|
+
for (const e of s(this, o).values())
|
|
111
|
+
e.kind === "hydrated" && t++;
|
|
112
|
+
return t;
|
|
113
|
+
}
|
|
114
|
+
// ── NEW: 메타 / lazy API ─────────────────────────────────────────────
|
|
115
|
+
/**
|
|
116
|
+
* 인덱스 가상모듈이 호출. 기존 hydrated 항목이 있으면 meta만 갱신(HMR) — entry는 보존.
|
|
117
|
+
* meta 등록만으로는 `getAll()` 결과에 안 들어간다.
|
|
118
|
+
*/
|
|
119
|
+
registerMeta(t) {
|
|
120
|
+
const e = s(this, o).get(t.id);
|
|
121
|
+
if (e === void 0) {
|
|
122
|
+
s(this, o).set(t.id, { kind: "meta", meta: t }), u(this, h, g).call(this);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (e.kind === "meta") {
|
|
126
|
+
s(this, o).set(t.id, { kind: "meta", meta: t }), u(this, h, g).call(this);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (e.kind === "pending") {
|
|
130
|
+
s(this, o).set(t.id, {
|
|
131
|
+
kind: "pending",
|
|
132
|
+
meta: t,
|
|
133
|
+
promise: e.promise,
|
|
134
|
+
resolve: e.resolve,
|
|
135
|
+
reject: e.reject
|
|
136
|
+
}), u(this, h, g).call(this);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const r = {
|
|
140
|
+
...e.entry,
|
|
141
|
+
title: t.title,
|
|
142
|
+
filePath: t.filePath,
|
|
143
|
+
source: t.source,
|
|
144
|
+
meta: F(t, e.entry.meta.component)
|
|
145
|
+
};
|
|
146
|
+
s(this, o).set(t.id, { kind: "hydrated", meta: t, entry: r }), u(this, h, g).call(this);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* entry 가상모듈이 호출. pending Promise들을 resolve.
|
|
150
|
+
* meta가 없는 상태에서 호출되면(=직접 import) 임시 meta를 합성한다 (defensive).
|
|
151
|
+
*/
|
|
152
|
+
hydrateEntry(t, e, r) {
|
|
153
|
+
const n = s(this, o).get(t);
|
|
154
|
+
let a;
|
|
155
|
+
n === void 0 ? (console.warn(
|
|
156
|
+
`[jogak] hydrateEntry called for unknown id "${t}" — synthesizing minimal meta`
|
|
157
|
+
), a = {
|
|
158
|
+
id: t,
|
|
159
|
+
title: t,
|
|
160
|
+
jogakNames: e.map((d) => d.name),
|
|
161
|
+
autoArgTypes: {},
|
|
162
|
+
userArgTypes: {},
|
|
163
|
+
source: "",
|
|
164
|
+
filePath: "",
|
|
165
|
+
metaExtras: {}
|
|
166
|
+
}) : a = n.meta;
|
|
167
|
+
const c = {
|
|
168
|
+
id: a.id,
|
|
169
|
+
title: a.title,
|
|
170
|
+
jogaks: e,
|
|
171
|
+
meta: F(a, r),
|
|
172
|
+
...a.filePath ? { filePath: a.filePath } : {},
|
|
173
|
+
...a.source ? { source: a.source } : {}
|
|
174
|
+
};
|
|
175
|
+
if ((n == null ? void 0 : n.kind) === "pending") {
|
|
176
|
+
s(this, o).set(t, { kind: "hydrated", meta: a, entry: c }), u(this, h, g).call(this), n.resolve(c);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
s(this, o).set(t, { kind: "hydrated", meta: a, entry: c }), u(this, h, g).call(this);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* 어댑터가 호출. hydrated였던 entry를 meta 상태로 되돌린다.
|
|
183
|
+
* HMR meta-update 이벤트에서 args/component 변경을 강제 re-hydrate 시키기 위함.
|
|
184
|
+
* unknown / meta / pending 상태에는 영향 없음.
|
|
185
|
+
*/
|
|
186
|
+
invalidateEntry(t) {
|
|
187
|
+
const e = s(this, o).get(t);
|
|
188
|
+
e === void 0 || e.kind !== "hydrated" || (s(this, o).set(t, { kind: "meta", meta: e.meta }), u(this, h, g).call(this));
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* UI/어댑터가 호출. entry id로 완전한 RegistryEntry를 비동기 획득.
|
|
192
|
+
*
|
|
193
|
+
* - hydrated → 즉시 resolve된 Promise
|
|
194
|
+
* - pending → 기존 Promise 반환 (멱등)
|
|
195
|
+
* - meta → loader 트리거 후 새 Promise 반환, 상태를 pending으로
|
|
196
|
+
* - unknown → 즉시 reject (UnknownEntryError)
|
|
197
|
+
*/
|
|
198
|
+
requestEntry(t) {
|
|
199
|
+
const e = s(this, o).get(t);
|
|
200
|
+
if (e === void 0)
|
|
201
|
+
return Promise.reject(new S(t));
|
|
202
|
+
if (e.kind === "hydrated")
|
|
203
|
+
return Promise.resolve(e.entry);
|
|
204
|
+
if (e.kind === "pending")
|
|
205
|
+
return e.promise;
|
|
206
|
+
const r = s(this, P);
|
|
207
|
+
if (r === void 0)
|
|
208
|
+
return Promise.reject(
|
|
209
|
+
new Error(
|
|
210
|
+
"[jogak] entry loader not set — virtual:jogak index module did not load"
|
|
211
|
+
)
|
|
212
|
+
);
|
|
213
|
+
let n, a;
|
|
214
|
+
const c = new Promise((d, m) => {
|
|
215
|
+
n = d, a = m;
|
|
216
|
+
});
|
|
217
|
+
return s(this, o).set(t, {
|
|
218
|
+
kind: "pending",
|
|
219
|
+
meta: e.meta,
|
|
220
|
+
promise: c,
|
|
221
|
+
resolve: n,
|
|
222
|
+
reject: a
|
|
223
|
+
}), r(t).then(
|
|
224
|
+
() => {
|
|
225
|
+
const d = s(this, o).get(t);
|
|
226
|
+
(d == null ? void 0 : d.kind) !== "hydrated" && a(
|
|
227
|
+
new Error(`[jogak] entry module loaded but did not hydrate: ${t}`)
|
|
228
|
+
);
|
|
229
|
+
},
|
|
230
|
+
(d) => {
|
|
231
|
+
const m = d instanceof Error ? d : new Error(String(d)), p = s(this, o).get(t);
|
|
232
|
+
(p == null ? void 0 : p.kind) === "pending" && p.promise === c && s(this, o).set(t, { kind: "meta", meta: e.meta }), a(m);
|
|
233
|
+
}
|
|
234
|
+
), c;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* 사이드바 메타 전용 — meta-only / pending / hydrated 모두 포함.
|
|
238
|
+
*
|
|
239
|
+
* F2: 내부 캐시. mutation 시점에 invalidate되며 재계산 전까지 동일 reference를 반환한다.
|
|
240
|
+
* useSyncExternalStore의 referential identity 요구를 만족시키기 위함.
|
|
241
|
+
*/
|
|
242
|
+
getAllMeta() {
|
|
243
|
+
if (s(this, v) !== void 0) return s(this, v);
|
|
244
|
+
const t = [];
|
|
245
|
+
for (const r of u(this, h, x).call(this)) {
|
|
246
|
+
const n = s(this, o).get(r);
|
|
247
|
+
n !== void 0 && t.push(n.meta);
|
|
248
|
+
}
|
|
249
|
+
const e = t;
|
|
250
|
+
return l(this, v, e), e;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* 사이드바 트리 전용 — 모든 상태의 meta를 트리화.
|
|
254
|
+
* F2: getAllMeta와 동일한 캐시 정책.
|
|
255
|
+
*/
|
|
256
|
+
getMetaTree() {
|
|
257
|
+
if (s(this, y) !== void 0) return s(this, y);
|
|
258
|
+
const t = {};
|
|
259
|
+
for (const e of u(this, h, x).call(this)) {
|
|
260
|
+
const r = s(this, o).get(e);
|
|
261
|
+
if (r === void 0) continue;
|
|
262
|
+
const n = r.meta, a = n.title.split("/");
|
|
263
|
+
let c = t;
|
|
264
|
+
for (let m = 0; m < a.length - 1; m++) {
|
|
265
|
+
const p = a[m];
|
|
266
|
+
if (p === void 0) continue;
|
|
267
|
+
const b = c[p];
|
|
268
|
+
(b === void 0 || "id" in b) && (c[p] = {}), c = c[p];
|
|
269
|
+
}
|
|
270
|
+
const d = a[a.length - 1];
|
|
271
|
+
d !== void 0 && (c[d] = n);
|
|
272
|
+
}
|
|
273
|
+
return l(this, y, t), t;
|
|
274
|
+
}
|
|
275
|
+
/** 진단 — 상태 머신 노출. */
|
|
276
|
+
getEntryState(t) {
|
|
277
|
+
const e = s(this, o).get(t);
|
|
278
|
+
return e === void 0 ? "unknown" : e.kind;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* dynamic import 함수를 외부에서 주입. plugin이 인덱스 모듈에서 호출한다.
|
|
282
|
+
* 빌드/SSR에서 정적 import 매핑으로 교체할 때도 사용.
|
|
283
|
+
*/
|
|
284
|
+
setEntryLoader(t) {
|
|
285
|
+
l(this, P, t);
|
|
286
|
+
}
|
|
287
|
+
// ── F2: subscribe API ────────────────────────────────────────────────
|
|
288
|
+
/**
|
|
289
|
+
* 등록/해제/메타 갱신/hydrate/clear 시 호출되는 listener를 등록한다.
|
|
290
|
+
*
|
|
291
|
+
* - listener는 무인자, 동기 호출. 어떤 변화가 있었는지는 listener가
|
|
292
|
+
* `getAllMeta()`/`getMetaTree()`로 직접 확인.
|
|
293
|
+
* - mutation 도중 listener에서 `subscribe`/`unsubscribe`를 호출하는 재진입은
|
|
294
|
+
* 안전 (내부적으로 listener Set을 한 번 복사한 뒤 순회).
|
|
295
|
+
* - listener 예외는 catch + console.error 후 계속 (다른 listener 보장).
|
|
296
|
+
* - 반환값은 unsubscribe 함수 (멱등 — 두 번 호출해도 안전).
|
|
297
|
+
*/
|
|
298
|
+
subscribe(t) {
|
|
299
|
+
s(this, T).add(t);
|
|
300
|
+
let e = !0;
|
|
301
|
+
return () => {
|
|
302
|
+
e && (e = !1, s(this, T).delete(t));
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
o = new WeakMap(), P = new WeakMap(), T = new WeakMap(), v = new WeakMap(), y = new WeakMap(), k = new WeakMap(), E = new WeakMap(), w = new WeakMap(), j = new WeakMap(), A = new WeakMap(), h = new WeakSet(), // ── 내부 헬퍼 ─────────────────────────────────────────────────────────
|
|
307
|
+
/**
|
|
308
|
+
* 캐시 invalidate + listener 통지를 단일 헬퍼로.
|
|
309
|
+
* batch 모드에서는 dirty 플래그만 켜고 실제 통지는 batch 종료 시점에 한다.
|
|
310
|
+
*/
|
|
311
|
+
g = function() {
|
|
312
|
+
if (l(this, v, void 0), l(this, y, void 0), l(this, k, void 0), l(this, E, void 0), l(this, w, void 0), s(this, j)) {
|
|
313
|
+
l(this, A, !0);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const t = Array.from(s(this, T));
|
|
317
|
+
for (const e of t)
|
|
318
|
+
try {
|
|
319
|
+
e();
|
|
320
|
+
} catch (r) {
|
|
321
|
+
console.error("[jogak] subscribe listener threw:", r);
|
|
322
|
+
}
|
|
323
|
+
}, /**
|
|
324
|
+
* 모든 외부 노출 collection 이 공유하는 정렬된 id 순서.
|
|
325
|
+
* mutation 시 #cachedSortedIds 가 undefined 로 invalidate, 다음 호출에서 한 번만 재계산.
|
|
326
|
+
*
|
|
327
|
+
* 정렬 정책은 module-private `compareMetaForOrdering` 단일 source.
|
|
328
|
+
*/
|
|
329
|
+
x = function() {
|
|
330
|
+
if (s(this, w) !== void 0) return s(this, w);
|
|
331
|
+
const t = [];
|
|
332
|
+
for (const [r, n] of s(this, o))
|
|
333
|
+
t.push({ id: r, title: n.meta.title });
|
|
334
|
+
t.sort(I);
|
|
335
|
+
const e = t.map((r) => r.id);
|
|
336
|
+
return l(this, w, e), e;
|
|
337
|
+
}, /**
|
|
338
|
+
* register() 처럼 여러 mutation을 묶어 단일 notify로 처리.
|
|
339
|
+
* 내부 전용 — public API 아님.
|
|
340
|
+
*/
|
|
341
|
+
U = function(t) {
|
|
342
|
+
if (s(this, j)) {
|
|
343
|
+
t();
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
l(this, j, !0), l(this, A, !1);
|
|
347
|
+
try {
|
|
348
|
+
t();
|
|
349
|
+
} finally {
|
|
350
|
+
l(this, j, !1), s(this, A) && (l(this, A, !1), u(this, h, g).call(this));
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
function q(i) {
|
|
354
|
+
const t = i.meta.argTypes ?? {};
|
|
355
|
+
return {
|
|
356
|
+
id: i.id,
|
|
357
|
+
title: i.title,
|
|
358
|
+
jogakNames: i.jogaks.map((e) => e.name),
|
|
359
|
+
autoArgTypes: {},
|
|
360
|
+
userArgTypes: t,
|
|
361
|
+
source: i.source ?? "",
|
|
362
|
+
filePath: i.filePath ?? "",
|
|
363
|
+
metaExtras: {
|
|
364
|
+
...i.meta.tags !== void 0 ? { tags: i.meta.tags } : {},
|
|
365
|
+
...i.meta.parameters !== void 0 ? { parameters: i.meta.parameters } : {}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function F(i, t) {
|
|
370
|
+
const e = {
|
|
371
|
+
...i.autoArgTypes
|
|
372
|
+
};
|
|
373
|
+
for (const r of Object.keys(i.userArgTypes)) {
|
|
374
|
+
const n = i.userArgTypes[r];
|
|
375
|
+
n !== void 0 && (e[r] = { ...e[r], ...n });
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
title: i.title,
|
|
379
|
+
component: t,
|
|
380
|
+
argTypes: e,
|
|
381
|
+
...i.metaExtras.tags !== void 0 ? { tags: i.metaExtras.tags } : {},
|
|
382
|
+
...i.metaExtras.parameters !== void 0 ? { parameters: i.metaExtras.parameters } : {}
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
function I(i, t) {
|
|
386
|
+
const e = i.title.localeCompare(t.title, "en", {
|
|
387
|
+
sensitivity: "base",
|
|
388
|
+
numeric: !0
|
|
389
|
+
});
|
|
390
|
+
return e !== 0 ? e : i.id.localeCompare(t.id, "en", { sensitivity: "base", numeric: !0 });
|
|
391
|
+
}
|
|
392
|
+
const R = new $();
|
|
393
|
+
export {
|
|
394
|
+
$ as C,
|
|
395
|
+
S as U,
|
|
396
|
+
R as d
|
|
397
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var L=Object.defineProperty;var z=i=>{throw TypeError(i)};var N=(i,t,e)=>t in i?L(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var S=(i,t,e)=>N(i,typeof t!="symbol"?t+"":t,e),M=(i,t,e)=>t.has(i)||z("Cannot "+e);var s=(i,t,e)=>(M(i,t,"read from private field"),e?e.call(i):t.get(i)),f=(i,t,e)=>t.has(i)?z("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(i):t.set(i,e),l=(i,t,e,r)=>(M(i,t,"write to private field"),r?r.call(i,e):t.set(i,e),e),u=(i,t,e)=>(M(i,t,"access private method"),e);class b extends Error{constructor(e){super(`[jogak] Unknown entry id: ${e}`);S(this,"id");this.name="UnknownEntryError",this.id=e}}var o,P,T,v,y,k,E,w,j,A,h,g,x,U;class R{constructor(){f(this,h);f(this,o,new Map);f(this,P);f(this,T,new Set);f(this,v);f(this,y);f(this,k);f(this,E);f(this,w);f(this,j,!1);f(this,A,!1)}register(t){const e=$(t);u(this,h,U).call(this,()=>{this.registerMeta(e),this.hydrateEntry(t.id,t.jogaks,t.meta.component)})}unregister(t){const e=s(this,o).get(t);e!==void 0&&(e.kind==="pending"&&e.reject(new b(t)),s(this,o).delete(t),u(this,h,g).call(this))}get(t){const e=s(this,o).get(t);return(e==null?void 0:e.kind)==="hydrated"?e.entry:void 0}getAll(){if(s(this,k)!==void 0)return s(this,k);const t=[];for(const r of u(this,h,x).call(this)){const n=s(this,o).get(r);(n==null?void 0:n.kind)==="hydrated"&&t.push(n.entry)}const e=t;return l(this,k,e),e}search(t){const e=t.toLowerCase();return this.getAll().filter(r=>r.title.toLowerCase().includes(e))}getTree(){if(s(this,E)!==void 0)return s(this,E);const t={};for(const e of this.getAll()){const r=e.title.split("/");let n=t;for(let c=0;c<r.length-1;c++){const d=r[c];if(d===void 0)continue;const m=n[d];(m===void 0||"id"in m)&&(n[d]={}),n=n[d]}const a=r[r.length-1];a!==void 0&&(n[a]=e)}return l(this,E,t),t}clear(){if(s(this,o).size!==0){for(const t of s(this,o).values())t.kind==="pending"&&t.reject(new Error("[jogak] registry cleared"));s(this,o).clear(),u(this,h,g).call(this)}}get size(){let t=0;for(const e of s(this,o).values())e.kind==="hydrated"&&t++;return t}registerMeta(t){const e=s(this,o).get(t.id);if(e===void 0){s(this,o).set(t.id,{kind:"meta",meta:t}),u(this,h,g).call(this);return}if(e.kind==="meta"){s(this,o).set(t.id,{kind:"meta",meta:t}),u(this,h,g).call(this);return}if(e.kind==="pending"){s(this,o).set(t.id,{kind:"pending",meta:t,promise:e.promise,resolve:e.resolve,reject:e.reject}),u(this,h,g).call(this);return}const r={...e.entry,title:t.title,filePath:t.filePath,source:t.source,meta:F(t,e.entry.meta.component)};s(this,o).set(t.id,{kind:"hydrated",meta:t,entry:r}),u(this,h,g).call(this)}hydrateEntry(t,e,r){const n=s(this,o).get(t);let a;n===void 0?(console.warn(`[jogak] hydrateEntry called for unknown id "${t}" — synthesizing minimal meta`),a={id:t,title:t,jogakNames:e.map(d=>d.name),autoArgTypes:{},userArgTypes:{},source:"",filePath:"",metaExtras:{}}):a=n.meta;const c={id:a.id,title:a.title,jogaks:e,meta:F(a,r),...a.filePath?{filePath:a.filePath}:{},...a.source?{source:a.source}:{}};if((n==null?void 0:n.kind)==="pending"){s(this,o).set(t,{kind:"hydrated",meta:a,entry:c}),u(this,h,g).call(this),n.resolve(c);return}s(this,o).set(t,{kind:"hydrated",meta:a,entry:c}),u(this,h,g).call(this)}invalidateEntry(t){const e=s(this,o).get(t);e===void 0||e.kind!=="hydrated"||(s(this,o).set(t,{kind:"meta",meta:e.meta}),u(this,h,g).call(this))}requestEntry(t){const e=s(this,o).get(t);if(e===void 0)return Promise.reject(new b(t));if(e.kind==="hydrated")return Promise.resolve(e.entry);if(e.kind==="pending")return e.promise;const r=s(this,P);if(r===void 0)return Promise.reject(new Error("[jogak] entry loader not set — virtual:jogak index module did not load"));let n,a;const c=new Promise((d,m)=>{n=d,a=m});return s(this,o).set(t,{kind:"pending",meta:e.meta,promise:c,resolve:n,reject:a}),r(t).then(()=>{const d=s(this,o).get(t);(d==null?void 0:d.kind)!=="hydrated"&&a(new Error(`[jogak] entry module loaded but did not hydrate: ${t}`))},d=>{const m=d instanceof Error?d:new Error(String(d)),p=s(this,o).get(t);(p==null?void 0:p.kind)==="pending"&&p.promise===c&&s(this,o).set(t,{kind:"meta",meta:e.meta}),a(m)}),c}getAllMeta(){if(s(this,v)!==void 0)return s(this,v);const t=[];for(const r of u(this,h,x).call(this)){const n=s(this,o).get(r);n!==void 0&&t.push(n.meta)}const e=t;return l(this,v,e),e}getMetaTree(){if(s(this,y)!==void 0)return s(this,y);const t={};for(const e of u(this,h,x).call(this)){const r=s(this,o).get(e);if(r===void 0)continue;const n=r.meta,a=n.title.split("/");let c=t;for(let m=0;m<a.length-1;m++){const p=a[m];if(p===void 0)continue;const C=c[p];(C===void 0||"id"in C)&&(c[p]={}),c=c[p]}const d=a[a.length-1];d!==void 0&&(c[d]=n)}return l(this,y,t),t}getEntryState(t){const e=s(this,o).get(t);return e===void 0?"unknown":e.kind}setEntryLoader(t){l(this,P,t)}subscribe(t){s(this,T).add(t);let e=!0;return()=>{e&&(e=!1,s(this,T).delete(t))}}}o=new WeakMap,P=new WeakMap,T=new WeakMap,v=new WeakMap,y=new WeakMap,k=new WeakMap,E=new WeakMap,w=new WeakMap,j=new WeakMap,A=new WeakMap,h=new WeakSet,g=function(){if(l(this,v,void 0),l(this,y,void 0),l(this,k,void 0),l(this,E,void 0),l(this,w,void 0),s(this,j)){l(this,A,!0);return}const t=Array.from(s(this,T));for(const e of t)try{e()}catch(r){console.error("[jogak] subscribe listener threw:",r)}},x=function(){if(s(this,w)!==void 0)return s(this,w);const t=[];for(const[r,n]of s(this,o))t.push({id:r,title:n.meta.title});t.sort(q);const e=t.map(r=>r.id);return l(this,w,e),e},U=function(t){if(s(this,j)){t();return}l(this,j,!0),l(this,A,!1);try{t()}finally{l(this,j,!1),s(this,A)&&(l(this,A,!1),u(this,h,g).call(this))}};function $(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 F(i,t){const e={...i.autoArgTypes};for(const r of Object.keys(i.userArgTypes)){const n=i.userArgTypes[r];n!==void 0&&(e[r]={...e[r],...n})}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 q(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 I=new R;exports.ComponentRegistry=R;exports.UnknownEntryError=b;exports.defaultRegistry=I;
|
package/dist/registry.d.ts
CHANGED
|
@@ -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;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ComponentType, ReactElement } from 'react';
|
|
2
|
+
import { RegistryEntry } from '../../../index.js';
|
|
3
|
+
export interface JogakClientShellProps {
|
|
4
|
+
readonly jogakId: string;
|
|
5
|
+
/**
|
|
6
|
+
* 서버에서 직렬화하여 전달된 RegistryEntry 배열.
|
|
7
|
+
* Server Component → Client 경계를 넘기 위해 `meta.component`는 직렬화되지 않는다.
|
|
8
|
+
*/
|
|
9
|
+
readonly initialEntries: readonly RegistryEntry[];
|
|
10
|
+
/**
|
|
11
|
+
* jogakId에 해당하는 컴포넌트.
|
|
12
|
+
* 함수는 Server Component에서 직렬화 불가하므로,
|
|
13
|
+
* Client 페이지가 자체 import하여 직접 prop으로 전달한다.
|
|
14
|
+
*/
|
|
15
|
+
readonly component: ComponentType<Record<string, unknown>>;
|
|
16
|
+
/**
|
|
17
|
+
* 렌더에 사용할 args. 미지정 시 첫 번째 jogak의 args를 사용한다.
|
|
18
|
+
*/
|
|
19
|
+
readonly args?: Readonly<Record<string, unknown>>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Next.js App Router용 클라이언트 셸.
|
|
23
|
+
*
|
|
24
|
+
* 서버에서 받은 entry 메타데이터를 클라이언트 레지스트리에 로드하고,
|
|
25
|
+
* 함수 prop은 Action spy로 자동 주입한 뒤 React DOM으로 렌더한다.
|
|
26
|
+
*/
|
|
27
|
+
export declare function JogakClientShell({ jogakId, initialEntries, component, args, }: JogakClientShellProps): ReactElement;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),r=require("react"),k=require("react-dom/client"),v=require("../../registry-DRRMxvoz.cjs"),y=require("../../actions-D9bnuJ1b.cjs");function g({jogakId:s,initialEntries:c,component:i,args:u}){var f;const[j]=r.useState(()=>{const t=new v.ComponentRegistry;for(const a of c)t.register(a);return t}),e=j.get(s),l=r.useRef(null),n=r.useRef(null),d=u??((f=e==null?void 0:e.jogaks[0])==null?void 0:f.args)??{};return r.useEffect(()=>{const t=l.current;if(t===null||e===void 0)return;const a=y.injectActions(d,e.meta.argTypes??{});n.current===null&&(n.current=k.createRoot(t)),n.current.render(r.createElement(i,a))},[e,i,d]),r.useEffect(()=>()=>{var t;(t=n.current)==null||t.unmount(),n.current=null},[]),e===void 0?o.jsxs("div",{"data-testid":"jogak-not-found",children:["Jogak not found: ",s]}):o.jsxs("div",{"data-testid":"jogak-client-shell",children:[o.jsx("h2",{"data-testid":"jogak-title",children:e.title}),o.jsx("div",{ref:l,"data-testid":"jogak-preview"})]})}function h({jogakId:s,initialEntries:c,component:i,args:u}){return o.jsx(g,{jogakId:s,initialEntries:c,component:i,...u!==void 0?{args:u}:{}})}exports.JogakClientShell=g;exports.JogakLayout=h;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs as d, jsx as u } from "react/jsx-runtime";
|
|
2
|
+
import { useState as v, useRef as g, useEffect as m, createElement as j } from "react";
|
|
3
|
+
import { createRoot as k } from "react-dom/client";
|
|
4
|
+
import { C as h } from "../../registry-CnBX6XxF.js";
|
|
5
|
+
import { i as R } from "../../actions-BvvUNlgo.js";
|
|
6
|
+
function y({
|
|
7
|
+
jogakId: n,
|
|
8
|
+
initialEntries: s,
|
|
9
|
+
component: o,
|
|
10
|
+
args: i
|
|
11
|
+
}) {
|
|
12
|
+
var f;
|
|
13
|
+
const [p] = v(() => {
|
|
14
|
+
const e = new h();
|
|
15
|
+
for (const c of s) e.register(c);
|
|
16
|
+
return e;
|
|
17
|
+
}), t = p.get(n), a = g(null), r = g(null), l = i ?? ((f = t == null ? void 0 : t.jogaks[0]) == null ? void 0 : f.args) ?? {};
|
|
18
|
+
return m(() => {
|
|
19
|
+
const e = a.current;
|
|
20
|
+
if (e === null || t === void 0) return;
|
|
21
|
+
const c = R(l, t.meta.argTypes ?? {});
|
|
22
|
+
r.current === null && (r.current = k(e)), r.current.render(j(o, c));
|
|
23
|
+
}, [t, o, l]), m(() => () => {
|
|
24
|
+
var e;
|
|
25
|
+
(e = r.current) == null || e.unmount(), r.current = null;
|
|
26
|
+
}, []), t === void 0 ? /* @__PURE__ */ d("div", { "data-testid": "jogak-not-found", children: [
|
|
27
|
+
"Jogak not found: ",
|
|
28
|
+
n
|
|
29
|
+
] }) : /* @__PURE__ */ d("div", { "data-testid": "jogak-client-shell", children: [
|
|
30
|
+
/* @__PURE__ */ u("h2", { "data-testid": "jogak-title", children: t.title }),
|
|
31
|
+
/* @__PURE__ */ u("div", { ref: a, "data-testid": "jogak-preview" })
|
|
32
|
+
] });
|
|
33
|
+
}
|
|
34
|
+
function E({
|
|
35
|
+
jogakId: n,
|
|
36
|
+
initialEntries: s,
|
|
37
|
+
component: o,
|
|
38
|
+
args: i
|
|
39
|
+
}) {
|
|
40
|
+
return /* @__PURE__ */ u(
|
|
41
|
+
y,
|
|
42
|
+
{
|
|
43
|
+
jogakId: n,
|
|
44
|
+
initialEntries: s,
|
|
45
|
+
component: o,
|
|
46
|
+
...i !== void 0 ? { args: i } : {}
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
y as JogakClientShell,
|
|
52
|
+
E as JogakLayout
|
|
53
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ComponentType, ReactElement } from 'react';
|
|
2
|
+
import { RegistryEntry } from '../../../index.js';
|
|
3
|
+
export interface JogakLayoutProps {
|
|
4
|
+
readonly jogakId: string;
|
|
5
|
+
readonly initialEntries: readonly RegistryEntry[];
|
|
6
|
+
readonly component: ComponentType<Record<string, unknown>>;
|
|
7
|
+
readonly args?: Readonly<Record<string, unknown>>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Server Component — 직렬화 가능한 entry 메타데이터를 Client Shell로 전달한다.
|
|
11
|
+
*
|
|
12
|
+
* `entry.meta.component`는 함수이므로 Server → Client 경계를 넘을 수 없다.
|
|
13
|
+
* 호출자가 Client Component(`'use client'`)에서 컴포넌트를 import해
|
|
14
|
+
* `component` prop으로 직접 주입해야 한다.
|
|
15
|
+
*
|
|
16
|
+
* 사용 예 (App Router):
|
|
17
|
+
* ```tsx
|
|
18
|
+
* // app/showcase/page.tsx
|
|
19
|
+
* import { JogakLayout } from '@jogak/core/renderers/next'
|
|
20
|
+
* import { Button } from '@/components/Button' // 'use client' 모듈
|
|
21
|
+
* import { entries } from '@/jogak-entries' // 직렬화 가능한 메타만 담긴 배열
|
|
22
|
+
*
|
|
23
|
+
* export default function Page() {
|
|
24
|
+
* return <JogakLayout jogakId="Components/Button" initialEntries={entries} component={Button} />
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function JogakLayout({ jogakId, initialEntries, component, args, }: JogakLayoutProps): ReactElement;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ComponentRegistry } from '../../index.js';
|
|
3
|
+
export interface JogakProviderProps {
|
|
4
|
+
readonly registry?: ComponentRegistry;
|
|
5
|
+
readonly children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare function JogakProvider({ registry, children }: JogakProviderProps): React.ReactElement;
|
|
8
|
+
export declare function useRegistry(): ComponentRegistry;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react"),k=require("react-dom/client"),S=require("../../actions-D9bnuJ1b.cjs"),b=require("react/jsx-runtime"),m=require("../../registry-DRRMxvoz.cjs"),R={framework:"react",render(t,e,n){const r=t.meta.component,s=S.injectActions(e,t.meta.argTypes??{}),o=n._jogakRoot;if(o!==void 0)o.render(a.createElement(r,s));else{const u=k.createRoot(n);u.render(a.createElement(r,s)),n._jogakRoot=u}},unmount(t){const e=t._jogakRoot;e==null||e.unmount(),delete t._jogakRoot}},d=a.createContext(m.defaultRegistry);function E({registry:t=m.defaultRegistry,children:e}){return b.jsx(d.Provider,{value:t,children:e})}function g(){return a.useContext(d)}function f(t,e){const n=t.getEntryState(e);if(n==="unknown")return{status:"unknown"};if(n==="hydrated"){const s=t.get(e);return s===void 0?{status:"error",error:new Error(`[jogak] inconsistent registry state for id "${e}"`)}:{status:"ready",entry:s}}const r=p(t,e);return r===void 0?{status:"error",error:new Error(`[jogak] meta missing for id "${e}"`)}:{status:"loading",meta:r}}function p(t,e){for(const n of t.getAllMeta())if(n.id===e)return n}function M(t){const e=g(),[n,r]=a.useState(()=>f(e,t));return a.useEffect(()=>{let s=!1,o=null;const u=()=>{if(s)return;const i=f(e,t);r(i),i.status==="loading"&&o!=="loading"?(o="loading",e.requestEntry(t).catch(l=>{if(s)return;const y=l instanceof Error?l:new Error(String(l));r({status:"error",error:y})})):o=i.status};u();const c=e.subscribe(u);return()=>{s=!0,c()}},[e,t]),n}function j(t){return e=>t.subscribe(e)}function v(t){let e=null,n=null,r=null;return()=>{const s=t.getAllMeta(),o=t.getMetaTree();return r!==null&&s===e&&o===n||(e=s,n=o,r={metas:s,metaTree:o}),r}}function h(){const t=g(),e=a.useMemo(()=>j(t),[t]),n=a.useMemo(()=>v(t),[t]),r=a.useSyncExternalStore(e,n,n),s=a.useCallback(o=>{const u=o.trim().toLowerCase();return u.length===0?r.metas:r.metas.filter(c=>c.title.toLowerCase().includes(u))},[r.metas]);return{metas:r.metas,metaTree:r.metaTree,searchMeta:s}}exports.JogakProvider=E;exports.reactAdapter=R;exports.useEntry=M;exports.useRegistry=g;exports.useRegistryMeta=h;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { reactAdapter } from './adapter.js';
|
|
2
|
+
export { JogakProvider, useRegistry } from './JogakProvider.js';
|
|
3
|
+
export type { JogakProviderProps } from './JogakProvider.js';
|
|
4
|
+
export { useEntry } from './useEntry.js';
|
|
5
|
+
export type { UseEntryState } from './useEntry.js';
|
|
6
|
+
export { useRegistryMeta } from './useRegistryMeta.js';
|
|
7
|
+
export type { UseRegistryMetaReturn } from './useRegistryMeta.js';
|