@ishibashi0112/webview2-bridge-gen 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +12 -0
  2. package/dist/cli.js +62 -6
  3. package/dist/cli.js.map +1 -1
  4. package/dist/generate.d.ts +1 -0
  5. package/dist/generate.d.ts.map +1 -1
  6. package/dist/generate.js +1 -0
  7. package/dist/generate.js.map +1 -1
  8. package/dist/init.d.ts +32 -0
  9. package/dist/init.d.ts.map +1 -0
  10. package/dist/init.js +93 -0
  11. package/dist/init.js.map +1 -0
  12. package/package.json +6 -3
  13. package/template/README.md +10 -0
  14. package/template/myapp/README.md +91 -0
  15. package/template/myapp/_gitignore +6 -0
  16. package/template/myapp/contract/contract.schema.json +66 -0
  17. package/template/myapp/contract/contract.ts +8 -0
  18. package/template/myapp/dotnet/Directory.Build.props +10 -0
  19. package/template/myapp/dotnet/MyApp.Contract/Generated/Dispatcher.Generated.vb +30 -0
  20. package/template/myapp/dotnet/MyApp.Contract/Generated/Dto.vb +39 -0
  21. package/template/myapp/dotnet/MyApp.Contract/Generated/Events.vb +32 -0
  22. package/template/myapp/dotnet/MyApp.Contract/Generated/Interfaces.vb +20 -0
  23. package/template/myapp/dotnet/MyApp.Contract/MyApp.Contract.vbproj +9 -0
  24. package/template/myapp/dotnet/MyApp.Contract/Runtime/Dispatcher.vb +151 -0
  25. package/template/myapp/dotnet/MyApp.Contract/Runtime/IBridgeEmitter.vb +22 -0
  26. package/template/myapp/dotnet/MyApp.Contract/Runtime/JsonRpc.vb +130 -0
  27. package/template/myapp/dotnet/MyApp.Host/Bridge/WebViewBridge.vb +106 -0
  28. package/template/myapp/dotnet/MyApp.Host/MainForm.vb +90 -0
  29. package/template/myapp/dotnet/MyApp.Host/MyApp.Host.vbproj +28 -0
  30. package/template/myapp/dotnet/MyApp.Host/Program.vb +12 -0
  31. package/template/myapp/dotnet/MyApp.Impl/CustomersApi.vb +38 -0
  32. package/template/myapp/dotnet/MyApp.Impl/MyApp.Impl.vbproj +9 -0
  33. package/template/myapp/dotnet/MyApp.sln +34 -0
  34. package/template/myapp/package.json +16 -0
  35. package/template/myapp/pnpm-workspace.yaml +6 -0
  36. package/template/myapp/web/index.html +13 -0
  37. package/template/myapp/web/package.json +23 -0
  38. package/template/myapp/web/src/bridge.ts +29 -0
  39. package/template/myapp/web/src/generated/contract-types.ts +33 -0
  40. package/template/myapp/web/src/main.tsx +37 -0
  41. package/template/myapp/web/src/vite-env.d.ts +6 -0
  42. package/template/myapp/web/tsconfig.json +8 -0
  43. package/template/myapp/web/vite.config.ts +17 -0
  44. package/template/myapp/webview2-bridge.gen.json +11 -0
@@ -0,0 +1,34 @@
1
+ 
2
+ Microsoft Visual Studio Solution File, Format Version 12.00
3
+ # Visual Studio Version 17
4
+ VisualStudioVersion = 17.0.31903.59
5
+ MinimumVisualStudioVersion = 10.0.40219.1
6
+ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "MyApp.Contract", "MyApp.Contract\MyApp.Contract.vbproj", "{9113F13B-E3F8-43BE-B184-7DA5F4E71CC8}"
7
+ EndProject
8
+ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "MyApp.Impl", "MyApp.Impl\MyApp.Impl.vbproj", "{8F20CF7D-8898-4C92-937C-7A4F5A615C38}"
9
+ EndProject
10
+ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "MyApp.Host", "MyApp.Host\MyApp.Host.vbproj", "{2C185B08-450B-4660-893D-AFD11D214B13}"
11
+ EndProject
12
+ Global
13
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
14
+ Debug|Any CPU = Debug|Any CPU
15
+ Release|Any CPU = Release|Any CPU
16
+ EndGlobalSection
17
+ GlobalSection(SolutionProperties) = preSolution
18
+ HideSolutionNode = FALSE
19
+ EndGlobalSection
20
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
21
+ {9113F13B-E3F8-43BE-B184-7DA5F4E71CC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22
+ {9113F13B-E3F8-43BE-B184-7DA5F4E71CC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
23
+ {9113F13B-E3F8-43BE-B184-7DA5F4E71CC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
24
+ {9113F13B-E3F8-43BE-B184-7DA5F4E71CC8}.Release|Any CPU.Build.0 = Release|Any CPU
25
+ {8F20CF7D-8898-4C92-937C-7A4F5A615C38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26
+ {8F20CF7D-8898-4C92-937C-7A4F5A615C38}.Debug|Any CPU.Build.0 = Debug|Any CPU
27
+ {8F20CF7D-8898-4C92-937C-7A4F5A615C38}.Release|Any CPU.ActiveCfg = Release|Any CPU
28
+ {8F20CF7D-8898-4C92-937C-7A4F5A615C38}.Release|Any CPU.Build.0 = Release|Any CPU
29
+ {2C185B08-450B-4660-893D-AFD11D214B13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30
+ {2C185B08-450B-4660-893D-AFD11D214B13}.Debug|Any CPU.Build.0 = Debug|Any CPU
31
+ {2C185B08-450B-4660-893D-AFD11D214B13}.Release|Any CPU.ActiveCfg = Release|Any CPU
32
+ {2C185B08-450B-4660-893D-AFD11D214B13}.Release|Any CPU.Build.0 = Release|Any CPU
33
+ EndGlobalSection
34
+ EndGlobal
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "myapp",
3
+ "private": true,
4
+ "type": "module",
5
+ "packageManager": "pnpm@11.18.0",
6
+ "scripts": {
7
+ "gen": "webview2-bridge-gen",
8
+ "gen:check": "webview2-bridge-gen --check",
9
+ "dev": "pnpm --filter web dev",
10
+ "build:web": "pnpm --filter web build"
11
+ },
12
+ "devDependencies": {
13
+ "@ishibashi0112/webview2-bridge-gen": "^0.3.0",
14
+ "zod": "^4.5.4"
15
+ }
16
+ }
@@ -0,0 +1,6 @@
1
+ packages:
2
+ - web
3
+
4
+ # gen が使う tsx は esbuild に依存する。pnpm 11 は postinstall を既定で止めるので許可が必要
5
+ allowBuilds:
6
+ esbuild: true
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" href="data:," />
7
+ <title>MyApp</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="./src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "web",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "vite",
7
+ "build": "tsc --noEmit -p tsconfig.json && vite build",
8
+ "typecheck": "tsc --noEmit -p tsconfig.json"
9
+ },
10
+ "dependencies": {
11
+ "@ishibashi0112/webview2-bridge-client": "^0.3.0",
12
+ "react": "^19.2.8",
13
+ "react-dom": "^19.2.8",
14
+ "zod": "^4.5.4"
15
+ },
16
+ "devDependencies": {
17
+ "@types/react": "^19.2.18",
18
+ "@types/react-dom": "^19.2.7",
19
+ "@vitejs/plugin-react": "^6.1.1",
20
+ "typescript": "^5.9.3",
21
+ "vite": "^8.2.2"
22
+ }
23
+ }
@@ -0,0 +1,29 @@
1
+ import { MemoryTransport, createClient, selectTransport, type MemoryHandlers } from "@ishibashi0112/webview2-bridge-client";
2
+ import { contract, type Contract } from "../../contract/contract";
3
+
4
+ // ブラウザ単体(pnpm dev)で動かすためのモック。VB 側 CustomersApi と振る舞いを揃える
5
+ const customers = [
6
+ { id: "1", name: "山田商事" },
7
+ { id: "2", name: "佐藤工業" },
8
+ { id: "3", name: "鈴木電機" },
9
+ ];
10
+ const handlers: MemoryHandlers<Contract> = {
11
+ customers: {
12
+ list: async (input, { emit }) => {
13
+ emit("progress", { percent: 0 });
14
+ await new Promise((r) => setTimeout(r, 100));
15
+ const kw = input.keyword ?? "";
16
+ emit("progress", { percent: 100 });
17
+ return { items: customers.filter((c) => c.name.includes(kw)) };
18
+ },
19
+ },
20
+ };
21
+
22
+ // window.chrome.webview があれば WebView2(VB ホスト内)、なければ VITE_TRANSPORT(既定 memory)
23
+ const selected = selectTransport({
24
+ mode: import.meta.env.VITE_TRANSPORT,
25
+ factories: { memory: () => new MemoryTransport<Contract>(handlers, { delay: 50 }) },
26
+ });
27
+
28
+ export const transportMode = selected.mode;
29
+ export const client = createClient(contract, selected.transport);
@@ -0,0 +1,33 @@
1
+ // <auto-generated>
2
+ // This code was generated by @ishibashi0112/webview2-bridge-gen from contract.schema.json.
3
+ // DO NOT EDIT. Changes will be lost when `pnpm gen` runs.
4
+ // </auto-generated>
5
+ import type { z } from "zod";
6
+ import type { contract } from "../../../contract/contract";
7
+
8
+ type C = typeof contract;
9
+
10
+ // ---- methods
11
+ /** `customers.list` の入力 */
12
+ export type CustomersListInput = z.input<C["methods"]["customers"]["list"]["input"]>;
13
+ /** `customers.list` の出力 */
14
+ export type CustomersListOutput = z.output<C["methods"]["customers"]["list"]["output"]>;
15
+
16
+ // ---- events
17
+ /** `event.progress` のペイロード */
18
+ export type ProgressEvent = z.output<C["events"]["progress"]>;
19
+
20
+ // ---- named types (.meta({ id }))
21
+ export type Customer = CustomersListOutput["items"][number];
22
+
23
+ // ---- maps
24
+ export interface MethodMap {
25
+ "customers.list": { input: CustomersListInput; output: CustomersListOutput };
26
+ }
27
+ export interface EventMap {
28
+ "progress": ProgressEvent;
29
+ }
30
+ export type MethodName = keyof MethodMap;
31
+ export type EventName = keyof EventMap;
32
+ export const methodNames = ["customers.list"] as const;
33
+ export const eventNames = ["progress"] as const;
@@ -0,0 +1,37 @@
1
+ import { useEffect, useState } from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import { client, transportMode } from "./bridge";
4
+ import type { Customer } from "./generated/contract-types";
5
+
6
+ function App() {
7
+ const [keyword, setKeyword] = useState("");
8
+ const [items, setItems] = useState<Customer[]>([]);
9
+ const [percent, setPercent] = useState<number | null>(null);
10
+ const [error, setError] = useState<string | null>(null);
11
+
12
+ // Host → Web のイベント(VB の BridgeEvents.Progress)
13
+ useEffect(() => client.events.on("progress", (p) => setPercent(p.percent)), []);
14
+
15
+ const search = async () => {
16
+ setError(null);
17
+ try {
18
+ const res = await client.customers.list({ keyword: keyword || undefined });
19
+ setItems(res.items);
20
+ } catch (e) {
21
+ setError(String(e));
22
+ }
23
+ };
24
+
25
+ return (
26
+ <div style={{ fontFamily: "sans-serif", padding: 16 }}>
27
+ <p>transport: <b>{transportMode}</b></p>
28
+ <input value={keyword} onChange={(e) => setKeyword(e.target.value)} placeholder="keyword" />
29
+ <button onClick={search}>customers.list</button>
30
+ {percent !== null && <span style={{ marginLeft: 8 }}>{percent}%</span>}
31
+ {error && <p style={{ color: "red" }}>{error}</p>}
32
+ <ul>{items.map((c) => <li key={c.id}>{c.id}: {c.name}</li>)}</ul>
33
+ </div>
34
+ );
35
+ }
36
+
37
+ createRoot(document.getElementById("root")!).render(<App />);
@@ -0,0 +1,6 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ /** transport の明示指定: "memory" | "webview2"。未指定なら自動(WebView2 内なら webview2、それ以外は memory) */
5
+ readonly VITE_TRANSPORT?: string;
6
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022", "module": "ESNext", "moduleResolution": "bundler",
4
+ "strict": true, "esModuleInterop": true, "skipLibCheck": true, "isolatedModules": true,
5
+ "lib": ["ES2022", "DOM", "DOM.Iterable"], "jsx": "react-jsx", "types": ["vite/client"], "noEmit": true
6
+ },
7
+ "include": ["src", "vite.config.ts", "../contract"]
8
+ }
@@ -0,0 +1,17 @@
1
+ import react from "@vitejs/plugin-react";
2
+ import { defineConfig } from "vite";
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ // 仮想ホスト(https://app.local/index.html)や exe 隣のフォルダから読むため、相対パスで出力する
7
+ base: "./",
8
+ server: {
9
+ port: 5173,
10
+ strictPort: true,
11
+ },
12
+ build: {
13
+ outDir: "dist",
14
+ emptyOutDir: true,
15
+ sourcemap: true,
16
+ },
17
+ });
@@ -0,0 +1,11 @@
1
+ {
2
+ "contract": "contract/contract.ts",
3
+ "schemaOut": "contract/contract.schema.json",
4
+ "ts": { "outDir": "web/src/generated", "contractImport": "../../../contract/contract" },
5
+ "vb": {
6
+ "outDir": "dotnet/MyApp.Contract/Generated",
7
+ "namespace": "MyApp.Contract",
8
+ "runtime": { "outDir": "dotnet/MyApp.Contract/Runtime" },
9
+ "winforms": { "outDir": "dotnet/MyApp.Host/Bridge" }
10
+ }
11
+ }