Version Packages - #441
Merged
Merged
Version Packages#441
Conversation
Contributor
✅ Patchwork glance readyhttps://patchwork-preview-441.patchwork.inkandswitch.comA peek at |
github-actions
Bot
force-pushed
the
changeset-release/main
branch
3 times, most recently
from
September 22, 2026 15:09
fec5e22 to
aab5f30
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
September 22, 2026 15:28
aab5f30 to
1c1e771
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
September 23, 2026 16:53
1c1e771 to
c0448dd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@inkandswitch/patchwork-bootloader@0.8.0
Minor Changes
1cafc5e: Every Repo on the origin — each tab's
createRepo()and the automerge protocol handler worker's, in both the plain and the keyhive branch — passesheadsChannel, named<storagePrefix>-heads. When a tab persists commits it authored, its Repo posts the document's new heads on that BroadcastChannel; a sibling with the document open reloads it from the shared IndexedDB into its handle, and ignores announcements for documents it does not have open or heads it already knows. The channel also carries what the sync server holds: every tab talks to that server as the same identity, so one tab'sonRemoteHeadsobservation is a fact for all of them, and each keeps the newest one per peer rather than the last one to arrive. Only a real observation is announced, never a relay of a relay. Every node keeps the same signer and peer id, its own socket to the sync server and the shared database; what changes is how a write in one tab reaches the others.The siblings mesh is gone with it:
siblingAdapters()and the@inkandswitch/patchwork-bootloader/siblingsexport are removed, and no Repo passessubductionAdapters. Under one peer id the Subduction core never pushes a commit back to the sending peer's other connections, so the mesh links only added sync rounds.The option lives in this workspace's pnpm patch of
@automerge/automerge-repo@2.6.0-subduction.48, which also carries three fixes: afindresolves from local storage as soon as shared storage holds the document, before the first server round; aheads-changedthat saved nothing new (a reload, for instance) opens no server round; a document still initializing hydrates from local storage when a sync round fails while disconnected. A reload whose storage read fails is retried a few times, then logged once and left until the next announcement.A reload updates the handle, not the Subduction node's resident tree, so a commit that reached a tab only over the channel is one that tab cannot push: its hash is in the set every push is filtered against, and it is not in the tree a round reads. A containment backstop watches for that. When an entry's handle holds heads no peer has been seen holding, and a settling delay passes without a sibling reporting that the server has them, the tab writes those commits to storage a second time — which is what puts them in its tree — and then opens a round that can carry them. Each commit costs at most one such duplicate write, and a tab that is offline still does the write, so the reconnect round finds the tree already correct. The write is owed to the commit, not to the round: the cap on heal rounds gates the rounds alone, and a commit stops counting as stranded only once it has been stored or some peer has been seen holding it. Where every tab is online and pushing its own edits, the sibling's report arrives inside the settling delay and none of this runs.
Consumers installing from npm get the unpatched fork, where
headsChannelis ignored and tabs meet only through the server, until the fork is republished with these changes and the catalog pin is bumped.Patch Changes
7f54bd8: The automerge protocol handler worker evicts the documents its Repo loaded once no
automerge:handoff has been in flight for five seconds. A page load is a burst of handoffs through the same folder documents; they now stay hot across the load and are released after it, instead of living in the SharedWorker for as long as any tab is open. A headlessautomerge:<folder>/pathredirect waits up to three seconds for the folder to hold every head a connected Subduction peer has advertised, since a re-found folder comes back from IndexedDB before its sync round lands.Eviction goes through
Repo.removeFromCache, which this workspace's pnpm patch of@automerge/automerge-repo@2.6.0-subduction.48makes real:removeFromCacheawaits each source'sdetach, and the Subduction source'sdetachpersists unsaved commits, runs one sync round if no peer has them, drops its entry andheads-changedlistener, and unsubscribes the ephemeral topic, so the document can be collected and a laterfindattaches afresh. The Vite plugin ships and applies this patch for consumers installing@inkandswitch/patchworkfrom npm.f7d2e8c: IndexedDB is opened on the node's own thread:
createRepoand the automerge protocol handler worker useIndexedDBStorageAdapterin place ofIndexedDBWorkerStorageAdapter. Measured insites/bench, the worker adapter bought no main-thread time (same boot, same cold load of 40 documents, 1ms flush latency either way) and cost a dedicated worker per tab, about 30 MB across three. The origin-wide signer is unchanged.32ed577:
@automerge/automerge-repo-keyhiveis loaded only where keyhive is in use:createRepoand the automerge protocol handler workerimport()it inside their keyhive branch, andpatchwork-elementsandpatchwork-pluginsno longer import it at runtime. Its entry module carries the keyhive wasm as a 3 MB base64 string, so the static imports put a 3.1 MB chunk in every tab's modulepreload list and in the worker whether or not the site enabled keyhive, at 7 to 10 MB of memory per tab, and 8 MB in the protocol-handler worker. The chunk is still emitted under/packages/and listed in the import map for tool code. Type imports are unchanged.isKeyhiveDocinpatchwork-plugins, and the keyhive access gates inpatchwork-elements, decide from the document id's bytes: an id shorter than 32 bytes, or one whose bytes 16 through 31 are all zero, is a legacy document. They used to construct a keyhiveDocumentIdand take a throw as legacy, but that constructor is an ed25519 point decode and accepts about half of legacy padded ids, so about half of legacy documents went throughbestAccessForDoc. This is the check behind ARK'sisUnprotectedDoc, which it recommends over the deprecateddocIdFromAutomergeUrl.When keyhive access to a document changes,
patchwork-elementslooks up the document's handle by its automerge document id before retrying. It used the keyhiveDocumentIdstring, which is hex and never matched a handle, so an unavailable handle was never dropped before the retry.The vite plugin gives the worker chunks an empty module-preload dependency list. Vite wraps a dynamic import in a preload helper that touches
documentwhen it has dependencies to preload, and a worker has nodocument.1d22480: Every tab and worker now runs one automerge wasm instance, streamed from
/automerge.wasm.The bare
@automerge/automerge,@automerge/automerge-repo,@automerge/automerge-subductionand@keyhive/keyhivespecifiers resolve to their/slimbuilds everywhere: in the vite plugin's bundle, in the importmap a tool sees at runtime, and in the dev server's worker bundles. The fullfat entries embed and instantiate their own copy of the wasm on import, so a single value import of the bare name (there were four in our own packages) used to cost each tab a second automerge instance and a second, byte-identicalautomerge.wasmdownload. The/packages/@automerge/automerge.jschunk is no longer emitted; the bare name points at/packages/@automerge/automerge/slim.js.initWasmin the host and the protocol-handler worker hand the wasm-bindgen init aRequestinstead of buffering the bytes first, so both automerge and subduction go throughWebAssembly.instantiateStreaming: no 5 MB transient copy, and the compiled module is eligible for Chrome's code cache.@inkandswitch/patchwork-bootloader/externalsand/externals-listexport the alias table asslim.pnpm lint(scripts/lint-slim-imports.mts, run in CI) fails on any import of a bare name in the table, type-only ones included, so the fullfat entries stay out of every bundle.aa9af7e: The tab no longer heartbeats the automerge SharedWorker. The ping/pong, the second-connection probe, instance ids, and the recovery rate limit are gone: since every tab is its own Subduction node, the worker's control port carries only console forwarding, a debug toggle, and
connectClassicSync, so a silent port strands nothing. The worker is respawned on the nextget()if the browser terminates it (its control port firesclose).SharedWorkerHandle.onRecreatedis removed; it had no listeners.@inkandswitch/patchworkdrops its page-lifecycle logging, which existed to line up against sync-socket reaps in a worker that no longer holds the tab's socket.1d22480: The service worker no longer re-caches a passthrough response whose etag matches the copy it already holds. Every tab boot used to clone the whole bundle's responses and write them back to Cache Storage, holding a second copy of each body in the service worker's process until the write landed; with several tabs opening at once that peaked at a few hundred MB.
Updated dependencies [32ed577]
Updated dependencies [1d22480]
@inkandswitch/patchwork-elements@6.0.3
Patch Changes
32ed577:
@automerge/automerge-repo-keyhiveis loaded only where keyhive is in use:createRepoand the automerge protocol handler workerimport()it inside their keyhive branch, andpatchwork-elementsandpatchwork-pluginsno longer import it at runtime. Its entry module carries the keyhive wasm as a 3 MB base64 string, so the static imports put a 3.1 MB chunk in every tab's modulepreload list and in the worker whether or not the site enabled keyhive, at 7 to 10 MB of memory per tab, and 8 MB in the protocol-handler worker. The chunk is still emitted under/packages/and listed in the import map for tool code. Type imports are unchanged.isKeyhiveDocinpatchwork-plugins, and the keyhive access gates inpatchwork-elements, decide from the document id's bytes: an id shorter than 32 bytes, or one whose bytes 16 through 31 are all zero, is a legacy document. They used to construct a keyhiveDocumentIdand take a throw as legacy, but that constructor is an ed25519 point decode and accepts about half of legacy padded ids, so about half of legacy documents went throughbestAccessForDoc. This is the check behind ARK'sisUnprotectedDoc, which it recommends over the deprecateddocIdFromAutomergeUrl.When keyhive access to a document changes,
patchwork-elementslooks up the document's handle by its automerge document id before retrying. It used the keyhiveDocumentIdstring, which is hex and never matched a handle, so an unavailable handle was never dropped before the retry.The vite plugin gives the worker chunks an empty module-preload dependency list. Vite wraps a dynamic import in a preload helper that touches
documentwhen it has dependencies to preload, and a worker has nodocument.1d22480: Every tab and worker now runs one automerge wasm instance, streamed from
/automerge.wasm.The bare
@automerge/automerge,@automerge/automerge-repo,@automerge/automerge-subductionand@keyhive/keyhivespecifiers resolve to their/slimbuilds everywhere: in the vite plugin's bundle, in the importmap a tool sees at runtime, and in the dev server's worker bundles. The fullfat entries embed and instantiate their own copy of the wasm on import, so a single value import of the bare name (there were four in our own packages) used to cost each tab a second automerge instance and a second, byte-identicalautomerge.wasmdownload. The/packages/@automerge/automerge.jschunk is no longer emitted; the bare name points at/packages/@automerge/automerge/slim.js.initWasmin the host and the protocol-handler worker hand the wasm-bindgen init aRequestinstead of buffering the bytes first, so both automerge and subduction go throughWebAssembly.instantiateStreaming: no 5 MB transient copy, and the compiled module is eligible for Chrome's code cache.@inkandswitch/patchwork-bootloader/externalsand/externals-listexport the alias table asslim.pnpm lint(scripts/lint-slim-imports.mts, run in CI) fails on any import of a bare name in the table, type-only ones included, so the fullfat entries stay out of every bundle.@inkandswitch/patchwork-filesystem@0.2.10
Patch Changes
1d22480: Every tab and worker now runs one automerge wasm instance, streamed from
/automerge.wasm.The bare
@automerge/automerge,@automerge/automerge-repo,@automerge/automerge-subductionand@keyhive/keyhivespecifiers resolve to their/slimbuilds everywhere: in the vite plugin's bundle, in the importmap a tool sees at runtime, and in the dev server's worker bundles. The fullfat entries embed and instantiate their own copy of the wasm on import, so a single value import of the bare name (there were four in our own packages) used to cost each tab a second automerge instance and a second, byte-identicalautomerge.wasmdownload. The/packages/@automerge/automerge.jschunk is no longer emitted; the bare name points at/packages/@automerge/automerge/slim.js.initWasmin the host and the protocol-handler worker hand the wasm-bindgen init aRequestinstead of buffering the bytes first, so both automerge and subduction go throughWebAssembly.instantiateStreaming: no 5 MB transient copy, and the compiled module is eligible for Chrome's code cache.@inkandswitch/patchwork-bootloader/externalsand/externals-listexport the alias table asslim.pnpm lint(scripts/lint-slim-imports.mts, run in CI) fails on any import of a bare name in the table, type-only ones included, so the fullfat entries stay out of every bundle.@inkandswitch/patchwork@0.8.3
Patch Changes
2558064: The vite plugin applies this repo's pnpm patch of
@automerge/automerge-repo(patches/@automerge__automerge-repo@<version>.patch, shipped in the package asdist/patches/) to every copy of automerge-repo vite bundles for a site, in place of the two hand-written edits it carried before. A site installing from npm gets the same automerge-repo as this workspace: the realdetachbehind eviction, themeshadapter role, and whatever else the patch holds.Covered: the page build's chunks, including the
/packages/@automerge/automerge-repo*.jsimport-map chunks that patchwork's own protocol-handler worker imports from; the dev server's pre-bundled deps (an esbuildonLoadplugin inoptimizeDeps); and module workers a site builds through vite (new Worker(new URL("./x.ts", import.meta.url), { type: "module" })), which vite bundles in a separate rollup pass with onlyworker.plugins— theconfig()plugin's worker config now setsworker.pluginsto[wasm(), patches({ complete: false })], so those bundles are patched too. A site that passesworker: falseand writes its ownworker.pluginshas to addpatches({ complete: false })to them itself.patches()fails the build if any file the patch edits never reached the bundler;patches({ complete: false })skips that check, for a worker bundle that may import none or only some of them. The patch is pinned to one automerge-repo version; a version bump fails the build until the patch is re-made against it.1cafc5e: Every Repo on the origin — each tab's
createRepo()and the automerge protocol handler worker's, in both the plain and the keyhive branch — passesheadsChannel, named<storagePrefix>-heads. When a tab persists commits it authored, its Repo posts the document's new heads on that BroadcastChannel; a sibling with the document open reloads it from the shared IndexedDB into its handle, and ignores announcements for documents it does not have open or heads it already knows. The channel also carries what the sync server holds: every tab talks to that server as the same identity, so one tab'sonRemoteHeadsobservation is a fact for all of them, and each keeps the newest one per peer rather than the last one to arrive. Only a real observation is announced, never a relay of a relay. Every node keeps the same signer and peer id, its own socket to the sync server and the shared database; what changes is how a write in one tab reaches the others.The siblings mesh is gone with it:
siblingAdapters()and the@inkandswitch/patchwork-bootloader/siblingsexport are removed, and no Repo passessubductionAdapters. Under one peer id the Subduction core never pushes a commit back to the sending peer's other connections, so the mesh links only added sync rounds.The option lives in this workspace's pnpm patch of
@automerge/automerge-repo@2.6.0-subduction.48, which also carries three fixes: afindresolves from local storage as soon as shared storage holds the document, before the first server round; aheads-changedthat saved nothing new (a reload, for instance) opens no server round; a document still initializing hydrates from local storage when a sync round fails while disconnected. A reload whose storage read fails is retried a few times, then logged once and left until the next announcement.A reload updates the handle, not the Subduction node's resident tree, so a commit that reached a tab only over the channel is one that tab cannot push: its hash is in the set every push is filtered against, and it is not in the tree a round reads. A containment backstop watches for that. When an entry's handle holds heads no peer has been seen holding, and a settling delay passes without a sibling reporting that the server has them, the tab writes those commits to storage a second time — which is what puts them in its tree — and then opens a round that can carry them. Each commit costs at most one such duplicate write, and a tab that is offline still does the write, so the reconnect round finds the tree already correct. The write is owed to the commit, not to the round: the cap on heal rounds gates the rounds alone, and a commit stops counting as stranded only once it has been stored or some peer has been seen holding it. Where every tab is online and pushing its own edits, the sibling's report arrives inside the settling delay and none of this runs.
Consumers installing from npm get the unpatched fork, where
headsChannelis ignored and tabs meet only through the server, until the fork is republished with these changes and the catalog pin is bumped.f7d2e8c: IndexedDB is opened on the node's own thread:
createRepoand the automerge protocol handler worker useIndexedDBStorageAdapterin place ofIndexedDBWorkerStorageAdapter. Measured insites/bench, the worker adapter bought no main-thread time (same boot, same cold load of 40 documents, 1ms flush latency either way) and cost a dedicated worker per tab, about 30 MB across three. The origin-wide signer is unchanged.32ed577:
@automerge/automerge-repo-keyhiveis loaded only where keyhive is in use:createRepoand the automerge protocol handler workerimport()it inside their keyhive branch, andpatchwork-elementsandpatchwork-pluginsno longer import it at runtime. Its entry module carries the keyhive wasm as a 3 MB base64 string, so the static imports put a 3.1 MB chunk in every tab's modulepreload list and in the worker whether or not the site enabled keyhive, at 7 to 10 MB of memory per tab, and 8 MB in the protocol-handler worker. The chunk is still emitted under/packages/and listed in the import map for tool code. Type imports are unchanged.isKeyhiveDocinpatchwork-plugins, and the keyhive access gates inpatchwork-elements, decide from the document id's bytes: an id shorter than 32 bytes, or one whose bytes 16 through 31 are all zero, is a legacy document. They used to construct a keyhiveDocumentIdand take a throw as legacy, but that constructor is an ed25519 point decode and accepts about half of legacy padded ids, so about half of legacy documents went throughbestAccessForDoc. This is the check behind ARK'sisUnprotectedDoc, which it recommends over the deprecateddocIdFromAutomergeUrl.When keyhive access to a document changes,
patchwork-elementslooks up the document's handle by its automerge document id before retrying. It used the keyhiveDocumentIdstring, which is hex and never matched a handle, so an unavailable handle was never dropped before the retry.The vite plugin gives the worker chunks an empty module-preload dependency list. Vite wraps a dynamic import in a preload helper that touches
documentwhen it has dependencies to preload, and a worker has nodocument.86d59d4: Add the
importModulesInWorkersetup option. It defaults totrue, keeping plugin-descriptor discovery in the module-loader worker;falseimports each Automerge package directly on the main thread instead.1d22480: Every tab and worker now runs one automerge wasm instance, streamed from
/automerge.wasm.The bare
@automerge/automerge,@automerge/automerge-repo,@automerge/automerge-subductionand@keyhive/keyhivespecifiers resolve to their/slimbuilds everywhere: in the vite plugin's bundle, in the importmap a tool sees at runtime, and in the dev server's worker bundles. The fullfat entries embed and instantiate their own copy of the wasm on import, so a single value import of the bare name (there were four in our own packages) used to cost each tab a second automerge instance and a second, byte-identicalautomerge.wasmdownload. The/packages/@automerge/automerge.jschunk is no longer emitted; the bare name points at/packages/@automerge/automerge/slim.js.initWasmin the host and the protocol-handler worker hand the wasm-bindgen init aRequestinstead of buffering the bytes first, so both automerge and subduction go throughWebAssembly.instantiateStreaming: no 5 MB transient copy, and the compiled module is eligible for Chrome's code cache.@inkandswitch/patchwork-bootloader/externalsand/externals-listexport the alias table asslim.pnpm lint(scripts/lint-slim-imports.mts, run in CI) fails on any import of a bare name in the table, type-only ones included, so the fullfat entries stay out of every bundle.aa9af7e: The tab no longer heartbeats the automerge SharedWorker. The ping/pong, the second-connection probe, instance ids, and the recovery rate limit are gone: since every tab is its own Subduction node, the worker's control port carries only console forwarding, a debug toggle, and
connectClassicSync, so a silent port strands nothing. The worker is respawned on the nextget()if the browser terminates it (its control port firesclose).SharedWorkerHandle.onRecreatedis removed; it had no listeners.@inkandswitch/patchworkdrops its page-lifecycle logging, which existed to line up against sync-socket reaps in a worker that no longer holds the tab's socket.Updated dependencies [7f54bd8]
Updated dependencies [1cafc5e]
Updated dependencies [f7d2e8c]
Updated dependencies [32ed577]
Updated dependencies [1d22480]
Updated dependencies [aa9af7e]
Updated dependencies [1d22480]
@inkandswitch/patchwork-plugins@1.2.6
Patch Changes
32ed577:
@automerge/automerge-repo-keyhiveis loaded only where keyhive is in use:createRepoand the automerge protocol handler workerimport()it inside their keyhive branch, andpatchwork-elementsandpatchwork-pluginsno longer import it at runtime. Its entry module carries the keyhive wasm as a 3 MB base64 string, so the static imports put a 3.1 MB chunk in every tab's modulepreload list and in the worker whether or not the site enabled keyhive, at 7 to 10 MB of memory per tab, and 8 MB in the protocol-handler worker. The chunk is still emitted under/packages/and listed in the import map for tool code. Type imports are unchanged.isKeyhiveDocinpatchwork-plugins, and the keyhive access gates inpatchwork-elements, decide from the document id's bytes: an id shorter than 32 bytes, or one whose bytes 16 through 31 are all zero, is a legacy document. They used to construct a keyhiveDocumentIdand take a throw as legacy, but that constructor is an ed25519 point decode and accepts about half of legacy padded ids, so about half of legacy documents went throughbestAccessForDoc. This is the check behind ARK'sisUnprotectedDoc, which it recommends over the deprecateddocIdFromAutomergeUrl.When keyhive access to a document changes,
patchwork-elementslooks up the document's handle by its automerge document id before retrying. It used the keyhiveDocumentIdstring, which is hex and never matched a handle, so an unavailable handle was never dropped before the retry.The vite plugin gives the worker chunks an empty module-preload dependency list. Vite wraps a dynamic import in a preload helper that touches
documentwhen it has dependencies to preload, and a worker has nodocument.1d22480: Every tab and worker now runs one automerge wasm instance, streamed from
/automerge.wasm.The bare
@automerge/automerge,@automerge/automerge-repo,@automerge/automerge-subductionand@keyhive/keyhivespecifiers resolve to their/slimbuilds everywhere: in the vite plugin's bundle, in the importmap a tool sees at runtime, and in the dev server's worker bundles. The fullfat entries embed and instantiate their own copy of the wasm on import, so a single value import of the bare name (there were four in our own packages) used to cost each tab a second automerge instance and a second, byte-identicalautomerge.wasmdownload. The/packages/@automerge/automerge.jschunk is no longer emitted; the bare name points at/packages/@automerge/automerge/slim.js.initWasmin the host and the protocol-handler worker hand the wasm-bindgen init aRequestinstead of buffering the bytes first, so both automerge and subduction go throughWebAssembly.instantiateStreaming: no 5 MB transient copy, and the compiled module is eligible for Chrome's code cache.@inkandswitch/patchwork-bootloader/externalsand/externals-listexport the alias table asslim.pnpm lint(scripts/lint-slim-imports.mts, run in CI) fails on any import of a bare name in the table, type-only ones included, so the fullfat entries stay out of every bundle.@inkandswitch/edge-handles@0.1.4
Patch Changes
1d22480: Every tab and worker now runs one automerge wasm instance, streamed from
/automerge.wasm.The bare
@automerge/automerge,@automerge/automerge-repo,@automerge/automerge-subductionand@keyhive/keyhivespecifiers resolve to their/slimbuilds everywhere: in the vite plugin's bundle, in the importmap a tool sees at runtime, and in the dev server's worker bundles. The fullfat entries embed and instantiate their own copy of the wasm on import, so a single value import of the bare name (there were four in our own packages) used to cost each tab a second automerge instance and a second, byte-identicalautomerge.wasmdownload. The/packages/@automerge/automerge.jschunk is no longer emitted; the bare name points at/packages/@automerge/automerge/slim.js.initWasmin the host and the protocol-handler worker hand the wasm-bindgen init aRequestinstead of buffering the bytes first, so both automerge and subduction go throughWebAssembly.instantiateStreaming: no 5 MB transient copy, and the compiled module is eligible for Chrome's code cache.@inkandswitch/patchwork-bootloader/externalsand/externals-listexport the alias table asslim.pnpm lint(scripts/lint-slim-imports.mts, run in CI) fails on any import of a bare name in the table, type-only ones included, so the fullfat entries stay out of every bundle.@inkandswitch/patchwork-providers@0.5.3
Patch Changes
1d22480: Every tab and worker now runs one automerge wasm instance, streamed from
/automerge.wasm.The bare
@automerge/automerge,@automerge/automerge-repo,@automerge/automerge-subductionand@keyhive/keyhivespecifiers resolve to their/slimbuilds everywhere: in the vite plugin's bundle, in the importmap a tool sees at runtime, and in the dev server's worker bundles. The fullfat entries embed and instantiate their own copy of the wasm on import, so a single value import of the bare name (there were four in our own packages) used to cost each tab a second automerge instance and a second, byte-identicalautomerge.wasmdownload. The/packages/@automerge/automerge.jschunk is no longer emitted; the bare name points at/packages/@automerge/automerge/slim.js.initWasmin the host and the protocol-handler worker hand the wasm-bindgen init aRequestinstead of buffering the bytes first, so both automerge and subduction go throughWebAssembly.instantiateStreaming: no 5 MB transient copy, and the compiled module is eligible for Chrome's code cache.@inkandswitch/patchwork-bootloader/externalsand/externals-listexport the alias table asslim.pnpm lint(scripts/lint-slim-imports.mts, run in CI) fails on any import of a bare name in the table, type-only ones included, so the fullfat entries stay out of every bundle.