From a5938a47bd7a410db75eb3ee7c65231794f92c21 Mon Sep 17 00:00:00 2001 From: John Mumm Date: Fri, 30 Oct 2026 11:28:37 +0000 Subject: [PATCH] Move Patchwork to ARK 0.8.0-alpha.1 --- .changeset/keyhive-0-6.md | 15 ++ core/bootloader/package.json | 4 + .../src/automerge-protocol-handler.ts | 24 +- core/bootloader/src/keyhive-sync-server.ts | 62 +++++ core/bootloader/src/storage.ts | 8 +- core/elements/src/legacy-impl.ts | 8 +- core/elements/src/patchwork-view.ts | 8 +- core/patchwork/src/repo.ts | 14 +- core/patchwork/src/site-kit/index.ts | 1 - core/patchwork/src/site-kit/options.ts | 20 +- core/patchwork/src/site-kit/sync-servers.ts | 26 +- core/patchwork/src/vite/patchwork-plugin.ts | 1 - ..._automerge-repo@2.6.0-subduction.49.patch} | 112 ++++---- pnpm-lock.yaml | 250 +++++++++--------- pnpm-workspace.yaml | 27 +- 15 files changed, 315 insertions(+), 265 deletions(-) create mode 100644 .changeset/keyhive-0-6.md create mode 100644 core/bootloader/src/keyhive-sync-server.ts rename patches/{@automerge__automerge-repo@2.6.0-subduction.48.patch => @automerge__automerge-repo@2.6.0-subduction.49.patch} (96%) diff --git a/.changeset/keyhive-0-6.md b/.changeset/keyhive-0-6.md new file mode 100644 index 000000000..1d82d3f22 --- /dev/null +++ b/.changeset/keyhive-0-6.md @@ -0,0 +1,15 @@ +--- +"@inkandswitch/patchwork": minor +"@inkandswitch/patchwork-bootloader": minor +"@inkandswitch/patchwork-elements": patch +--- + +Move to `@automerge/automerge-repo-keyhive` 0.8.0-alpha.1 and `@keyhive/keyhive` 0.6.0. The other exact pins move with them so the consumer's tree keeps a single copy of automerge-repo: `@automerge/automerge-repo` and its adapters, `@automerge/react` and `@automerge/vanillajs` to 2.6.0-subduction.49, and `@automerge/automerge-subduction` to 0.20.1. The shipped automerge-repo patch makes the same changes as before, rebased onto 2.6.0-subduction.49. A site applying the patch from `@inkandswitch/patchwork/dist/patches` should take the new one. + +ARK no longer ships named sync servers, so a keyhive build finds its server's identity at startup. The tab and the automerge protocol handler worker fetch the server's contact card from `/keyhive/contact-card` on the `syncServers.subduction` host, and keep the last card fetched so a start without a network can use it. The server has to serve that endpoint. `keyhive.syncServer` and the `PatchworkKeyhiveSyncServer` type are gone; point `syncServers.subduction` at the server instead. `keyhive: true` and `keyhive: { useIdFactory }` are unchanged. + +New in `@inkandswitch/patchwork-bootloader`: `loadSyncServerIdentity(url, storage)` from `@inkandswitch/patchwork-bootloader/keyhive-sync-server`, for a site that builds its own keyhive Repo. + +The new keyhive can't read state written by 0.3, so keyhive state moves to a new `-keyhive-0.8` database and the old one is left untouched. Existing installs start with fresh keyhive state on upgrade. + +The keyhive access gates in `patchwork-elements` use ARK's `accessForDoc`, which replaces `bestAccessForDoc`. ARK no longer has public access, so a document opens only for its members. diff --git a/core/bootloader/package.json b/core/bootloader/package.json index f30f0a030..1b734ba5c 100644 --- a/core/bootloader/package.json +++ b/core/bootloader/package.json @@ -39,6 +39,10 @@ "import": "./dist/storage.js", "types": "./dist/storage.d.ts" }, + "./keyhive-sync-server": { + "import": "./dist/keyhive-sync-server.js", + "types": "./dist/keyhive-sync-server.d.ts" + }, "./service-worker": { "import": "./dist/service-worker.js", "types": "./dist/service-worker.d.ts" diff --git a/core/bootloader/src/automerge-protocol-handler.ts b/core/bootloader/src/automerge-protocol-handler.ts index 9f0a457ec..c0296a821 100644 --- a/core/bootloader/src/automerge-protocol-handler.ts +++ b/core/bootloader/src/automerge-protocol-handler.ts @@ -22,13 +22,11 @@ import { } from "@automerge/automerge-repo/slim"; import { IndexedDBStorageAdapter } from "@automerge/automerge-repo-storage-indexeddb"; -import type { - AutomergeRepoKeyhive, - SyncServerSelection, -} from "@automerge/automerge-repo-keyhive"; +import type { AutomergeRepoKeyhive } from "@automerge/automerge-repo-keyhive"; import { loadOrCreateSigner } from "./signer.js"; import { keyhiveStorageName, storagePrefix } from "./storage.js"; +import { loadSyncServerIdentity } from "./keyhive-sync-server.js"; import { startWorkerControl } from "./worker-control.js"; import { AUTOMERGE_WASM, SUBDUCTION_WASM } from "./emitted.js"; import { createResolver } from "./resolver.js"; @@ -41,7 +39,7 @@ import { declare const __SYNC_SERVER__: { url: string; - keyhive?: SyncServerSelection; + keyhive?: boolean; useIdFactory?: boolean; }; @@ -106,7 +104,7 @@ async function buildRepo(): Promise { await initWasm(); const { repo, hive } = syncServer.keyhive - ? await buildKeyhiveRepo(syncServer.keyhive) + ? await buildKeyhiveRepo() : { repo: await buildPlainRepo() }; builtRepo = repo; @@ -127,12 +125,14 @@ async function buildPlainRepo(): Promise { }); } -async function buildKeyhiveRepo( - keyhiveSyncServer: SyncServerSelection -): Promise<{ repo: Repo; hive: AutomergeRepoKeyhive }> { +async function buildKeyhiveRepo(): Promise<{ + repo: Repo; + hive: AutomergeRepoKeyhive; +}> { const { initKeyhiveWasm, initializeAutomergeRepoKeyhive } = await import("@automerge/automerge-repo-keyhive"); initKeyhiveWasm(); + const keyhiveStorage = new IndexedDBStorageAdapter(keyhiveStorageName); const { hive, repo } = await initializeAutomergeRepoKeyhive({ // ARK injects an `idFactory` deriving document ids from keyhive. A site // can opt out of it with `keyhive: { useIdFactory: false }`. @@ -140,14 +140,12 @@ async function buildKeyhiveRepo( new Repo( syncServer.useIdFactory === false ? config : { ...config, idFactory } ), - storage: new IndexedDBStorageAdapter(keyhiveStorageName), + storage: keyhiveStorage, peerIdSuffix: `${storagePrefix}-resolver` + Math.random().toString(36).slice(2), automaticArchiveIngestion: true, cachingMode: "periodic", - // ARK selects the relay via `syncServer`, which pairs the contact card with - // the matching peer id. Omitting it defaults to "subduction". - syncServer: keyhiveSyncServer, + syncServer: await loadSyncServerIdentity(syncServer.url, keyhiveStorage), repo: { storage: new IndexedDBStorageAdapter(), subductionWebsocketEndpoints: [syncServer.url], diff --git a/core/bootloader/src/keyhive-sync-server.ts b/core/bootloader/src/keyhive-sync-server.ts new file mode 100644 index 000000000..5f42241f3 --- /dev/null +++ b/core/bootloader/src/keyhive-sync-server.ts @@ -0,0 +1,62 @@ +import type { + PeerId, + StorageAdapterInterface, +} from "@automerge/automerge-repo/slim"; +import type { SyncServerIdentity } from "@automerge/automerge-repo-keyhive"; + +const CONTACT_CARD_KEY = ["patchwork", "sync-server-contact-card"]; + +/** + * The keyhive identity of the sync server at `url` (a ws:// or wss:// URL), + * which serves its contact card at `/keyhive/contact-card` on the same host. + * + * The card is fetched on every start so a server that has been redeployed + * with a new card is picked up. The last card fetched for each URL is kept + * in `storage` so a start without a network still has one. Fails only when + * no card can be fetched and none was saved for `url`. + * + * The card is trusted on first use. Nothing here checks it against a known + * identity so it is only as trustworthy as the connection it came over. + * + * Keyhive's wasm must be initialized before this is called. + */ +export async function loadSyncServerIdentity( + url: string, + storage: StorageAdapterInterface +): Promise { + const { ContactCard } = await import("@automerge/automerge-repo-keyhive"); + const key = [...CONTACT_CARD_KEY, url]; + + // The server's keyhive identity and its subduction peer id are the same + // key. ARK identifies a peer by the base64 of that key. + const identity = (contactCard: Uint8Array): SyncServerIdentity => { + const id = ContactCard.fromBytes(contactCard).individualId.toBytes(); + const peerId = btoa(String.fromCharCode(...id)) as PeerId; + return { contactCard, peerId }; + }; + + try { + const fetched = identity(await fetchContactCard(url)); + await storage.save(key, fetched.contactCard); + return fetched; + } catch (error) { + const saved = await storage.load(key); + if (!saved) { + throw new Error(`no keyhive contact card for ${url}`, { cause: error }); + } + console.warn( + `using the saved keyhive contact card for ${url}. Fetching it failed`, + error + ); + return identity(saved); + } +} + +async function fetchContactCard(url: string): Promise { + const cardUrl = new URL("/keyhive/contact-card", url.replace(/^ws/, "http")); + const response = await fetch(cardUrl); + if (!response.ok) { + throw new Error(`GET ${cardUrl} responded with ${response.status}`); + } + return new Uint8Array(await response.arrayBuffer()); +} diff --git a/core/bootloader/src/storage.ts b/core/bootloader/src/storage.ts index 8e06ab291..265f9de51 100644 --- a/core/bootloader/src/storage.ts +++ b/core/bootloader/src/storage.ts @@ -13,10 +13,10 @@ export const storagePrefix = : DEFAULT_STORAGE_PREFIX; /** - * The keyhive version this build stores state for. Keyhive versions can't read - * each other's state, so each gets its own database; `${storagePrefix}-keyhive` - * (no version) holds the state written by automerge-repo-keyhive 0.5. + * The automerge-repo-keyhive version this build stores keyhive state for. + * Versions can't read each other's state, so each gets its own database; + * `${storagePrefix}-keyhive` (no version) holds the state written by 0.5. */ -export const keyhiveStorageVersion = "0.6"; +export const keyhiveStorageVersion = "0.8"; export const keyhiveStorageName = `${storagePrefix}-keyhive-${keyhiveStorageVersion}`; diff --git a/core/elements/src/legacy-impl.ts b/core/elements/src/legacy-impl.ts index a8f7030cd..23118436d 100644 --- a/core/elements/src/legacy-impl.ts +++ b/core/elements/src/legacy-impl.ts @@ -323,12 +323,12 @@ export class LegacyImpl { if (this.#element.hive && this.#docUrl) { // Legacy (padded-zero) doc: skip keyhive gate if (isKeyhiveDoc(this.#docUrl)) { - const bestAccess = await this.#element.hive.bestAccessForDoc( + const access = await this.#element.hive.accessForDoc( this.#element.hive.active.individual.id, this.#docUrl ); if (epoch !== this.#initEpoch) return; - const accessLevel = bestAccess ? bestAccess.toString() : "None"; + const accessLevel = access ? access.toString() : "None"; if (accessLevel === "None") { this.#state = State.unable; @@ -559,11 +559,11 @@ export class LegacyImpl { let accessCheckSucceeded = false; try { if (!isKeyhiveDoc(this.#docUrl)) return; - const bestAccess = await this.#element.hive.bestAccessForDoc( + const access = await this.#element.hive.accessForDoc( this.#element.hive.active.individual.id, this.#docUrl ); - hasAccess = !!bestAccess; + hasAccess = !!access; accessCheckSucceeded = true; } catch { return; diff --git a/core/elements/src/patchwork-view.ts b/core/elements/src/patchwork-view.ts index 51a66b307..6f9853e3d 100644 --- a/core/elements/src/patchwork-view.ts +++ b/core/elements/src/patchwork-view.ts @@ -318,12 +318,12 @@ export function registerPatchworkViewElement( const keyhiveDoc = isKeyhiveDoc(this.url); if (keyhiveDoc) { - const bestAccess = await params.hive.bestAccessForDoc( + const access = await params.hive.accessForDoc( params.hive.active.individual.id, this.url ); if (epoch !== this.#initEpoch) return; - const accessLevel = bestAccess ? bestAccess.toString() : "None"; + const accessLevel = access ? access.toString() : "None"; if (accessLevel === "None") { this.#state = State.unable; @@ -508,11 +508,11 @@ export function registerPatchworkViewElement( let accessCheckSucceeded = false; try { if (!isKeyhiveDoc(this.url)) return; - const bestAccess = await params.hive.bestAccessForDoc( + const access = await params.hive.accessForDoc( params.hive.active.individual.id, this.url ); - hasAccess = !!bestAccess; + hasAccess = !!access; accessCheckSucceeded = true; } catch { return; diff --git a/core/patchwork/src/repo.ts b/core/patchwork/src/repo.ts index 6e8471673..796110eba 100644 --- a/core/patchwork/src/repo.ts +++ b/core/patchwork/src/repo.ts @@ -6,10 +6,7 @@ import { SUBDUCTION_WASM, } from "@inkandswitch/patchwork-bootloader/emitted"; import * as AutomergeRepo from "@automerge/automerge-repo/slim"; -import type { - AutomergeRepoKeyhive, - SyncServerSelection, -} from "@automerge/automerge-repo-keyhive"; +import type { AutomergeRepoKeyhive } from "@automerge/automerge-repo-keyhive"; // eslint-disable-next-line // @ts-ignore — the default init is a wasm-bindgen runtime helper not in the .d.ts import initSubduction from "@automerge/automerge-subduction/slim"; @@ -17,6 +14,7 @@ import { keyhiveStorageName, storagePrefix, } from "@inkandswitch/patchwork-bootloader/storage"; +import { loadSyncServerIdentity } from "@inkandswitch/patchwork-bootloader/keyhive-sync-server"; import type { SignerIdentity } from "./types.js"; import debug from "debug"; @@ -24,7 +22,7 @@ const log = debug("patchwork:setup:repo"); declare const __SYNC_SERVER__: { url: string; - keyhive?: SyncServerSelection; + keyhive?: boolean; useIdFactory?: boolean; }; const syncServer = @@ -75,6 +73,7 @@ export async function createRepo(): Promise { const { initKeyhiveWasm, initializeAutomergeRepoKeyhive } = await import("@automerge/automerge-repo-keyhive"); initKeyhiveWasm(); + const keyhiveStorage = new IndexedDBStorageAdapter(keyhiveStorageName); const { hive, repo } = await initializeAutomergeRepoKeyhive({ // ARK injects an `idFactory` deriving document ids from keyhive. A site // can opt out of it with `keyhive: { useIdFactory: false }`. @@ -84,12 +83,11 @@ export async function createRepo(): Promise { ? repoConfig : { ...repoConfig, idFactory } ), - storage: new IndexedDBStorageAdapter(keyhiveStorageName), + storage: keyhiveStorage, peerIdSuffix: storagePrefix + Math.random().toString(36).slice(2), automaticArchiveIngestion: true, cachingMode: "periodic", - // ARK selects the relay via `syncServer`, defaulting to "subduction". - syncServer: syncServer.keyhive, + syncServer: await loadSyncServerIdentity(syncServer.url, keyhiveStorage), repo: { storage: new IndexedDBStorageAdapter(), subductionWebsocketEndpoints: [syncServer.url], diff --git a/core/patchwork/src/site-kit/index.ts b/core/patchwork/src/site-kit/index.ts index d2a6932bb..2d0c24dd1 100644 --- a/core/patchwork/src/site-kit/index.ts +++ b/core/patchwork/src/site-kit/index.ts @@ -12,7 +12,6 @@ export type { PatchworkIconsOptions, PatchworkHtmlOptions, PatchworkNetlifyOptions, - PatchworkKeyhiveSyncServer, PatchworkKeyhiveOptions, PatchworkSyncServersOptions, } from "./options.js"; diff --git a/core/patchwork/src/site-kit/options.ts b/core/patchwork/src/site-kit/options.ts index fa1dcfd69..37b6df223 100644 --- a/core/patchwork/src/site-kit/options.ts +++ b/core/patchwork/src/site-kit/options.ts @@ -1,5 +1,3 @@ -import type { SyncServerIdentity } from "@automerge/automerge-repo-keyhive"; - /** * The bundler-agnostic option shape for a Patchwork site's generated * static assets (icons, index.html, manifest.webmanifest, Netlify config). @@ -36,17 +34,7 @@ export interface PatchworkNetlifyOptions { immutableAssets?: boolean; } -export type PatchworkKeyhiveSyncServer = - | "keyhive" - | "subduction" - | ({ url: string } & SyncServerIdentity); - export interface PatchworkKeyhiveOptions { - /** - * Which relay ARK registers and grants access to. Default `"subduction"`. - * A custom identity also carries the WebSocket URL to reach it on. - */ - syncServer?: PatchworkKeyhiveSyncServer; /** * Use the `idFactory` ARK injects into the repo config, which derives * document ids from keyhive. Default true. `false` drops it and lets the @@ -58,7 +46,7 @@ export interface PatchworkKeyhiveOptions { export type PatchworkSyncServersOptions = { /** wss:// URL for the legacy automerge-repo sync-server channel (connected on demand via connectClassicSync). Default: wss://sync3.automerge.org. Pass false to skip its preconnect hint. */ classic?: string | false; - /** wss:// URL for the subduction channel. Default: wss://subduction.sync.inkandswitch.com. Overrides the URL a named `keyhive.syncServer` would otherwise imply. */ + /** wss:// URL for the subduction channel. Default: wss://subduction.sync.inkandswitch.com. A keyhive build uses it too, and fetches the server's contact card from `/keyhive/contact-card` on the same host. */ subduction?: string; }; @@ -93,9 +81,9 @@ export interface PatchworkSiteOptions { backgroundColor?: string; /** - * Enables keyhive for this build. `true` takes every default; an object - * picks the relay and turns individual behaviour off. Omitted or `false` - * builds a plain subduction repo. + * Enables keyhive for this build, against the `syncServers.subduction` + * server. `true` takes every default; an object turns individual behaviour + * off. Omitted or `false` builds a plain subduction repo. */ keyhive?: boolean | PatchworkKeyhiveOptions; diff --git a/core/patchwork/src/site-kit/sync-servers.ts b/core/patchwork/src/site-kit/sync-servers.ts index eeeeb580c..980892372 100644 --- a/core/patchwork/src/site-kit/sync-servers.ts +++ b/core/patchwork/src/site-kit/sync-servers.ts @@ -1,5 +1,4 @@ import type { PatchworkSiteOptions } from "./options.js"; -import type { SyncServerSelection } from "@automerge/automerge-repo-keyhive"; // Mirrors core/bootloader/src/sync-config.ts's DEFAULT_CLASSIC_SYNC_SERVER // and automerge-protocol-handler-worker.ts's SUBDUCTION_SYNC_URL selection — @@ -9,32 +8,19 @@ import type { SyncServerSelection } from "@automerge/automerge-repo-keyhive"; export const DEFAULT_SYNC_SERVERS = { classic: "wss://sync3.automerge.org", subduction: "wss://subduction.sync.inkandswitch.com", - keyhive: "wss://keyhive.sync.automerge.org", }; export function resolvePrimarySyncServer(options: PatchworkSiteOptions): { url: string; - keyhive?: SyncServerSelection; + keyhive?: boolean; useIdFactory?: boolean; } { - const subduction = (options.syncServers || undefined)?.subduction; - if (!options.keyhive) { - return { url: subduction ?? DEFAULT_SYNC_SERVERS.subduction }; - } + const url = + (options.syncServers || undefined)?.subduction ?? + DEFAULT_SYNC_SERVERS.subduction; + if (!options.keyhive) return { url }; const keyhive = options.keyhive === true ? {} : options.keyhive; - const useIdFactory = keyhive.useIdFactory ?? true; - const syncServer = keyhive.syncServer ?? "subduction"; - if (typeof syncServer === "string") { - return { - keyhive: syncServer, - url: subduction ?? DEFAULT_SYNC_SERVERS[syncServer], - useIdFactory, - }; - } - // A custom relay carries the only URL it can be reached on, so it wins over - // `syncServers.subduction`. - const { url, ...identity } = syncServer; - return { keyhive: identity, url, useIdFactory }; + return { url, keyhive: true, useIdFactory: keyhive.useIdFactory ?? true }; } function wsToHttpOrigin(wsUrl: string): string { diff --git a/core/patchwork/src/vite/patchwork-plugin.ts b/core/patchwork/src/vite/patchwork-plugin.ts index 438793dba..025c30a1a 100644 --- a/core/patchwork/src/vite/patchwork-plugin.ts +++ b/core/patchwork/src/vite/patchwork-plugin.ts @@ -87,7 +87,6 @@ export type { PatchworkIconsOptions, PatchworkHtmlOptions, PatchworkNetlifyOptions, - PatchworkKeyhiveSyncServer, PatchworkKeyhiveOptions, PatchworkSyncServersOptions, } from "../site-kit/options.js"; diff --git a/patches/@automerge__automerge-repo@2.6.0-subduction.48.patch b/patches/@automerge__automerge-repo@2.6.0-subduction.49.patch similarity index 96% rename from patches/@automerge__automerge-repo@2.6.0-subduction.48.patch rename to patches/@automerge__automerge-repo@2.6.0-subduction.49.patch index 083083ac5..b36fffe54 100644 --- a/patches/@automerge__automerge-repo@2.6.0-subduction.48.patch +++ b/patches/@automerge__automerge-repo@2.6.0-subduction.49.patch @@ -1,5 +1,5 @@ diff --git a/dist/DocumentSource.d.ts b/dist/DocumentSource.d.ts -index 08d36a6efcf9b93ba170dfe8a6a54e51a1b8f92d..fafdbda628f968bb266588d5a45192f5fb965cde 100644 +index 08d36a6..fafdbda 100644 --- a/dist/DocumentSource.d.ts +++ b/dist/DocumentSource.d.ts @@ -34,7 +34,7 @@ export interface DocumentSource { @@ -12,7 +12,7 @@ index 08d36a6efcf9b93ba170dfe8a6a54e51a1b8f92d..fafdbda628f968bb266588d5a45192f5 /** * Optional: drain any pending writes for the given documents (or all diff --git a/dist/Repo.d.ts b/dist/Repo.d.ts -index 15d4ca65aa613fb567335f09c8fcb8cb9c4a954a..d1839005b1a01612be7bd85e9369443f81e7af3a 100644 +index 15d4ca6..d183900 100644 --- a/dist/Repo.d.ts +++ b/dist/Repo.d.ts @@ -36,7 +36,7 @@ export declare class Repo extends EventEmitter { @@ -52,7 +52,7 @@ index 15d4ca65aa613fb567335f09c8fcb8cb9c4a954a..d1839005b1a01612be7bd85e9369443f /** A function that determines whether we should share a document with a peer * diff --git a/dist/Repo.js b/dist/Repo.js -index adfddd9b3926510604274217c42f97f104e119a3..6662564892a1ba850e12072fac41bf37f644a826 100644 +index adfddd9..6662564 100644 --- a/dist/Repo.js +++ b/dist/Repo.js @@ -57,7 +57,7 @@ export class Repo extends EventEmitter { @@ -88,7 +88,7 @@ index adfddd9b3926510604274217c42f97f104e119a3..6662564892a1ba850e12072fac41bf37 async shutdown() { // Quiesce Subduction first — stops reconnect loops, flushes pending diff --git a/dist/subduction/AdapterConnections.d.ts b/dist/subduction/AdapterConnections.d.ts -index 55231beca6494ed4ab0eaeb45383b822bcea5fe3..419c4ec3d17dc9f521292d780d293f5b1aafa8ce 100644 +index 55231be..419c4ec 100644 --- a/dist/subduction/AdapterConnections.d.ts +++ b/dist/subduction/AdapterConnections.d.ts @@ -10,6 +10,6 @@ export declare class AdapterConnections implements ConnectionManager { @@ -101,7 +101,7 @@ index 55231beca6494ed4ab0eaeb45383b822bcea5fe3..419c4ec3d17dc9f521292d780d293f5b //# sourceMappingURL=AdapterConnections.d.ts.map \ No newline at end of file diff --git a/dist/subduction/AdapterConnections.js b/dist/subduction/AdapterConnections.js -index 40f525a6be944be10dd5e707c73f6af48d7ffde1..51d27e89d02439b4724eb830aceb9339c65a761c 100644 +index 40f525a..51d27e8 100644 --- a/dist/subduction/AdapterConnections.js +++ b/dist/subduction/AdapterConnections.js @@ -57,11 +57,12 @@ export class AdapterConnections { @@ -121,7 +121,7 @@ index 40f525a6be944be10dd5e707c73f6af48d7ffde1..51d27e89d02439b4724eb830aceb9339 } catch { diff --git a/dist/subduction/SubductionConnections.js b/dist/subduction/SubductionConnections.js -index 4760a1899a8c0127db4840d5de090f6825211d97..5b9d19d4dd1cfb0cb242f140d5401af53aadd6a9 100644 +index 4760a18..5b9d19d 100644 --- a/dist/subduction/SubductionConnections.js +++ b/dist/subduction/SubductionConnections.js @@ -15,7 +15,9 @@ export class SubductionConnections { @@ -136,7 +136,7 @@ index 4760a1899a8c0127db4840d5de090f6825211d97..5b9d19d4dd1cfb0cb242f140d5401af5 } return false; diff --git a/dist/subduction/source.d.ts b/dist/subduction/source.d.ts -index c1f722a51f7e273ee8161e4569b1602c2e3c3d11..670510ad8797d5bd0b66945b89d52544efd42503 100644 +index c1f722a..670510a 100644 --- a/dist/subduction/source.d.ts +++ b/dist/subduction/source.d.ts @@ -119,16 +119,19 @@ export interface SubductionSourceOptions { @@ -162,7 +162,7 @@ index c1f722a51f7e273ee8161e4569b1602c2e3c3d11..670510ad8797d5bd0b66945b89d52544 /** Check whether a sedimentree is currently in heal-backoff. */ isHealing(sedimentreeId: SedimentreeId): boolean; diff --git a/dist/subduction/source.js b/dist/subduction/source.js -index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1d76c3ae9 100644 +index 2934f2c..4a05697 100644 --- a/dist/subduction/source.js +++ b/dist/subduction/source.js @@ -1,7 +1,7 @@ @@ -427,7 +427,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 throttledSave(); // Subscribe to ephemeral messages for this sedimentree void (async () => { -@@ -441,6 +549,7 @@ export class SubductionSource { +@@ -447,6 +555,7 @@ export class SubductionSource { this.#log.debug(`failed to seed persistedHashes for ${sidStr.slice(0, 8)}: %O`, e); } })(); @@ -435,7 +435,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 // Replay the last-known remote heads for this sedimentree so the // DocHandle reflects the last sync state immediately on (re)attach, // before any network round-trip completes. Does not re-persist. -@@ -457,7 +566,49 @@ export class SubductionSource { +@@ -463,7 +572,49 @@ export class SubductionSource { })(); this.#scheduleRecompute(this.#entries.get(sidStr)); } @@ -486,7 +486,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 shareConfigChanged() { for (const entry of this.#entries.values()) { // A share-config change can flip a previously-denied fetch to -@@ -598,6 +749,208 @@ export class SubductionSource { +@@ -604,6 +755,208 @@ export class SubductionSource { entry.lastSyncResult === "no-peers") && entry.lastSyncGeneration !== this.#connectionGeneration()); } @@ -695,7 +695,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 #recomputeEntry(entry) { // No new background syncs once shutting down: `shutdown()`'s quiesce // round is the sole sync initiator from that point. A recompute walk -@@ -625,6 +978,10 @@ export class SubductionSource { +@@ -631,6 +984,10 @@ export class SubductionSource { entry.syncInFlight = true; void this.#doSync(entry); } @@ -706,7 +706,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 else if (Automerge.getHeads(entry.handle.fullDoc()).length === 0 && !this.#anyConnectionManagerConnecting()) { // All connections settled and sync failed — give up. -@@ -632,12 +989,31 @@ export class SubductionSource { +@@ -638,12 +995,31 @@ export class SubductionSource { entry.query.sourceUnavailable("subduction"); } } @@ -741,7 +741,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 } return; } -@@ -663,6 +1039,8 @@ export class SubductionSource { +@@ -669,6 +1045,8 @@ export class SubductionSource { await entry.saveSettled; this.#log.debug(`doSync ${sid} (state=${entry.syncState})`); const peerResultMap = await subduction.syncWithAllPeers(sedimentreeId, true, timeoutMs !== undefined ? timeoutMs : this.#syncTimeout); @@ -750,7 +750,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 const results = peerResultMap.entries(); const anySuccess = results.some(r => r.success); this.#log.debug(`doSync ${sid}: ${results.length} peer(s), success=${anySuccess}`); -@@ -676,7 +1054,7 @@ export class SubductionSource { +@@ -682,7 +1060,7 @@ export class SubductionSource { // arrives, without waiting for further state transitions. // // During "initializing", `#loadBlobsAndTransition` performs one @@ -759,7 +759,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 // here too would duplicate storage reads on first open. // // Also retry when the handle is empty: a previous load may have -@@ -754,42 +1132,63 @@ export class SubductionSource { +@@ -760,42 +1138,63 @@ export class SubductionSource { return out; } /** @@ -842,7 +842,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 } let toApply = blobsWithIds.map(u => u.blob); if (this.#blobInterceptor) { -@@ -835,10 +1234,22 @@ export class SubductionSource { +@@ -841,10 +1240,22 @@ export class SubductionSource { this.#scheduleCompaction(entry); return true; } @@ -867,7 +867,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 entry.syncState = "running"; if (Automerge.getHeads(entry.handle.fullDoc()).length === 0) { if (this.#blobInterceptor && hadBlobs) { -@@ -864,6 +1275,21 @@ export class SubductionSource { +@@ -870,6 +1281,21 @@ export class SubductionSource { } } catch (e) { @@ -889,7 +889,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 this.#log.debug(`loadBlobsAndTransition threw for ${entry.sedimentreeId .toString() .slice(0, 8)}: %O`, e); -@@ -948,6 +1374,7 @@ export class SubductionSource { +@@ -954,6 +1380,7 @@ export class SubductionSource { entry.saveSettled = new Promise(r => { resolveSaveSettled = r; }); @@ -897,7 +897,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 try { const doc = entry.handle.fullDoc(); if (!doc) -@@ -989,6 +1416,14 @@ export class SubductionSource { +@@ -995,6 +1422,14 @@ export class SubductionSource { // so future mutations to either side stay isolated. entry.lastSaveError = null; entry.lastSavedHeads = new Set(currentSet); @@ -912,7 +912,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 // Detect a post-save delta the `heads-changed` listener didn't // fire on. `getChangeByHash` calls inside `#saveNewCommits` can // shift what `getHeads` returns for the same doc reference on -@@ -1014,6 +1449,8 @@ export class SubductionSource { +@@ -1020,6 +1455,8 @@ export class SubductionSource { entry.saveInProgress = false; resolveSaveSettled(); } @@ -921,7 +921,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 // Trigger an immediate sync — the only broadcast path for newly // saved commits (`#saveNewCommits` is store-only). If a sync is // already in flight, flag a re-sync for when it completes; otherwise -@@ -1062,7 +1499,7 @@ export class SubductionSource { +@@ -1068,7 +1505,7 @@ export class SubductionSource { const newCommitMetas = commitMetas.filter(m => !entry.knownHashes.has(m.head)); const newFragmentMetas = fragmentMetas.filter(m => !entry.knownHashes.has(m.head)); if (newCommitMetas.length === 0 && newFragmentMetas.length === 0) { @@ -930,7 +930,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 } const newCommitBytes = newCommitMetas.length === 0 ? [] -@@ -1143,7 +1580,7 @@ export class SubductionSource { +@@ -1149,7 +1586,7 @@ export class SubductionSource { : new AggregateError(prepErrors, `${prepErrors.length} inputs failed to prepare`); } if (commitInputs.length === 0 && fragmentInputs.length === 0) { @@ -939,7 +939,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 } // Record hashes BEFORE `storeBuiltBatch` so the synchronous // `commit-saved` / `fragment-saved` events fired from the storage -@@ -1171,8 +1608,15 @@ export class SubductionSource { +@@ -1177,8 +1614,15 @@ export class SubductionSource { `${fragmentInputs.length} fragments):`, e); throw e; } @@ -956,7 +956,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 } /** * Kick off a compaction pass without blocking the save loop. -@@ -1321,6 +1765,7 @@ export class SubductionSource { +@@ -1327,6 +1771,7 @@ export class SubductionSource { return; this.#scheduler.resetHealState(sid); entry.lastSyncResult = null; @@ -964,7 +964,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 this.#scheduleRecompute(entry); } // ── Flush ─────────────────────────────────────────────────────────── -@@ -1430,6 +1875,11 @@ export class SubductionSource { +@@ -1436,6 +1881,11 @@ export class SubductionSource { mgr.shutdown(); } this.#scheduler.shutdown(); @@ -976,7 +976,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 for (const entry of this.#entries.values()) this.#flushInbound(entry); for (const entry of this.#entries.values()) { -@@ -1468,6 +1918,7 @@ export class SubductionSource { +@@ -1474,6 +1924,7 @@ export class SubductionSource { for (const endpoint of this.#websocketEndpoints) { endpoint.shutdown?.(); } @@ -984,7 +984,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 this.#storage.close(); await this.#awaitStorageIdle(); return; -@@ -1481,6 +1932,7 @@ export class SubductionSource { +@@ -1487,6 +1938,7 @@ export class SubductionSource { for (const endpoint of this.#websocketEndpoints) { endpoint.shutdown?.(); } @@ -993,7 +993,7 @@ index 4692619444edfae0ef5f111cef6ce29499507afa..8625c93795d5870df6472d144725aae1 await this.#awaitStorageIdle(); } diff --git a/src/DocumentSource.ts b/src/DocumentSource.ts -index 363cbbad5af3f2db28ed5fa0ca85ca584a60bb49..d9eb3c5d8429607480867bf105d0e772ba1aecfd 100644 +index 363cbba..d9eb3c5 100644 --- a/src/DocumentSource.ts +++ b/src/DocumentSource.ts @@ -37,7 +37,7 @@ export interface DocumentSource { @@ -1006,7 +1006,7 @@ index 363cbbad5af3f2db28ed5fa0ca85ca584a60bb49..d9eb3c5d8429607480867bf105d0e772 shareConfigChanged(): void diff --git a/src/Repo.ts b/src/Repo.ts -index 0b408d6bda6582078083949c2fea63cfd0ef5e1b..e784353a779c092f418b0e0f15d1bb6e7182f47d 100644 +index 0b408d6..e784353 100644 --- a/src/Repo.ts +++ b/src/Repo.ts @@ -136,6 +136,8 @@ export class Repo extends EventEmitter { @@ -1072,7 +1072,7 @@ index 0b408d6bda6582078083949c2fea63cfd0ef5e1b..e784353a779c092f418b0e0f15d1bb6e /** A function that determines whether we should share a document with a peer diff --git a/src/subduction/AdapterConnections.ts b/src/subduction/AdapterConnections.ts -index 4426f11291a00b230332c63d77c683bb7ab02d24..e1fb64697b94637cd9dd968a6cebe8f5e06d89b2 100644 +index 4426f11..e1fb646 100644 --- a/src/subduction/AdapterConnections.ts +++ b/src/subduction/AdapterConnections.ts @@ -52,7 +52,7 @@ export class AdapterConnections implements ConnectionManager { @@ -1110,7 +1110,7 @@ index 4426f11291a00b230332c63d77c683bb7ab02d24..e1fb64697b94637cd9dd968a6cebe8f5 } catch { // Transport connection failed (e.g. peer disconnected during handshake) diff --git a/src/subduction/SubductionConnections.ts b/src/subduction/SubductionConnections.ts -index 0d5510500c1e3a8e0d84b6f9b5f87f42096ee8e3..6b8376be24f932f21ab3ddc4b76bc81ff39a5030 100644 +index 0d55105..6b8376b 100644 --- a/src/subduction/SubductionConnections.ts +++ b/src/subduction/SubductionConnections.ts @@ -28,7 +28,9 @@ export class SubductionConnections implements ConnectionManager { @@ -1125,7 +1125,7 @@ index 0d5510500c1e3a8e0d84b6f9b5f87f42096ee8e3..6b8376be24f932f21ab3ddc4b76bc81f return false } diff --git a/src/subduction/source.ts b/src/subduction/source.ts -index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e1863930872430 100644 +index 353fb23..740ffc0 100644 --- a/src/subduction/source.ts +++ b/src/subduction/source.ts @@ -16,7 +16,7 @@ import { DocumentSource } from "../DocumentSource.js" @@ -1523,7 +1523,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 throttledSave() // Subscribe to ephemeral messages for this sedimentree -@@ -851,6 +1041,7 @@ export class SubductionSource implements DocumentSource { +@@ -857,6 +1047,7 @@ export class SubductionSource implements DocumentSource { } })() @@ -1531,7 +1531,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 // Replay the last-known remote heads for this sedimentree so the // DocHandle reflects the last sync state immediately on (re)attach, // before any network round-trip completes. Does not re-persist. -@@ -877,7 +1068,45 @@ export class SubductionSource implements DocumentSource { +@@ -883,7 +1074,45 @@ export class SubductionSource implements DocumentSource { this.#scheduleRecompute(this.#entries.get(sidStr)) } @@ -1578,7 +1578,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 shareConfigChanged(): void { for (const entry of this.#entries.values()) { -@@ -1024,6 +1253,205 @@ export class SubductionSource implements DocumentSource { +@@ -1030,6 +1259,205 @@ export class SubductionSource implements DocumentSource { ) } @@ -1784,7 +1784,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 #recomputeEntry(entry: SedimentreeEntry) { // No new background syncs once shutting down: `shutdown()`'s quiesce // round is the sole sync initiator from that point. A recompute walk -@@ -1051,6 +1479,9 @@ export class SubductionSource implements DocumentSource { +@@ -1057,6 +1485,9 @@ export class SubductionSource implements DocumentSource { entry.query.sourcePending("subduction") entry.syncInFlight = true void this.#doSync(entry) @@ -1794,7 +1794,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 } else if ( Automerge.getHeads(entry.handle.fullDoc()).length === 0 && !this.#anyConnectionManagerConnecting() -@@ -1060,13 +1491,31 @@ export class SubductionSource implements DocumentSource { +@@ -1066,13 +1497,31 @@ export class SubductionSource implements DocumentSource { entry.query.sourceUnavailable("subduction") } } @@ -1829,7 +1829,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 } return } -@@ -1103,6 +1552,8 @@ export class SubductionSource implements DocumentSource { +@@ -1109,6 +1558,8 @@ export class SubductionSource implements DocumentSource { timeoutMs !== undefined ? timeoutMs : this.#syncTimeout ) @@ -1838,7 +1838,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 const results = peerResultMap.entries() const anySuccess = results.some(r => r.success) this.#log.debug( -@@ -1120,7 +1571,7 @@ export class SubductionSource implements DocumentSource { +@@ -1126,7 +1577,7 @@ export class SubductionSource implements DocumentSource { // arrives, without waiting for further state transitions. // // During "initializing", `#loadBlobsAndTransition` performs one @@ -1847,7 +1847,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 // here too would duplicate storage reads on first open. // // Also retry when the handle is empty: a previous load may have -@@ -1204,7 +1655,7 @@ export class SubductionSource implements DocumentSource { +@@ -1210,7 +1661,7 @@ export class SubductionSource implements DocumentSource { } /** @@ -1856,7 +1856,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 * handle via `Automerge.loadIncremental`. If new data was loaded, signal * the query so it can transition to "ready". * -@@ -1213,41 +1664,64 @@ export class SubductionSource implements DocumentSource { +@@ -1219,41 +1670,64 @@ export class SubductionSource implements DocumentSource { */ async #loadBlobsIntoHandle( entry: SedimentreeEntry, @@ -1940,7 +1940,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 } let toApply = blobsWithIds.map(u => u.blob) -@@ -1300,10 +1774,32 @@ export class SubductionSource implements DocumentSource { +@@ -1306,10 +1780,32 @@ export class SubductionSource implements DocumentSource { return true } @@ -1975,7 +1975,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 entry.syncState = "running" -@@ -1328,6 +1824,24 @@ export class SubductionSource implements DocumentSource { +@@ -1334,6 +1830,24 @@ export class SubductionSource implements DocumentSource { entry.query.sourcePending("subduction") } } catch (e) { @@ -2000,7 +2000,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 this.#log.debug( `loadBlobsAndTransition threw for ${entry.sedimentreeId .toString() -@@ -1416,6 +1930,7 @@ export class SubductionSource implements DocumentSource { +@@ -1422,6 +1936,7 @@ export class SubductionSource implements DocumentSource { resolveSaveSettled = r }) @@ -2008,7 +2008,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 try { const doc = entry.handle.fullDoc() if (!doc) return -@@ -1438,7 +1953,7 @@ export class SubductionSource implements DocumentSource { +@@ -1444,7 +1959,7 @@ export class SubductionSource implements DocumentSource { `syncInFlight=${entry.syncInFlight}` ) @@ -2017,7 +2017,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 try { result = await this.#saveNewCommits(entry, doc, subduction) } catch (e) { -@@ -1467,6 +1982,14 @@ export class SubductionSource implements DocumentSource { +@@ -1473,6 +1988,14 @@ export class SubductionSource implements DocumentSource { // so future mutations to either side stay isolated. entry.lastSaveError = null entry.lastSavedHeads = new Set(currentSet) @@ -2032,7 +2032,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 // Detect a post-save delta the `heads-changed` listener didn't // fire on. `getChangeByHash` calls inside `#saveNewCommits` can -@@ -1498,6 +2021,8 @@ export class SubductionSource implements DocumentSource { +@@ -1504,6 +2027,8 @@ export class SubductionSource implements DocumentSource { resolveSaveSettled() } @@ -2041,7 +2041,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 // Trigger an immediate sync — the only broadcast path for newly // saved commits (`#saveNewCommits` is store-only). If a sync is // already in flight, flag a re-sync for when it completes; otherwise -@@ -1521,7 +2046,7 @@ export class SubductionSource implements DocumentSource { +@@ -1527,7 +2052,7 @@ export class SubductionSource implements DocumentSource { entry: SedimentreeEntry, doc: Automerge.Doc, subduction: Subduction @@ -2050,7 +2050,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 // Ask the doc directly for its level-0 loose commits and its // higher-level fragments. Automerge core owns the compaction // policy (which commits get absorbed into which fragments); we -@@ -1558,7 +2083,7 @@ export class SubductionSource implements DocumentSource { +@@ -1564,7 +2089,7 @@ export class SubductionSource implements DocumentSource { ) if (newCommitMetas.length === 0 && newFragmentMetas.length === 0) { @@ -2059,7 +2059,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 } const newCommitBytes = -@@ -1677,7 +2202,7 @@ export class SubductionSource implements DocumentSource { +@@ -1683,7 +2208,7 @@ export class SubductionSource implements DocumentSource { } if (commitInputs.length === 0 && fragmentInputs.length === 0) { @@ -2068,7 +2068,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 } // Record hashes BEFORE `storeBuiltBatch` so the synchronous -@@ -1712,9 +2237,16 @@ export class SubductionSource implements DocumentSource { +@@ -1718,9 +2243,16 @@ export class SubductionSource implements DocumentSource { throw e } @@ -2086,7 +2086,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 } /** -@@ -1892,6 +2424,7 @@ export class SubductionSource implements DocumentSource { +@@ -1898,6 +2430,7 @@ export class SubductionSource implements DocumentSource { if (entry === undefined) return this.#scheduler.resetHealState(sid) entry.lastSyncResult = null @@ -2094,7 +2094,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 this.#scheduleRecompute(entry) } -@@ -2021,6 +2554,11 @@ export class SubductionSource implements DocumentSource { +@@ -2027,6 +2560,11 @@ export class SubductionSource implements DocumentSource { this.#scheduler.shutdown() @@ -2106,7 +2106,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 for (const entry of this.#entries.values()) this.#flushInbound(entry) for (const entry of this.#entries.values()) { -@@ -2076,6 +2614,7 @@ export class SubductionSource implements DocumentSource { +@@ -2082,6 +2620,7 @@ export class SubductionSource implements DocumentSource { for (const endpoint of this.#websocketEndpoints) { endpoint.shutdown?.() } @@ -2114,7 +2114,7 @@ index 4bd5d5cf682f3792f403efa44914ca88fa8f4006..083d991ab3c0937ce6b3c2fa74e18639 this.#storage.close() await this.#awaitStorageIdle() return -@@ -2090,6 +2629,7 @@ export class SubductionSource implements DocumentSource { +@@ -2096,6 +2635,7 @@ export class SubductionSource implements DocumentSource { endpoint.shutdown?.() } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1593ba90..79a864862 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,21 +36,21 @@ catalogs: overrides: '@automerge/automerge': 3.5.0 - '@automerge/automerge-repo': 2.6.0-subduction.48 - '@automerge/automerge-repo-keyhive': 0.6.0-alpha.1 - '@automerge/automerge-repo-network-broadcastchannel': 2.6.0-subduction.48 - '@automerge/automerge-repo-network-messagechannel': 2.6.0-subduction.48 - '@automerge/automerge-repo-network-websocket': 2.6.0-subduction.48 - '@automerge/automerge-repo-react-hooks': 2.6.0-subduction.48 - '@automerge/automerge-repo-storage-indexeddb': 2.6.0-subduction.48 - '@automerge/automerge-subduction': 0.16.1 - '@automerge/react': 2.6.0-subduction.48 - '@automerge/vanillajs': 2.6.0-subduction.48 - '@keyhive/keyhive': 0.3.0-alpha.1 + '@automerge/automerge-repo': 2.6.0-subduction.49 + '@automerge/automerge-repo-keyhive': 0.8.0-alpha.1 + '@automerge/automerge-repo-network-broadcastchannel': 2.6.0-subduction.49 + '@automerge/automerge-repo-network-messagechannel': 2.6.0-subduction.49 + '@automerge/automerge-repo-network-websocket': 2.6.0-subduction.49 + '@automerge/automerge-repo-react-hooks': 2.6.0-subduction.49 + '@automerge/automerge-repo-storage-indexeddb': 2.6.0-subduction.49 + '@automerge/automerge-subduction': 0.20.1 + '@automerge/react': 2.6.0-subduction.49 + '@automerge/vanillajs': 2.6.0-subduction.49 + '@keyhive/keyhive': 0.6.0 solid-automerge: ^2.0.1 patchedDependencies: - '@automerge/automerge-repo@2.6.0-subduction.48': 3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e + '@automerge/automerge-repo@2.6.0-subduction.49': 21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1 importers: @@ -81,29 +81,29 @@ importers: specifier: 3.5.0 version: 3.5.0 '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) '@automerge/automerge-repo-keyhive': - specifier: 0.6.0-alpha.1 - version: 0.6.0-alpha.1(ws@8.21.1) + specifier: 0.8.0-alpha.1 + version: 0.8.0-alpha.1(ws@8.21.1) '@automerge/automerge-repo-network-broadcastchannel': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@automerge/automerge-repo-network-messagechannel': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@automerge/automerge-repo-network-websocket': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@automerge/automerge-repo-storage-indexeddb': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@automerge/automerge-subduction': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.20.1 + version: 0.20.1 '@automerge/vanillajs': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@codemirror/commands': specifier: 'catalog:' version: 6.10.4 @@ -129,8 +129,8 @@ importers: specifier: workspace:^ version: link:../../packages/providers/core '@keyhive/keyhive': - specifier: 0.3.0-alpha.1 - version: 0.3.0-alpha.1 + specifier: 0.6.0 + version: 0.6.0 '@types/debug': specifier: ^4.1.13 version: 4.1.13 @@ -170,14 +170,14 @@ importers: specifier: 3.5.0 version: 3.5.0 '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) '@automerge/automerge-repo-keyhive': - specifier: 0.6.0-alpha.1 - version: 0.6.0-alpha.1(ws@8.21.1) + specifier: 0.8.0-alpha.1 + version: 0.8.0-alpha.1(ws@8.21.1) '@automerge/automerge-subduction': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.20.1 + version: 0.20.1 '@inkandswitch/patchwork-filesystem': specifier: workspace:^ version: link:../filesystem @@ -215,8 +215,8 @@ importers: specifier: 3.5.0 version: 3.5.0 '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) debug: specifier: ^4.4.3 version: 4.4.3 @@ -225,11 +225,11 @@ importers: version: 2.0.3 devDependencies: '@automerge/automerge-repo-network-messagechannel': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@automerge/automerge-subduction': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.20.1 + version: 0.20.1 '@types/debug': specifier: ^4.1.13 version: 4.1.13 @@ -246,20 +246,20 @@ importers: specifier: 3.5.0 version: 3.5.0 '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) '@automerge/automerge-repo-keyhive': - specifier: 0.6.0-alpha.1 - version: 0.6.0-alpha.1(ws@8.21.1) + specifier: 0.8.0-alpha.1 + version: 0.8.0-alpha.1(ws@8.21.1) '@automerge/automerge-repo-storage-indexeddb': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@automerge/automerge-subduction': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.20.1 + version: 0.20.1 '@automerge/vanillajs': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@inkandswitch/patchwork-bootloader': specifier: workspace:^ version: link:../bootloader @@ -320,11 +320,11 @@ importers: specifier: 3.5.0 version: 3.5.0 '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) '@automerge/automerge-repo-keyhive': - specifier: 0.6.0-alpha.1 - version: 0.6.0-alpha.1(ws@8.21.1) + specifier: 0.8.0-alpha.1 + version: 0.8.0-alpha.1(ws@8.21.1) '@inkandswitch/patchwork-filesystem': specifier: workspace:^ version: link:../filesystem @@ -351,11 +351,11 @@ importers: specifier: 3.5.0 version: 3.5.0 '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) '@automerge/automerge-subduction': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.20.1 + version: 0.20.1 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -366,8 +366,8 @@ importers: packages/providers/core: devDependencies: '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -379,11 +379,11 @@ importers: version: link:../../core devDependencies: '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) '@automerge/automerge-repo-react-hooks': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/react': specifier: 'catalog:' version: 18.3.1 @@ -401,11 +401,11 @@ importers: version: link:../../core devDependencies: '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) solid-automerge: specifier: ^2.0.1 - version: 2.0.1(@automerge/automerge-repo@2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e))(solid-js@1.9.14) + version: 2.0.1(@automerge/automerge-repo@2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1))(solid-js@1.9.14) solid-js: specifier: ^1.9.13 version: 1.9.14 @@ -416,17 +416,17 @@ importers: sites/bench: dependencies: '@automerge/automerge-repo': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) '@automerge/automerge-repo-network-broadcastchannel': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@automerge/automerge-repo-storage-indexeddb': - specifier: 2.6.0-subduction.48 - version: 2.6.0-subduction.48 + specifier: 2.6.0-subduction.49 + version: 2.6.0-subduction.49 '@automerge/automerge-subduction': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.20.1 + version: 0.20.1 '@inkandswitch/patchwork': specifier: workspace:* version: link:../../core/patchwork @@ -449,45 +449,45 @@ importers: packages: - '@automerge/automerge-repo-keyhive@0.6.0-alpha.1': - resolution: {integrity: sha512-U/KVwRlKevLfqsZ37uSZgOXfQsR1pwQ0soRgq+BnERf7nhKN+LrdpK7xHDXv8Z4xTa1bAmnmCSAnvARjVZ3+Iw==} + '@automerge/automerge-repo-keyhive@0.8.0-alpha.1': + resolution: {integrity: sha512-CdytRHw97dxfo9ikcYLTnyXknoXwRYlSXA5goDuB9+/W+VpbZPUtaggWx6NB5/CZEqcq5Qflvkdq9AIfDLBXKg==} engines: {node: '>=22.13'} - '@automerge/automerge-repo-network-broadcastchannel@2.6.0-subduction.48': - resolution: {integrity: sha512-fyq/ZqWkrYOuNrQ917KeCaRSuY6fzqH6Q4KCb5czjwKPKO2zFIGKVfK5hZjYsHGWRKuh5BzViaONHn6bJ0Jk4w==} + '@automerge/automerge-repo-network-broadcastchannel@2.6.0-subduction.49': + resolution: {integrity: sha512-n9G5Kb4fr8nX9vt2sStVtA2AYlgVIlJL/UOz4G/uW6Wp6v4Tr2OWzLSa+dL0MyrDjumFUhXlqjulzKVtHOMkGA==} engines: {node: '>=22.13'} - '@automerge/automerge-repo-network-messagechannel@2.6.0-subduction.48': - resolution: {integrity: sha512-pf+cmCi/TWQZpqrm+iinVpIM2Ecfzp8JpGEo28SPbE2Q8+eLyO2cz1Dssnuep1+KQ8k7Dfx7aUF9AD7/6jAvTQ==} + '@automerge/automerge-repo-network-messagechannel@2.6.0-subduction.49': + resolution: {integrity: sha512-4ciBhzHzghEGF7u+koATwu5erKgdYmAWjxiVSLeUUds+d60xOvXU38f/75aZ94CmJdbBhwpz3C+vlsU+lV2CHg==} engines: {node: '>=22.13'} - '@automerge/automerge-repo-network-websocket@2.6.0-subduction.48': - resolution: {integrity: sha512-TRKAq4iTdrSpOQYxyKZMJDJ5Civa+vONrAHBZkpK+DGShzqBB6vCdTCsrBGBF2Q63H33qQM0XYBQEQKIa/zM+Q==} + '@automerge/automerge-repo-network-websocket@2.6.0-subduction.49': + resolution: {integrity: sha512-9kDSyUW0Zcgz0nOYfu8K3c0IQqkPgdTrJPuhjke11lJ7oM+vJxtOYEstkJ/6xH78vkZU8i/96GbpjpTOAZgw8g==} engines: {node: '>=22.13'} - '@automerge/automerge-repo-react-hooks@2.6.0-subduction.48': - resolution: {integrity: sha512-o75EWDGUGdtmfH/EtwK1lnFoXKAWKY7pGHTkKNsPTZvLiHpafdm2ksk5JOzNcNGv7GMxwvXhMnmy2GOruYsj4g==} + '@automerge/automerge-repo-react-hooks@2.6.0-subduction.49': + resolution: {integrity: sha512-r/GE1HBEuaG0njchLKGprfev7m2MwMlY9uN4l4kyFN2ahemPtel0Lmr/Z27B+4avpNceYzcGIpcwaQvLrgoJGg==} engines: {node: '>=22.13'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@automerge/automerge-repo-storage-indexeddb@2.6.0-subduction.48': - resolution: {integrity: sha512-7XIn/iGrAVS4ugva8m0bU1shhRtuy/fdCAgF6qaIEvbi7XQllLVn3miTTiusLaksNhnRtbMfDLUknazU+vVHew==} + '@automerge/automerge-repo-storage-indexeddb@2.6.0-subduction.49': + resolution: {integrity: sha512-IWqLJUnVx2+3ieKdSCEJ19FSjnBf9JWhsSf1Jj7VlRqpmQjrgbzVhj/90ojFZA9mdjvDZjHvVbAr+jiA/rd3Kw==} engines: {node: '>=22.13'} - '@automerge/automerge-repo@2.6.0-subduction.48': - resolution: {integrity: sha512-HNS1YsD0XmQ0vtwIincF7NvEBrQuOMnk+mjCVluRiIpUFvcaVeNAFXCCyBVeXubmg88AHe+LkIQ96v/lyHZ7Wg==} + '@automerge/automerge-repo@2.6.0-subduction.49': + resolution: {integrity: sha512-2RRd2rrgrAMIj4hXtDCvNtqqpurjkw9I8Hdv9W+CRhMIZPl8QaAVmG1Bs4+TKBELw6WLQA6ISlrpnIChGzhpDA==} engines: {node: '>=22.13'} - '@automerge/automerge-subduction@0.16.1': - resolution: {integrity: sha512-alH7U4eYn0O7sT6hNLv7CJhNODJi+QD6qfRQTNfZCxL3Q5JZdJ8lFpdvXUkBf+I3bu0GLvVlTaYPWGrBihjpIw==} + '@automerge/automerge-subduction@0.20.1': + resolution: {integrity: sha512-lkRDaVr1I+C1N/IKSvn+TtT7WJnmxM0ntfUshG40Xi3INTL2//e8NcMJ8tEXh4GZYdCof37aG/diNuMLndHApQ==} '@automerge/automerge@3.5.0': resolution: {integrity: sha512-ejbqJWfXWM2QbTcUK/5ugYiQiyOP7LYVAp/RuSvthCc07oek0FClMxEuouuhjrLjVPDSI34RP1ftGc45PF7WRA==} - '@automerge/vanillajs@2.6.0-subduction.48': - resolution: {integrity: sha512-pmgwTtukitG5kY60cJ7x527IQgeG0NSnoSU35Is1xmswS+05QYpZ1vVdeyKNlGcIz2Kttdvn4vzm/45h0eicYQ==} + '@automerge/vanillajs@2.6.0-subduction.49': + resolution: {integrity: sha512-hcIvt0lSiYAwrSZ4ruatnZpPssjGJ0sJSyWsnytuBhQ2cgEDlFz8YesUf9Us4N7UeREMOo9cDsNZwE52XUSdkw==} engines: {node: '>=22.13'} '@babel/runtime@7.29.7': @@ -1071,8 +1071,8 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@keyhive/keyhive@0.3.0-alpha.1': - resolution: {integrity: sha512-2MsnK989GTGR+j+2LwyiekeaXYAWcBUY5Em4b6nVOLRmLJn/rtdgaB9EfOi52gkxW0TqAi3njrHXX0eJBdoxXA==} + '@keyhive/keyhive@0.6.0': + resolution: {integrity: sha512-Y9Vikg1EWAxs7doLgKVNY0qxqANmiP0O5UT25G+UAqNY4FkClEjH3VVE2iuzAaof0cZ9lP0bIvw8iL49pqoeRw==} '@lezer/common@1.5.2': resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==} @@ -1830,7 +1830,7 @@ packages: solid-automerge@2.0.1: resolution: {integrity: sha512-GhYw6/KGYH5q2a44UMnGOFdJ91YW8TGa4S5UFFRw/IC2Q6B0lfLGizUNitqYu39zt1citmILxqFrGhHThqNlOQ==} peerDependencies: - '@automerge/automerge-repo': 2.6.0-subduction.48 + '@automerge/automerge-repo': 2.6.0-subduction.49 solid-js: ^1.9.13 solid-js@1.9.14: @@ -2038,12 +2038,12 @@ packages: snapshots: - '@automerge/automerge-repo-keyhive@0.6.0-alpha.1(ws@8.21.1)': + '@automerge/automerge-repo-keyhive@0.8.0-alpha.1(ws@8.21.1)': dependencies: - '@automerge/automerge-repo': 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) - '@automerge/automerge-repo-network-websocket': 2.6.0-subduction.48 - '@automerge/automerge-subduction': 0.16.1 - '@keyhive/keyhive': 0.3.0-alpha.1 + '@automerge/automerge-repo': 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) + '@automerge/automerge-repo-network-websocket': 2.6.0-subduction.49 + '@automerge/automerge-subduction': 0.20.1 + '@keyhive/keyhive': 0.6.0 '@noble/hashes': 2.2.0 cbor-x: 1.6.4 eventemitter3: 5.0.4 @@ -2054,26 +2054,26 @@ snapshots: - utf-8-validate - ws - '@automerge/automerge-repo-network-broadcastchannel@2.6.0-subduction.48': + '@automerge/automerge-repo-network-broadcastchannel@2.6.0-subduction.49': dependencies: - '@automerge/automerge-repo': 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + '@automerge/automerge-repo': 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@automerge/automerge-repo-network-messagechannel@2.6.0-subduction.48': + '@automerge/automerge-repo-network-messagechannel@2.6.0-subduction.49': dependencies: - '@automerge/automerge-repo': 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + '@automerge/automerge-repo': 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) eventemitter3: 5.0.4 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@automerge/automerge-repo-network-websocket@2.6.0-subduction.48': + '@automerge/automerge-repo-network-websocket@2.6.0-subduction.49': dependencies: - '@automerge/automerge-repo': 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + '@automerge/automerge-repo': 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) cbor-x: 1.6.4 debug: 4.4.3 eventemitter3: 5.0.4 @@ -2083,10 +2083,10 @@ snapshots: - supports-color - utf-8-validate - '@automerge/automerge-repo-react-hooks@2.6.0-subduction.48(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@automerge/automerge-repo-react-hooks@2.6.0-subduction.49(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@automerge/automerge': 3.5.0 - '@automerge/automerge-repo': 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + '@automerge/automerge-repo': 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) eventemitter3: 5.0.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -2095,18 +2095,18 @@ snapshots: - supports-color - utf-8-validate - '@automerge/automerge-repo-storage-indexeddb@2.6.0-subduction.48': + '@automerge/automerge-repo-storage-indexeddb@2.6.0-subduction.49': dependencies: - '@automerge/automerge-repo': 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + '@automerge/automerge-repo': 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@automerge/automerge-repo@2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e)': + '@automerge/automerge-repo@2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1)': dependencies: '@automerge/automerge': 3.5.0 - '@automerge/automerge-subduction': 0.16.1 + '@automerge/automerge-subduction': 0.20.1 bs58check: 4.0.0 cbor-x: 1.6.4 debug: 4.4.3 @@ -2121,17 +2121,17 @@ snapshots: - supports-color - utf-8-validate - '@automerge/automerge-subduction@0.16.1': {} + '@automerge/automerge-subduction@0.20.1': {} '@automerge/automerge@3.5.0': {} - '@automerge/vanillajs@2.6.0-subduction.48': + '@automerge/vanillajs@2.6.0-subduction.49': dependencies: - '@automerge/automerge-repo': 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) - '@automerge/automerge-repo-network-broadcastchannel': 2.6.0-subduction.48 - '@automerge/automerge-repo-network-messagechannel': 2.6.0-subduction.48 - '@automerge/automerge-repo-network-websocket': 2.6.0-subduction.48 - '@automerge/automerge-repo-storage-indexeddb': 2.6.0-subduction.48 + '@automerge/automerge-repo': 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) + '@automerge/automerge-repo-network-broadcastchannel': 2.6.0-subduction.49 + '@automerge/automerge-repo-network-messagechannel': 2.6.0-subduction.49 + '@automerge/automerge-repo-network-websocket': 2.6.0-subduction.49 + '@automerge/automerge-repo-storage-indexeddb': 2.6.0-subduction.49 transitivePeerDependencies: - bufferutil - supports-color @@ -2599,7 +2599,7 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} - '@keyhive/keyhive@0.3.0-alpha.1': {} + '@keyhive/keyhive@0.6.0': {} '@lezer/common@1.5.2': {} @@ -3351,9 +3351,9 @@ snapshots: slash@3.0.0: {} - solid-automerge@2.0.1(@automerge/automerge-repo@2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e))(solid-js@1.9.14): + solid-automerge@2.0.1(@automerge/automerge-repo@2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1))(solid-js@1.9.14): dependencies: - '@automerge/automerge-repo': 2.6.0-subduction.48(patch_hash=3560381ba62410bed0716e7ef08af4200bcf8c0af4aa0794c1d5d05d23e97d5e) + '@automerge/automerge-repo': 2.6.0-subduction.49(patch_hash=21f240da042b5b197fd48a9391ebaa35217f6a768d11b503014baf8d2d3c5df1) '@solid-primitives/utils': 6.4.1(solid-js@1.9.14) cabbages: 0.2.10 solid-js: 1.9.14 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ab3e35b23..e21b2d2f2 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -25,25 +25,26 @@ minimumReleaseAgeExclude: - "@inkandswitch/*" - "@chee/*" - solid-automerge + - '@keyhive/keyhive@0.6.0' catalog: "@automerge/automerge": 3.5.0 - "@automerge/automerge-repo": 2.6.0-subduction.48 - "@automerge/automerge-repo-keyhive": 0.6.0-alpha.1 - "@automerge/automerge-repo-network-broadcastchannel": 2.6.0-subduction.48 - "@automerge/automerge-repo-network-messagechannel": 2.6.0-subduction.48 - "@automerge/automerge-repo-network-websocket": 2.6.0-subduction.48 - "@automerge/automerge-repo-react-hooks": 2.6.0-subduction.48 - "@automerge/automerge-repo-storage-indexeddb": 2.6.0-subduction.48 - "@automerge/automerge-repo-storage-nodefs": 2.6.0-subduction.48 - "@automerge/automerge-subduction": 0.16.1 - "@automerge/react": 2.6.0-subduction.48 - "@automerge/vanillajs": 2.6.0-subduction.48 + "@automerge/automerge-repo": 2.6.0-subduction.49 + "@automerge/automerge-repo-keyhive": 0.8.0-alpha.1 + "@automerge/automerge-repo-network-broadcastchannel": 2.6.0-subduction.49 + "@automerge/automerge-repo-network-messagechannel": 2.6.0-subduction.49 + "@automerge/automerge-repo-network-websocket": 2.6.0-subduction.49 + "@automerge/automerge-repo-react-hooks": 2.6.0-subduction.49 + "@automerge/automerge-repo-storage-indexeddb": 2.6.0-subduction.49 + "@automerge/automerge-repo-storage-nodefs": 2.6.0-subduction.49 + "@automerge/automerge-subduction": 0.20.1 + "@automerge/react": 2.6.0-subduction.49 + "@automerge/vanillajs": 2.6.0-subduction.49 "@codemirror/commands": ^6.10.4 "@codemirror/language": ^6.12.4 "@codemirror/state": ^6.7.1 "@codemirror/view": ^6.43.6 - "@keyhive/keyhive": 0.3.0-alpha.1 + "@keyhive/keyhive": 0.6.0 solid-automerge: ^2.0.1 solid-js: ^1.9.13 "@types/node": ^24.0.0 @@ -58,4 +59,4 @@ allowBuilds: esbuild: true patchedDependencies: - '@automerge/automerge-repo@2.6.0-subduction.48': patches/@automerge__automerge-repo@2.6.0-subduction.48.patch + '@automerge/automerge-repo@2.6.0-subduction.49': patches/@automerge__automerge-repo@2.6.0-subduction.49.patch