@inkandswitch/patchwork-bootloader 0.4.4 → 0.5.2
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 +38 -0
- package/dist/automerge-worker.js +8 -18
- package/dist/externals-list.d.ts +5 -0
- package/dist/externals-list.js +41 -0
- package/dist/externals.d.ts +14 -3
- package/dist/externals.js +50 -38
- package/dist/global.css +30 -0
- package/dist/service-worker.js +5 -1
- package/dist/sync-config.d.ts +1 -1
- package/dist/sync-config.js +3 -1
- package/package.json +20 -14
- package/src/automerge-worker.ts +16 -23
- package/src/externals-list.ts +43 -0
- package/src/externals.ts +64 -38
- package/src/global.css +30 -0
- package/src/service-worker.ts +6 -1
- package/src/sync-config.ts +6 -1
- package/dist/site.d.ts +0 -96
- package/dist/site.js +0 -517
- package/dist/vite/importmap-plugin.d.ts +0 -4
- package/dist/vite/importmap-plugin.js +0 -101
- package/dist/vite/patchwork-plugin.d.ts +0 -14
- package/dist/vite/patchwork-plugin.js +0 -8
- package/dist/vite/service-worker-plugin.d.ts +0 -2
- package/dist/vite/service-worker-plugin.js +0 -42
- package/src/site.ts +0 -797
- package/src/vite/importmap-plugin.ts +0 -129
- package/src/vite/patchwork-plugin.ts +0 -20
- package/src/vite/service-worker-plugin.ts +0 -46
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @inkandswitch/patchwork-bootloader
|
|
2
2
|
|
|
3
|
+
## 0.5.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f00dcb8: Add `repository` metadata pointing at inkandswitch/patchwork-system, so npm links each package to its source directory and can attest provenance when published from CI.
|
|
8
|
+
- Updated dependencies [f00dcb8]
|
|
9
|
+
- @inkandswitch/patchwork-filesystem@0.2.5
|
|
10
|
+
- @inkandswitch/patchwork-elements@4.0.4
|
|
11
|
+
- @inkandswitch/patchwork-plugins@1.0.3
|
|
12
|
+
|
|
13
|
+
## 0.5.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 5f70c14: Add `repository` metadata pointing at inkandswitch/patchwork-next, so npm links each package to its source directory and can attest provenance when published from CI.
|
|
18
|
+
- Updated dependencies [5f70c14]
|
|
19
|
+
- @inkandswitch/patchwork-filesystem@0.2.4
|
|
20
|
+
- @inkandswitch/patchwork-elements@4.0.3
|
|
21
|
+
- @inkandswitch/patchwork-plugins@1.0.2
|
|
22
|
+
|
|
23
|
+
## 0.5.0
|
|
24
|
+
|
|
25
|
+
### Minor Changes
|
|
26
|
+
|
|
27
|
+
- bd63259: Move the site boot sequence and the vite plugin out to `@inkandswitch/patchwork`. The `./site` and `./vite` exports are gone; import from `@inkandswitch/patchwork` and `@inkandswitch/patchwork/vite` instead.
|
|
28
|
+
|
|
29
|
+
Split the externals list into `./externals-list` so the list can be read without pulling in node builtins, and export `resolveExternal` and the wasm asset emitter so another package's vite plugin can resolve the bootloader's own dependencies from the bootloader's `node_modules`. Export `./global.css` and `./module-loader`.
|
|
30
|
+
|
|
31
|
+
Fall back to a url-keyed cache lookup in the service worker when the request-keyed one misses, so a cors request (the wasm `<link rel=preload crossorigin>`) still hits the cache offline.
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- 0aa315d: Configure Subduction or Keyhive with exclusive `syncServers` configuration. `syncServers.keyhive` replaces the `keyhive` and `keyhiveSyncServer` site options and the runtime `setup({ keyhive })` option. Selecting a named ARK relay or providing a custom relay identity and URL enables Keyhive, and configured server URLs now control worker connections as well as connection hints.
|
|
36
|
+
- Updated dependencies [bd63259]
|
|
37
|
+
- Updated dependencies [bd63259]
|
|
38
|
+
- @inkandswitch/patchwork-elements@4.0.2
|
|
39
|
+
- @inkandswitch/patchwork-filesystem@0.2.3
|
|
40
|
+
|
|
3
41
|
## 0.4.4
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
package/dist/automerge-worker.js
CHANGED
|
@@ -23,19 +23,9 @@ import { HANDOFF_CHANNEL, SYNCSTATE_CHANNEL, } from "./types.js";
|
|
|
23
23
|
const siteName = typeof __SITE_NAME__ !== "undefined"
|
|
24
24
|
? __SITE_NAME__
|
|
25
25
|
: "patchwork.inkandswitch.com";
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
? "wss://keyhive.sync.automerge.org"
|
|
30
|
-
: "wss://subduction.sync.inkandswitch.com";
|
|
31
|
-
if (useKeyhiveSyncServer) {
|
|
32
|
-
const g = globalThis;
|
|
33
|
-
g.process ??= {};
|
|
34
|
-
g.process.env = {
|
|
35
|
-
...(g.process.env ?? {}),
|
|
36
|
-
KEYHIVE_SERVER_IDENTITY: "keyhive-sync",
|
|
37
|
-
};
|
|
38
|
-
}
|
|
26
|
+
const syncServer = typeof __SYNC_SERVER__ !== "undefined"
|
|
27
|
+
? __SYNC_SERVER__
|
|
28
|
+
: { url: "wss://subduction.sync.inkandswitch.com" };
|
|
39
29
|
const RESOLVE_TIMEOUT_MS = 30_000;
|
|
40
30
|
const CACHEABLE_STATUSES = [200, 203, 204];
|
|
41
31
|
// A fresh instance means a new repo peerId and cold in-memory state, so a tab
|
|
@@ -153,7 +143,7 @@ const subductionPortProvider = makePortProvider();
|
|
|
153
143
|
let subductionEndpoints = null;
|
|
154
144
|
function getSubductionEndpoints() {
|
|
155
145
|
return (subductionEndpoints ??= [
|
|
156
|
-
new WorkerWebSocketEndpoint(
|
|
146
|
+
new WorkerWebSocketEndpoint(syncServer.url, {
|
|
157
147
|
worker: subductionPortProvider.source,
|
|
158
148
|
}),
|
|
159
149
|
]);
|
|
@@ -179,8 +169,8 @@ async function setUpRepoHive() {
|
|
|
179
169
|
initSubductionSync(new Uint8Array(subductionWasm));
|
|
180
170
|
await initializeWasm(new Uint8Array(automergeWasm));
|
|
181
171
|
log("wasm initialized");
|
|
182
|
-
const built =
|
|
183
|
-
? await buildKeyhiveRepo()
|
|
172
|
+
const built = syncServer.keyhive
|
|
173
|
+
? await buildKeyhiveRepo(syncServer.keyhive)
|
|
184
174
|
: await buildPlainRepo();
|
|
185
175
|
self.repo = built.repo;
|
|
186
176
|
if (built.hive)
|
|
@@ -216,7 +206,7 @@ async function buildPlainRepo() {
|
|
|
216
206
|
console.log("[patchwork] shared-worker subduction identity:", identity);
|
|
217
207
|
return { repo, identity };
|
|
218
208
|
}
|
|
219
|
-
async function buildKeyhiveRepo() {
|
|
209
|
+
async function buildKeyhiveRepo(keyhiveSyncServer) {
|
|
220
210
|
initKeyhiveWasm();
|
|
221
211
|
const { hive, repo } = await initializeAutomergeRepoKeyhiveRustWithRepo({
|
|
222
212
|
createRepo: (config) => new Repo(config),
|
|
@@ -226,7 +216,7 @@ async function buildKeyhiveRepo() {
|
|
|
226
216
|
cachingMode: "periodic",
|
|
227
217
|
// ARK selects the relay via `syncServer`, which pairs the contact card with
|
|
228
218
|
// the matching peer id. Omitting it defaults to "subduction".
|
|
229
|
-
|
|
219
|
+
syncServer: keyhiveSyncServer,
|
|
230
220
|
repo: {
|
|
231
221
|
storage: new IndexedDBWorkerStorageAdapter(),
|
|
232
222
|
subductionWebsocketEndpoints: getSubductionEndpoints(),
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* these dependencies will be built into the outdir, and injected into the importmap
|
|
3
|
+
*/
|
|
4
|
+
const externals = [
|
|
5
|
+
"@automerge/automerge",
|
|
6
|
+
"@automerge/automerge/slim",
|
|
7
|
+
"@automerge/automerge-repo",
|
|
8
|
+
"@automerge/automerge-repo/slim",
|
|
9
|
+
// Port-donation plumbing for WorkerWebSocketEndpoint: tabs spawn the shared
|
|
10
|
+
// proxy entry and donate its port to the automerge worker (Chrome can't
|
|
11
|
+
// spawn workers from inside a SharedWorker). See setup.ts/automerge-worker.ts.
|
|
12
|
+
"@automerge/automerge-repo/worker-port",
|
|
13
|
+
"@automerge/automerge-repo/subduction-websocket-worker-shared",
|
|
14
|
+
"@automerge/automerge-repo-network-messagechannel",
|
|
15
|
+
"@automerge/automerge-repo-network-websocket",
|
|
16
|
+
"@automerge/automerge-repo-storage-indexeddb",
|
|
17
|
+
"@automerge/automerge-repo-keyhive",
|
|
18
|
+
"@automerge/automerge-subduction",
|
|
19
|
+
"@automerge/automerge-subduction/slim",
|
|
20
|
+
"@keyhive/keyhive",
|
|
21
|
+
"@keyhive/keyhive/slim",
|
|
22
|
+
"@inkandswitch/patchwork-bootloader",
|
|
23
|
+
"@inkandswitch/patchwork-elements",
|
|
24
|
+
"@inkandswitch/patchwork-filesystem",
|
|
25
|
+
"@inkandswitch/patchwork-plugins",
|
|
26
|
+
"@inkandswitch/patchwork-providers",
|
|
27
|
+
"@inkandswitch/patchwork",
|
|
28
|
+
// sad
|
|
29
|
+
"@codemirror/state",
|
|
30
|
+
"@codemirror/view",
|
|
31
|
+
"@codemirror/language",
|
|
32
|
+
"@codemirror/commands",
|
|
33
|
+
// rip
|
|
34
|
+
"solid-js",
|
|
35
|
+
"solid-js/html",
|
|
36
|
+
"solid-js/web",
|
|
37
|
+
"solid-js/h",
|
|
38
|
+
"solid-js/store",
|
|
39
|
+
"solid-js/jsx-runtime",
|
|
40
|
+
];
|
|
41
|
+
export default externals;
|
package/dist/externals.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
export { default } from "./externals-list.js";
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
+
* Resolve one of this package's own dependencies from its node_modules
|
|
4
|
+
* rather than the site's, so a vite plugin bundling it never needs the site
|
|
5
|
+
* to install it or agree on a version. Exported so `@inkandswitch/patchwork`'s
|
|
6
|
+
* vite plugin (which lives in a different package) can reuse this for the
|
|
7
|
+
* externals bootloader actually owns, while resolving itself separately.
|
|
8
|
+
*
|
|
9
|
+
* This goes through rollup's resolver rather than import.meta.resolve or
|
|
10
|
+
* require.resolve because those apply node's conditions: subduction (and
|
|
11
|
+
* others) would hand us `dist/esm/node.js`, which imports node:path and blows
|
|
12
|
+
* up at bundle time. rollup applies the browser conditions vite configured.
|
|
3
13
|
*/
|
|
4
|
-
declare
|
|
5
|
-
|
|
14
|
+
export declare function resolveExternal(this: import("rollup").PluginContext, name: string): Promise<string>;
|
|
15
|
+
/** Emits automerge/keyhive/subduction's wasm binaries as build assets, so the service worker can fetch them. */
|
|
16
|
+
export declare function emitWasmAssets(this: import("rollup").PluginContext): void;
|
package/dist/externals.js
CHANGED
|
@@ -1,40 +1,52 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
export { default } from "./externals-list.js";
|
|
1
6
|
/**
|
|
2
|
-
*
|
|
7
|
+
* pretend the import came from inside this package, so node_modules resolution
|
|
8
|
+
* walks up from *our* directory and finds our copy of each external. that's why
|
|
9
|
+
* a consuming site never has to install them or agree with us about versions.
|
|
3
10
|
*/
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
11
|
+
const self = fileURLToPath(import.meta.url);
|
|
12
|
+
/**
|
|
13
|
+
* Resolve one of this package's own dependencies from its node_modules
|
|
14
|
+
* rather than the site's, so a vite plugin bundling it never needs the site
|
|
15
|
+
* to install it or agree on a version. Exported so `@inkandswitch/patchwork`'s
|
|
16
|
+
* vite plugin (which lives in a different package) can reuse this for the
|
|
17
|
+
* externals bootloader actually owns, while resolving itself separately.
|
|
18
|
+
*
|
|
19
|
+
* This goes through rollup's resolver rather than import.meta.resolve or
|
|
20
|
+
* require.resolve because those apply node's conditions: subduction (and
|
|
21
|
+
* others) would hand us `dist/esm/node.js`, which imports node:path and blows
|
|
22
|
+
* up at bundle time. rollup applies the browser conditions vite configured.
|
|
23
|
+
*/
|
|
24
|
+
export async function resolveExternal(name) {
|
|
25
|
+
const resolved = await this.resolve(name, self, { skipSelf: true });
|
|
26
|
+
if (!resolved) {
|
|
27
|
+
throw new Error(`@inkandswitch/patchwork-bootloader: couldn't resolve the external ` +
|
|
28
|
+
`"${name}". it should be one of the bootloader's own dependencies.`);
|
|
29
|
+
}
|
|
30
|
+
return resolved.id;
|
|
31
|
+
}
|
|
32
|
+
/** Emits automerge/keyhive/subduction's wasm binaries as build assets, so the service worker can fetch them. */
|
|
33
|
+
export function emitWasmAssets() {
|
|
34
|
+
const automergeWasmPath = require.resolve("@automerge/automerge/automerge.wasm");
|
|
35
|
+
this.emitFile({
|
|
36
|
+
type: "asset",
|
|
37
|
+
fileName: "automerge.wasm",
|
|
38
|
+
source: readFileSync(automergeWasmPath),
|
|
39
|
+
});
|
|
40
|
+
const keyhiveWasmPath = require.resolve("@keyhive/keyhive/keyhive_wasm.wasm");
|
|
41
|
+
this.emitFile({
|
|
42
|
+
type: "asset",
|
|
43
|
+
fileName: "keyhive_wasm.wasm",
|
|
44
|
+
source: readFileSync(keyhiveWasmPath),
|
|
45
|
+
});
|
|
46
|
+
const subdWasmPath = require.resolve("@automerge/automerge-subduction/wasm");
|
|
47
|
+
this.emitFile({
|
|
48
|
+
type: "asset",
|
|
49
|
+
fileName: "subduction.wasm",
|
|
50
|
+
source: readFileSync(subdWasmPath),
|
|
51
|
+
});
|
|
52
|
+
}
|
package/dist/global.css
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
html,
|
|
2
|
+
body {
|
|
3
|
+
overscroll-behavior: none;
|
|
4
|
+
font-family: system-ui, sans-serif;
|
|
5
|
+
font-size: 16px;
|
|
6
|
+
height: 100%;
|
|
7
|
+
height: 100vh;
|
|
8
|
+
height: 100dvh;
|
|
9
|
+
|
|
10
|
+
@media all and (display-mode: standalone) {
|
|
11
|
+
height: 100lvh;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
patchwork-view {
|
|
16
|
+
display: block;
|
|
17
|
+
height: 100%;
|
|
18
|
+
width: 100%;
|
|
19
|
+
contain: layout;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@media (prefers-reduced-motion: reduce) {
|
|
23
|
+
*,
|
|
24
|
+
*:before,
|
|
25
|
+
*:after {
|
|
26
|
+
animation-duration: 0.001s !important;
|
|
27
|
+
transition-duration: 0.001s !important;
|
|
28
|
+
animation-iteration-count: 1 !important;
|
|
29
|
+
}
|
|
30
|
+
}
|
package/dist/service-worker.js
CHANGED
|
@@ -255,7 +255,11 @@ async function servePassthrough(fetchEvent, cache, cached) {
|
|
|
255
255
|
}
|
|
256
256
|
async function respond(fetchEvent, handoffURL) {
|
|
257
257
|
const cache = await caches.open(cachename);
|
|
258
|
-
|
|
258
|
+
// A cors request (e.g. the wasm `<link rel=preload crossorigin>`) can miss
|
|
259
|
+
// an entry that a url-keyed lookup finds, so fall back to the bare url —
|
|
260
|
+
// offline boot depends on this hitting.
|
|
261
|
+
const cached = (await cache.match(fetchEvent.request)) ??
|
|
262
|
+
(await cache.match(fetchEvent.request.url));
|
|
259
263
|
try {
|
|
260
264
|
return handoffURL
|
|
261
265
|
? await serveHandoff(fetchEvent, cache, handoffURL, cached)
|
package/dist/sync-config.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** localStorage key: optional override for the classic sync WebSocket URL. */
|
|
2
2
|
export declare const CLASSIC_SYNC_SERVER_KEY = "patchworkClassicSyncServer";
|
|
3
|
-
export declare const DEFAULT_CLASSIC_SYNC_SERVER
|
|
3
|
+
export declare const DEFAULT_CLASSIC_SYNC_SERVER: string;
|
|
4
4
|
export declare function readClassicSyncServer(storage?: Pick<Storage, "getItem">): string;
|
|
5
5
|
export type ConnectClassicSyncMessage = {
|
|
6
6
|
type: "connect-classic-sync";
|
package/dist/sync-config.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** localStorage key: optional override for the classic sync WebSocket URL. */
|
|
2
2
|
export const CLASSIC_SYNC_SERVER_KEY = "patchworkClassicSyncServer";
|
|
3
|
-
export const DEFAULT_CLASSIC_SYNC_SERVER = "
|
|
3
|
+
export const DEFAULT_CLASSIC_SYNC_SERVER = typeof __CLASSIC_SYNC_SERVER__ !== "undefined"
|
|
4
|
+
? __CLASSIC_SYNC_SERVER__
|
|
5
|
+
: "wss://sync3.automerge.org";
|
|
4
6
|
export function readClassicSyncServer(storage = globalThis.localStorage) {
|
|
5
7
|
const override = storage.getItem(CLASSIC_SYNC_SERVER_KEY)?.trim();
|
|
6
8
|
if (!override)
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkandswitch/patchwork-bootloader",
|
|
3
|
-
"
|
|
3
|
+
"repository": {
|
|
4
|
+
"type": "git",
|
|
5
|
+
"url": "git+https://github.com/inkandswitch/patchwork-system.git",
|
|
6
|
+
"directory": "core/bootloader"
|
|
7
|
+
},
|
|
8
|
+
"version": "0.5.2",
|
|
4
9
|
"author": "chee",
|
|
5
10
|
"type": "module",
|
|
6
11
|
"license": "MIT",
|
|
@@ -17,9 +22,9 @@
|
|
|
17
22
|
"import": "./dist/externals.js",
|
|
18
23
|
"types": "./dist/externals.d.ts"
|
|
19
24
|
},
|
|
20
|
-
"./
|
|
21
|
-
"import": "./dist/
|
|
22
|
-
"types": "./dist/
|
|
25
|
+
"./externals-list": {
|
|
26
|
+
"import": "./dist/externals-list.js",
|
|
27
|
+
"types": "./dist/externals-list.d.ts"
|
|
23
28
|
},
|
|
24
29
|
"./service-worker": {
|
|
25
30
|
"import": "./dist/service-worker.js",
|
|
@@ -29,18 +34,19 @@
|
|
|
29
34
|
"import": "./dist/automerge-worker.js",
|
|
30
35
|
"types": "./dist/automerge-worker.d.ts"
|
|
31
36
|
},
|
|
37
|
+
"./module-loader": {
|
|
38
|
+
"import": "./dist/module-loader.js",
|
|
39
|
+
"types": "./dist/module-loader.d.ts"
|
|
40
|
+
},
|
|
32
41
|
"./module-loader-worker": {
|
|
33
42
|
"import": "./dist/module-loader-worker.js",
|
|
34
43
|
"types": "./dist/module-loader-worker.d.ts"
|
|
35
44
|
},
|
|
36
|
-
"./site": {
|
|
37
|
-
"import": "./dist/site.js",
|
|
38
|
-
"types": "./dist/site.d.ts"
|
|
39
|
-
},
|
|
40
45
|
"./types": {
|
|
41
46
|
"import": "./dist/types.js",
|
|
42
47
|
"types": "./dist/types.d.ts"
|
|
43
|
-
}
|
|
48
|
+
},
|
|
49
|
+
"./global.css": "./dist/global.css"
|
|
44
50
|
},
|
|
45
51
|
"dependencies": {
|
|
46
52
|
"@automerge/automerge": "3.3.2",
|
|
@@ -62,10 +68,10 @@
|
|
|
62
68
|
"service-worker-types": "npm:@types/serviceworker@^0.0.153",
|
|
63
69
|
"solid-js": "^1.9.13",
|
|
64
70
|
"tinyargs": "^0.1.4",
|
|
65
|
-
"@inkandswitch/patchwork-elements": "^4.0.
|
|
66
|
-
"@inkandswitch/patchwork-
|
|
67
|
-
"@inkandswitch/patchwork-
|
|
68
|
-
"@inkandswitch/patchwork-
|
|
71
|
+
"@inkandswitch/patchwork-elements": "^4.0.4",
|
|
72
|
+
"@inkandswitch/patchwork-plugins": "^1.0.3",
|
|
73
|
+
"@inkandswitch/patchwork-providers": "^0.4.2",
|
|
74
|
+
"@inkandswitch/patchwork-filesystem": "^0.2.5"
|
|
69
75
|
},
|
|
70
76
|
"peerDependencies": {
|
|
71
77
|
"@automerge/automerge": "3.3.2",
|
|
@@ -88,7 +94,7 @@
|
|
|
88
94
|
}
|
|
89
95
|
},
|
|
90
96
|
"scripts": {
|
|
91
|
-
"build": "tsc",
|
|
97
|
+
"build": "tsc && cp src/global.css dist/global.css",
|
|
92
98
|
"dev": "tsc -w --preserveWatchOutput"
|
|
93
99
|
}
|
|
94
100
|
}
|
package/src/automerge-worker.ts
CHANGED
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
initializeAutomergeRepoKeyhiveRustWithRepo,
|
|
35
35
|
initKeyhiveWasm,
|
|
36
36
|
type AutomergeRepoKeyhiveRust,
|
|
37
|
+
type SyncServerSelection,
|
|
37
38
|
} from "@automerge/automerge-repo-keyhive";
|
|
38
39
|
|
|
39
40
|
import { DEFAULT_CLASSIC_SYNC_SERVER } from "./sync-config.js";
|
|
@@ -52,29 +53,19 @@ import {
|
|
|
52
53
|
} from "./types.js";
|
|
53
54
|
|
|
54
55
|
declare const __SITE_NAME__: string;
|
|
55
|
-
declare const
|
|
56
|
-
|
|
56
|
+
declare const __SYNC_SERVER__: {
|
|
57
|
+
url: string;
|
|
58
|
+
keyhive?: SyncServerSelection;
|
|
59
|
+
};
|
|
57
60
|
|
|
58
61
|
const siteName =
|
|
59
62
|
typeof __SITE_NAME__ !== "undefined"
|
|
60
63
|
? __SITE_NAME__
|
|
61
64
|
: "patchwork.inkandswitch.com";
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const SUBDUCTION_SYNC_URL = useKeyhiveSyncServer
|
|
67
|
-
? "wss://keyhive.sync.automerge.org"
|
|
68
|
-
: "wss://subduction.sync.inkandswitch.com";
|
|
69
|
-
|
|
70
|
-
if (useKeyhiveSyncServer) {
|
|
71
|
-
const g = globalThis as any;
|
|
72
|
-
g.process ??= {};
|
|
73
|
-
g.process.env = {
|
|
74
|
-
...(g.process.env ?? {}),
|
|
75
|
-
KEYHIVE_SERVER_IDENTITY: "keyhive-sync",
|
|
76
|
-
};
|
|
77
|
-
}
|
|
65
|
+
const syncServer =
|
|
66
|
+
typeof __SYNC_SERVER__ !== "undefined"
|
|
67
|
+
? __SYNC_SERVER__
|
|
68
|
+
: { url: "wss://subduction.sync.inkandswitch.com" };
|
|
78
69
|
|
|
79
70
|
const RESOLVE_TIMEOUT_MS = 30_000;
|
|
80
71
|
|
|
@@ -213,7 +204,7 @@ const subductionPortProvider = makePortProvider();
|
|
|
213
204
|
let subductionEndpoints: WorkerWebSocketEndpoint[] | null = null;
|
|
214
205
|
function getSubductionEndpoints(): WorkerWebSocketEndpoint[] {
|
|
215
206
|
return (subductionEndpoints ??= [
|
|
216
|
-
new WorkerWebSocketEndpoint(
|
|
207
|
+
new WorkerWebSocketEndpoint(syncServer.url, {
|
|
217
208
|
worker: subductionPortProvider.source,
|
|
218
209
|
}),
|
|
219
210
|
]);
|
|
@@ -246,8 +237,8 @@ async function setUpRepoHive(): Promise<RepoHive> {
|
|
|
246
237
|
await initializeWasm(new Uint8Array(automergeWasm));
|
|
247
238
|
log("wasm initialized");
|
|
248
239
|
|
|
249
|
-
const built: BuiltRepo =
|
|
250
|
-
? await buildKeyhiveRepo()
|
|
240
|
+
const built: BuiltRepo = syncServer.keyhive
|
|
241
|
+
? await buildKeyhiveRepo(syncServer.keyhive)
|
|
251
242
|
: await buildPlainRepo();
|
|
252
243
|
|
|
253
244
|
(self as any).repo = built.repo;
|
|
@@ -291,7 +282,9 @@ async function buildPlainRepo(): Promise<BuiltRepo> {
|
|
|
291
282
|
return { repo, identity };
|
|
292
283
|
}
|
|
293
284
|
|
|
294
|
-
async function buildKeyhiveRepo(
|
|
285
|
+
async function buildKeyhiveRepo(
|
|
286
|
+
keyhiveSyncServer: SyncServerSelection
|
|
287
|
+
): Promise<BuiltRepo> {
|
|
295
288
|
initKeyhiveWasm();
|
|
296
289
|
const { hive, repo } = await initializeAutomergeRepoKeyhiveRustWithRepo({
|
|
297
290
|
createRepo: (config) => new Repo(config),
|
|
@@ -301,7 +294,7 @@ async function buildKeyhiveRepo(): Promise<BuiltRepo> {
|
|
|
301
294
|
cachingMode: "periodic",
|
|
302
295
|
// ARK selects the relay via `syncServer`, which pairs the contact card with
|
|
303
296
|
// the matching peer id. Omitting it defaults to "subduction".
|
|
304
|
-
|
|
297
|
+
syncServer: keyhiveSyncServer,
|
|
305
298
|
repo: {
|
|
306
299
|
storage: new IndexedDBWorkerStorageAdapter(),
|
|
307
300
|
subductionWebsocketEndpoints: getSubductionEndpoints(),
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* these dependencies will be built into the outdir, and injected into the importmap
|
|
3
|
+
*/
|
|
4
|
+
const externals = [
|
|
5
|
+
"@automerge/automerge",
|
|
6
|
+
"@automerge/automerge/slim",
|
|
7
|
+
"@automerge/automerge-repo",
|
|
8
|
+
"@automerge/automerge-repo/slim",
|
|
9
|
+
// Port-donation plumbing for WorkerWebSocketEndpoint: tabs spawn the shared
|
|
10
|
+
// proxy entry and donate its port to the automerge worker (Chrome can't
|
|
11
|
+
// spawn workers from inside a SharedWorker). See setup.ts/automerge-worker.ts.
|
|
12
|
+
"@automerge/automerge-repo/worker-port",
|
|
13
|
+
"@automerge/automerge-repo/subduction-websocket-worker-shared",
|
|
14
|
+
"@automerge/automerge-repo-network-messagechannel",
|
|
15
|
+
"@automerge/automerge-repo-network-websocket",
|
|
16
|
+
"@automerge/automerge-repo-storage-indexeddb",
|
|
17
|
+
"@automerge/automerge-repo-keyhive",
|
|
18
|
+
"@automerge/automerge-subduction",
|
|
19
|
+
"@automerge/automerge-subduction/slim",
|
|
20
|
+
"@keyhive/keyhive",
|
|
21
|
+
"@keyhive/keyhive/slim",
|
|
22
|
+
"@inkandswitch/patchwork-bootloader",
|
|
23
|
+
"@inkandswitch/patchwork-elements",
|
|
24
|
+
"@inkandswitch/patchwork-filesystem",
|
|
25
|
+
"@inkandswitch/patchwork-plugins",
|
|
26
|
+
"@inkandswitch/patchwork-providers",
|
|
27
|
+
"@inkandswitch/patchwork",
|
|
28
|
+
|
|
29
|
+
// sad
|
|
30
|
+
"@codemirror/state",
|
|
31
|
+
"@codemirror/view",
|
|
32
|
+
"@codemirror/language",
|
|
33
|
+
"@codemirror/commands",
|
|
34
|
+
|
|
35
|
+
// rip
|
|
36
|
+
"solid-js",
|
|
37
|
+
"solid-js/html",
|
|
38
|
+
"solid-js/web",
|
|
39
|
+
"solid-js/h",
|
|
40
|
+
"solid-js/store",
|
|
41
|
+
"solid-js/jsx-runtime",
|
|
42
|
+
];
|
|
43
|
+
export default externals;
|
package/src/externals.ts
CHANGED
|
@@ -1,42 +1,68 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
|
|
7
|
+
export { default } from "./externals-list.js";
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
|
-
*
|
|
10
|
+
* pretend the import came from inside this package, so node_modules resolution
|
|
11
|
+
* walks up from *our* directory and finds our copy of each external. that's why
|
|
12
|
+
* a consuming site never has to install them or agree with us about versions.
|
|
3
13
|
*/
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
14
|
+
const self = fileURLToPath(import.meta.url);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Resolve one of this package's own dependencies from its node_modules
|
|
18
|
+
* rather than the site's, so a vite plugin bundling it never needs the site
|
|
19
|
+
* to install it or agree on a version. Exported so `@inkandswitch/patchwork`'s
|
|
20
|
+
* vite plugin (which lives in a different package) can reuse this for the
|
|
21
|
+
* externals bootloader actually owns, while resolving itself separately.
|
|
22
|
+
*
|
|
23
|
+
* This goes through rollup's resolver rather than import.meta.resolve or
|
|
24
|
+
* require.resolve because those apply node's conditions: subduction (and
|
|
25
|
+
* others) would hand us `dist/esm/node.js`, which imports node:path and blows
|
|
26
|
+
* up at bundle time. rollup applies the browser conditions vite configured.
|
|
27
|
+
*/
|
|
28
|
+
export async function resolveExternal(
|
|
29
|
+
this: import("rollup").PluginContext,
|
|
30
|
+
name: string
|
|
31
|
+
): Promise<string> {
|
|
32
|
+
const resolved = await this.resolve(name, self, { skipSelf: true });
|
|
33
|
+
if (!resolved) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`@inkandswitch/patchwork-bootloader: couldn't resolve the external ` +
|
|
36
|
+
`"${name}". it should be one of the bootloader's own dependencies.`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return resolved.id;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Emits automerge/keyhive/subduction's wasm binaries as build assets, so the service worker can fetch them. */
|
|
43
|
+
export function emitWasmAssets(this: import("rollup").PluginContext): void {
|
|
44
|
+
const automergeWasmPath = require.resolve(
|
|
45
|
+
"@automerge/automerge/automerge.wasm"
|
|
46
|
+
);
|
|
47
|
+
this.emitFile({
|
|
48
|
+
type: "asset",
|
|
49
|
+
fileName: "automerge.wasm",
|
|
50
|
+
source: readFileSync(automergeWasmPath),
|
|
51
|
+
});
|
|
27
52
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
const keyhiveWasmPath = require.resolve(
|
|
54
|
+
"@keyhive/keyhive/keyhive_wasm.wasm"
|
|
55
|
+
);
|
|
56
|
+
this.emitFile({
|
|
57
|
+
type: "asset",
|
|
58
|
+
fileName: "keyhive_wasm.wasm",
|
|
59
|
+
source: readFileSync(keyhiveWasmPath),
|
|
60
|
+
});
|
|
33
61
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
];
|
|
42
|
-
export default externals;
|
|
62
|
+
const subdWasmPath = require.resolve("@automerge/automerge-subduction/wasm");
|
|
63
|
+
this.emitFile({
|
|
64
|
+
type: "asset",
|
|
65
|
+
fileName: "subduction.wasm",
|
|
66
|
+
source: readFileSync(subdWasmPath),
|
|
67
|
+
});
|
|
68
|
+
}
|