Skip to content

Add Bun-first SQLite runtime adapter for Node-targeted bundles#5

Open
Copilot wants to merge 5 commits into
mainfrom
copilot/fix-node-targeted-npm-clis
Open

Add Bun-first SQLite runtime adapter for Node-targeted bundles#5
Copilot wants to merge 5 commits into
mainfrom
copilot/fix-node-targeted-npm-clis

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 17, 2026

Node-targeted consumers could still fail at runtime because the package statically imported bun:sqlite, which survives bundling into Node CLI artifacts. This change keeps Bun as the primary runtime while allowing Node consumers to load the package without pulling in bun:* imports at module initialization.

  • Runtime backend selection

    • Replace the top-level bun:sqlite import with a runtime-selected SQLite adapter.
    • Prefer bun:sqlite on Bun.
    • Fall back to built-in node:sqlite on supported Node runtimes.
  • Engine/store lifecycle

    • Make SecretStore.open() asynchronous so the backend can be resolved lazily.
    • Update engine call sites to await store initialization without changing the public SecretsEngine API.
  • Packaging and runtime expectations

    • Build the published package for a Node target so bundled consumers do not retain a hard bun:sqlite dependency.
    • Document Bun-first/Node-compatible runtime behavior and the Node requirement for built-in SQLite support.
  • Regression coverage

    • Add a bundle-level regression test that builds a Node-targeted consumer and executes it under Node to verify the package no longer fails with ERR_UNSUPPORTED_ESM_URL_SCHEME.
import { SecretsEngine } from "@wgtechlabs/secrets-engine";

const secrets = await SecretsEngine.open({ path: "/tmp/secrets-store" });
await secrets.set("cli.version", "1.0.0");

console.log(await secrets.get("cli.version"));

await secrets.close();
Original prompt

This section details on the original issue you should resolve

<issue_title>Node-targeted npm CLIs fail because the package imports bun:sqlite</issue_title>
<issue_description>## Summary
Using @wgtechlabs/secrets-engine in a package that is built for Node and published to npm can fail at runtime because the package imports bun:sqlite.

In practice this makes the package Bun-only for bundled Node CLI releases, even when the consumer application itself targets Node.

Repro

Consumer build:

bun build src/index.ts --outfile dist/index.js --target node
node dist/index.js --version

Actual result

Node fails during module loading with:

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. Received protocol 'bun:'

Why this matters

I hit this in a released npm CLI because Bun bundled the dependency graph into a Node-targeted artifact, and the resulting build still contained bun:sqlite imports.

That means the package is not currently safe to consume from a published Node CLI unless the consumer is also effectively Bun-only.

Expected result

One of these should happen:

  1. The package provides a Node-safe backend or conditional runtime adapter.
  2. The package clearly documents that it is Bun-only.
  3. The package exposes a storage abstraction that allows Node consumers to avoid bundling bun:* imports.

Notes

I am happy to help test a fix from the consumer side.
</issue_description>

<agent_instructions>Let's add support to both Node and Bun but make the bun the primary support.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits March 17, 2026 14:23
Co-authored-by: warengonzaga <15052701+warengonzaga@users.noreply.github.com>
Co-authored-by: warengonzaga <15052701+warengonzaga@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix npm CLIs failing due to bun:sqlite import Add Bun-first SQLite runtime adapter for Node-targeted bundles Mar 17, 2026
Copilot AI requested a review from warengonzaga March 17, 2026 14:28
@warengonzaga warengonzaga marked this pull request as ready for review April 29, 2026 06:24
Copilot AI review requested due to automatic review settings April 29, 2026 06:24
@github-project-automation github-project-automation Bot moved this to Backlog in Workbench Apr 29, 2026
@warengonzaga warengonzaga moved this from Backlog to In Review in Workbench Apr 29, 2026
@warengonzaga warengonzaga added core [Area] Core logic, business rules, and primary functionality [issues, PRs] enhancement [Type] New feature or improvement to existing functionality [issues, PRs] data [Area] Database, storage, caching, or data models [issues, PRs] infra [Area] Build system, CI/CD, deployment, config, and DevOps [issues, PRs] labels Apr 29, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a runtime-selected SQLite adapter so @wgtechlabs/secrets-engine can be bundled for (and executed on) Node without a hard bun:sqlite import at module init time, while keeping Bun as the preferred runtime.

Changes:

  • Replace static bun:sqlite import with a lazy runtime adapter that prefers Bun and falls back to node:sqlite.
  • Make SecretStore.open() async and update engine call sites to await store initialization.
  • Update packaging/metadata + docs, and add a regression test that bundles a Node-targeted consumer and runs it under Node.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/engine.test.ts Adds a bundle-level regression test that builds for target: "node" and executes via node
src/store.ts Introduces runtime-selected SQLite opener (Bun-first, Node fallback) and makes SecretStore.open() async
src/engine.ts Awaits async store initialization in engine open + detached-store cleanup
package.json Builds dist with --target node and declares engines.node >= 22.5.0
README.md Documents Bun-first / Node-compatible behavior and Node’s built-in sqlite requirement

Comment thread tests/engine.test.ts Outdated
@warengonzaga
Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 29, 2026

@copilot apply changes based on the comments in this thread

Applied the thread feedback in 58939a9. The Node-targeted bundle regression now skips when the local node runtime cannot import node:sqlite, so Node 20 CI won’t fail while newer Node runtimes still exercise the path.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment thread tests/engine.test.ts
Comment on lines +70 to +71
const nodeSqliteRuntimeTest = supportsNodeSqliteRuntime() ? test : test.skip;

Comment thread tests/engine.test.ts Outdated
Comment on lines +97 to +126
const bundlePath = join(testDir, "dist", "consumer.js");
const nodeStorePath = join(testDir, "node-store");
const sourceImport = relative(testDir, join(process.cwd(), "src/index.ts")).replaceAll(
"\\",
"/",
);

await writeFile(
consumerEntry,
`
import { SecretsEngine } from ${JSON.stringify(sourceImport)};

const secrets = await SecretsEngine.open({ path: ${JSON.stringify(nodeStorePath)} });
await secrets.set("cli.version", "1.0.0");
console.log(await secrets.get("cli.version"));
await secrets.close();
`,
);

const buildResult = await Bun.build({
entrypoints: [consumerEntry],
outfile: bundlePath,
target: "node",
});

expect(buildResult.success).toBe(true);

const result = spawnSync("node", [bundlePath], {
encoding: "utf-8",
});
@warengonzaga
Copy link
Copy Markdown
Member

@copilot apply code review as necessary as possible.

Agent-Logs-Url: https://github.com/wgtechlabs/secrets-engine/sessions/ada469b0-2d80-4373-be8b-f7106b172483

Co-authored-by: warengonzaga <15052701+warengonzaga@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 3, 2026

@copilot apply code review as necessary as possible.

Applied the remaining review fixes in 87f86ba. CI now uses Node 22.5.0 so the Node SQLite regression runs on a supported runtime, and the generated bundle now uses .mjs so Node exercises the ESM loader path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Area] Core logic, business rules, and primary functionality [issues, PRs] data [Area] Database, storage, caching, or data models [issues, PRs] enhancement [Type] New feature or improvement to existing functionality [issues, PRs] infra [Area] Build system, CI/CD, deployment, config, and DevOps [issues, PRs]

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

Node-targeted npm CLIs fail because the package imports bun:sqlite

3 participants