Bundles
A bundle is a named set of loaded extensions, identified by the
SHA-256 of its sorted (extension_name, content_hash) tuples. Save
a configuration once, replay it on any machine that has the cas-cache
seeded with the same component blobs.
The two problems bundles solve
-
Repeated rebuilds of the same embedded set. Today you can
sqlink compose --embed uuid,json1,caseto bake those three extensions into a fresh sqlink binary. Running it again with the same extension list still spawns a full build — the cas-cache deduplicates extension bytes but doesn't remember "you already built sqlink with this exact set." -
No reproducible round-trip from a live connection. A common workflow: open a db, dynamically
.loadsome extensions to explore, then want to capture that configuration so collaborators can launch sqlink with the same extension set. Without bundles that means transcribing the.loadlines by hand.
Identity model
Identity is set_hash (SHA-256 hex of the sorted member tuples).
The short name is a per-database alias.
__cas_bundle (id, name UNIQUE, set_hash, created_at, last_used_at)
__cas_bundle_member (bundle_id, extension_name, content_hash)
__cas_bundle_binary (bundle_id, target_triple, binary_path, built_at)
Multiple names can point at the same set_hash. Two databases can
disagree on what myset means short-wise; the set_hash is portable.
Dot commands
.bundle save NAME [--no-build] -- snapshot loaded extensions; build optionally
.bundle build NAME [--target X] -- bake a binary for the current target
.bundle list -- table: name | hash | members | binaries | last_used
.bundle show NAME|HASH -- members + binaries detail
.bundle delete NAME -- remove an alias
.bundle gc [--keep N|--older-than 30d]
Launch flag
sqlink --bundle myset db.sqlite # auto: exec baked binary if present, else load
sqlink --bundle-baked myset db.sqlite # force baked path; error if not built
sqlink --bundle-load myset db.sqlite # force dynamic load; skip any baked binary
sqlink --bundle 4c8e db.sqlite # hash-prefix lookup
How .bundle build works
.bundle save mysetrecords the bundle metadata..bundle build mysetinvokes the host'sspi.spawn-buildwith(cargo_package="sqlite-cli", features=["embed-uuid", "embed-json1", ...]).- Host runs
cargo build -p sqlite-cli --features ... --target wasm32-wasip2 --release. - For wasm targets, host then runs
wasm-tools component newon the output. For native targets, the binary IS the output. - The produced binary path is copied to
~/.cache/sqlink/builds/<set-hash>/and recorded in__cas_bundle_binary.
Requires the spawn-build capability:
sqlink --grant spawn-build mydb.sqlite
> .bundle build myset
Without the grant, .bundle build errors with a helpful
remediation message.
What's not in v1
- Bundle schema (
--with-schema) — capture the DDL too. - Bundle data (
--with-data) — overlaps withwal-archive. - Cross-target builds —
--target Xrequires the toolchain locally. - Bundle publishing / registry — share bundles across machines.
- True multi-name aliasing — v1's
name UNIQUEconstraint means the first save wins; v1.1 will introduce__cas_bundle_alias.
See the full plan for the source-of-truth design.