@jogak/core 0.1.0-alpha.8 → 0.1.0-alpha.9
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 +23 -0
- package/dist/adapter.d.ts +80 -0
- package/dist/builder-detect.d.ts +9 -0
- package/dist/config.d.ts +21 -8
- package/dist/detect-global-css-CDcuUAYE.cjs +1 -0
- package/dist/detect-global-css-CIVMmgzy.js +33 -0
- package/dist/index.cjs +43 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +210 -162
- package/dist/preview-entry/protocol.d.ts +29 -0
- package/dist/preview-entry/source.d.ts +30 -0
- package/dist/server.cjs +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.mjs +45 -0
- package/dist/types.d.ts +17 -5
- package/dist/vite/index.cjs +118 -0
- package/dist/vite/index.mjs +183 -207
- package/package.json +8 -3
- package/dist/index.js +0 -1
- package/dist/vite/index.js +0 -116
- /package/dist/build/{index.js → index.cjs} +0 -0
- /package/dist/meta/{extractor-child.js → extractor-child.cjs} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,29 @@ All notable changes to Jogak packages are documented here. The repository follow
|
|
|
5
5
|
|
|
6
6
|
Version numbers apply to all packages in the workspace (synchronized release).
|
|
7
7
|
|
|
8
|
+
## [0.1.0-alpha.9] — 2026-05-09
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`@jogak/vite-adapter`**, **`@jogak/next-adapter`**, **`@jogak/webpack-adapter`**, **`@jogak/standalone-adapter`**: 새 builder-agnostic adapter 패키지군. CLI가 사용자 cwd의 빌더(`next.config`, `vite.config`, `webpack.config`)를 감지하여 해당 adapter를 dynamic import한다. 사용자 컴포넌트는 사용자의 정상 빌더 client에서 평가되므로 utility class compiler(Tailwind v4 등)이 자연스럽게 동작한다.
|
|
13
|
+
- **`@jogak/core`**: `BuilderAdapter` ABI(`adapter.ts`), 빌더 자동 감지(`detectBuilder`, `@jogak/core/server`), preview entry 공통 source(`renderPreviewEntrySource`), postMessage 프로토콜(`@jogak/core/preview-entry/protocol`).
|
|
14
|
+
- **`JogakPluginOptions.userPreviewUrl` / `previewEntryPath`**: adapter dispatch 결과를 host UI iframe src로 주입하는 통로. (`userViteUrl`은 alpha.8 호환을 위해 alias로 유지)
|
|
15
|
+
- **`@jogak/next-adapter`**: Next 14+ App Router에 `<userRoot>/app/jogak-preview/page.tsx` scaffold(`.gitignore` 자동, shutdown cleanup). `next dev` child process spawn + HTTP poll ready 감지. CLI가 사전 생성한 `.jogak/registry.ts`의 entries를 import하여 모듈 평가 시점에 등록.
|
|
16
|
+
- **`@jogak/webpack-adapter`**: `<userRoot>/.jogak/webpack-preview/preview-entry.tsx` scaffold + `webpack-dev-server` programmatic API + `webpack-merge`로 사용자 webpack.config 통합.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **`@jogak/core`**: `fs`/`path`를 사용하는 server-only utility(`detectBuilder`, `resolveGlobalCssPaths`, `detectUserGlobalCss`)를 `@jogak/core/server` subpath로 분리. client bundle에 Node 모듈이 leak되는 문제를 차단.
|
|
21
|
+
- **`@jogak/core`**, **`@jogak/ui`**, all adapters: CJS 산출물 확장자를 `.js` → `.cjs`로 변경. `"type": "module"` 환경에서 `.js`가 ESM으로 해석되어 발생하던 `exports is not defined in ES module scope` 오류를 해소.
|
|
22
|
+
- **`previewIsolation`** default: `'shadow'` → `'iframe'`. shadow DOM 모드는 일부 portal 라이브러리(Radix 등)와 호환성 이슈가 있어 iframe 격리를 표준으로.
|
|
23
|
+
- **`@jogak/ui`** preview-frame: 기존 `__jogak_setProps__` 직접 호출 프로토콜 → postMessage(`jogak:setProps` / `jogak:rendered` / `jogak:error`)로 통일. 모든 어댑터의 iframe entry가 동일 프로토콜을 따른다.
|
|
24
|
+
- **`@jogak/cli`**: `jogak dev`가 registry 생성 완료를 대기한 뒤 어댑터를 spawn (이전: fire-and-forget). non-vite 어댑터의 scaffold가 비어있는 registry를 import하던 race condition 해소.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **`@jogak/cli`**: 어댑터 dynamic import 시 `import.meta.resolve`/`createRequire`가 cli/dist 기준으로 해석돼 사용자 cwd의 어댑터 패키지를 찾지 못하던 문제. `<cwd>/node_modules/@jogak/${name}-adapter/package.json`을 직접 읽어 `exports['.'].import` 경로로 해석하도록 변경.
|
|
29
|
+
- **`@jogak/next-adapter`**: 이전 시도의 `__jogak_preview__` 경로는 Next App Router의 private folder convention(`_`로 시작하는 폴더는 라우팅 제외)과 충돌해 404. `jogak-preview`로 변경.
|
|
30
|
+
|
|
8
31
|
## [0.1.0-alpha.3] — 2026-05-07
|
|
9
32
|
|
|
10
33
|
### Added
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 알파.9: 빌더-agnostic 어댑터 ABI.
|
|
3
|
+
*
|
|
4
|
+
* jogak이 사용자 빌더(Vite / Next.js / Webpack / Vanilla)에 무관하게 사용자 컴포넌트를
|
|
5
|
+
* 사용자 빌더의 정상 client에서 평가하도록 하는 공통 인터페이스. core는 어떤 빌더도
|
|
6
|
+
* 직접 import하지 않고 어댑터 dispatch만 책임진다.
|
|
7
|
+
*
|
|
8
|
+
* 어댑터 구현체는 별도 패키지로 분리:
|
|
9
|
+
* - `@jogak/vite-adapter`
|
|
10
|
+
* - `@jogak/next-adapter`
|
|
11
|
+
* - `@jogak/webpack-adapter`
|
|
12
|
+
* - `@jogak/standalone-adapter`
|
|
13
|
+
*
|
|
14
|
+
* `@jogak/cli`가 사용자 cwd 시그널로 builder를 자동 감지하고 해당 adapter를 dynamic import.
|
|
15
|
+
*/
|
|
16
|
+
export type BuilderName = 'vite' | 'next' | 'webpack' | 'standalone' | 'custom';
|
|
17
|
+
export type GlobalCssSpec = boolean | string | readonly string[];
|
|
18
|
+
/**
|
|
19
|
+
* 모든 빌더 어댑터가 구현해야 하는 공통 ABI.
|
|
20
|
+
*/
|
|
21
|
+
export interface BuilderAdapter {
|
|
22
|
+
readonly name: BuilderName;
|
|
23
|
+
/** dev server를 spawn. 사용자 빌더의 정상 client + jogak preview entry 주입. */
|
|
24
|
+
spawnDev(opts: SpawnDevOptions): Promise<DevHandle>;
|
|
25
|
+
/** 정적 산출물 빌드. iframe entry를 사용자 빌더로 빌드 + jogak SPA outDir에 통합. */
|
|
26
|
+
build(opts: BuildOptions): Promise<BuildResult>;
|
|
27
|
+
/** preview entry 통신/주입에 필요한 metadata. */
|
|
28
|
+
readonly previewEntryMeta: PreviewEntryMeta;
|
|
29
|
+
}
|
|
30
|
+
export interface SpawnDevOptions {
|
|
31
|
+
readonly cwd: string;
|
|
32
|
+
readonly globalCss?: GlobalCssSpec;
|
|
33
|
+
readonly port?: number;
|
|
34
|
+
readonly host?: string | boolean;
|
|
35
|
+
/** 로그 출력 — 미지정 시 console 사용. */
|
|
36
|
+
readonly logger?: HostLogger;
|
|
37
|
+
/** adapter별 추가 옵션 (vite: configFile, next: appDir 등). */
|
|
38
|
+
readonly extra?: Readonly<Record<string, unknown>>;
|
|
39
|
+
}
|
|
40
|
+
export interface DevHandle {
|
|
41
|
+
/** dev server URL (jogak SPA가 iframe src base로 사용). */
|
|
42
|
+
readonly url: string;
|
|
43
|
+
readonly port: number;
|
|
44
|
+
/** SIGINT/SIGTERM 시 jogak CLI가 호출. 멱등 보장. */
|
|
45
|
+
close(): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
export interface BuildOptions {
|
|
48
|
+
readonly cwd: string;
|
|
49
|
+
readonly globalCss?: GlobalCssSpec;
|
|
50
|
+
/** 사용자 빌더 산출물의 출력 디렉토리. jogak이 outDir/preview/로 복사. */
|
|
51
|
+
readonly previewOutDir: string;
|
|
52
|
+
readonly logger?: HostLogger;
|
|
53
|
+
readonly extra?: Readonly<Record<string, unknown>>;
|
|
54
|
+
}
|
|
55
|
+
export interface BuildResult {
|
|
56
|
+
/** 사용자 빌더가 생성한 산출물 절대 경로 디렉토리 (= previewOutDir). */
|
|
57
|
+
readonly outDir: string;
|
|
58
|
+
/** 사용자 빌더가 emit한 entry HTML의 path-relative URL (예: 'index.html'). */
|
|
59
|
+
readonly entryHtml: string;
|
|
60
|
+
readonly assetCount: number;
|
|
61
|
+
readonly totalBytes: number;
|
|
62
|
+
readonly elapsedMs: number;
|
|
63
|
+
}
|
|
64
|
+
export interface PreviewEntryMeta {
|
|
65
|
+
/** dev URL의 entry path (예: '/__jogak_preview__/index.html'). adapter별 routing. */
|
|
66
|
+
readonly devEntryPath: string;
|
|
67
|
+
/** build 산출물의 entry HTML basename (예: 'index.html'). */
|
|
68
|
+
readonly buildEntryName: string;
|
|
69
|
+
/** preview entry 가상 모듈 ID (모든 adapter 공통: 'virtual:jogak/preview-entry'). */
|
|
70
|
+
readonly previewEntryVirtualId: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 어댑터에 전달하는 logger 인터페이스. core가 ui/host에 의존하지 않도록 별도 정의.
|
|
74
|
+
* 미지정 시 console fallback.
|
|
75
|
+
*/
|
|
76
|
+
export interface HostLogger {
|
|
77
|
+
info(message: string): void;
|
|
78
|
+
warn(message: string): void;
|
|
79
|
+
error(message: string): void;
|
|
80
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BuilderName } from './adapter.js';
|
|
2
|
+
export interface DetectBuilderResult {
|
|
3
|
+
readonly name: Exclude<BuilderName, 'custom'>;
|
|
4
|
+
/** 감지에 사용된 시그널 — 디버깅용. */
|
|
5
|
+
readonly signal: string;
|
|
6
|
+
/** 모호 환경 검출 시 추가 매칭 시그널 (warning 출력용). */
|
|
7
|
+
readonly ambiguous?: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function detectBuilder(cwd: string): DetectBuilderResult;
|
package/dist/config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BuilderName } from './adapter.js';
|
|
1
2
|
import { JogakPluginOptions, UserViteOptions } from './types.js';
|
|
2
3
|
/**
|
|
3
4
|
* `jogak.config.{ts,mts,mjs,js,json}`의 default export 타입.
|
|
@@ -28,18 +29,30 @@ export interface JogakConfig extends JogakPluginOptions {
|
|
|
28
29
|
/** 빌드 소스맵. 기본 false. CLI `--sourcemap`로 override. */
|
|
29
30
|
readonly sourcemap?: boolean;
|
|
30
31
|
/**
|
|
31
|
-
*
|
|
32
|
-
* 자동 탐지해 별도 vite dev server를 띄워 iframe src로 사용한다.
|
|
32
|
+
* @deprecated 알파.10 제거 예정. `builder: 'vite' + builderOptions`로 마이그.
|
|
33
33
|
*
|
|
34
|
-
* `
|
|
34
|
+
* 알파.8 alias. 알파.9에서는 `builder: 'vite'` + `builderOptions: { configFile, port, host }`로 권장.
|
|
35
|
+
*/
|
|
36
|
+
readonly userVite?: UserViteOptions;
|
|
37
|
+
/**
|
|
38
|
+
* 알파.9: 사용자 빌더 명시. 미지정 시 cwd 시그널로 자동 감지
|
|
39
|
+
* (`vite.config.*` / `next.config.*` / `webpack.config.*` / `react-scripts` dep 등).
|
|
35
40
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
41
|
+
* - `'vite' | 'next' | 'webpack' | 'standalone'`: 해당 어댑터 강제.
|
|
42
|
+
* - `undefined` (default): 자동 감지.
|
|
38
43
|
*
|
|
39
|
-
*
|
|
40
|
-
* defineJogakConfig({ userVite: { port: 5174 } })
|
|
44
|
+
* `'custom'`은 알파.10에서 사용자 정의 어댑터 인스턴스 통로 도입 시 활성.
|
|
41
45
|
*/
|
|
42
|
-
readonly
|
|
46
|
+
readonly builder?: Exclude<BuilderName, 'custom'>;
|
|
47
|
+
/**
|
|
48
|
+
* 알파.9: 어댑터별 추가 옵션. 어댑터 ABI의 `extra`로 그대로 전달.
|
|
49
|
+
*
|
|
50
|
+
* - vite-adapter: `{ configFile?, port?, host?, disabled? }`
|
|
51
|
+
* - next-adapter: `{ appDir?, port? }`
|
|
52
|
+
* - webpack-adapter: `{ configFile?, port? }`
|
|
53
|
+
* - standalone-adapter: 미지원
|
|
54
|
+
*/
|
|
55
|
+
readonly builderOptions?: Readonly<Record<string, unknown>>;
|
|
43
56
|
}
|
|
44
57
|
/**
|
|
45
58
|
* `jogak.config.ts`에서 사용자가 호출하는 identity helper.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const n=require("node:fs"),t=require("node:path"),a=["src/index.css","src/main.css","src/styles.css","src/styles/globals.css","src/styles/index.css","src/app/globals.css","src/global.css","src/app.css"];function l(s){for(const e of a){const r=t.resolve(s,e);if(n.existsSync(r))return[r]}return[]}function f(s,e){if(s===void 0||s===!1)return[];if(s===!0)return l(e);if(typeof s=="string")return s.length>0?[t.resolve(e,s)]:[];const r=[];for(const c of s)typeof c=="string"&&c.length>0&&r.push(t.resolve(e,c));return r}exports.detectUserGlobalCss=l;exports.resolveGlobalCssPaths=f;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { existsSync as l } from "node:fs";
|
|
2
|
+
import { resolve as t } from "node:path";
|
|
3
|
+
const n = [
|
|
4
|
+
"src/index.css",
|
|
5
|
+
"src/main.css",
|
|
6
|
+
"src/styles.css",
|
|
7
|
+
"src/styles/globals.css",
|
|
8
|
+
"src/styles/index.css",
|
|
9
|
+
"src/app/globals.css",
|
|
10
|
+
"src/global.css",
|
|
11
|
+
"src/app.css"
|
|
12
|
+
];
|
|
13
|
+
function f(s) {
|
|
14
|
+
for (const r of n) {
|
|
15
|
+
const e = t(s, r);
|
|
16
|
+
if (l(e)) return [e];
|
|
17
|
+
}
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
function o(s, r) {
|
|
21
|
+
if (s === void 0 || s === !1) return [];
|
|
22
|
+
if (s === !0) return f(r);
|
|
23
|
+
if (typeof s == "string")
|
|
24
|
+
return s.length > 0 ? [t(r, s)] : [];
|
|
25
|
+
const e = [];
|
|
26
|
+
for (const c of s)
|
|
27
|
+
typeof c == "string" && c.length > 0 && e.push(t(r, c));
|
|
28
|
+
return e;
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
f as d,
|
|
32
|
+
o as r
|
|
33
|
+
};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";var D=Object.defineProperty;var z=n=>{throw TypeError(n)};var X=(n,t,e)=>t in n?D(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var F=(n,t,e)=>X(n,typeof t!="symbol"?t+"":t,e),I=(n,t,e)=>t.has(n)||z("Cannot "+e);var r=(n,t,e)=>(I(n,t,"read from private field"),e?e.call(n):t.get(n)),f=(n,t,e)=>t.has(n)?z("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(n):t.set(n,e),c=(n,t,e,i)=>(I(n,t,"write to private field"),i?i.call(n,e):t.set(n,e),e),l=(n,t,e)=>(I(n,t,"access private method"),e);var J=(n,t,e,i)=>({set _(s){c(n,t,s,e)},get _(){return r(n,t,i)}});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class R extends Error{constructor(e){super(`[jogak] Unknown entry id: ${e}`);F(this,"id");this.name="UnknownEntryError",this.id=e}}var a,M,T,v,k,E,w,j,A,C,u,m,S,$;class U{constructor(){f(this,u);f(this,a,new Map);f(this,M);f(this,T,new Set);f(this,v);f(this,k);f(this,E);f(this,w);f(this,j);f(this,A,!1);f(this,C,!1)}register(t){const e=V(t);l(this,u,$).call(this,()=>{this.registerMeta(e),this.hydrateEntry(t.id,t.jogaks,t.meta.component)})}unregister(t){const e=r(this,a).get(t);e!==void 0&&(e.kind==="pending"&&e.reject(new R(t)),r(this,a).delete(t),l(this,u,m).call(this))}get(t){const e=r(this,a).get(t);return(e==null?void 0:e.kind)==="hydrated"?e.entry:void 0}getAll(){if(r(this,E)!==void 0)return r(this,E);const t=[];for(const i of l(this,u,S).call(this)){const s=r(this,a).get(i);(s==null?void 0:s.kind)==="hydrated"&&t.push(s.entry)}const e=t;return c(this,E,e),e}search(t){const e=t.toLowerCase();return this.getAll().filter(i=>i.title.toLowerCase().includes(e))}getTree(){if(r(this,w)!==void 0)return r(this,w);const t={};for(const e of this.getAll()){const i=e.title.split("/");let s=t;for(let h=0;h<i.length-1;h++){const d=i[h];if(d===void 0)continue;const g=s[d];(g===void 0||"id"in g)&&(s[d]={}),s=s[d]}const o=i[i.length-1];o!==void 0&&(s[o]=e)}return c(this,w,t),t}clear(){if(r(this,a).size!==0){for(const t of r(this,a).values())t.kind==="pending"&&t.reject(new Error("[jogak] registry cleared"));r(this,a).clear(),l(this,u,m).call(this)}}get size(){let t=0;for(const e of r(this,a).values())e.kind==="hydrated"&&t++;return t}registerMeta(t){const e=r(this,a).get(t.id);if(e===void 0){r(this,a).set(t.id,{kind:"meta",meta:t}),l(this,u,m).call(this);return}if(e.kind==="meta"){r(this,a).set(t.id,{kind:"meta",meta:t}),l(this,u,m).call(this);return}if(e.kind==="pending"){r(this,a).set(t.id,{kind:"pending",meta:t,promise:e.promise,resolve:e.resolve,reject:e.reject}),l(this,u,m).call(this);return}const i={...e.entry,title:t.title,filePath:t.filePath,source:t.source,meta:N(t,e.entry.meta.component)};r(this,a).set(t.id,{kind:"hydrated",meta:t,entry:i}),l(this,u,m).call(this)}hydrateEntry(t,e,i){const s=r(this,a).get(t);let o;s===void 0?(console.warn(`[jogak] hydrateEntry called for unknown id "${t}" — synthesizing minimal meta`),o={id:t,title:t,jogakNames:e.map(d=>d.name),autoArgTypes:{},userArgTypes:{},source:"",filePath:"",metaExtras:{}}):o=s.meta;const h={id:o.id,title:o.title,jogaks:e,meta:N(o,i),...o.filePath?{filePath:o.filePath}:{},...o.source?{source:o.source}:{}};if((s==null?void 0:s.kind)==="pending"){r(this,a).set(t,{kind:"hydrated",meta:o,entry:h}),l(this,u,m).call(this),s.resolve(h);return}r(this,a).set(t,{kind:"hydrated",meta:o,entry:h}),l(this,u,m).call(this)}invalidateEntry(t){const e=r(this,a).get(t);e===void 0||e.kind!=="hydrated"||(r(this,a).set(t,{kind:"meta",meta:e.meta}),l(this,u,m).call(this))}requestEntry(t){const e=r(this,a).get(t);if(e===void 0)return Promise.reject(new R(t));if(e.kind==="hydrated")return Promise.resolve(e.entry);if(e.kind==="pending")return e.promise;const i=r(this,M);if(i===void 0)return Promise.reject(new Error("[jogak] entry loader not set — virtual:jogak index module did not load"));let s,o;const h=new Promise((d,g)=>{s=d,o=g});return r(this,a).set(t,{kind:"pending",meta:e.meta,promise:h,resolve:s,reject:o}),i(t).then(()=>{const d=r(this,a).get(t);(d==null?void 0:d.kind)!=="hydrated"&&o(new Error(`[jogak] entry module loaded but did not hydrate: ${t}`))},d=>{const g=d instanceof Error?d:new Error(String(d)),y=r(this,a).get(t);(y==null?void 0:y.kind)==="pending"&&y.promise===h&&r(this,a).set(t,{kind:"meta",meta:e.meta}),o(g)}),h}getAllMeta(){if(r(this,v)!==void 0)return r(this,v);const t=[];for(const i of l(this,u,S).call(this)){const s=r(this,a).get(i);s!==void 0&&t.push(s.meta)}const e=t;return c(this,v,e),e}getMetaTree(){if(r(this,k)!==void 0)return r(this,k);const t={};for(const e of l(this,u,S).call(this)){const i=r(this,a).get(e);if(i===void 0)continue;const s=i.meta,o=s.title.split("/");let h=t;for(let g=0;g<o.length-1;g++){const y=o[g];if(y===void 0)continue;const O=h[y];(O===void 0||"id"in O)&&(h[y]={}),h=h[y]}const d=o[o.length-1];d!==void 0&&(h[d]=s)}return c(this,k,t),t}getEntryState(t){const e=r(this,a).get(t);return e===void 0?"unknown":e.kind}setEntryLoader(t){c(this,M,t)}subscribe(t){r(this,T).add(t);let e=!0;return()=>{e&&(e=!1,r(this,T).delete(t))}}}a=new WeakMap,M=new WeakMap,T=new WeakMap,v=new WeakMap,k=new WeakMap,E=new WeakMap,w=new WeakMap,j=new WeakMap,A=new WeakMap,C=new WeakMap,u=new WeakSet,m=function(){if(c(this,v,void 0),c(this,k,void 0),c(this,E,void 0),c(this,w,void 0),c(this,j,void 0),r(this,A)){c(this,C,!0);return}const t=Array.from(r(this,T));for(const e of t)try{e()}catch(i){console.error("[jogak] subscribe listener threw:",i)}},S=function(){if(r(this,j)!==void 0)return r(this,j);const t=[];for(const[i,s]of r(this,a))t.push({id:i,title:s.meta.title});t.sort(G);const e=t.map(i=>i.id);return c(this,j,e),e},$=function(t){if(r(this,A)){t();return}c(this,A,!0),c(this,C,!1);try{t()}finally{c(this,A,!1),r(this,C)&&(c(this,C,!1),l(this,u,m).call(this))}};function V(n){const t=n.meta.argTypes??{};return{id:n.id,title:n.title,jogakNames:n.jogaks.map(e=>e.name),autoArgTypes:{},userArgTypes:t,source:n.source??"",filePath:n.filePath??"",metaExtras:{...n.meta.tags!==void 0?{tags:n.meta.tags}:{},...n.meta.parameters!==void 0?{parameters:n.meta.parameters}:{}}}}function N(n,t){const e={...n.autoArgTypes};for(const i of Object.keys(n.userArgTypes)){const s=n.userArgTypes[i];s!==void 0&&(e[i]={...e[i],...s})}return{title:n.title,component:t,argTypes:e,...n.metaExtras.tags!==void 0?{tags:n.metaExtras.tags}:{},...n.metaExtras.parameters!==void 0?{parameters:n.metaExtras.parameters}:{}}}function G(n,t){const e=n.title.localeCompare(t.title,"en",{sensitivity:"base",numeric:!0});return e!==0?e:n.id.localeCompare(t.id,"en",{sensitivity:"base",numeric:!0})}const H=new U;var p,P,x,b,_;class q{constructor(){f(this,b);f(this,p,[]);f(this,P,new Set);f(this,x,1)}emit(t,e){const i={id:J(this,x)._++,name:t,args:e,timestamp:Date.now()};c(this,p,[...r(this,p),i]),l(this,b,_).call(this)}subscribe(t){return r(this,P).add(t),t(r(this,p)),()=>{r(this,P).delete(t)}}clear(){r(this,p).length!==0&&(c(this,p,[]),l(this,b,_).call(this))}getLogs(){return r(this,p)}}p=new WeakMap,P=new WeakMap,x=new WeakMap,b=new WeakSet,_=function(){for(const t of r(this,P))t(r(this,p))};const L=new q;function B(n,t=L){return(...e)=>{t.emit(n,e)}}function K(n,t,e=L){const i={...n};for(const s of Object.keys(t)){const o=t[s];if(o===void 0)continue;const h=o.action!==void 0&&o.action!==!1,d=o.type==="function";if(!h&&!d||typeof i[s]=="function")continue;const g=typeof o.action=="string"?o.action:s;i[s]=B(g,e)}return i}function Q(n){return n}const W=`
|
|
2
|
+
import { reactAdapter } from '@jogak/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 Y(n={}){const e=(n.extraImports??[]).map(i=>`import ${JSON.stringify(i)}`).join(`
|
|
43
|
+
`);return W.replace("__EXTRA_IMPORTS__",e)}exports.ActionChannel=q;exports.ComponentRegistry=U;exports.UnknownEntryError=R;exports.action=B;exports.defaultActionChannel=L;exports.defaultRegistry=H;exports.defineJogakConfig=Q;exports.injectActions=K;exports.renderPreviewEntrySource=Y;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,3 +2,6 @@ export type { ArgType, JogakMeta, Jogak, RegistryEntry, RegistryEntryMeta, Categ
|
|
|
2
2
|
export { ComponentRegistry, defaultRegistry, UnknownEntryError } from './registry.js';
|
|
3
3
|
export { ActionChannel, defaultActionChannel, action, injectActions, type ActionLog, type ActionListener, } from './actions.js';
|
|
4
4
|
export { defineJogakConfig, type JogakConfig } from './config.js';
|
|
5
|
+
export type { BuilderAdapter, BuilderName, GlobalCssSpec, SpawnDevOptions, DevHandle, BuildOptions, BuildResult, PreviewEntryMeta, HostLogger, } from './adapter.js';
|
|
6
|
+
export type { JogakMessageToFrame, JogakMessageFromFrame, } from './preview-entry/protocol.js';
|
|
7
|
+
export { renderPreviewEntrySource, type RenderPreviewEntryOptions, } from './preview-entry/source.js';
|