@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,101 @@
|
|
|
1
|
+
import { createElement as l, useContext as S, createContext as b, useState as y, useEffect as E, useMemo as f, useSyncExternalStore as R, useCallback as h } from "react";
|
|
2
|
+
import { createRoot as j } from "react-dom/client";
|
|
3
|
+
import { i as v } from "../../actions-BvvUNlgo.js";
|
|
4
|
+
import { jsx as w } from "react/jsx-runtime";
|
|
5
|
+
import { d as g } from "../../registry-CnBX6XxF.js";
|
|
6
|
+
const P = {
|
|
7
|
+
framework: "react",
|
|
8
|
+
render(t, e, n) {
|
|
9
|
+
const r = t.meta.component, o = v(e, t.meta.argTypes ?? {}), s = n._jogakRoot;
|
|
10
|
+
if (s !== void 0)
|
|
11
|
+
s.render(l(r, o));
|
|
12
|
+
else {
|
|
13
|
+
const a = j(n);
|
|
14
|
+
a.render(l(r, o)), n._jogakRoot = a;
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
unmount(t) {
|
|
18
|
+
const e = t._jogakRoot;
|
|
19
|
+
e == null || e.unmount(), delete t._jogakRoot;
|
|
20
|
+
}
|
|
21
|
+
}, d = b(g);
|
|
22
|
+
function $({ registry: t = g, children: e }) {
|
|
23
|
+
return /* @__PURE__ */ w(d.Provider, { value: t, children: e });
|
|
24
|
+
}
|
|
25
|
+
function p() {
|
|
26
|
+
return S(d);
|
|
27
|
+
}
|
|
28
|
+
function m(t, e) {
|
|
29
|
+
const n = t.getEntryState(e);
|
|
30
|
+
if (n === "unknown")
|
|
31
|
+
return { status: "unknown" };
|
|
32
|
+
if (n === "hydrated") {
|
|
33
|
+
const o = t.get(e);
|
|
34
|
+
return o === void 0 ? {
|
|
35
|
+
status: "error",
|
|
36
|
+
error: new Error(`[jogak] inconsistent registry state for id "${e}"`)
|
|
37
|
+
} : { status: "ready", entry: o };
|
|
38
|
+
}
|
|
39
|
+
const r = x(t, e);
|
|
40
|
+
return r === void 0 ? {
|
|
41
|
+
status: "error",
|
|
42
|
+
error: new Error(`[jogak] meta missing for id "${e}"`)
|
|
43
|
+
} : { status: "loading", meta: r };
|
|
44
|
+
}
|
|
45
|
+
function x(t, e) {
|
|
46
|
+
for (const n of t.getAllMeta())
|
|
47
|
+
if (n.id === e) return n;
|
|
48
|
+
}
|
|
49
|
+
function G(t) {
|
|
50
|
+
const e = p(), [n, r] = y(
|
|
51
|
+
() => m(e, t)
|
|
52
|
+
);
|
|
53
|
+
return E(() => {
|
|
54
|
+
let o = !1, s = null;
|
|
55
|
+
const a = () => {
|
|
56
|
+
if (o) return;
|
|
57
|
+
const c = m(e, t);
|
|
58
|
+
r(c), c.status === "loading" && s !== "loading" ? (s = "loading", e.requestEntry(t).catch((i) => {
|
|
59
|
+
if (o) return;
|
|
60
|
+
const k = i instanceof Error ? i : new Error(String(i));
|
|
61
|
+
r({ status: "error", error: k });
|
|
62
|
+
})) : s = c.status;
|
|
63
|
+
};
|
|
64
|
+
a();
|
|
65
|
+
const u = e.subscribe(a);
|
|
66
|
+
return () => {
|
|
67
|
+
o = !0, u();
|
|
68
|
+
};
|
|
69
|
+
}, [e, t]), n;
|
|
70
|
+
}
|
|
71
|
+
function M(t) {
|
|
72
|
+
return (e) => t.subscribe(e);
|
|
73
|
+
}
|
|
74
|
+
function C(t) {
|
|
75
|
+
let e = null, n = null, r = null;
|
|
76
|
+
return () => {
|
|
77
|
+
const o = t.getAllMeta(), s = t.getMetaTree();
|
|
78
|
+
return r !== null && o === e && s === n || (e = o, n = s, r = { metas: o, metaTree: s }), r;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function J() {
|
|
82
|
+
const t = p(), e = f(() => M(t), [t]), n = f(() => C(t), [t]), r = R(e, n, n), o = h(
|
|
83
|
+
(s) => {
|
|
84
|
+
const a = s.trim().toLowerCase();
|
|
85
|
+
return a.length === 0 ? r.metas : r.metas.filter((u) => u.title.toLowerCase().includes(a));
|
|
86
|
+
},
|
|
87
|
+
[r.metas]
|
|
88
|
+
);
|
|
89
|
+
return {
|
|
90
|
+
metas: r.metas,
|
|
91
|
+
metaTree: r.metaTree,
|
|
92
|
+
searchMeta: o
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export {
|
|
96
|
+
$ as JogakProvider,
|
|
97
|
+
P as reactAdapter,
|
|
98
|
+
G as useEntry,
|
|
99
|
+
p as useRegistry,
|
|
100
|
+
J as useRegistryMeta
|
|
101
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { RegistryEntry, RegistryEntryMeta } from '../../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Lazy entry hydration hook 상태값.
|
|
4
|
+
*
|
|
5
|
+
* - `loading` : 메타는 있으나 entry 모듈은 아직 hydrate 전. `meta`로 헤더/skeleton 표시 가능.
|
|
6
|
+
* - `ready` : `requestEntry` 가 resolve 되어 완전한 `RegistryEntry` 가용.
|
|
7
|
+
* - `error` : hydration 도중 에러 — `UnknownEntryError` 포함.
|
|
8
|
+
* - `unknown` : 등록되지 않은 id (`registerMeta` / `register` 둘 다 호출되지 않음).
|
|
9
|
+
*
|
|
10
|
+
* 본 타입은 어댑터 표면에 export 되어 ui 패키지가 `Preview` 분기에 사용한다.
|
|
11
|
+
*/
|
|
12
|
+
export type UseEntryState = {
|
|
13
|
+
readonly status: 'loading';
|
|
14
|
+
readonly meta: RegistryEntryMeta;
|
|
15
|
+
} | {
|
|
16
|
+
readonly status: 'ready';
|
|
17
|
+
readonly entry: RegistryEntry;
|
|
18
|
+
} | {
|
|
19
|
+
readonly status: 'error';
|
|
20
|
+
readonly error: Error;
|
|
21
|
+
} | {
|
|
22
|
+
readonly status: 'unknown';
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Lazy entry hydration 훅 (Phase 1 — 명시적 status 분기, Suspense 미사용).
|
|
26
|
+
*
|
|
27
|
+
* 동작:
|
|
28
|
+
* 1. 마운트 시점에 `getEntryState(id)`로 초기 상태 결정 (useState lazy init).
|
|
29
|
+
* 2. effect에서 `registry.subscribe`로 mutation을 감시 — registerMeta /
|
|
30
|
+
* hydrateEntry / invalidateEntry 등 모든 변경에 자동 재산출.
|
|
31
|
+
* 3. recompute 결과가 `loading`이고 직전 상태가 `loading`이 아니었으면
|
|
32
|
+
* `requestEntry(id)`를 트리거. 결과 entry는 hydrate가 notify를 통해
|
|
33
|
+
* 자동 반영하므로 then 안에서 setState 불필요(에러만 처리).
|
|
34
|
+
* 4. id 변경 시 effect 재실행, cleanup의 `cancelled` 플래그로 stale 차단.
|
|
35
|
+
*
|
|
36
|
+
* F4 통합: HMR 'jogak:meta-update' 이벤트가 invalidateEntry → requestEntry
|
|
37
|
+
* 흐름을 트리거하면 hydrated 상태였던 entry가 새 args/component로 다시
|
|
38
|
+
* hydrate되어 화면에 in-place 반영된다 (full-reload 회피).
|
|
39
|
+
*/
|
|
40
|
+
export declare function useEntry(id: string): UseEntryState;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CategoryMetaTree, RegistryEntryMeta } from '../../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* `useRegistryMeta` 반환 타입.
|
|
4
|
+
* `useRegistry`가 hydrated entry만 반영하는 것과 달리, 본 훅은 meta-only / pending 항목까지 포함.
|
|
5
|
+
*
|
|
6
|
+
* - `metas` : `registry.getAllMeta()` 결과 — registry 내부 캐시로 referential identity 보장
|
|
7
|
+
* - `metaTree` : `registry.getMetaTree()` 결과 — 사이드바 트리 구성용
|
|
8
|
+
* - `searchMeta`: title 부분 일치(대소문자 무시) — Phase 1은 단순 string 매칭
|
|
9
|
+
*/
|
|
10
|
+
export interface UseRegistryMetaReturn {
|
|
11
|
+
readonly metas: readonly RegistryEntryMeta[];
|
|
12
|
+
readonly metaTree: CategoryMetaTree;
|
|
13
|
+
readonly searchMeta: (query: string) => readonly RegistryEntryMeta[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 사이드바/검색용 메타 훅.
|
|
17
|
+
*
|
|
18
|
+
* `useSyncExternalStore` 기반으로 registry 변경(`register`/`unregister`/`registerMeta`/
|
|
19
|
+
* `hydrateEntry`/`clear`)에 자동 반응한다. registry 내부 snapshot 캐시(F2)와
|
|
20
|
+
* 외부 closure cache(makeGetSnapshot)의 이중 안전망으로 referential identity를 보장하여
|
|
21
|
+
* 무한 re-render를 방지한다.
|
|
22
|
+
*
|
|
23
|
+
* SSR: `getServerSnapshot`은 `getSnapshot`과 동일 함수. `defaultRegistry`는 module singleton이라
|
|
24
|
+
* 서버/클라이언트 동일 객체를 반환하며, registry가 비어있다면 빈 배열을 반환 후 클라이언트에서
|
|
25
|
+
* subscribe 통지로 자연 보정된다(`useSyncExternalStore`가 hydration 직후 client snapshot으로 전환).
|
|
26
|
+
*/
|
|
27
|
+
export declare function useRegistryMeta(): UseRegistryMetaReturn;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RegistryEntry } from '../../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* RegistryEntry를 Custom Element로 등록한다.
|
|
4
|
+
*
|
|
5
|
+
* Shadow DOM으로 스타일을 격리하므로 호스트 페이지 스타일이 프리뷰를 오염하지 않는다.
|
|
6
|
+
* Preact를 사용하여 React 런타임(~150KB) 없이 ~3KB로 렌더링한다.
|
|
7
|
+
*
|
|
8
|
+
* Attribute로 받은 값은 string이므로 ArgType.type을 보고 boolean/number로 캐스팅한다.
|
|
9
|
+
* 함수 prop은 attribute로 받을 수 없으므로 어댑터가 자동으로 Action spy를 주입한다.
|
|
10
|
+
*/
|
|
11
|
+
export declare function defineJogakElement(tagName: string, entry: RegistryEntry): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var k=e=>{throw TypeError(e)};var u=(e,t,n)=>t.has(e)||k("Cannot "+n);var c=(e,t,n)=>(u(e,t,"read from private field"),n?n.call(e):t.get(e)),l=(e,t,n)=>t.has(e)?k("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),a=(e,t,n,s)=>(u(e,t,"write to private field"),s?s.call(e,n):t.set(e,n),n),d=(e,t,n)=>(u(e,t,"access private method"),n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("preact"),C=require("../../actions-D9bnuJ1b.cjs");function g(e,t){var s,o,i,h;if(customElements.get(e)!==void 0)return;class n extends HTMLElement{constructor(){super();l(this,i);l(this,s,{});l(this,o);a(this,o,this.attachShadow({mode:"open"}))}static get observedAttributes(){return Object.keys(t.meta.argTypes??{})}connectedCallback(){d(this,i,h).call(this)}attributeChangedCallback(r,b,E){var f;const v=(f=t.meta.argTypes)==null?void 0:f[r];a(this,s,{...c(this,s),[r]:p(E,v)}),d(this,i,h).call(this)}disconnectedCallback(){m.render(null,c(this,o))}}s=new WeakMap,o=new WeakMap,i=new WeakSet,h=function(){const r=t.meta.component,b=C.injectActions(c(this,s),t.meta.argTypes??{});m.render(m.h(r,b),c(this,o))},customElements.define(e,n)}function p(e,t){if(e!==null)return(t==null?void 0:t.type)==="boolean"?e!=="false"&&e!=="0":(t==null?void 0:t.type)==="number"?Number(e):e}exports.defineJogakElement=g;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { defineJogakElement } from './define.js';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
var b = (t) => {
|
|
2
|
+
throw TypeError(t);
|
|
3
|
+
};
|
|
4
|
+
var u = (t, e, n) => e.has(t) || b("Cannot " + n);
|
|
5
|
+
var c = (t, e, n) => (u(t, e, "read from private field"), n ? n.call(t) : e.get(t)), r = (t, e, n) => e.has(t) ? b("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, n), m = (t, e, n, s) => (u(t, e, "write to private field"), s ? s.call(t, n) : e.set(t, n), n), a = (t, e, n) => (u(t, e, "access private method"), n);
|
|
6
|
+
import { render as k, h as E } from "preact";
|
|
7
|
+
import { i as v } from "../../actions-BvvUNlgo.js";
|
|
8
|
+
function H(t, e) {
|
|
9
|
+
var s, o, i, d;
|
|
10
|
+
if (customElements.get(t) !== void 0) return;
|
|
11
|
+
class n extends HTMLElement {
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
r(this, i);
|
|
15
|
+
r(this, s, {});
|
|
16
|
+
r(this, o);
|
|
17
|
+
m(this, o, this.attachShadow({ mode: "open" }));
|
|
18
|
+
}
|
|
19
|
+
static get observedAttributes() {
|
|
20
|
+
return Object.keys(e.meta.argTypes ?? {});
|
|
21
|
+
}
|
|
22
|
+
connectedCallback() {
|
|
23
|
+
a(this, i, d).call(this);
|
|
24
|
+
}
|
|
25
|
+
attributeChangedCallback(l, h, p) {
|
|
26
|
+
var f;
|
|
27
|
+
const C = (f = e.meta.argTypes) == null ? void 0 : f[l];
|
|
28
|
+
m(this, s, {
|
|
29
|
+
...c(this, s),
|
|
30
|
+
[l]: A(p, C)
|
|
31
|
+
}), a(this, i, d).call(this);
|
|
32
|
+
}
|
|
33
|
+
disconnectedCallback() {
|
|
34
|
+
k(null, c(this, o));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
s = new WeakMap(), o = new WeakMap(), i = new WeakSet(), d = function() {
|
|
38
|
+
const l = e.meta.component, h = v(c(this, s), e.meta.argTypes ?? {});
|
|
39
|
+
k(E(l, h), c(this, o));
|
|
40
|
+
}, customElements.define(t, n);
|
|
41
|
+
}
|
|
42
|
+
function A(t, e) {
|
|
43
|
+
if (t !== null)
|
|
44
|
+
return (e == null ? void 0 : e.type) === "boolean" ? t !== "false" && t !== "0" : (e == null ? void 0 : e.type) === "number" ? Number(t) : t;
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
H as defineJogakElement
|
|
48
|
+
};
|
package/dist/server.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("node:fs"),l=require("node:path"),u=require("./detect-global-css-CDcuUAYE.cjs"),d=["ts","js","mjs","cjs"],b=["ts","js","mjs","cjs"],j=["ts","mts","js","mjs","cjs"];function h(s){const e=C(s),n={...(e==null?void 0:e.dependencies)??{},...(e==null?void 0:e.devDependencies)??{}},t=a(s,d,"next.config"),f="next"in n,p="react-scripts"in n,i=a(s,b,"webpack.config"),g="webpack"in n,r=a(s,j,"vite.config");if(t||f){const c=[];return r&&c.push("vite.config.* (마이그레이션 중?)"),{name:"next",signal:t?"next.config.*":"package.json: next dep",...c.length>0?{ambiguous:c}:{}}}return p?{name:"webpack",signal:"package.json: react-scripts dep (CRA)"}:i||g?{name:"webpack",signal:i?"webpack.config.*":"package.json: webpack dep"}:r?{name:"vite",signal:"vite.config.*"}:{name:"standalone",signal:"(no builder signals)"}}function a(s,e,n){for(const t of e)if(o.existsSync(l.resolve(s,`${n}.${t}`)))return!0;return!1}function C(s){const e=l.resolve(s,"package.json");if(o.existsSync(e))try{const n=o.readFileSync(e,"utf-8");return JSON.parse(n)}catch{return}}exports.detectUserGlobalCss=u.detectUserGlobalCss;exports.resolveGlobalCssPaths=u.resolveGlobalCssPaths;exports.detectBuilder=h;
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 알파.9: server-only 유틸리티 (Node.js only).
|
|
3
|
+
*
|
|
4
|
+
* 본 subpath의 함수들은 `node:fs`/`node:path`를 사용하므로 브라우저 client 번들에
|
|
5
|
+
* 포함되어서는 안 된다. CLI / 어댑터 / Vite plugin 등 Node 환경에서만 import.
|
|
6
|
+
*
|
|
7
|
+
* 사용처:
|
|
8
|
+
* - `@jogak/cli`: detectBuilder
|
|
9
|
+
* - `@jogak/vite-adapter` / `@jogak/next-adapter` / `@jogak/webpack-adapter`: resolveGlobalCssPaths
|
|
10
|
+
*/
|
|
11
|
+
export { detectBuilder, type DetectBuilderResult, } from './builder-detect.js';
|
|
12
|
+
export { detectUserGlobalCss, resolveGlobalCssPaths, } from './vite-plugin/detect-global-css.js';
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { existsSync as r, readFileSync as u } from "node:fs";
|
|
2
|
+
import { resolve as f } from "node:path";
|
|
3
|
+
import { d as N, r as S } from "./detect-global-css-CIVMmgzy.js";
|
|
4
|
+
const m = ["ts", "js", "mjs", "cjs"], d = ["ts", "js", "mjs", "cjs"], j = ["ts", "mts", "js", "mjs", "cjs"];
|
|
5
|
+
function k(n) {
|
|
6
|
+
const e = b(n), s = {
|
|
7
|
+
...(e == null ? void 0 : e.dependencies) ?? {},
|
|
8
|
+
...(e == null ? void 0 : e.devDependencies) ?? {}
|
|
9
|
+
}, t = c(n, m, "next.config"), p = "next" in s, g = "react-scripts" in s, o = c(n, d, "webpack.config"), l = "webpack" in s, i = c(n, j, "vite.config");
|
|
10
|
+
if (t || p) {
|
|
11
|
+
const a = [];
|
|
12
|
+
return i && a.push("vite.config.* (마이그레이션 중?)"), {
|
|
13
|
+
name: "next",
|
|
14
|
+
signal: t ? "next.config.*" : "package.json: next dep",
|
|
15
|
+
...a.length > 0 ? { ambiguous: a } : {}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return g ? {
|
|
19
|
+
name: "webpack",
|
|
20
|
+
signal: "package.json: react-scripts dep (CRA)"
|
|
21
|
+
} : o || l ? {
|
|
22
|
+
name: "webpack",
|
|
23
|
+
signal: o ? "webpack.config.*" : "package.json: webpack dep"
|
|
24
|
+
} : i ? { name: "vite", signal: "vite.config.*" } : { name: "standalone", signal: "(no builder signals)" };
|
|
25
|
+
}
|
|
26
|
+
function c(n, e, s) {
|
|
27
|
+
for (const t of e)
|
|
28
|
+
if (r(f(n, `${s}.${t}`))) return !0;
|
|
29
|
+
return !1;
|
|
30
|
+
}
|
|
31
|
+
function b(n) {
|
|
32
|
+
const e = f(n, "package.json");
|
|
33
|
+
if (r(e))
|
|
34
|
+
try {
|
|
35
|
+
const s = u(e, "utf-8");
|
|
36
|
+
return JSON.parse(s);
|
|
37
|
+
} catch {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
k as detectBuilder,
|
|
43
|
+
N as detectUserGlobalCss,
|
|
44
|
+
S as resolveGlobalCssPaths
|
|
45
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";const n=`
|
|
2
|
+
import { reactAdapter } from '@jogak/core/renderers/react'
|
|
3
|
+
import { defaultRegistry } from '@jogak/core'
|
|
4
|
+
__EXTRA_IMPORTS__
|
|
5
|
+
|
|
6
|
+
const rootEl = document.getElementById('jogak-preview-root')
|
|
7
|
+
if (rootEl === null) throw new Error('[jogak] #jogak-preview-root not found')
|
|
8
|
+
|
|
9
|
+
let currentContainer = null
|
|
10
|
+
|
|
11
|
+
async function renderEntry(entryId, args) {
|
|
12
|
+
const entry = await defaultRegistry.requestEntry(entryId)
|
|
13
|
+
if (currentContainer === null) {
|
|
14
|
+
currentContainer = document.createElement('div')
|
|
15
|
+
rootEl.replaceChildren(currentContainer)
|
|
16
|
+
}
|
|
17
|
+
reactAdapter.render(entry, args, currentContainer)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function unmount() {
|
|
21
|
+
if (currentContainer !== null) {
|
|
22
|
+
reactAdapter.unmount(currentContainer)
|
|
23
|
+
currentContainer = null
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
window.addEventListener('message', (event) => {
|
|
28
|
+
const data = event.data
|
|
29
|
+
if (data == null || typeof data !== 'object') return
|
|
30
|
+
if (data.type === 'jogak:setProps') {
|
|
31
|
+
void renderEntry(data.entryId, data.args ?? {}).then(() => {
|
|
32
|
+
window.parent.postMessage({ type: 'jogak:rendered', entryId: data.entryId }, '*')
|
|
33
|
+
}).catch((err) => {
|
|
34
|
+
window.parent.postMessage({ type: 'jogak:error', message: String(err?.message ?? err) }, '*')
|
|
35
|
+
})
|
|
36
|
+
} else if (data.type === 'jogak:unmount') {
|
|
37
|
+
unmount()
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
window.parent.postMessage({ type: 'jogak:ready' }, '*')
|
|
42
|
+
`;function o(e={}){const r=(e.extraImports??[]).map(t=>`import ${JSON.stringify(t)}`).join(`
|
|
43
|
+
`);return n.replace("__EXTRA_IMPORTS__",r)}exports.renderPreviewEntrySource=o;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const n = `
|
|
2
|
+
import { reactAdapter } from '@jogak/core/renderers/react'
|
|
3
|
+
import { defaultRegistry } from '@jogak/core'
|
|
4
|
+
__EXTRA_IMPORTS__
|
|
5
|
+
|
|
6
|
+
const rootEl = document.getElementById('jogak-preview-root')
|
|
7
|
+
if (rootEl === null) throw new Error('[jogak] #jogak-preview-root not found')
|
|
8
|
+
|
|
9
|
+
let currentContainer = null
|
|
10
|
+
|
|
11
|
+
async function renderEntry(entryId, args) {
|
|
12
|
+
const entry = await defaultRegistry.requestEntry(entryId)
|
|
13
|
+
if (currentContainer === null) {
|
|
14
|
+
currentContainer = document.createElement('div')
|
|
15
|
+
rootEl.replaceChildren(currentContainer)
|
|
16
|
+
}
|
|
17
|
+
reactAdapter.render(entry, args, currentContainer)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function unmount() {
|
|
21
|
+
if (currentContainer !== null) {
|
|
22
|
+
reactAdapter.unmount(currentContainer)
|
|
23
|
+
currentContainer = null
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
window.addEventListener('message', (event) => {
|
|
28
|
+
const data = event.data
|
|
29
|
+
if (data == null || typeof data !== 'object') return
|
|
30
|
+
if (data.type === 'jogak:setProps') {
|
|
31
|
+
void renderEntry(data.entryId, data.args ?? {}).then(() => {
|
|
32
|
+
window.parent.postMessage({ type: 'jogak:rendered', entryId: data.entryId }, '*')
|
|
33
|
+
}).catch((err) => {
|
|
34
|
+
window.parent.postMessage({ type: 'jogak:error', message: String(err?.message ?? err) }, '*')
|
|
35
|
+
})
|
|
36
|
+
} else if (data.type === 'jogak:unmount') {
|
|
37
|
+
unmount()
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
window.parent.postMessage({ type: 'jogak:ready' }, '*')
|
|
42
|
+
`;
|
|
43
|
+
function a(e = {}) {
|
|
44
|
+
const r = (e.extraImports ?? []).map((t) => `import ${JSON.stringify(t)}`).join(`
|
|
45
|
+
`);
|
|
46
|
+
return n.replace("__EXTRA_IMPORTS__", r);
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
a as r
|
|
50
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -139,4 +139,165 @@ export interface JogakPluginOptions {
|
|
|
139
139
|
* 또는 `--force`를 관리해야 한다.
|
|
140
140
|
*/
|
|
141
141
|
readonly disableCacheValidation?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* 사용자 명시 path alias. 미지정 시 사용자 tsconfig의 `compilerOptions.paths`를
|
|
144
|
+
* 자동으로 읽어 vite `resolve.alias`로 등록한다 (shadcn/ui 같이 `@/`를 쓰는
|
|
145
|
+
* 일반적 환경 대응).
|
|
146
|
+
*
|
|
147
|
+
* 자동 추출은 단순 prefix 매핑(`"@/*": ["./src/*"]`)만 처리하므로,
|
|
148
|
+
* `extends` 체인이나 복합 glob 패턴을 쓰는 경우 본 옵션으로 명시 전달한다.
|
|
149
|
+
* 본 옵션이 자동 추출 결과를 덮어쓴다.
|
|
150
|
+
*
|
|
151
|
+
* 값은 alias prefix → 절대 경로(또는 cwd 기준 상대 경로) 맵이다.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* jogak({ resolveAlias: { '@': './src', '@components': './src/components' } })
|
|
155
|
+
*/
|
|
156
|
+
readonly resolveAlias?: Readonly<Record<string, string>>;
|
|
157
|
+
/**
|
|
158
|
+
* 사용자 globalCss를 jogak SPA에 import한다 (알파.6 opt-in).
|
|
159
|
+
*
|
|
160
|
+
* 동기:
|
|
161
|
+
* - `runHost`는 vite root를 `@jogak/ui` 패키지로 두고 사용자 `vite.config.ts`/
|
|
162
|
+
* `main.tsx`를 무시하므로(`configFile: false`), 사용자 `index.css`(Tailwind/
|
|
163
|
+
* shadcn 디자인 토큰)가 jogak SPA에 자동 적용되지 않는다.
|
|
164
|
+
* - 본 옵션이 `true`이거나 명시 경로면 plugin이 사용자 css를 가상 모듈로
|
|
165
|
+
* 주입해 jogak SPA가 import한다.
|
|
166
|
+
*
|
|
167
|
+
* 의미:
|
|
168
|
+
* - `false` (default): 미주입. jogak chrome 기본 스타일만 사용 (알파.4~5 동작 그대로).
|
|
169
|
+
* - `true`: `<userRoot>/src/{index,main,styles,global,app,globals}.css` 후보를
|
|
170
|
+
* 순차 검사해 **첫 발견 1개**만 import. 미발견 시 빈 모듈 (no-op).
|
|
171
|
+
* - `string`: 사용자 root 기준 상대 경로 또는 절대 경로 1개. 자동 감지 비활성화.
|
|
172
|
+
* - `string[]`: 명시 경로 N개를 배열 순서대로 모두 import. 자동 감지 비활성화.
|
|
173
|
+
*
|
|
174
|
+
* 자동 감지 후보 (우선순위 순):
|
|
175
|
+
* 1. `src/index.css` (shadcn/ui Vite)
|
|
176
|
+
* 2. `src/main.css`
|
|
177
|
+
* 3. `src/styles.css`
|
|
178
|
+
* 4. `src/styles/globals.css` (Next.js shadcn)
|
|
179
|
+
* 5. `src/styles/index.css`
|
|
180
|
+
* 6. `src/app/globals.css` (Next.js App Router shadcn)
|
|
181
|
+
* 7. `src/global.css`
|
|
182
|
+
* 8. `src/app.css`
|
|
183
|
+
*
|
|
184
|
+
* 격리:
|
|
185
|
+
* - jogak UI는 알파.4~5에서 Tailwind v4 + `prefix=jogak`로 마이그레이션되어
|
|
186
|
+
* 사용자 utility class와 충돌 zero (예: 사용자 `.bg-primary` ≠ jogak `.jogak\:bg-...`).
|
|
187
|
+
* - jogak CSS variable은 `--jogak-*` prefix → 사용자 `:root { --primary }` 같은
|
|
188
|
+
* 토큰과 namespace 충돌 zero.
|
|
189
|
+
* - 단, 사용자 css의 `*` selector / `body` selector / reset 류는 jogak chrome에
|
|
190
|
+
* 영향 가능. README의 "scope 가이드" 패턴 참조.
|
|
191
|
+
*
|
|
192
|
+
* 한계 (알파.7+ 로드맵):
|
|
193
|
+
* - 사용자 css를 preview 영역으로만 한정하는 Shadow DOM/iframe 격리는 미지원.
|
|
194
|
+
* - `previewIsolation` 옵션은 알파.7+에서 별도 도입.
|
|
195
|
+
* - `globalCss: true` 자동 감지는 dev 시작 시점에 한 번만 수행 — 후보 css 파일이
|
|
196
|
+
* dev 시작 후에 새로 추가되면 dev 서버 재시작이 필요하다. 명시 경로
|
|
197
|
+
* (`globalCss: './src/index.css'`)는 파일이 나중에 생성되어도 정상 hot reload된다.
|
|
198
|
+
*
|
|
199
|
+
* @default false
|
|
200
|
+
*
|
|
201
|
+
* @example 자동 감지
|
|
202
|
+
* jogak({ globalCss: true })
|
|
203
|
+
*
|
|
204
|
+
* @example 명시 경로
|
|
205
|
+
* jogak({ globalCss: './src/index.css' })
|
|
206
|
+
*
|
|
207
|
+
* @example 다중 import (디자인 토큰 + reset 분리)
|
|
208
|
+
* jogak({ globalCss: ['./src/tokens.css', './src/index.css'] })
|
|
209
|
+
*/
|
|
210
|
+
readonly globalCss?: boolean | string | readonly string[];
|
|
211
|
+
/**
|
|
212
|
+
* Preview 영역의 격리 모드 (알파.7 도입, 알파.8에서 default `'iframe'`로 변경).
|
|
213
|
+
*
|
|
214
|
+
* 알파.8의 default `'iframe'`은 사용자 vite 인스턴스를 spawn하여 그 vite의 정상 client에
|
|
215
|
+
* iframe document를 마운트한다. 사용자 plugins(@tailwindcss/vite 등)이 그대로 작동하므로
|
|
216
|
+
* **사용자 컴포넌트가 사용자 디자인 시스템 그대로 보인다**. 동시에 outer document의
|
|
217
|
+
* jogak chrome은 iframe 외부라 사용자 css 영향 zero (양방향 격리).
|
|
218
|
+
*
|
|
219
|
+
* 모드:
|
|
220
|
+
* - `'iframe'` (default, 알파.8): Preview를 사용자 vite의 정상 client(iframe)에 마운트.
|
|
221
|
+
* 사용자 utility 정상 컴파일 + 사용자 globalCss 적용 + Radix Portal 정상 (iframe document.body).
|
|
222
|
+
* chrome 침범 zero. cross-origin postMessage로 entry/args 전달.
|
|
223
|
+
* `userVite` 옵션으로 spawn 동작 제어.
|
|
224
|
+
* - `'shadow'` (deprecated, 알파.9 부활 검토): Preview를 ShadowRoot에 마운트. 알파.8 v1에서는
|
|
225
|
+
* 사용자 vite 산출물을 shadow에 inject하는 통로가 미구현 — 사용자 utility 미적용 한계.
|
|
226
|
+
* chrome 침범은 zero지만 사용자 컴포넌트 시각이 raw에 가까움.
|
|
227
|
+
* - `'none'` (deprecated, 알파.10 제거 검토): 사용자 globalCss를 outer document에 inject.
|
|
228
|
+
* jogak chrome이 사용자 reset/preflight 영향을 받음 (back-compat).
|
|
229
|
+
*
|
|
230
|
+
* @default 'iframe'
|
|
231
|
+
*
|
|
232
|
+
* @example 사용자 vite 자동 spawn + iframe 모드 (default — 미지정 시 적용)
|
|
233
|
+
* jogak({ globalCss: true }) // previewIsolation 'iframe', 사용자 vite 자동 탐지
|
|
234
|
+
*
|
|
235
|
+
* @example 사용자 vite 스폰 비활성 + 사용자 reset이 chrome에도 영향 (back-compat)
|
|
236
|
+
* jogak({ globalCss: true, previewIsolation: 'none' })
|
|
237
|
+
*/
|
|
238
|
+
readonly previewIsolation?: 'none' | 'shadow' | 'iframe';
|
|
239
|
+
/**
|
|
240
|
+
* 알파.8 internal: 본 jogak() plugin이 사용자 vite scope의 preview-frame entry용으로
|
|
241
|
+
* 동작하는지. CLI의 spawnUserVite가 사용자 vite에 jogak()을 mergeConfig로 inject할 때
|
|
242
|
+
* `previewFrame: true`를 함께 설정한다.
|
|
243
|
+
*
|
|
244
|
+
* `previewFrame: true`일 때:
|
|
245
|
+
* - jogak SPA chrome 가상 모듈(`_jogakCodeTheme`/`_jogakPreviewIsolation`/`_jogakUserViteUrl`/
|
|
246
|
+
* `_jogakMetas`) emit 비활성화
|
|
247
|
+
* - entry 가상 모듈(`virtual:jogak/entry/<slug>`)은 그대로 emit (preview-entry가 사용)
|
|
248
|
+
* - 사용자 측 vite plugins(@tailwindcss/vite 등)와 공존
|
|
249
|
+
*
|
|
250
|
+
* 사용자가 직접 설정하는 옵션이 아니다.
|
|
251
|
+
*/
|
|
252
|
+
readonly previewFrame?: boolean;
|
|
253
|
+
/**
|
|
254
|
+
* @deprecated 알파.10 제거 예정. `userPreviewUrl` 사용.
|
|
255
|
+
*
|
|
256
|
+
* 알파.8 internal: jogak SPA가 iframe src로 사용할 사용자 vite의 base URL.
|
|
257
|
+
*/
|
|
258
|
+
readonly userViteUrl?: string;
|
|
259
|
+
/**
|
|
260
|
+
* 알파.9 internal: jogak SPA가 iframe src로 사용할 어댑터 dev URL
|
|
261
|
+
* (예: `http://localhost:5174`). CLI의 어댑터 dispatch 결과가 host 통해 plugin에 전달.
|
|
262
|
+
*
|
|
263
|
+
* 빈 문자열 시 fallback (jogak SPA Vite scope의 preview-frame).
|
|
264
|
+
*
|
|
265
|
+
* 사용자가 직접 설정하는 옵션이 아니다.
|
|
266
|
+
*/
|
|
267
|
+
readonly userPreviewUrl?: string;
|
|
268
|
+
/**
|
|
269
|
+
* 알파.9 internal: iframe src의 path (예: `/__jogak_preview__/index.html`).
|
|
270
|
+
* `BuilderAdapter.previewEntryMeta.devEntryPath` 값. 어댑터별 routing.
|
|
271
|
+
*
|
|
272
|
+
* 사용자가 직접 설정하는 옵션이 아니다.
|
|
273
|
+
*/
|
|
274
|
+
readonly previewEntryPath?: string;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* 알파.8: 사용자 vite 인스턴스 spawn 옵션.
|
|
278
|
+
*
|
|
279
|
+
* jogak CLI는 사용자 cwd의 `vite.config.{ts,mts,js,mjs,cjs}`를 자동 탐지해 별도
|
|
280
|
+
* vite dev server를 spawn한다. iframe 모드의 src로 사용되어 사용자 컴포넌트가
|
|
281
|
+
* 사용자 vite plugins(@tailwindcss/vite, custom alias 등)의 정상 client에서
|
|
282
|
+
* 평가된다.
|
|
283
|
+
*/
|
|
284
|
+
export interface UserViteOptions {
|
|
285
|
+
/**
|
|
286
|
+
* 사용자 vite.config.ts 절대/상대 경로. 미지정 시 cwd에서 자동 탐지
|
|
287
|
+
* (`vite.config.ts` > `vite.config.mts` > `vite.config.js` > `vite.config.mjs` > `vite.config.cjs`).
|
|
288
|
+
*/
|
|
289
|
+
readonly configFile?: string;
|
|
290
|
+
/**
|
|
291
|
+
* 사용자 vite dev server 포트. 미지정 시 0(free port).
|
|
292
|
+
*/
|
|
293
|
+
readonly port?: number;
|
|
294
|
+
/**
|
|
295
|
+
* 사용자 vite dev server host. 미지정 시 'localhost'.
|
|
296
|
+
*/
|
|
297
|
+
readonly host?: string | boolean;
|
|
298
|
+
/**
|
|
299
|
+
* 사용자 vite spawn을 비활성화. 알파.7.1 동등 fallback 동작
|
|
300
|
+
* (사용자 utility 미컴파일).
|
|
301
|
+
*/
|
|
302
|
+
readonly disabled?: boolean;
|
|
142
303
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../plugin-Wtlz0hae.cjs");exports.jogak=e.jogak;
|