@jtfmumm/patchwork-standalone-frame 0.4.1 → 0.4.3

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 (2) hide show
  1. package/README.md +138 -89
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,25 +2,146 @@
2
2
 
3
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
- ## Quick start: standalone app from an automerge tool
5
+ ## Quick start
6
6
 
7
- This guide walks through building a standalone web app from a patchwork tool published as an automerge FolderDoc.
7
+ Scaffold a new project:
8
8
 
9
- ### Prerequisites
9
+ ```
10
+ pnpm create @jtfmumm/patchwork-standalone
11
+ ```
12
+
13
+ This prompts for your tool name, automerge URL, sync server, and mode (legacy or keyhive), then generates a ready-to-run project. After scaffolding:
10
14
 
11
- - Node.js 18+
12
- - pnpm
15
+ ```
16
+ cd my-standalone-app
17
+ pnpm install
18
+ pnpm build
19
+ ```
13
20
 
14
- ### 1. Create the project
21
+ For development:
15
22
 
16
23
  ```
17
- mkdir my-standalone-app && cd my-standalone-app
18
- pnpm init
24
+ pnpm dev
25
+ ```
26
+
27
+ ## How it works
28
+
29
+ The standalone frame takes a patchwork tool and wraps it in an app shell with document management. You need three packages:
30
+
31
+ - **`@jtfmumm/patchwork-standalone-frame`**: the frame itself
32
+ - **`@jtfmumm/automerge-deps`**: fetches tool modules from a sync server at build time
33
+ - **`@jtfmumm/patchwork-standalone-vite`**: Vite plugin handling build configuration
34
+
35
+ Tools are published as automerge FolderDocs. `automerge-deps install` downloads them into `node_modules/` so they work like normal dependencies.
36
+
37
+ ## API
38
+
39
+ ### `mountStandaloneApp(root, toolOrPlugins, config?)`
40
+
41
+ Mounts the standalone frame into a DOM element.
42
+
43
+ - **`root`**: the HTML element to mount into
44
+ - **`toolOrPlugins`**: either a `ToolRegistration<D>` object or a `Plugin<D>[]` array (patchwork plugin convention)
45
+ - **`config`**: optional `StandaloneFrameConfig`
46
+
47
+ ### Plugin convention
48
+
49
+ Tools that export a `plugins` array with `patchwork:tool` and `patchwork:datatype` entries can be passed directly:
50
+
51
+ ```typescript
52
+ import { plugins } from "my-tool";
53
+ mountStandaloneApp(root, plugins);
54
+ ```
55
+
56
+ ### ToolRegistration
57
+
58
+ For tools that don't use the plugin convention:
59
+
60
+ ```typescript
61
+ const myTool: ToolRegistration<MyDoc> = {
62
+ id: "my-tool",
63
+ name: "My Tool",
64
+ defaultTitle: "Untitled",
65
+ init: (doc, repo) => { /* initialize a blank document */ },
66
+ getTitle: (doc) => doc.title || "Untitled",
67
+ setTitle: (doc, title) => { doc.title = title; },
68
+ render: (handle, element) => { /* mount UI, return cleanup function */ },
69
+ };
70
+
71
+ mountStandaloneApp(root, myTool);
72
+ ```
73
+
74
+ ### Legacy mode
75
+
76
+ Pass `{ legacyMode: true, repo }` to use a plain automerge repo without keyhive. You construct and configure the repo yourself.
77
+
78
+ ```typescript
79
+ import { Repo } from "@automerge/automerge-repo";
80
+ import { IndexedDBStorageAdapter } from "@automerge/automerge-repo-storage-indexeddb";
81
+ import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket";
82
+ import { mountStandaloneApp } from "@jtfmumm/patchwork-standalone-frame";
83
+ import { plugins } from "my-tool";
84
+
85
+ const repo = new Repo({
86
+ storage: new IndexedDBStorageAdapter(),
87
+ network: [new WebSocketClientAdapter("wss://your-sync-server.example.com")],
88
+ });
89
+
90
+ const root = document.getElementById("root");
91
+ if (root) {
92
+ mountStandaloneApp(root, plugins, { legacyMode: true, repo });
93
+ }
94
+ ```
95
+
96
+ ### Keyhive mode (default)
97
+
98
+ When `legacyMode` is not set, the frame initializes keyhive automatically, including WASM loading, repo creation, and access control. You don't need to create a repo yourself.
99
+
100
+ Keyhive mode requires one additional dependency:
101
+
102
+ ```
103
+ pnpm add @automerge/automerge-repo-keyhive
104
+ ```
105
+
106
+ Then your entry point is simpler, with no repo setup needed:
107
+
108
+ ```typescript
109
+ import { mountStandaloneApp } from "@jtfmumm/patchwork-standalone-frame";
110
+ import { plugins } from "my-tool";
111
+
112
+ const root = document.getElementById("root");
113
+ if (root) {
114
+ mountStandaloneApp(root, plugins, {
115
+ syncUrl: "wss://your-keyhive-sync-server.example.com",
116
+ });
117
+ }
19
118
  ```
20
119
 
21
- ### 2. Install dependencies
120
+ ### Config options
121
+
122
+ | Option | Description |
123
+ |--------|-------------|
124
+ | `legacyMode` | Use plain automerge docs without keyhive. Default: `false` |
125
+ | `repo` | Pre-built repo for legacy mode. Required when `legacyMode` is `true` |
126
+ | `syncUrl` | WebSocket sync server URL for keyhive mode |
127
+
128
+ The sync server URL is resolved in this order:
129
+
130
+ 1. `config.syncUrl`
131
+ 2. `VITE_SYNC_URL` environment variable
132
+ 3. `tool.syncUrl` from the registration
133
+ 4. `ws://localhost:3030` (default)
134
+
135
+ ## Manual setup
136
+
137
+ If you prefer to set up a project manually instead of using the scaffolder, here are the steps:
138
+
139
+ ### 1. Create the project and install dependencies
22
140
 
23
141
  ```
142
+ mkdir my-standalone-app && cd my-standalone-app
143
+ pnpm init
144
+
24
145
  pnpm add @jtfmumm/patchwork-standalone-frame \
25
146
  @automerge/automerge @automerge/automerge-repo \
26
147
  @automerge/automerge-repo-network-websocket \
@@ -30,7 +151,7 @@ pnpm add @jtfmumm/patchwork-standalone-frame \
30
151
  pnpm add -D @jtfmumm/automerge-deps @jtfmumm/patchwork-standalone-vite vite
31
152
  ```
32
153
 
33
- ### 3. Configure automerge-deps
154
+ ### 2. Configure automerge-deps
34
155
 
35
156
  Create `automerge-deps.json` to specify the tool and sync server for fetching the tool:
36
157
 
@@ -43,17 +164,15 @@ Create `automerge-deps.json` to specify the tool and sync server for fetching th
43
164
  }
44
165
  ```
45
166
 
46
- ### 4. Fetch the tool
167
+ ### 3. Fetch the tool
47
168
 
48
169
  ```
49
170
  npx automerge-deps install
50
171
  ```
51
172
 
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
173
+ ### 4. Create the entry point
55
174
 
56
- **`src/main.ts`**
175
+ **`src/main.ts`** (legacy mode shown; see keyhive mode above for the alternative)
57
176
  ```typescript
58
177
  import { Repo } from "@automerge/automerge-repo";
59
178
  import { IndexedDBStorageAdapter } from "@automerge/automerge-repo-storage-indexeddb";
@@ -72,7 +191,7 @@ if (root) {
72
191
  }
73
192
  ```
74
193
 
75
- ### 6. Create the HTML shell
194
+ ### 5. Create the HTML shell
76
195
 
77
196
  **`index.html`**
78
197
  ```html
@@ -94,7 +213,7 @@ if (root) {
94
213
  </html>
95
214
  ```
96
215
 
97
- ### 7. Configure Vite
216
+ ### 6. Configure Vite
98
217
 
99
218
  **`vite.config.ts`**
100
219
  ```typescript
@@ -106,9 +225,7 @@ export default defineConfig({
106
225
  });
107
226
  ```
108
227
 
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
228
+ ### 7. Add scripts to package.json
112
229
 
113
230
  ```json
114
231
  {
@@ -121,7 +238,7 @@ The `tools` option lists tool packages fetched by `automerge-deps`. This enables
121
238
  }
122
239
  ```
123
240
 
124
- ### 9. Run
241
+ ### 8. Run
125
242
 
126
243
  ```
127
244
  pnpm dev
@@ -133,71 +250,3 @@ For production builds:
133
250
  pnpm build
134
251
  pnpm preview
135
252
  ```
136
-
137
- ## API
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
152
- const myTool: ToolRegistration<MyDoc> = {
153
- id: "my-tool",
154
- name: "My Tool",
155
- defaultTitle: "Untitled",
156
- init: (doc, repo) => { /* initialize a blank document */ },
157
- getTitle: (doc) => doc.title || "Untitled",
158
- setTitle: (doc, title) => { doc.title = title; },
159
- render: (handle, element) => { /* mount UI, return cleanup function */ },
160
- };
161
-
162
- mountStandaloneApp(root, myTool);
163
- ```
164
-
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.
181
-
182
- ```typescript
183
- import { plugins } from "my-tool";
184
-
185
- mountStandaloneApp(root, plugins, {
186
- syncUrl: "wss://your-keyhive-sync-server.example.com",
187
- });
188
- ```
189
-
190
- ### Config options
191
-
192
- | Option | Description |
193
- |--------|-------------|
194
- | `legacyMode` | Use plain automerge docs without keyhive. Default: `false` |
195
- | `repo` | Pre-built repo for legacy mode. Required when `legacyMode` is `true` |
196
- | `syncUrl` | WebSocket sync server URL for keyhive mode |
197
-
198
- The sync server URL is resolved in this order:
199
-
200
- 1. `config.syncUrl`
201
- 2. `VITE_SYNC_URL` environment variable
202
- 3. `tool.syncUrl` from the registration
203
- 4. `ws://localhost:3030` (default)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jtfmumm/patchwork-standalone-frame",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Reusable standalone frame for patchwork tools with keyhive, doc history, and access control",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",