@jogak/core 0.1.0-alpha.0 → 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.
Files changed (76) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/dist/actions-BvvUNlgo.js +69 -0
  3. package/dist/actions-D9bnuJ1b.cjs +1 -0
  4. package/dist/adapter.d.ts +80 -0
  5. package/dist/adapters/next/index.cjs +73 -0
  6. package/dist/adapters/next/index.d.ts +5 -0
  7. package/dist/adapters/next/index.mjs +222 -0
  8. package/dist/adapters/next/scaffold.d.ts +23 -0
  9. package/dist/adapters/next/spawn-dev.d.ts +2 -0
  10. package/dist/adapters/standalone/index.cjs +1 -0
  11. package/dist/adapters/standalone/index.d.ts +3 -0
  12. package/dist/adapters/standalone/index.mjs +21 -0
  13. package/dist/adapters/vite/build.d.ts +2 -0
  14. package/dist/adapters/vite/index.cjs +22 -0
  15. package/dist/adapters/vite/index.d.ts +5 -0
  16. package/dist/adapters/vite/index.mjs +134 -0
  17. package/dist/adapters/vite/preview-frame-plugin.d.ts +6 -0
  18. package/dist/adapters/vite/spawn-dev.d.ts +2 -0
  19. package/dist/adapters/webpack/index.cjs +74 -0
  20. package/dist/adapters/webpack/index.d.ts +5 -0
  21. package/dist/adapters/webpack/index.mjs +214 -0
  22. package/dist/adapters/webpack/scaffold.d.ts +18 -0
  23. package/dist/adapters/webpack/spawn-dev.d.ts +2 -0
  24. package/dist/builder-detect.d.ts +9 -0
  25. package/dist/config.d.ts +71 -0
  26. package/dist/detect-global-css-CDcuUAYE.cjs +1 -0
  27. package/dist/detect-global-css-CIVMmgzy.js +33 -0
  28. package/dist/index.cjs +1 -0
  29. package/dist/index.d.ts +5 -1
  30. package/dist/index.mjs +13 -413
  31. package/dist/plugin-DhT-PH1R.js +354 -0
  32. package/dist/plugin-Wtlz0hae.cjs +50 -0
  33. package/dist/preview-entry/protocol.d.ts +29 -0
  34. package/dist/preview-entry/source.d.ts +30 -0
  35. package/dist/registry-CnBX6XxF.js +397 -0
  36. package/dist/registry-DRRMxvoz.cjs +1 -0
  37. package/dist/registry.d.ts +3 -0
  38. package/dist/renderers/next/client/Preview.d.ts +27 -0
  39. package/dist/renderers/next/client/index.d.ts +2 -0
  40. package/dist/renderers/next/index.cjs +1 -0
  41. package/dist/renderers/next/index.d.ts +4 -0
  42. package/dist/renderers/next/index.mjs +53 -0
  43. package/dist/renderers/next/server/JogakLayout.d.ts +28 -0
  44. package/dist/renderers/next/server/index.d.ts +2 -0
  45. package/dist/renderers/react/JogakProvider.d.ts +8 -0
  46. package/dist/renderers/react/adapter.d.ts +2 -0
  47. package/dist/renderers/react/index.cjs +1 -0
  48. package/dist/renderers/react/index.d.ts +7 -0
  49. package/dist/renderers/react/index.mjs +101 -0
  50. package/dist/renderers/react/useEntry.d.ts +40 -0
  51. package/dist/renderers/react/useRegistryMeta.d.ts +27 -0
  52. package/dist/renderers/web-components/define.d.ts +11 -0
  53. package/dist/renderers/web-components/index.cjs +1 -0
  54. package/dist/renderers/web-components/index.d.ts +1 -0
  55. package/dist/renderers/web-components/index.mjs +48 -0
  56. package/dist/server.cjs +1 -0
  57. package/dist/server.d.ts +12 -0
  58. package/dist/server.mjs +45 -0
  59. package/dist/source-9OiU8x_y.cjs +43 -0
  60. package/dist/source-D44KTQPu.js +50 -0
  61. package/dist/types.d.ts +161 -0
  62. package/dist/vite/index.cjs +1 -0
  63. package/dist/vite/index.mjs +2 -275
  64. package/dist/vite-plugin/detect-global-css.d.ts +33 -0
  65. package/dist/vite-plugin/index.cjs +1 -0
  66. package/dist/vite-plugin/index.d.ts +12 -0
  67. package/dist/vite-plugin/index.mjs +4 -0
  68. package/dist/vite-plugin/resolve-paths.d.ts +32 -0
  69. package/dist/{vite → vite-plugin}/virtual-ids.d.ts +17 -0
  70. package/package.json +101 -10
  71. package/dist/index.js +0 -1
  72. package/dist/vite/index.js +0 -41
  73. /package/dist/build/{index.js → index.cjs} +0 -0
  74. /package/dist/meta/{extractor-child.js → extractor-child.cjs} +0 -0
  75. /package/dist/{vite → vite-plugin}/cache-validate.d.ts +0 -0
  76. /package/dist/{vite → vite-plugin}/plugin.d.ts +0 -0
@@ -1,277 +1,4 @@
1
- import { resolve as S, join as $ } from "node:path";
2
- import { existsSync as j } from "node:fs";
3
- import { stat as I, rm as G, readdir as U, readFile as C } from "node:fs/promises";
4
- import { c as R } from "../extractor-client-CReBed7x.js";
5
- const B = [
6
- "@jogak/core",
7
- "@jogak/react",
8
- "@jogak/web-components",
9
- "@jogak/next"
10
- ];
11
- async function P(t) {
12
- try {
13
- const u = await I(t);
14
- if (!u.isDirectory())
15
- return u.mtimeMs;
16
- } catch {
17
- return 0;
18
- }
19
- let n = 0, m;
20
- try {
21
- m = await U(t);
22
- } catch {
23
- return 0;
24
- }
25
- for (const u of m) {
26
- const p = $(t, u);
27
- try {
28
- const l = await I(p);
29
- if (l.isDirectory()) {
30
- const a = await P(p);
31
- a > n && (n = a);
32
- } else l.mtimeMs > n && (n = l.mtimeMs);
33
- } catch {
34
- continue;
35
- }
36
- }
37
- return n;
38
- }
39
- async function J(t) {
40
- const n = S(t.root, "node_modules/.vite/deps");
41
- if (!j(n))
42
- return { purged: !1 };
43
- const m = $(n, "_metadata.json");
44
- if (!j(m))
45
- return { purged: !1 };
46
- let u;
47
- try {
48
- u = (await I(m)).mtimeMs;
49
- } catch (l) {
50
- return t.logger.warn(
51
- `[jogak] cache validation: failed to stat _metadata.json (${l.message})`
52
- ), { purged: !1 };
53
- }
54
- const p = t.packages ?? B;
55
- for (const l of p) {
56
- const a = S(t.root, "node_modules", l, "dist");
57
- if (!j(a)) continue;
58
- let i;
59
- try {
60
- i = await P(a);
61
- } catch (y) {
62
- t.logger.warn(
63
- `[jogak] cache validation: failed to walk ${l}/dist (${y.message})`
64
- );
65
- continue;
66
- }
67
- if (i > u + 1e3)
68
- try {
69
- return await G(n, { recursive: !0, force: !0 }), t.logger.info(
70
- `[jogak] vite deps cache invalidated (stale): ${l} dist newer than cache`
71
- ), { purged: !0, reason: l };
72
- } catch (y) {
73
- return t.logger.warn(
74
- `[jogak] cache validation: failed to purge ${n} (${y.message})`
75
- ), { purged: !1 };
76
- }
77
- }
78
- return { purged: !1 };
79
- }
80
- const D = "virtual:jogak", T = "\0" + D, F = "virtual:jogak/entry/", x = "\0" + F;
81
- function K(t) {
82
- return Buffer.from(t, "utf8").toString("base64url");
83
- }
84
- function X(t) {
85
- return Buffer.from(t, "base64url").toString("utf8");
86
- }
87
- function A(t) {
88
- return {
89
- title: t.title,
90
- jogakNamesKey: [...t.jogakNames].sort().join("|")
91
- };
92
- }
93
- function W(t, n) {
94
- return t !== void 0 && t.title === n.title && t.jogakNamesKey === n.jogakNamesKey;
95
- }
96
- function Z(t = {}) {
97
- const {
98
- patterns: n = ["src/**/*.jogak.ts", "src/**/*.jogak.tsx"],
99
- codeTheme: m = "vsDark"
100
- } = t, u = t.cwd, p = t.tsConfigFilePath, l = t.disableCacheValidation === !0;
101
- let a, i, y;
102
- const w = /* @__PURE__ */ new Map(), k = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map();
103
- async function N() {
104
- const { glob: e } = await import("glob"), g = y ?? process.cwd(), o = await e(n, { cwd: g, absolute: !0 }), d = [];
105
- w.clear(), k.clear();
106
- for (const s of o) {
107
- let f = "";
108
- try {
109
- f = await C(s, "utf8");
110
- } catch {
111
- continue;
112
- }
113
- let v = {}, r = null;
114
- if (i !== void 0) {
115
- try {
116
- v = await i.extract(s);
117
- } catch {
118
- v = {};
119
- }
120
- try {
121
- r = await i.extractMeta(s);
122
- } catch {
123
- r = null;
124
- }
125
- }
126
- if (r === null) continue;
127
- const c = r.title;
128
- w.set(c, s), k.set(s, c);
129
- const h = {
130
- id: c,
131
- title: r.title,
132
- jogakNames: r.jogakNames,
133
- autoArgTypes: v,
134
- userArgTypes: r.userArgTypes,
135
- source: f,
136
- filePath: s,
137
- metaExtras: r.metaExtras
138
- };
139
- _.set(s, A(h)), d.push({ id: c, filePath: s, meta: h });
140
- }
141
- return d;
142
- }
143
- return {
144
- name: "vite-plugin-jogak",
145
- async configResolved(e) {
146
- y = u ?? e.root, e.command === "serve" && !l && await J({
147
- root: e.root,
148
- logger: {
149
- info: (o) => e.logger.info(o),
150
- warn: (o) => e.logger.warn(o)
151
- }
152
- });
153
- const g = p ?? S(y, "tsconfig.json");
154
- i = j(g) ? R({ tsConfigFilePath: g }) : R();
155
- },
156
- configureServer(e) {
157
- a = e;
158
- },
159
- buildEnd() {
160
- i == null || i.releaseCache();
161
- },
162
- resolveId(e) {
163
- if (e === D)
164
- return T;
165
- if (e.startsWith(F))
166
- return "\0" + e;
167
- },
168
- async load(e) {
169
- if (e === T) {
170
- const o = (await N()).map((d) => d.meta);
171
- return `import { defaultRegistry } from '@jogak/core'
172
-
173
- const _entryLoader = (slug) =>
174
- import(/* @vite-ignore */ '/@id/__x00__virtual:jogak/entry/' + slug)
175
- defaultRegistry.setEntryLoader((id) => {
176
- const slug = ${Y()}
177
- return _entryLoader(slug(id))
178
- })
179
-
180
- const _metas = ${JSON.stringify(o)}
181
-
182
- for (const m of _metas) defaultRegistry.registerMeta(m)
183
-
184
- export const _jogakCodeTheme = ${JSON.stringify(m)}
185
- export const _jogakMetas = _metas
186
- `;
187
- }
188
- if (e.startsWith(x)) {
189
- const g = e.slice(x.length), o = X(g);
190
- let d = w.get(o);
191
- return d === void 0 && (await N(), d = w.get(o)), d === void 0 ? `// [jogak] unknown entry id: ${JSON.stringify(o)}
192
- export {}
193
- ` : `import * as _user from ${JSON.stringify(d)}
194
- import { defaultRegistry } from '@jogak/core'
195
-
196
- const _meta = _user.default
197
- const _named = { ..._user }
198
- delete _named.default
199
- const _jogaks = Object.values(_named).filter(
200
- (v) => v !== null && typeof v === 'object' && typeof v.name === 'string'
201
- )
202
- defaultRegistry.hydrateEntry(${JSON.stringify(o)}, _jogaks, _meta?.component)
203
-
204
- if (import.meta.hot) {
205
- import.meta.hot.accept()
206
- }
207
-
208
- export {}
209
- `;
210
- }
211
- },
212
- async handleHotUpdate({ file: e, modules: g }) {
213
- const o = /\.jogak\.(tsx?|jsx?)$/.test(e), d = /\.(tsx?|jsx?)$/.test(e) && !o;
214
- if (!o && !d || a === void 0 || !o) return;
215
- const s = a.moduleGraph.getModuleById(
216
- T
217
- ), f = k.get(e), v = f !== void 0 ? x + K(f) : void 0, r = v !== void 0 ? a.moduleGraph.getModuleById(v) : void 0;
218
- let c = null, h = {}, M = "";
219
- if (i !== void 0) {
220
- try {
221
- c = await i.extractMeta(e);
222
- } catch {
223
- c = null;
224
- }
225
- try {
226
- h = await i.extract(e);
227
- } catch {
228
- h = {};
229
- }
230
- try {
231
- M = await C(e, "utf8");
232
- } catch {
233
- M = "";
234
- }
235
- }
236
- if (c === null) {
237
- s !== void 0 && a.moduleGraph.invalidateModule(s), r !== void 0 && a.moduleGraph.invalidateModule(r), a.ws.send({ type: "full-reload" });
238
- return;
239
- }
240
- const b = A(c), O = _.get(e), L = W(O, b);
241
- if (_.set(e, b), !L || f === void 0) {
242
- s !== void 0 && a.moduleGraph.invalidateModule(s), r !== void 0 && a.moduleGraph.invalidateModule(r), a.ws.send({ type: "full-reload" });
243
- return;
244
- }
245
- const V = {
246
- id: f,
247
- title: c.title,
248
- jogakNames: c.jogakNames,
249
- autoArgTypes: h,
250
- userArgTypes: c.userArgTypes,
251
- source: M,
252
- filePath: e,
253
- metaExtras: c.metaExtras
254
- };
255
- r !== void 0 && a.moduleGraph.invalidateModule(r), a.ws.send({
256
- type: "custom",
257
- event: "jogak:meta-update",
258
- data: { id: f, meta: V }
259
- });
260
- const E = [...g];
261
- return r !== void 0 && !E.includes(r) && E.push(r), E;
262
- }
263
- };
264
- }
265
- function Y() {
266
- return `(rawId) => {
267
- if (typeof Buffer !== 'undefined') return Buffer.from(rawId, 'utf8').toString('base64url')
268
- // 브라우저 폴백: btoa는 binary string 기준이라 UTF-8을 한번 인코딩해야 한다.
269
- const enc = new TextEncoder().encode(rawId)
270
- let bin = ''
271
- for (let i = 0; i < enc.length; i++) bin += String.fromCharCode(enc[i])
272
- return btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')
273
- }`;
274
- }
1
+ import { j } from "../plugin-DhT-PH1R.js";
275
2
  export {
276
- Z as jogak
3
+ j as jogak
277
4
  };
@@ -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[];
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../plugin-Wtlz0hae.cjs");exports.jogak=e.jogak;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 알파.10: jogak host vite plugin entry.
3
+ *
4
+ * 알파.9까지 `@jogak/core/vite`로 노출됐던 플러그인. alpha.10에서는
5
+ * `@jogak/core/vite-plugin`으로 정식 노출되며 `@jogak/core/vite`도 별칭으로 유지된다.
6
+ *
7
+ * 이 플러그인은 jogak host SPA의 vite scope에서 동작 — `*.jogak.tsx` 글롭 디스커버리,
8
+ * 가상 모듈(`virtual:jogak`, `virtual:jogak/entry/*`) emit, HMR self-accept 등을
9
+ * 담당한다. 사용자 vite scope의 preview-frame plugin은 별개로
10
+ * `@jogak/core/adapters/vite`가 보유한다.
11
+ */
12
+ export * from './plugin.js';
@@ -0,0 +1,4 @@
1
+ import { j } from "../plugin-DhT-PH1R.js";
2
+ export {
3
+ j as jogak
4
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * 사용자 tsconfig의 `compilerOptions.paths`를 vite `resolve.alias`로 변환한다.
3
+ *
4
+ * 동기:
5
+ * - `runHost`는 vite root를 `@jogak/ui` 패키지로 두고 사용자 `vite.config.ts`를
6
+ * 무시하므로(`configFile: false`), 사용자가 정의한 alias가 적용되지 않는다.
7
+ * - shadcn/ui 같은 라이브러리는 `@/lib/utils` 같은 alias를 컴포넌트 안에서
8
+ * 사용하고, 사용자가 작성한 `*.jogak.tsx`도 같은 alias로 컴포넌트를 import.
9
+ * - 따라서 jogak이 사용자의 path alias를 자동으로 인식하지 못하면 dev/build에서
10
+ * "Failed to resolve import" 에러가 난다.
11
+ *
12
+ * 처리 범위:
13
+ * - 단순 prefix 매핑: `"@/*": ["./src/*"]` → `{ "@": "<baseDir>/src" }`
14
+ * - references로 분할된 tsconfig (Vite 기본 스캐폴드 = `tsconfig.json` +
15
+ * `tsconfig.app.json`): 후보 경로 두 개 모두 시도하고 먼저 발견된 매핑을 채택.
16
+ *
17
+ * 미처리 (의도적):
18
+ * - `extends` 체인: TypeScript Compiler API를 부모 V8에 로드하기 부담이 커서
19
+ * 단순 정규식 + JSON 파싱으로 처리. 대부분의 사용자 케이스(scaffold default,
20
+ * shadcn/ui)는 references 패턴이라 본 범위에서 충분.
21
+ * - 복합 glob 패턴: 두 개 이상의 와일드카드를 포함하는 매핑은 처리하지 않는다.
22
+ *
23
+ * 자동 추출이 실패하면 `JogakPluginOptions.resolveAlias`로 명시적 alias를
24
+ * 전달할 수 있다 (사용자 fallback).
25
+ */
26
+ /**
27
+ * 사용자 tsconfig 후보 경로들에서 paths를 추출해 alias 맵으로 합친다.
28
+ *
29
+ * @param primaryTsConfig 사용자가 명시했거나 자동 감지된 1차 tsconfig 절대 경로
30
+ * @param userRoot 사용자 프로젝트 루트 — references 분할 시 fallback 후보 위치 계산용
31
+ */
32
+ export declare function readTsConfigAlias(primaryTsConfig: string, userRoot: string): Readonly<Record<string, string>>;
@@ -15,5 +15,22 @@ 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;
21
+ /**
22
+ * Preview frame entry (알파.8) — 사용자 vite scope의 iframe entry.
23
+ * jogakPreviewFramePlugin이 emit. 사용자 vite의 module graph에 포함되어
24
+ * 사용자 plugins(@tailwindcss/vite 등)가 정상 처리.
25
+ */
26
+ export declare const VIRTUAL_PREVIEW_ENTRY_ID = "virtual:jogak/preview-entry";
27
+ export declare const RESOLVED_VIRTUAL_PREVIEW_ENTRY_ID: string;
28
+ /**
29
+ * Preview-scope의 사용자 globalCss (알파.8) — 알파.6의 `virtual:jogak/global-css`는
30
+ * jogak SPA scope. 본 모듈은 사용자 vite scope의 preview-frame entry용.
31
+ * jogakPreviewFramePlugin이 emit.
32
+ */
33
+ export declare const VIRTUAL_PREVIEW_GLOBAL_CSS_ID = "virtual:jogak/preview-global-css";
34
+ export declare const RESOLVED_VIRTUAL_PREVIEW_GLOBAL_CSS_ID: string;
18
35
  export declare function idToSlug(id: string): string;
19
36
  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.0",
3
+ "version": "0.1.0-alpha.10.2",
4
4
  "description": "Core types, registry, and Vite plugin for Jogak — a lightweight Storybook alternative.",
5
5
  "keywords": [
6
6
  "jogak",
@@ -25,22 +25,69 @@
25
25
  },
26
26
  "type": "module",
27
27
  "sideEffects": false,
28
- "main": "./dist/index.js",
28
+ "main": "./dist/index.cjs",
29
29
  "module": "./dist/index.mjs",
30
30
  "types": "./dist/index.d.ts",
31
31
  "exports": {
32
32
  ".": {
33
33
  "types": "./dist/index.d.ts",
34
34
  "import": "./dist/index.mjs",
35
- "require": "./dist/index.js"
35
+ "require": "./dist/index.cjs"
36
+ },
37
+ "./vite-plugin": {
38
+ "types": "./dist/vite-plugin/index.d.ts",
39
+ "import": "./dist/vite-plugin/index.mjs",
40
+ "require": "./dist/vite-plugin/index.cjs"
36
41
  },
37
42
  "./vite": {
38
- "types": "./dist/vite/plugin.d.ts",
39
- "import": "./dist/vite/index.mjs"
43
+ "types": "./dist/vite-plugin/index.d.ts",
44
+ "import": "./dist/vite/index.mjs",
45
+ "require": "./dist/vite/index.cjs"
40
46
  },
41
47
  "./build": {
42
48
  "types": "./dist/build/index.d.ts",
43
- "import": "./dist/build/index.mjs"
49
+ "import": "./dist/build/index.mjs",
50
+ "require": "./dist/build/index.cjs"
51
+ },
52
+ "./server": {
53
+ "types": "./dist/server.d.ts",
54
+ "import": "./dist/server.mjs",
55
+ "require": "./dist/server.cjs"
56
+ },
57
+ "./adapters/vite": {
58
+ "types": "./dist/adapters/vite/index.d.ts",
59
+ "import": "./dist/adapters/vite/index.mjs",
60
+ "require": "./dist/adapters/vite/index.cjs"
61
+ },
62
+ "./adapters/next": {
63
+ "types": "./dist/adapters/next/index.d.ts",
64
+ "import": "./dist/adapters/next/index.mjs",
65
+ "require": "./dist/adapters/next/index.cjs"
66
+ },
67
+ "./adapters/webpack": {
68
+ "types": "./dist/adapters/webpack/index.d.ts",
69
+ "import": "./dist/adapters/webpack/index.mjs",
70
+ "require": "./dist/adapters/webpack/index.cjs"
71
+ },
72
+ "./adapters/standalone": {
73
+ "types": "./dist/adapters/standalone/index.d.ts",
74
+ "import": "./dist/adapters/standalone/index.mjs",
75
+ "require": "./dist/adapters/standalone/index.cjs"
76
+ },
77
+ "./renderers/react": {
78
+ "types": "./dist/renderers/react/index.d.ts",
79
+ "import": "./dist/renderers/react/index.mjs",
80
+ "require": "./dist/renderers/react/index.cjs"
81
+ },
82
+ "./renderers/next": {
83
+ "types": "./dist/renderers/next/index.d.ts",
84
+ "import": "./dist/renderers/next/index.mjs",
85
+ "require": "./dist/renderers/next/index.cjs"
86
+ },
87
+ "./renderers/web-components": {
88
+ "types": "./dist/renderers/web-components/index.d.ts",
89
+ "import": "./dist/renderers/web-components/index.mjs",
90
+ "require": "./dist/renderers/web-components/index.cjs"
44
91
  }
45
92
  },
46
93
  "files": [
@@ -58,25 +105,69 @@
58
105
  },
59
106
  "dependencies": {
60
107
  "glob": "^11.0.0",
61
- "ts-morph": "^23.0.0"
108
+ "ts-morph": "^23.0.0",
109
+ "preact": "^10.23.0"
62
110
  },
63
111
  "devDependencies": {
64
112
  "vite": "^6.0.0",
65
113
  "vite-plugin-dts": "^4.0.0",
114
+ "vitest": "^2.0.0",
66
115
  "typescript": "^5.5.0",
67
- "@types/node": "^20.14.0"
116
+ "@types/node": "^20.14.0",
117
+ "@types/react": "^19.0.0",
118
+ "@types/react-dom": "^19.0.0",
119
+ "react": "^19.2.5",
120
+ "react-dom": "^19.2.5",
121
+ "@vitejs/plugin-react": "^4.3.0",
122
+ "next": "^15.0.0",
123
+ "webpack": "^5.0.0",
124
+ "webpack-dev-server": "^5.0.0",
125
+ "webpack-merge": "^6.0.0",
126
+ "html-webpack-plugin": "^5.0.0",
127
+ "@testing-library/react": "^16.3.2",
128
+ "happy-dom": "^20.9.0"
68
129
  },
69
130
  "peerDependencies": {
70
- "vite": "^6.0.0"
131
+ "vite": "^6.0.0 || ^7.0.0",
132
+ "react": "^18.2.0 || ^19.0.0",
133
+ "react-dom": "^18.2.0 || ^19.0.0",
134
+ "next": "^14.0.0 || ^15.0.0",
135
+ "webpack": "^5.0.0",
136
+ "webpack-dev-server": "^5.0.0",
137
+ "webpack-merge": "^6.0.0",
138
+ "html-webpack-plugin": "^5.0.0"
71
139
  },
72
140
  "peerDependenciesMeta": {
73
141
  "vite": {
74
142
  "optional": true
143
+ },
144
+ "react": {
145
+ "optional": true
146
+ },
147
+ "react-dom": {
148
+ "optional": true
149
+ },
150
+ "next": {
151
+ "optional": true
152
+ },
153
+ "webpack": {
154
+ "optional": true
155
+ },
156
+ "webpack-dev-server": {
157
+ "optional": true
158
+ },
159
+ "webpack-merge": {
160
+ "optional": true
161
+ },
162
+ "html-webpack-plugin": {
163
+ "optional": true
75
164
  }
76
165
  },
77
166
  "scripts": {
78
167
  "build": "vite build",
79
168
  "dev": "vite build --watch",
80
- "typecheck": "tsc --noEmit"
169
+ "typecheck": "tsc --noEmit",
170
+ "test": "vitest run",
171
+ "test:watch": "vitest"
81
172
  }
82
173
  }
package/dist/index.js DELETED
@@ -1 +0,0 @@
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,41 +0,0 @@
1
- "use strict";var V=Object.create;var N=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var q=(e,a,i,u)=>{if(a&&typeof a=="object"||typeof a=="function")for(let d of U(a))!J.call(e,d)&&d!==i&&N(e,d,{get:()=>a[d],enumerable:!(u=G(a,d))||u.enumerable});return e};var K=(e,a,i)=>(i=e!=null?V(B(e)):{},q(a||!e||!e.__esModule?N(i,"default",{value:e,enumerable:!0}):i,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("node:path"),_=require("node:fs"),v=require("node:fs/promises"),R=require("../extractor-client-CiWszHel.cjs"),X=["@jogak/core","@jogak/react","@jogak/web-components","@jogak/next"];async function P(e){try{const u=await v.stat(e);if(!u.isDirectory())return u.mtimeMs}catch{return 0}let a=0,i;try{i=await v.readdir(e)}catch{return 0}for(const u of i){const d=j.join(e,u);try{const g=await v.stat(d);if(g.isDirectory()){const r=await P(d);r>a&&(a=r)}else g.mtimeMs>a&&(a=g.mtimeMs)}catch{continue}}return a}async function W(e){const a=j.resolve(e.root,"node_modules/.vite/deps");if(!_.existsSync(a))return{purged:!1};const i=j.join(a,"_metadata.json");if(!_.existsSync(i))return{purged:!1};let u;try{u=(await v.stat(i)).mtimeMs}catch(g){return e.logger.warn(`[jogak] cache validation: failed to stat _metadata.json (${g.message})`),{purged:!1}}const d=e.packages??X;for(const g of d){const r=j.resolve(e.root,"node_modules",g,"dist");if(!_.existsSync(r))continue;let s;try{s=await P(r)}catch(p){e.logger.warn(`[jogak] cache validation: failed to walk ${g}/dist (${p.message})`);continue}if(s>u+1e3)try{return await v.rm(a,{recursive:!0,force:!0}),e.logger.info(`[jogak] vite deps cache invalidated (stale): ${g} dist newer than cache`),{purged:!0,reason:g}}catch(p){return e.logger.warn(`[jogak] cache validation: failed to purge ${a} (${p.message})`),{purged:!1}}}return{purged:!1}}const $="virtual:jogak",T="\0"+$,F="virtual:jogak/entry/",I="\0"+F;function Y(e){return Buffer.from(e,"utf8").toString("base64url")}function H(e){return Buffer.from(e,"base64url").toString("utf8")}function A(e){return{title:e.title,jogakNamesKey:[...e.jogakNames].sort().join("|")}}function z(e,a){return e!==void 0&&e.title===a.title&&e.jogakNamesKey===a.jogakNamesKey}function Q(e={}){const{patterns:a=["src/**/*.jogak.ts","src/**/*.jogak.tsx"],codeTheme:i="vsDark"}=e,u=e.cwd,d=e.tsConfigFilePath,g=e.disableCacheValidation===!0;let r,s,p;const k=new Map,x=new Map,M=new Map;async function b(){const{glob:t}=await import("glob"),m=p??process.cwd(),n=await t(a,{cwd:m,absolute:!0}),f=[];k.clear(),x.clear();for(const c of n){let y="";try{y=await v.readFile(c,"utf8")}catch{continue}let h={},o=null;if(s!==void 0){try{h=await s.extract(c)}catch{h={}}try{o=await s.extractMeta(c)}catch{o=null}}if(o===null)continue;const l=o.title;k.set(l,c),x.set(c,l);const w={id:l,title:o.title,jogakNames:o.jogakNames,autoArgTypes:h,userArgTypes:o.userArgTypes,source:y,filePath:c,metaExtras:o.metaExtras};M.set(c,A(w)),f.push({id:l,filePath:c,meta:w})}return f}return{name:"vite-plugin-jogak",async configResolved(t){p=u??t.root,t.command==="serve"&&!g&&await W({root:t.root,logger:{info:n=>t.logger.info(n),warn:n=>t.logger.warn(n)}});const m=d??j.resolve(p,"tsconfig.json");s=_.existsSync(m)?R.createPropsExtractor({tsConfigFilePath:m}):R.createPropsExtractor()},configureServer(t){r=t},buildEnd(){s==null||s.releaseCache()},resolveId(t){if(t===$)return T;if(t.startsWith(F))return"\0"+t},async load(t){if(t===T){const n=(await b()).map(f=>f.meta);return`import { defaultRegistry } from '@jogak/core'
2
-
3
- const _entryLoader = (slug) =>
4
- import(/* @vite-ignore */ '/@id/__x00__virtual:jogak/entry/' + slug)
5
- defaultRegistry.setEntryLoader((id) => {
6
- const slug = ${Z()}
7
- return _entryLoader(slug(id))
8
- })
9
-
10
- const _metas = ${JSON.stringify(n)}
11
-
12
- for (const m of _metas) defaultRegistry.registerMeta(m)
13
-
14
- export const _jogakCodeTheme = ${JSON.stringify(i)}
15
- export const _jogakMetas = _metas
16
- `}if(t.startsWith(I)){const m=t.slice(I.length),n=H(m);let f=k.get(n);return f===void 0&&(await b(),f=k.get(n)),f===void 0?`// [jogak] unknown entry id: ${JSON.stringify(n)}
17
- export {}
18
- `:`import * as _user from ${JSON.stringify(f)}
19
- import { defaultRegistry } from '@jogak/core'
20
-
21
- const _meta = _user.default
22
- const _named = { ..._user }
23
- delete _named.default
24
- const _jogaks = Object.values(_named).filter(
25
- (v) => v !== null && typeof v === 'object' && typeof v.name === 'string'
26
- )
27
- defaultRegistry.hydrateEntry(${JSON.stringify(n)}, _jogaks, _meta?.component)
28
-
29
- if (import.meta.hot) {
30
- import.meta.hot.accept()
31
- }
32
-
33
- export {}
34
- `}},async handleHotUpdate({file:t,modules:m}){const n=/\.jogak\.(tsx?|jsx?)$/.test(t),f=/\.(tsx?|jsx?)$/.test(t)&&!n;if(!n&&!f||r===void 0||!n)return;const c=r.moduleGraph.getModuleById(T),y=x.get(t),h=y!==void 0?I+Y(y):void 0,o=h!==void 0?r.moduleGraph.getModuleById(h):void 0;let l=null,w={},S="";if(s!==void 0){try{l=await s.extractMeta(t)}catch{l=null}try{w=await s.extract(t)}catch{w={}}try{S=await v.readFile(t,"utf8")}catch{S=""}}if(l===null){c!==void 0&&r.moduleGraph.invalidateModule(c),o!==void 0&&r.moduleGraph.invalidateModule(o),r.ws.send({type:"full-reload"});return}const C=A(l),D=M.get(t),O=z(D,C);if(M.set(t,C),!O||y===void 0){c!==void 0&&r.moduleGraph.invalidateModule(c),o!==void 0&&r.moduleGraph.invalidateModule(o),r.ws.send({type:"full-reload"});return}const L={id:y,title:l.title,jogakNames:l.jogakNames,autoArgTypes:w,userArgTypes:l.userArgTypes,source:S,filePath:t,metaExtras:l.metaExtras};o!==void 0&&r.moduleGraph.invalidateModule(o),r.ws.send({type:"custom",event:"jogak:meta-update",data:{id:y,meta:L}});const E=[...m];return o!==void 0&&!E.includes(o)&&E.push(o),E}}}function Z(){return`(rawId) => {
35
- if (typeof Buffer !== 'undefined') return Buffer.from(rawId, 'utf8').toString('base64url')
36
- // 브라우저 폴백: btoa는 binary string 기준이라 UTF-8을 한번 인코딩해야 한다.
37
- const enc = new TextEncoder().encode(rawId)
38
- let bin = ''
39
- for (let i = 0; i < enc.length; i++) bin += String.fromCharCode(enc[i])
40
- return btoa(bin).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')
41
- }`}exports.jogak=Q;
File without changes
File without changes
File without changes