@jtfmumm/patchwork-standalone-frame 0.2.0 → 0.3.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.md CHANGED
@@ -1,34 +1,184 @@
1
1
  # @jtfmumm/patchwork-standalone-frame
2
2
 
3
- A reusable standalone frame for patchwork tools. Provides keyhive initialization, repo setup, doc history, access control, top bar UI, and sharing modals.
3
+ A standalone frame for patchwork tools. Provides repo setup, doc history, top bar UI, sharing modals, and optional keyhive access control.
4
4
 
5
- ## Usage
5
+ ## Quick start: standalone app from an automerge tool
6
6
 
7
+ This guide walks through building a standalone web app from a patchwork tool published as an automerge FolderDoc.
8
+
9
+ ### Prerequisites
10
+
11
+ - Node.js 18+
12
+ - pnpm
13
+
14
+ ### 1. Create the project
15
+
16
+ ```
17
+ mkdir my-standalone-app && cd my-standalone-app
18
+ pnpm init
19
+ ```
20
+
21
+ ### 2. Install dependencies
22
+
23
+ ```
24
+ pnpm add @jtfmumm/patchwork-standalone-frame \
25
+ @automerge/automerge @automerge/automerge-repo \
26
+ @automerge/automerge-repo-network-websocket \
27
+ @automerge/automerge-repo-storage-indexeddb \
28
+ solid-js
29
+
30
+ pnpm add -D @jtfmumm/automerge-deps @jtfmumm/patchwork-standalone-vite vite
31
+ ```
32
+
33
+ ### 3. Configure automerge-deps
34
+
35
+ Create `automerge-deps.json` to specify the tool and sync server:
36
+
37
+ ```json
38
+ {
39
+ "syncServers": ["wss://your-sync-server.example.com"],
40
+ "dependencies": [
41
+ { "name": "my-tool", "url": "automerge:<tool-url>" }
42
+ ]
43
+ }
44
+ ```
45
+
46
+ ### 4. Fetch the tool
47
+
48
+ ```
49
+ npx automerge-deps install
50
+ ```
51
+
52
+ This downloads the tool's FolderDoc from the sync server and writes it to `node_modules/my-tool/`.
53
+
54
+ ### 5. Create the entry point
55
+
56
+ **`src/main.ts`**
57
+ ```typescript
58
+ import { Repo } from "@automerge/automerge-repo";
59
+ import { IndexedDBStorageAdapter } from "@automerge/automerge-repo-storage-indexeddb";
60
+ import { BrowserWebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket";
61
+ import { mountStandaloneApp } from "@jtfmumm/patchwork-standalone-frame";
62
+ import { plugins } from "my-tool";
63
+
64
+ const repo = new Repo({
65
+ storage: new IndexedDBStorageAdapter(),
66
+ network: [new BrowserWebSocketClientAdapter("wss://your-sync-server.example.com")],
67
+ });
68
+
69
+ const root = document.getElementById("root");
70
+ if (root) {
71
+ mountStandaloneApp(root, plugins, { legacyMode: true, repo });
72
+ }
73
+ ```
74
+
75
+ ### 6. Create the HTML shell
76
+
77
+ **`index.html`**
78
+ ```html
79
+ <!doctype html>
80
+ <html lang="en">
81
+ <head>
82
+ <meta charset="UTF-8" />
83
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
84
+ <title>My Tool</title>
85
+ <style>
86
+ * { margin: 0; padding: 0; }
87
+ html, body, #root { height: 100%; }
88
+ </style>
89
+ </head>
90
+ <body>
91
+ <div id="root"></div>
92
+ <script type="module" src="/src/main.ts"></script>
93
+ </body>
94
+ </html>
95
+ ```
96
+
97
+ ### 7. Configure Vite
98
+
99
+ **`vite.config.ts`**
7
100
  ```typescript
8
- import { mountStandaloneApp, type ToolRegistration } from "@jtfmumm/patchwork-standalone-frame";
101
+ import { defineConfig } from "vite";
102
+ import { patchworkStandalone } from "@jtfmumm/patchwork-standalone-vite";
103
+
104
+ export default defineConfig({
105
+ plugins: [patchworkStandalone({ tools: ["my-tool"] })],
106
+ });
107
+ ```
108
+
109
+ The `tools` option lists tool packages fetched by `automerge-deps`. This enables serving of the tool's code-split chunks during development.
110
+
111
+ ### 8. Add scripts to package.json
112
+
113
+ ```json
114
+ {
115
+ "scripts": {
116
+ "fetch-deps": "automerge-deps install",
117
+ "dev": "vite",
118
+ "build": "pnpm fetch-deps && vite build",
119
+ "preview": "vite preview"
120
+ }
121
+ }
122
+ ```
123
+
124
+ ### 9. Run
125
+
126
+ ```
127
+ pnpm dev
128
+ ```
129
+
130
+ For production builds:
131
+
132
+ ```
133
+ pnpm build
134
+ pnpm preview
135
+ ```
136
+
137
+ ## API
9
138
 
139
+ ### `mountStandaloneApp(root, toolOrPlugins, config?)`
140
+
141
+ Mounts the standalone frame into a DOM element.
142
+
143
+ - **`root`** — the HTML element to mount into
144
+ - **`toolOrPlugins`** — either a `ToolRegistration<D>` object or a `Plugin<D>[]` array (patchwork plugin convention)
145
+ - **`config`** — optional `StandaloneFrameConfig`
146
+
147
+ ### ToolRegistration
148
+
149
+ For tools that don't use the patchwork plugin convention:
150
+
151
+ ```typescript
10
152
  const myTool: ToolRegistration<MyDoc> = {
11
- id: "my-tool", // matches @patchwork.type
12
- name: "My Tool", // display name
13
- defaultTitle: "Untitled", // placeholder for new docs
14
- init: (doc, repo) => {
15
- // Initialize a blank document
16
- },
153
+ id: "my-tool",
154
+ name: "My Tool",
155
+ defaultTitle: "Untitled",
156
+ init: (doc, repo) => { /* initialize a blank document */ },
17
157
  getTitle: (doc) => doc.title || "Untitled",
18
158
  setTitle: (doc, title) => { doc.title = title; },
19
- isDocReady: (doc) => !!doc?.title,
20
- render: (handle, element) => {
21
- // Mount your UI into `element`, return a cleanup function
22
- },
159
+ render: (handle, element) => { /* mount UI, return cleanup function */ },
23
160
  };
24
161
 
25
- const root = document.getElementById("root");
26
- if (root) mountStandaloneApp(root, myTool);
162
+ mountStandaloneApp(root, myTool);
27
163
  ```
28
164
 
29
- ## Sync server
165
+ ### Plugin convention
166
+
167
+ Tools that export a `plugins` array with `patchwork:tool` and `patchwork:datatype` entries can be passed directly:
168
+
169
+ ```typescript
170
+ import { plugins } from "my-tool";
171
+ mountStandaloneApp(root, plugins);
172
+ ```
173
+
174
+ ### Legacy mode
175
+
176
+ Pass `{ legacyMode: true, repo }` to use a plain automerge repo without keyhive. You construct and configure the repo yourself. This is the recommended approach for standalone deployments.
177
+
178
+ ### Keyhive mode (default)
179
+
180
+ When `legacyMode` is not set, the frame initializes keyhive automatically, including WASM loading, repo creation, and access control. The sync server URL is resolved in this order:
30
181
 
31
- The sync server URL is resolved in this order:
32
182
  1. `VITE_SYNC_URL` environment variable
33
183
  2. `tool.syncUrl` from the registration
34
184
  3. `ws://localhost:3030` (default)
package/dist/index.d.ts CHANGED
@@ -34,6 +34,8 @@ export interface StandaloneFrameConfig {
34
34
  legacyMode?: boolean;
35
35
  /** Pre-built repo for legacy mode. Required when legacyMode is true. */
36
36
  repo?: FrameRepo;
37
+ /** WebSocket sync server URL. Overrides tool.syncUrl. */
38
+ syncUrl?: string;
37
39
  }
38
40
  export interface PluginDescription {
39
41
  id: string;