build!: bundle sqlite-shared, bump versions, complete the publish surface - #170
Conversation
…face Everything needed to publish the coordinated release in #167. sqlite-shared stays unpublished. docs/spec/adapters.md called it "an internal, non-public package", but record-adapter-sqlite declared it as a dependency and tsc emitted the import verbatim, so publishing that adapter would have required publishing sqlite-shared too — or shipped a package that cannot resolve. Bundling makes the documented intent true: - record-adapter-sqlite builds with tsup, inlining sqlite-shared and keeping @haverstack/core external. Inlining core would give the package its own copy of the error classes and break instanceof against the caller's copy. - sqlite-shared moves to devDependencies and is marked private. - SqlExecutor no longer appears in the emitted .d.ts. It was only ever reachable through an internal file that tsc happened to emit; the single-entry bundle drops it, so the public surface is now exactly the six intended symbols. Versions, for the packages already on npm: core 0.8.0 -> 0.9.0, and wire-types, adapter-local, blob-adapter-disk, adapter-api 0.6.0 -> 0.7.0. record-adapter-sqlite, conformance-fixtures and commons stay at 0.1.0 as first publishes. Adds the two missing publish scripts (record-adapter-sqlite, conformance-fixtures) and publish:all, which runs them in dependency order so no package is published before something it depends on. Adds scripts/verify-pack.mjs, run as verify:pack. It packs every publishable package, installs the tarballs into a throwaway project outside the workspace, and imports every entry point. This covers two things a green build cannot: that the subpath exports added in #168 resolve from a real tarball, and that sqlite-shared is absent from an installed tree. Both are silent-until-published failures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D5LtyME9WJky9jaB51tpjp
pnpm rewrites the workspace protocol at publish time, and workspace:* becomes an exact pin — the tarball for adapter-local@0.7.0 declared "@haverstack/core": "0.9.0", not a range. That bakes in the duplicate-copy hazard #167 documents. Publishing a core 0.9.1 would leave adapter-local demanding exactly 0.9.0, so an app depending on both gets two copies of core in its tree — and errors thrown inside the adapter carry a different class identity than the ones the app tests with instanceof. It is the same failure already visible in haverstack/server's node_modules, and with workspace:* it recurs on every patch release rather than being one-time drift. workspace:^ rewrites to ^0.9.0 instead. In the 0.x range that means >=0.9.0 <0.10.0, so patch releases dedupe to a single copy while a minor bump — which is this project's breaking-change signal — still requires a coordinated release. devDependencies keep workspace:*; they are never published. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D5LtyME9WJky9jaB51tpjp
|
Pushed a second commit (288005d) after a review question about whether anything pins a specific core version. Nothing hardcodes a version — but "dependencies": {
"@haverstack/core": "0.9.0",
"@haverstack/blob-adapter-disk": "0.7.0",
"@haverstack/record-adapter-sqlite": "0.1.0"
}That bakes the duplicate-copy hazard this PR's parent issue documents straight into the release. Publish a core It is the same failure already sitting in Fix: "dependencies": {
"@haverstack/core": "^0.9.0",
"@haverstack/blob-adapter-disk": "^0.7.0",
"@haverstack/record-adapter-sqlite": "^0.1.0"
}In the 0.x range
Re-verified after the change: 9 packages built, 9 typechecked, 1065 tests, format clean, and Generated by Claude Code |
Summary
Everything needed to publish the coordinated release in #167. Three things, all packaging.
1.
sqlite-sharedstays unpublished, and is now genuinely internal.docs/spec/adapters.mddescribed it as "an internal, non-public package", butrecord-adapter-sqlitedeclared it independenciesandtscemitted the import verbatim:So publishing
record-adapter-sqlitewould have meant publishingsqlite-sharedtoo — or shipping a package that cannot resolve at install time. This makes the documented intent true instead:record-adapter-sqlitebuilds withtsup, inliningsqlite-sharedand keeping@haverstack/coreexternal. Inlining core would give the package a private copy of the error classes and breakinstanceofagainst the caller's copy — the same class-identity hazard already visible inhaverstack/server's currentnode_modules.sqlite-sharedmoves todevDependenciesand is markedprivate.SqlExecutordisappears from the emitted.d.ts. It was only ever reachable through an internal file thattschappened to emit; a single-entry bundle drops it. The public surface is now exactlyNativeSQLiteRecordAdapter,NativeRecordInitializeOptions,NativeRecordOpenOptions,NativeTokenStore,NativeTokenStoreOptions,defaultTokenStorePath.node:sqliteis unaffected —src/node-sqlite.tsreaches it throughprocess.getBuiltinModule()rather than a static import, which survives bundling intact.2. Versions. For packages already on npm:
core0.8.0 → 0.9.0, andwire-types/adapter-local/blob-adapter-disk/adapter-api0.6.0 → 0.7.0.record-adapter-sqlite,conformance-fixturesandcommonsstay at 0.1.0 as first publishes. Every version currently in the repo is identical to what is already on the registry, sonpm publishwould reject all of them as-is.3. The publish surface is complete. Adds the two missing scripts (
publish:record-adapter-sqlite,publish:conformance-fixtures) andpublish:all, which runs all eight in dependency order so nothing is published before something it depends on.Closes the packaging half of #167. Follows #168, which reorganized the export surface.
Spec
docs/spec/adapters.md§ Package naming convention — thesqlite-sharedparagraph gains a statement that it is bundled rather than published, and thatSqlExecutoris therefore an internal collaborator rather than an extension point. That is the observable change: a third-party SQLite adapter can no longer be built by installingsqlite-shared, and the doc now says so rather than implying the opposite.Flagged as a real decision rather than a packaging tweak, because it forecloses something #161 (
record-adapter-do-sqlite) might have wanted — see Notes.CONTRIBUTING.mdandAGENTS.mdupdated to match, including a note thatsqlite-sharedbelongs indevDependenciesand that adding an export to it does not widen any package's public API. Both also drop stale references to "the two SQLite adapters", left over from therecord-adapter-sqljsremoval.Verification
verify:packis new (scripts/verify-pack.mjs) and is the one worth looking at. It packs every publishable package, installs the tarballs into a throwaway project outside the workspace, and imports each entry point. It covers two failure modes a green build cannot:exportsadded in Reorganize the public export surface: subpath entry points by concern, and an un-export audit #168 resolving from a real tarball rather than through a workspace link — a classic publish-time breakage;@haverstack/sqlite-sharedbeing absent from an installed tree, which is the regression guard for this PR.Both are silent until published, and unpublishing is not a clean remedy. Current output:
Checked by hand: the bundle's only external imports are
@haverstack/core,fsandcrypto;node:sqlitestill reached viaprocess.getBuiltinModule; the rolled.d.tsimports only from@haverstack/core,/adapterand/wire.CI needs no changes —
tsupis a devDependency, and the existing install → build → typecheck ordering already covers it.Notes for reviewers
This closes a door, deliberately.
docs/spec/adapters.mdsaidsqlite-sharedexists "so a second SQLite engine inherits the behavior rather than reimplementing it" while also calling it non-public — which only coexist if that second engine always lives in this repository. Bundling picks that reading. If #161'srecord-adapter-do-sqliteis meant to be buildable by a third party rather than merged here, this is the change to reconsider, and the remedy is small: publishsqlite-sharedand dropnoExternalfrom the tsup config. The spec now states the trade-off explicitly so it is a decision rather than an accident.record-adapter-sqliteis the only package that changed build tooling. Everything else stays on plaintsc. Worth a look at whether one bundler in an otherwise uniform repo is an acceptable cost — the alternative was publishingsqlite-shared.Version numbering is a judgement call. 0.9.0 for core follows #167's suggestion, holding 1.0.0 for when
haverstack/serverpasses the conformance suite — the point at which the wire protocol has been demonstrated by a second implementation. The 0.6.0 → 0.7.0 group keeps the existing pattern of adapters versioning independently of core.Not in scope: git tags and release notes, both still open on #167.
verify:packis not wired into CI — it packs and installs, so it is slower than the other jobs, and it is most useful as a pre-publish gate. Adding it as a release-workflow step would be reasonable follow-up.🤖 Generated with Claude Code
https://claude.ai/code/session_01D5LtyME9WJky9jaB51tpjp
Generated by Claude Code