hono-decks 1.1.0 → 1.2.1
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/README.ja.md +37 -2
- package/README.md +48 -4
- package/dist/adapters/hono-markdown.d.ts +39 -0
- package/dist/adapters/hono-markdown.js +47 -0
- package/dist/advanced.d.ts +5 -2
- package/dist/bin.js +77 -29
- package/dist/cli.js +77 -29
- package/dist/{init-vite-mLg3XlcN.js → init-vite-F2gLT72s.js} +35 -27
- package/dist/mod.d.ts +5 -2
- package/dist/node.d.ts +115 -112
- package/dist/node.js +76 -28
- package/dist/vite.js +76 -28
- package/package.json +5 -1
- package/skills/hono-decks/references/getting-started.md +1 -1
package/README.ja.md
CHANGED
|
@@ -69,8 +69,9 @@ npm run dev
|
|
|
69
69
|
npm run build
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
この連携には
|
|
73
|
-
|
|
72
|
+
この連携には standalone compiler/client export を持つアダプターが必要です。
|
|
73
|
+
新規インストールの既定値は `void-plugin-hono-jsx@^0.6.0` です。
|
|
74
|
+
`--install` は、インストール済みの互換アダプターを維持します。
|
|
74
75
|
`--install` を省略する場合は、Markdown 用の任意 peer も必要です:
|
|
75
76
|
`markdown-exit@^1.3.0 yaml@^2.9.1 markdown-it-container@^4.0.0 shiki@^4.5.0 @shikijs/transformers@^4.5.0`。
|
|
76
77
|
動作確認した組み合わせは Void 1.1.11、Vite 8.3.4、Hono 4.13.13 です。
|
|
@@ -474,3 +475,37 @@ app.route("/internal-slides", decksRouter({ source, dev: true }));
|
|
|
474
475
|
反映します。反映中に失敗した場合は、直前の内容へ戻します。OS やプロセスの停止時の
|
|
475
476
|
一括反映、複数プロセスの同時実行は保証しません。復元自体に失敗した場合は、
|
|
476
477
|
復旧用ファイルを残し、その場所をエラーに表示します。
|
|
478
|
+
|
|
479
|
+
## Markdownアダプター
|
|
480
|
+
|
|
481
|
+
従来の `build.markdown: "void"` に加えて、ビルド時に読み込むアダプターを指定できます。
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
export default defineDecksConfig({
|
|
485
|
+
mountPath: "/slides",
|
|
486
|
+
router: { clientEntryAssetPath: "/_assets/client" },
|
|
487
|
+
build: {
|
|
488
|
+
root: "decks",
|
|
489
|
+
markdown: { adapter: "hono-decks/adapters/hono-markdown" },
|
|
490
|
+
},
|
|
491
|
+
});
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
このブリッジは共通の `@ts-76/hono-markdown` を利用します。共通パッケージはVoid・Viteに依存しません。このアダプターを選ぶ場合はコンパイラー用peer dependenciesも導入します。
|
|
495
|
+
既存の `markdown: "void"` は、既に導入したVoidアダプターの公開コンパイラーAPIでも引き続き動作します。
|
|
496
|
+
`init --framework void --install` の導入手順、既存のdev/buildコマンドは変わりません。
|
|
497
|
+
|
|
498
|
+
設定はサーバー実行時にも読み込むため、アダプターは文字列で指定し、Node用のfactoryを設定ファイルへimportしません。
|
|
499
|
+
Hono+Vite・HonoXは引き続きMDXが標準で、VoidやMarkdown用パーサーの追加は不要です。
|
|
500
|
+
これらでMarkdownを使う場合は、共通パッケージとコンパイラー用peer dependenciesを導入し、上記ブリッジを選択します。
|
|
501
|
+
Viteは仮想モジュールを利用し、既存の `hono-decks compile` はファイル出力を維持します。
|
|
502
|
+
|
|
503
|
+
独自アダプターは `createMarkdownAdapter({ cwd, options })` をexportし、`read(source)`、非同期の
|
|
504
|
+
`compile(source, { sourcePath })`、`client(islands)` を返します。型は `hono-decks/adapters/hono-markdown` からimportできます。
|
|
505
|
+
スライド分割・メタデータ・アセット・ルーティング・表示中スライドの判定はhono-decksが担当し、Markdownの変換とislandのスケジュールはアダプターが担当します。
|
|
506
|
+
同じVoidアプリにhonoxpressを組み込んでも、ドキュメントとスライドが互いの内部実装に依存する必要はありません。
|
|
507
|
+
|
|
508
|
+
Hono+Vite・HonoXのinitは、dev serverが標準で`.js`を除外するため、拡張子なしの
|
|
509
|
+
`/_assets/client`を設定します。配信は既存アプリのミドルウェア・認可を通ります。
|
|
510
|
+
既存CLI構成の標準パス`/_assets/client.js`は維持します。VoidなしのMarkdown実アプリ検証は、
|
|
511
|
+
`HONO_MARKDOWN_PACKAGE`に共通パッケージのtarballを指定し、`node scripts/verify-vite-init.mjs`で実行できます。
|
package/README.md
CHANGED
|
@@ -68,9 +68,9 @@ npm run dev
|
|
|
68
68
|
npm run build
|
|
69
69
|
~~~
|
|
70
70
|
|
|
71
|
-
This integration requires
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
This integration requires an adapter with the `/markdown/compiler` and
|
|
72
|
+
`/markdown/client` exports. New installations default to `void-plugin-hono-jsx@^0.6.0`;
|
|
73
|
+
`--install` preserves an already installed compatible adapter. Without `--install`, also install the optional Markdown peers:
|
|
74
74
|
`markdown-exit@^1.3.0 yaml@^2.9.1 markdown-it-container@^4.0.0 shiki@^4.5.0 @shikijs/transformers@^4.5.0`.
|
|
75
75
|
The verified host versions are Void 1.1.11, Vite 8.3.4, and Hono 4.13.13.
|
|
76
76
|
|
|
@@ -465,7 +465,7 @@ At this level, the application owns the mount path, source policy, and option me
|
|
|
465
465
|
## Void Hono Markdown
|
|
466
466
|
|
|
467
467
|
Set `build.markdown: "void"` in `hono-decks.config.ts` to opt into `.md` decks
|
|
468
|
-
alongside MDX. This requires `void-plugin-hono-jsx@^0.
|
|
468
|
+
alongside MDX. This requires `void-plugin-hono-jsx@^0.6.0` with its standalone compiler and client exports.
|
|
469
469
|
See the [Void consumer fixture](https://github.com/ts-76/hono-decks/tree/main/fixtures/void-markdown)
|
|
470
470
|
for package verification, Void middleware hosting, supported syntax and limitations.
|
|
471
471
|
|
|
@@ -490,3 +490,47 @@ files (including cache files) on a publication error. Application-owned files
|
|
|
490
490
|
are preserved. This guarantees rollback on reported build failure, not
|
|
491
491
|
crash-atomic publication or coordination between concurrent compiler processes.
|
|
492
492
|
If rollback itself fails, the error lists retained recovery directories.
|
|
493
|
+
|
|
494
|
+
## Markdown adapters
|
|
495
|
+
|
|
496
|
+
The deck compiler accepts a build-only module reference as well as the existing
|
|
497
|
+
`build.markdown: "void"` preset:
|
|
498
|
+
|
|
499
|
+
```ts
|
|
500
|
+
export default defineDecksConfig({
|
|
501
|
+
mountPath: "/slides",
|
|
502
|
+
router: { clientEntryAssetPath: "/_assets/client" },
|
|
503
|
+
build: {
|
|
504
|
+
root: "decks",
|
|
505
|
+
markdown: { adapter: "hono-decks/adapters/hono-markdown" },
|
|
506
|
+
},
|
|
507
|
+
});
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
The Hono Markdown bridge uses `@ts-76/hono-markdown/compiler` and its browser
|
|
511
|
+
runtime. The common package has no Void or Vite dependency. Install its optional compiler peers when selecting this adapter. Existing
|
|
512
|
+
Void configurations continue to work with the adapter's public compiler API,
|
|
513
|
+
including compatible earlier adapter versions. `init --framework void
|
|
514
|
+
--install` retains the one-command setup and unchanged dev/build scripts.
|
|
515
|
+
|
|
516
|
+
Keep the adapter reference in config as a string: config is also imported by the
|
|
517
|
+
server runtime. The compiler loads adapters only during builds. Hono+Vite and
|
|
518
|
+
HonoX continue to default to MDX without installing Void or Markdown peers.
|
|
519
|
+
For Markdown in these hosts, install the common package and its compiler peers
|
|
520
|
+
and select the bridge above. Vite uses virtual modules; `hono-decks compile`
|
|
521
|
+
continues to emit files.
|
|
522
|
+
|
|
523
|
+
Custom build adapters export `createMarkdownAdapter({ cwd, options })`, returning
|
|
524
|
+
`read(source)`, asynchronous `compile(source, { sourcePath })`, and
|
|
525
|
+
`client(islands)`. Types are exported from `hono-decks/adapters/hono-markdown`.
|
|
526
|
+
The deck host owns splitting, metadata, assets, routing and the visible-slide
|
|
527
|
+
hydration gate; Markdown compilation and island scheduling belong to the adapter.
|
|
528
|
+
Document adapters such as honoxpress can use the same Markdown package in a Void
|
|
529
|
+
app without importing deck internals or changing their route ownership.
|
|
530
|
+
|
|
531
|
+
Hono+Vite/HonoX init selects the extensionless `/_assets/client` route because
|
|
532
|
+
`@hono/vite-dev-server` excludes `.js` requests by default. The client still goes
|
|
533
|
+
through the application's middleware and authorization. Existing standalone CLI
|
|
534
|
+
configurations retain their default `/_assets/client.js` route. For local
|
|
535
|
+
Markdown checks without Void, set `HONO_MARKDOWN_PACKAGE` to the common tarball
|
|
536
|
+
and run `node scripts/verify-vite-init.mjs`.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import "hono";
|
|
2
|
+
import "hono/jsx";
|
|
3
|
+
import "hono/utils/html";
|
|
4
|
+
//#region src/node/markdown-adapter.d.ts
|
|
5
|
+
interface MarkdownIsland {
|
|
6
|
+
id: string;
|
|
7
|
+
modulePath: string;
|
|
8
|
+
hydrate: string;
|
|
9
|
+
}
|
|
10
|
+
interface DeckMarkdownAdapter {
|
|
11
|
+
read(source: string): {
|
|
12
|
+
frontmatter: Record<string, unknown>;
|
|
13
|
+
content: string;
|
|
14
|
+
script: string;
|
|
15
|
+
};
|
|
16
|
+
compile(source: string, input: {
|
|
17
|
+
sourcePath: string;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
code: string;
|
|
20
|
+
headings: {
|
|
21
|
+
depth: number;
|
|
22
|
+
slug: string;
|
|
23
|
+
text: string;
|
|
24
|
+
}[];
|
|
25
|
+
clientCode: string;
|
|
26
|
+
islands?: MarkdownIsland[];
|
|
27
|
+
}>;
|
|
28
|
+
client(islands: MarkdownIsland[]): string;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/adapters/hono-markdown.d.ts
|
|
32
|
+
/** Node-only bridge. Existing Void configs retain their original compiler/runtime pair. */
|
|
33
|
+
declare function createHonoMarkdownAdapter(cwd: string, legacy?: boolean, options?: Record<string, unknown>): Promise<DeckMarkdownAdapter>;
|
|
34
|
+
declare function createMarkdownAdapter({ cwd, options }: {
|
|
35
|
+
cwd: string;
|
|
36
|
+
options?: Record<string, unknown>;
|
|
37
|
+
}): Promise<DeckMarkdownAdapter>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { type DeckMarkdownAdapter, type MarkdownIsland, createHonoMarkdownAdapter, createMarkdownAdapter };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
//#region src/adapters/hono-markdown.ts
|
|
5
|
+
/** Node-only bridge. Existing Void configs retain their original compiler/runtime pair. */
|
|
6
|
+
async function createHonoMarkdownAdapter(cwd, legacy = false, options) {
|
|
7
|
+
const require = createRequire(resolve(cwd, "package.json"));
|
|
8
|
+
const entry = legacy ? "void-plugin-hono-jsx/markdown/compiler" : "@ts-76/hono-markdown/compiler";
|
|
9
|
+
let compiler;
|
|
10
|
+
try {
|
|
11
|
+
compiler = await import(pathToFileURL(require.resolve(entry)).href);
|
|
12
|
+
} catch (cause) {
|
|
13
|
+
throw new Error(`Hono Markdown requires ${legacy ? "its public /markdown/compiler API" : "@ts-76/hono-markdown/compiler"} and Markdown peers installed in the app.`, { cause });
|
|
14
|
+
}
|
|
15
|
+
const read = compiler.readMarkdownModule ?? compiler.readStaticMarkdown;
|
|
16
|
+
const compile = compiler.compileMarkdownModule ?? compiler.compileStaticMarkdown;
|
|
17
|
+
if (typeof read !== "function" || typeof compile !== "function") throw new Error("Missing standalone compiler API");
|
|
18
|
+
const runtime = entry.startsWith("void-plugin") ? "void-plugin-hono-jsx/markdown/client" : "@ts-76/hono-markdown/client";
|
|
19
|
+
return {
|
|
20
|
+
read,
|
|
21
|
+
compile: (source, input) => compile(source, {
|
|
22
|
+
...input,
|
|
23
|
+
options
|
|
24
|
+
}),
|
|
25
|
+
client: (islands) => emitMarkdownClient(islands, runtime)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function createMarkdownAdapter({ cwd, options }) {
|
|
29
|
+
return createHonoMarkdownAdapter(cwd, false, options);
|
|
30
|
+
}
|
|
31
|
+
function emitMarkdownClient(islands, runtime) {
|
|
32
|
+
if (!islands.length) return "";
|
|
33
|
+
const literal = (value) => JSON.stringify(value).replace(/</g, "\\u003c");
|
|
34
|
+
return `import { hydrateMarkdownIslands } from ${literal(runtime)};
|
|
35
|
+
hydrateMarkdownIslands({ ${islands.map((island) => `${literal(island.id)}: () => import(${literal(island.modulePath)})`).join(",")} }, {
|
|
36
|
+
ready(element, start) {
|
|
37
|
+
const slide = element.closest('section[data-slide-state]');
|
|
38
|
+
if (!slide || slide.dataset.slideState === 'active') { start(); return; }
|
|
39
|
+
const observer = new MutationObserver(() => {
|
|
40
|
+
if (slide.dataset.slideState === 'active') { observer.disconnect(); start(); }
|
|
41
|
+
});
|
|
42
|
+
observer.observe(slide, { attributes: true, attributeFilter: ['data-slide-state'] });
|
|
43
|
+
}
|
|
44
|
+
});`;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { createHonoMarkdownAdapter, createMarkdownAdapter };
|
package/dist/advanced.d.ts
CHANGED
|
@@ -544,8 +544,11 @@ interface DefinedDecks<E extends Env = any> {
|
|
|
544
544
|
}
|
|
545
545
|
/** File-system settings consumed by the CLI. */
|
|
546
546
|
interface DecksBuildConfig {
|
|
547
|
-
/**
|
|
548
|
-
markdown?: "void"
|
|
547
|
+
/** Build-only Markdown adapter reference. "void" retains the compatible preset. */
|
|
548
|
+
markdown?: "void" | {
|
|
549
|
+
adapter: string;
|
|
550
|
+
options?: Record<string, unknown>;
|
|
551
|
+
};
|
|
549
552
|
/** Deck source directory. @default "decks" */
|
|
550
553
|
root?: string;
|
|
551
554
|
/** CLI output directory. Vite keeps modules in memory. @default "src/generated" */
|
package/dist/bin.js
CHANGED
|
@@ -8,10 +8,10 @@ import { unified } from "unified";
|
|
|
8
8
|
import remarkGfm from "remark-gfm";
|
|
9
9
|
import remarkMdx from "remark-mdx";
|
|
10
10
|
import remarkParse from "remark-parse";
|
|
11
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
12
11
|
import { compile } from "@mdx-js/mdx";
|
|
13
12
|
import remarkDirective from "remark-directive";
|
|
14
13
|
import { codeToHtml } from "shiki";
|
|
14
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
15
15
|
import { build } from "esbuild";
|
|
16
16
|
import { lookup } from "node:dns/promises";
|
|
17
17
|
import { isIP } from "node:net";
|
|
@@ -1506,29 +1506,20 @@ function extractDeckPrelude(source) {
|
|
|
1506
1506
|
};
|
|
1507
1507
|
}
|
|
1508
1508
|
//#endregion
|
|
1509
|
-
//#region src/node/
|
|
1510
|
-
|
|
1511
|
-
async function compileVoidMarkdownDecks(input) {
|
|
1509
|
+
//#region src/node/markdown-decks.ts
|
|
1510
|
+
async function compileMarkdownDecks(input, adapter) {
|
|
1512
1511
|
const markdownEntries = input.decks.filter((entry) => entry.sourcePath.endsWith(".md"));
|
|
1513
1512
|
const mdx = await compileMdxModuleDecks({
|
|
1514
1513
|
...input,
|
|
1515
1514
|
decks: input.decks.filter((entry) => !entry.sourcePath.endsWith(".md"))
|
|
1516
1515
|
});
|
|
1517
1516
|
if (!markdownEntries.length) return mdx;
|
|
1518
|
-
let compiler;
|
|
1519
|
-
try {
|
|
1520
|
-
compiler = await import(pathToFileURL(createRequire(resolve(input.cwd ?? process.cwd(), "package.json")).resolve("void-plugin-hono-jsx/markdown/compiler")).href);
|
|
1521
|
-
if (typeof (compiler.compileMarkdownModule ?? compiler.compileStaticMarkdown) !== "function" || typeof (compiler.readMarkdownModule ?? compiler.readStaticMarkdown) !== "function") throw new Error("Missing standalone compiler API");
|
|
1522
|
-
} catch (error) {
|
|
1523
|
-
throw new Error("Void Markdown requires void-plugin-hono-jsx with the public /markdown/compiler API and its Markdown peers installed in the app.", { cause: error });
|
|
1524
|
-
}
|
|
1525
|
-
const readModule = compiler.readMarkdownModule ?? compiler.readStaticMarkdown;
|
|
1526
|
-
const compileModule = compiler.compileMarkdownModule ?? compiler.compileStaticMarkdown;
|
|
1527
1517
|
const decks = [...mdx.decks];
|
|
1528
1518
|
const clients = /* @__PURE__ */ new Set();
|
|
1529
1519
|
const markdownIslands = /* @__PURE__ */ new Map();
|
|
1530
1520
|
for (const entry of markdownEntries) try {
|
|
1531
|
-
const
|
|
1521
|
+
const source = await input.readText(entry.sourcePath);
|
|
1522
|
+
const parsed = adapter.read(source);
|
|
1532
1523
|
if (input.clientComponentIds?.[entry.slug] && Object.keys(input.clientComponentIds[entry.slug]).length) throw new Error("Void Markdown slides support static components only; use MDX for hono-decks client components.");
|
|
1533
1524
|
const warnings = [];
|
|
1534
1525
|
const meta = toDeckFrontmatter(parsed.frontmatter, warnings);
|
|
@@ -1549,12 +1540,13 @@ async function compileVoidMarkdownDecks(input) {
|
|
|
1549
1540
|
const slides = [];
|
|
1550
1541
|
for (const [index, slideSource] of splitMarkdownSlides(parsed.content).entries()) {
|
|
1551
1542
|
const prelude = parsed.script ? `<script>\n${parsed.script}\n<\/script>\n` : "";
|
|
1552
|
-
const slide =
|
|
1543
|
+
const slide = adapter.read(prelude + slideSource);
|
|
1553
1544
|
const path = `${input.outDir}/decks/${entry.slug}/slide-${index}.ts`;
|
|
1554
|
-
const
|
|
1545
|
+
const rewritten = rewriteAssetUrls(`${prelude}---\n${JSON.stringify({
|
|
1555
1546
|
...parsed.frontmatter,
|
|
1556
1547
|
...slide.frontmatter
|
|
1557
|
-
})}\n---\n${slide.content}`, assets)
|
|
1548
|
+
})}\n---\n${slide.content}`, assets);
|
|
1549
|
+
const result = await adapter.compile(rewritten, { sourcePath: resolve(input.cwd ?? process.cwd(), entry.sourcePath) });
|
|
1558
1550
|
clientEntryRequired ||= Boolean(result.clientCode || result.islands?.length);
|
|
1559
1551
|
if (result.clientCode) clients.add(result.clientCode);
|
|
1560
1552
|
for (const island of result.islands ?? []) markdownIslands.set(island.id, island);
|
|
@@ -1604,6 +1596,7 @@ async function compileVoidMarkdownDecks(input) {
|
|
|
1604
1596
|
decks,
|
|
1605
1597
|
routerModule: emitModuleDecksRouter({ decks }),
|
|
1606
1598
|
clientCode: [...clients].join("\n"),
|
|
1599
|
+
clientModules: [adapter.client([...markdownIslands.values()])].filter(Boolean),
|
|
1607
1600
|
markdownIslands: [...markdownIslands.values()]
|
|
1608
1601
|
};
|
|
1609
1602
|
}
|
|
@@ -1640,6 +1633,64 @@ function splitMarkdownSlides(source) {
|
|
|
1640
1633
|
return splitSlideSources(protectedLines.join("\n")).map((slide) => slide.replace(new RegExp(`${prefix}(\\d+)_END`, "g"), (_, id) => fences[Number(id)]));
|
|
1641
1634
|
}
|
|
1642
1635
|
//#endregion
|
|
1636
|
+
//#region src/adapters/hono-markdown.ts
|
|
1637
|
+
/** Node-only bridge. Existing Void configs retain their original compiler/runtime pair. */
|
|
1638
|
+
async function createHonoMarkdownAdapter(cwd, legacy = false, options) {
|
|
1639
|
+
const require = createRequire(resolve(cwd, "package.json"));
|
|
1640
|
+
const entry = legacy ? "void-plugin-hono-jsx/markdown/compiler" : "@ts-76/hono-markdown/compiler";
|
|
1641
|
+
let compiler;
|
|
1642
|
+
try {
|
|
1643
|
+
compiler = await import(pathToFileURL(require.resolve(entry)).href);
|
|
1644
|
+
} catch (cause) {
|
|
1645
|
+
throw new Error(`Hono Markdown requires ${legacy ? "its public /markdown/compiler API" : "@ts-76/hono-markdown/compiler"} and Markdown peers installed in the app.`, { cause });
|
|
1646
|
+
}
|
|
1647
|
+
const read = compiler.readMarkdownModule ?? compiler.readStaticMarkdown;
|
|
1648
|
+
const compile = compiler.compileMarkdownModule ?? compiler.compileStaticMarkdown;
|
|
1649
|
+
if (typeof read !== "function" || typeof compile !== "function") throw new Error("Missing standalone compiler API");
|
|
1650
|
+
const runtime = entry.startsWith("void-plugin") ? "void-plugin-hono-jsx/markdown/client" : "@ts-76/hono-markdown/client";
|
|
1651
|
+
return {
|
|
1652
|
+
read,
|
|
1653
|
+
compile: (source, input) => compile(source, {
|
|
1654
|
+
...input,
|
|
1655
|
+
options
|
|
1656
|
+
}),
|
|
1657
|
+
client: (islands) => emitMarkdownClient(islands, runtime)
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
function emitMarkdownClient(islands, runtime) {
|
|
1661
|
+
if (!islands.length) return "";
|
|
1662
|
+
const literal = (value) => JSON.stringify(value).replace(/</g, "\\u003c");
|
|
1663
|
+
return `import { hydrateMarkdownIslands } from ${literal(runtime)};
|
|
1664
|
+
hydrateMarkdownIslands({ ${islands.map((island) => `${literal(island.id)}: () => import(${literal(island.modulePath)})`).join(",")} }, {
|
|
1665
|
+
ready(element, start) {
|
|
1666
|
+
const slide = element.closest('section[data-slide-state]');
|
|
1667
|
+
if (!slide || slide.dataset.slideState === 'active') { start(); return; }
|
|
1668
|
+
const observer = new MutationObserver(() => {
|
|
1669
|
+
if (slide.dataset.slideState === 'active') { observer.disconnect(); start(); }
|
|
1670
|
+
});
|
|
1671
|
+
observer.observe(slide, { attributes: true, attributeFilter: ['data-slide-state'] });
|
|
1672
|
+
}
|
|
1673
|
+
});`;
|
|
1674
|
+
}
|
|
1675
|
+
//#endregion
|
|
1676
|
+
//#region src/node/markdown-adapter.ts
|
|
1677
|
+
async function loadMarkdownAdapter(selection, cwd) {
|
|
1678
|
+
if (selection === "void") return createHonoMarkdownAdapter(cwd, true);
|
|
1679
|
+
if (selection.adapter === "hono-decks/adapters/hono-markdown") return createHonoMarkdownAdapter(cwd, false, selection.options);
|
|
1680
|
+
const module = await import(pathToFileURL(createRequire(resolve(cwd, "package.json")).resolve(selection.adapter)).href);
|
|
1681
|
+
if (typeof module.createMarkdownAdapter !== "function") throw new Error("Markdown adapter must export createMarkdownAdapter.");
|
|
1682
|
+
const adapter = await module.createMarkdownAdapter({
|
|
1683
|
+
cwd,
|
|
1684
|
+
options: selection.options
|
|
1685
|
+
});
|
|
1686
|
+
if (![
|
|
1687
|
+
adapter?.read,
|
|
1688
|
+
adapter?.compile,
|
|
1689
|
+
adapter?.client
|
|
1690
|
+
].every((value) => typeof value === "function")) throw new Error("Markdown adapter must provide read, compile and client functions.");
|
|
1691
|
+
return adapter;
|
|
1692
|
+
}
|
|
1693
|
+
//#endregion
|
|
1643
1694
|
//#region src/node/client-entry.ts
|
|
1644
1695
|
async function discoverClientComponentIds(input) {
|
|
1645
1696
|
const result = {};
|
|
@@ -1660,12 +1711,11 @@ async function emitClientEntryModule(input) {
|
|
|
1660
1711
|
registrations.push(`${JSON.stringify(clientId)}: ${localName}`);
|
|
1661
1712
|
}
|
|
1662
1713
|
}
|
|
1663
|
-
const
|
|
1664
|
-
if (registrations.length === 0 &&
|
|
1714
|
+
const clientModules = input.clientModules ?? [];
|
|
1715
|
+
if (registrations.length === 0 && clientModules.length === 0) return `export const decksClientEntry = ${JSON.stringify(input.extraCode ?? "")};\n`;
|
|
1665
1716
|
const result = await build({
|
|
1666
1717
|
stdin: {
|
|
1667
|
-
contents: `${
|
|
1668
|
-
hydrateMarkdownIslands({ ${markdown.map((entry) => `${javascriptString(entry.id)}: () => import(${javascriptString(entry.modulePath)})`).join(",")} });` : ""}
|
|
1718
|
+
contents: `${clientModules.join("\n")}
|
|
1669
1719
|
import { hydrateSlideIslands } from "hono-decks/client";
|
|
1670
1720
|
${imports.join("\n")}
|
|
1671
1721
|
|
|
@@ -1742,9 +1792,6 @@ function hashString(value) {
|
|
|
1742
1792
|
function safeIdentifier(value) {
|
|
1743
1793
|
return value.replace(/[^A-Za-z0-9_$]+/g, "_").replace(/^[^A-Za-z_$]+/, "_") || "_";
|
|
1744
1794
|
}
|
|
1745
|
-
function javascriptString(value) {
|
|
1746
|
-
return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
1747
|
-
}
|
|
1748
1795
|
//#endregion
|
|
1749
1796
|
//#region src/node/local-deck-io.ts
|
|
1750
1797
|
async function listFiles(cwd, dir) {
|
|
@@ -1952,7 +1999,7 @@ async function compileDeckModules(input) {
|
|
|
1952
1999
|
const out = normalizeRelativePath(input.out, "Output directory");
|
|
1953
2000
|
const root = normalizeDeckRoot(input.root);
|
|
1954
2001
|
const paths = await listFiles(input.cwd, join(input.cwd, root));
|
|
1955
|
-
const resolved = resolveDeckFiles(paths, root, { markdown: input.markdown
|
|
2002
|
+
const resolved = resolveDeckFiles(paths, root, { markdown: Boolean(input.markdown) });
|
|
1956
2003
|
const componentModulePaths = Object.fromEntries(resolved.flatMap((deck) => {
|
|
1957
2004
|
const path = deck.kind === "directory" ? findComponentModule(paths, root, deck.slug) : void 0;
|
|
1958
2005
|
return path ? [[deck.slug, path]] : [];
|
|
@@ -1980,7 +2027,8 @@ async function compileDeckModules(input) {
|
|
|
1980
2027
|
refresh: input.refreshOgp,
|
|
1981
2028
|
resolveOgp: input.resolveOgp ?? resolveOgpMetadata
|
|
1982
2029
|
});
|
|
1983
|
-
const
|
|
2030
|
+
const adapter = input.markdown && resolved.some((entry) => entry.sourcePath.endsWith(".md")) ? await loadMarkdownAdapter(input.markdown, input.cwd) : void 0;
|
|
2031
|
+
const generated = await (adapter ? (value) => compileMarkdownDecks(value, adapter) : compileMdxModuleDecks)({
|
|
1984
2032
|
cwd: input.cwd,
|
|
1985
2033
|
root,
|
|
1986
2034
|
outDir: out,
|
|
@@ -1999,7 +2047,7 @@ async function compileDeckModules(input) {
|
|
|
1999
2047
|
clientEntries: clientEntryPaths,
|
|
2000
2048
|
clientComponentIds,
|
|
2001
2049
|
extraCode: generated.clientCode,
|
|
2002
|
-
|
|
2050
|
+
clientModules: generated.clientModules,
|
|
2003
2051
|
onCss: (css) => {
|
|
2004
2052
|
clientCss = css;
|
|
2005
2053
|
}
|
|
@@ -2149,7 +2197,7 @@ async function loadDecksConfig(input) {
|
|
|
2149
2197
|
const config = (await import(`data:text/javascript;charset=utf-8,${encodeURIComponent(source)}#${Date.now()}`)).default;
|
|
2150
2198
|
if (!config || typeof config !== "object") throw new Error(`Config must have a default export: ${path}`);
|
|
2151
2199
|
if (typeof config.mountPath !== "string") throw new Error(`Config mountPath must be a string: ${path}`);
|
|
2152
|
-
if (config.build?.markdown !== void 0 && config.build.markdown !== "void") throw new Error("Config build.markdown must be \"void\".");
|
|
2200
|
+
if (config.build?.markdown !== void 0 && config.build.markdown !== "void" && (typeof config.build.markdown !== "object" || !config.build.markdown || typeof config.build.markdown.adapter !== "string" || !config.build.markdown.adapter.trim())) throw new Error("Config build.markdown must be \"void\" or an adapter reference.");
|
|
2153
2201
|
return {
|
|
2154
2202
|
path,
|
|
2155
2203
|
config,
|
|
@@ -2302,7 +2350,7 @@ async function runInitCommand(input, args, stdout, stderr) {
|
|
|
2302
2350
|
return { exitCode: 1 };
|
|
2303
2351
|
}
|
|
2304
2352
|
if (parsed.options.framework) try {
|
|
2305
|
-
const { initializeVite } = await import("./init-vite-
|
|
2353
|
+
const { initializeVite } = await import("./init-vite-F2gLT72s.js");
|
|
2306
2354
|
const sampleSlug = await initializeVite(input.cwd, parsed.options.framework, parsed.options.configFile, parsed.options.entry, parsed.options.install ? { adapter: parsed.options.adapter } : void 0);
|
|
2307
2355
|
stdout(`Initialized ${parsed.options.framework} decks at /slides/${sampleSlug}. Run your usual dev or build command; no manual compile is needed.`);
|
|
2308
2356
|
return { exitCode: 0 };
|
package/dist/cli.js
CHANGED
|
@@ -7,10 +7,10 @@ import { unified } from "unified";
|
|
|
7
7
|
import remarkGfm from "remark-gfm";
|
|
8
8
|
import remarkMdx from "remark-mdx";
|
|
9
9
|
import remarkParse from "remark-parse";
|
|
10
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
11
10
|
import { compile } from "@mdx-js/mdx";
|
|
12
11
|
import remarkDirective from "remark-directive";
|
|
13
12
|
import { codeToHtml } from "shiki";
|
|
13
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
14
14
|
import { build } from "esbuild";
|
|
15
15
|
import { lookup } from "node:dns/promises";
|
|
16
16
|
import { isIP } from "node:net";
|
|
@@ -1505,29 +1505,20 @@ function extractDeckPrelude(source) {
|
|
|
1505
1505
|
};
|
|
1506
1506
|
}
|
|
1507
1507
|
//#endregion
|
|
1508
|
-
//#region src/node/
|
|
1509
|
-
|
|
1510
|
-
async function compileVoidMarkdownDecks(input) {
|
|
1508
|
+
//#region src/node/markdown-decks.ts
|
|
1509
|
+
async function compileMarkdownDecks(input, adapter) {
|
|
1511
1510
|
const markdownEntries = input.decks.filter((entry) => entry.sourcePath.endsWith(".md"));
|
|
1512
1511
|
const mdx = await compileMdxModuleDecks({
|
|
1513
1512
|
...input,
|
|
1514
1513
|
decks: input.decks.filter((entry) => !entry.sourcePath.endsWith(".md"))
|
|
1515
1514
|
});
|
|
1516
1515
|
if (!markdownEntries.length) return mdx;
|
|
1517
|
-
let compiler;
|
|
1518
|
-
try {
|
|
1519
|
-
compiler = await import(pathToFileURL(createRequire(resolve(input.cwd ?? process.cwd(), "package.json")).resolve("void-plugin-hono-jsx/markdown/compiler")).href);
|
|
1520
|
-
if (typeof (compiler.compileMarkdownModule ?? compiler.compileStaticMarkdown) !== "function" || typeof (compiler.readMarkdownModule ?? compiler.readStaticMarkdown) !== "function") throw new Error("Missing standalone compiler API");
|
|
1521
|
-
} catch (error) {
|
|
1522
|
-
throw new Error("Void Markdown requires void-plugin-hono-jsx with the public /markdown/compiler API and its Markdown peers installed in the app.", { cause: error });
|
|
1523
|
-
}
|
|
1524
|
-
const readModule = compiler.readMarkdownModule ?? compiler.readStaticMarkdown;
|
|
1525
|
-
const compileModule = compiler.compileMarkdownModule ?? compiler.compileStaticMarkdown;
|
|
1526
1516
|
const decks = [...mdx.decks];
|
|
1527
1517
|
const clients = /* @__PURE__ */ new Set();
|
|
1528
1518
|
const markdownIslands = /* @__PURE__ */ new Map();
|
|
1529
1519
|
for (const entry of markdownEntries) try {
|
|
1530
|
-
const
|
|
1520
|
+
const source = await input.readText(entry.sourcePath);
|
|
1521
|
+
const parsed = adapter.read(source);
|
|
1531
1522
|
if (input.clientComponentIds?.[entry.slug] && Object.keys(input.clientComponentIds[entry.slug]).length) throw new Error("Void Markdown slides support static components only; use MDX for hono-decks client components.");
|
|
1532
1523
|
const warnings = [];
|
|
1533
1524
|
const meta = toDeckFrontmatter(parsed.frontmatter, warnings);
|
|
@@ -1548,12 +1539,13 @@ async function compileVoidMarkdownDecks(input) {
|
|
|
1548
1539
|
const slides = [];
|
|
1549
1540
|
for (const [index, slideSource] of splitMarkdownSlides(parsed.content).entries()) {
|
|
1550
1541
|
const prelude = parsed.script ? `<script>\n${parsed.script}\n<\/script>\n` : "";
|
|
1551
|
-
const slide =
|
|
1542
|
+
const slide = adapter.read(prelude + slideSource);
|
|
1552
1543
|
const path = `${input.outDir}/decks/${entry.slug}/slide-${index}.ts`;
|
|
1553
|
-
const
|
|
1544
|
+
const rewritten = rewriteAssetUrls(`${prelude}---\n${JSON.stringify({
|
|
1554
1545
|
...parsed.frontmatter,
|
|
1555
1546
|
...slide.frontmatter
|
|
1556
|
-
})}\n---\n${slide.content}`, assets)
|
|
1547
|
+
})}\n---\n${slide.content}`, assets);
|
|
1548
|
+
const result = await adapter.compile(rewritten, { sourcePath: resolve(input.cwd ?? process.cwd(), entry.sourcePath) });
|
|
1557
1549
|
clientEntryRequired ||= Boolean(result.clientCode || result.islands?.length);
|
|
1558
1550
|
if (result.clientCode) clients.add(result.clientCode);
|
|
1559
1551
|
for (const island of result.islands ?? []) markdownIslands.set(island.id, island);
|
|
@@ -1603,6 +1595,7 @@ async function compileVoidMarkdownDecks(input) {
|
|
|
1603
1595
|
decks,
|
|
1604
1596
|
routerModule: emitModuleDecksRouter({ decks }),
|
|
1605
1597
|
clientCode: [...clients].join("\n"),
|
|
1598
|
+
clientModules: [adapter.client([...markdownIslands.values()])].filter(Boolean),
|
|
1606
1599
|
markdownIslands: [...markdownIslands.values()]
|
|
1607
1600
|
};
|
|
1608
1601
|
}
|
|
@@ -1639,6 +1632,64 @@ function splitMarkdownSlides(source) {
|
|
|
1639
1632
|
return splitSlideSources(protectedLines.join("\n")).map((slide) => slide.replace(new RegExp(`${prefix}(\\d+)_END`, "g"), (_, id) => fences[Number(id)]));
|
|
1640
1633
|
}
|
|
1641
1634
|
//#endregion
|
|
1635
|
+
//#region src/adapters/hono-markdown.ts
|
|
1636
|
+
/** Node-only bridge. Existing Void configs retain their original compiler/runtime pair. */
|
|
1637
|
+
async function createHonoMarkdownAdapter(cwd, legacy = false, options) {
|
|
1638
|
+
const require = createRequire(resolve(cwd, "package.json"));
|
|
1639
|
+
const entry = legacy ? "void-plugin-hono-jsx/markdown/compiler" : "@ts-76/hono-markdown/compiler";
|
|
1640
|
+
let compiler;
|
|
1641
|
+
try {
|
|
1642
|
+
compiler = await import(pathToFileURL(require.resolve(entry)).href);
|
|
1643
|
+
} catch (cause) {
|
|
1644
|
+
throw new Error(`Hono Markdown requires ${legacy ? "its public /markdown/compiler API" : "@ts-76/hono-markdown/compiler"} and Markdown peers installed in the app.`, { cause });
|
|
1645
|
+
}
|
|
1646
|
+
const read = compiler.readMarkdownModule ?? compiler.readStaticMarkdown;
|
|
1647
|
+
const compile = compiler.compileMarkdownModule ?? compiler.compileStaticMarkdown;
|
|
1648
|
+
if (typeof read !== "function" || typeof compile !== "function") throw new Error("Missing standalone compiler API");
|
|
1649
|
+
const runtime = entry.startsWith("void-plugin") ? "void-plugin-hono-jsx/markdown/client" : "@ts-76/hono-markdown/client";
|
|
1650
|
+
return {
|
|
1651
|
+
read,
|
|
1652
|
+
compile: (source, input) => compile(source, {
|
|
1653
|
+
...input,
|
|
1654
|
+
options
|
|
1655
|
+
}),
|
|
1656
|
+
client: (islands) => emitMarkdownClient(islands, runtime)
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
function emitMarkdownClient(islands, runtime) {
|
|
1660
|
+
if (!islands.length) return "";
|
|
1661
|
+
const literal = (value) => JSON.stringify(value).replace(/</g, "\\u003c");
|
|
1662
|
+
return `import { hydrateMarkdownIslands } from ${literal(runtime)};
|
|
1663
|
+
hydrateMarkdownIslands({ ${islands.map((island) => `${literal(island.id)}: () => import(${literal(island.modulePath)})`).join(",")} }, {
|
|
1664
|
+
ready(element, start) {
|
|
1665
|
+
const slide = element.closest('section[data-slide-state]');
|
|
1666
|
+
if (!slide || slide.dataset.slideState === 'active') { start(); return; }
|
|
1667
|
+
const observer = new MutationObserver(() => {
|
|
1668
|
+
if (slide.dataset.slideState === 'active') { observer.disconnect(); start(); }
|
|
1669
|
+
});
|
|
1670
|
+
observer.observe(slide, { attributes: true, attributeFilter: ['data-slide-state'] });
|
|
1671
|
+
}
|
|
1672
|
+
});`;
|
|
1673
|
+
}
|
|
1674
|
+
//#endregion
|
|
1675
|
+
//#region src/node/markdown-adapter.ts
|
|
1676
|
+
async function loadMarkdownAdapter(selection, cwd) {
|
|
1677
|
+
if (selection === "void") return createHonoMarkdownAdapter(cwd, true);
|
|
1678
|
+
if (selection.adapter === "hono-decks/adapters/hono-markdown") return createHonoMarkdownAdapter(cwd, false, selection.options);
|
|
1679
|
+
const module = await import(pathToFileURL(createRequire(resolve(cwd, "package.json")).resolve(selection.adapter)).href);
|
|
1680
|
+
if (typeof module.createMarkdownAdapter !== "function") throw new Error("Markdown adapter must export createMarkdownAdapter.");
|
|
1681
|
+
const adapter = await module.createMarkdownAdapter({
|
|
1682
|
+
cwd,
|
|
1683
|
+
options: selection.options
|
|
1684
|
+
});
|
|
1685
|
+
if (![
|
|
1686
|
+
adapter?.read,
|
|
1687
|
+
adapter?.compile,
|
|
1688
|
+
adapter?.client
|
|
1689
|
+
].every((value) => typeof value === "function")) throw new Error("Markdown adapter must provide read, compile and client functions.");
|
|
1690
|
+
return adapter;
|
|
1691
|
+
}
|
|
1692
|
+
//#endregion
|
|
1642
1693
|
//#region src/node/client-entry.ts
|
|
1643
1694
|
async function discoverClientComponentIds(input) {
|
|
1644
1695
|
const result = {};
|
|
@@ -1659,12 +1710,11 @@ async function emitClientEntryModule(input) {
|
|
|
1659
1710
|
registrations.push(`${JSON.stringify(clientId)}: ${localName}`);
|
|
1660
1711
|
}
|
|
1661
1712
|
}
|
|
1662
|
-
const
|
|
1663
|
-
if (registrations.length === 0 &&
|
|
1713
|
+
const clientModules = input.clientModules ?? [];
|
|
1714
|
+
if (registrations.length === 0 && clientModules.length === 0) return `export const decksClientEntry = ${JSON.stringify(input.extraCode ?? "")};\n`;
|
|
1664
1715
|
const result = await build({
|
|
1665
1716
|
stdin: {
|
|
1666
|
-
contents: `${
|
|
1667
|
-
hydrateMarkdownIslands({ ${markdown.map((entry) => `${javascriptString(entry.id)}: () => import(${javascriptString(entry.modulePath)})`).join(",")} });` : ""}
|
|
1717
|
+
contents: `${clientModules.join("\n")}
|
|
1668
1718
|
import { hydrateSlideIslands } from "hono-decks/client";
|
|
1669
1719
|
${imports.join("\n")}
|
|
1670
1720
|
|
|
@@ -1741,9 +1791,6 @@ function hashString(value) {
|
|
|
1741
1791
|
function safeIdentifier(value) {
|
|
1742
1792
|
return value.replace(/[^A-Za-z0-9_$]+/g, "_").replace(/^[^A-Za-z_$]+/, "_") || "_";
|
|
1743
1793
|
}
|
|
1744
|
-
function javascriptString(value) {
|
|
1745
|
-
return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
1746
|
-
}
|
|
1747
1794
|
//#endregion
|
|
1748
1795
|
//#region src/node/local-deck-io.ts
|
|
1749
1796
|
async function listFiles(cwd, dir) {
|
|
@@ -1951,7 +1998,7 @@ async function compileDeckModules(input) {
|
|
|
1951
1998
|
const out = normalizeRelativePath(input.out, "Output directory");
|
|
1952
1999
|
const root = normalizeDeckRoot(input.root);
|
|
1953
2000
|
const paths = await listFiles(input.cwd, join(input.cwd, root));
|
|
1954
|
-
const resolved = resolveDeckFiles(paths, root, { markdown: input.markdown
|
|
2001
|
+
const resolved = resolveDeckFiles(paths, root, { markdown: Boolean(input.markdown) });
|
|
1955
2002
|
const componentModulePaths = Object.fromEntries(resolved.flatMap((deck) => {
|
|
1956
2003
|
const path = deck.kind === "directory" ? findComponentModule(paths, root, deck.slug) : void 0;
|
|
1957
2004
|
return path ? [[deck.slug, path]] : [];
|
|
@@ -1979,7 +2026,8 @@ async function compileDeckModules(input) {
|
|
|
1979
2026
|
refresh: input.refreshOgp,
|
|
1980
2027
|
resolveOgp: input.resolveOgp ?? resolveOgpMetadata
|
|
1981
2028
|
});
|
|
1982
|
-
const
|
|
2029
|
+
const adapter = input.markdown && resolved.some((entry) => entry.sourcePath.endsWith(".md")) ? await loadMarkdownAdapter(input.markdown, input.cwd) : void 0;
|
|
2030
|
+
const generated = await (adapter ? (value) => compileMarkdownDecks(value, adapter) : compileMdxModuleDecks)({
|
|
1983
2031
|
cwd: input.cwd,
|
|
1984
2032
|
root,
|
|
1985
2033
|
outDir: out,
|
|
@@ -1998,7 +2046,7 @@ async function compileDeckModules(input) {
|
|
|
1998
2046
|
clientEntries: clientEntryPaths,
|
|
1999
2047
|
clientComponentIds,
|
|
2000
2048
|
extraCode: generated.clientCode,
|
|
2001
|
-
|
|
2049
|
+
clientModules: generated.clientModules,
|
|
2002
2050
|
onCss: (css) => {
|
|
2003
2051
|
clientCss = css;
|
|
2004
2052
|
}
|
|
@@ -2148,7 +2196,7 @@ async function loadDecksConfig(input) {
|
|
|
2148
2196
|
const config = (await import(`data:text/javascript;charset=utf-8,${encodeURIComponent(source)}#${Date.now()}`)).default;
|
|
2149
2197
|
if (!config || typeof config !== "object") throw new Error(`Config must have a default export: ${path}`);
|
|
2150
2198
|
if (typeof config.mountPath !== "string") throw new Error(`Config mountPath must be a string: ${path}`);
|
|
2151
|
-
if (config.build?.markdown !== void 0 && config.build.markdown !== "void") throw new Error("Config build.markdown must be \"void\".");
|
|
2199
|
+
if (config.build?.markdown !== void 0 && config.build.markdown !== "void" && (typeof config.build.markdown !== "object" || !config.build.markdown || typeof config.build.markdown.adapter !== "string" || !config.build.markdown.adapter.trim())) throw new Error("Config build.markdown must be \"void\" or an adapter reference.");
|
|
2152
2200
|
return {
|
|
2153
2201
|
path,
|
|
2154
2202
|
config,
|
|
@@ -2301,7 +2349,7 @@ async function runInitCommand(input, args, stdout, stderr) {
|
|
|
2301
2349
|
return { exitCode: 1 };
|
|
2302
2350
|
}
|
|
2303
2351
|
if (parsed.options.framework) try {
|
|
2304
|
-
const { initializeVite } = await import("./init-vite-
|
|
2352
|
+
const { initializeVite } = await import("./init-vite-F2gLT72s.js");
|
|
2305
2353
|
const sampleSlug = await initializeVite(input.cwd, parsed.options.framework, parsed.options.configFile, parsed.options.entry, parsed.options.install ? { adapter: parsed.options.adapter } : void 0);
|
|
2306
2354
|
stdout(`Initialized ${parsed.options.framework} decks at /slides/${sampleSlug}. Run your usual dev or build command; no manual compile is needed.`);
|
|
2307
2355
|
return { exitCode: 0 };
|