Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Commands

Use Node.js 24 or newer for all commands in this repository. Native dependencies such as
`better-sqlite3` are built against the active Node ABI, so running Vitest or `npx` with Node 20
can produce misleading SQLite failures.
Use Node.js 24 or newer for all commands in this repository. The SQLite backend uses the
built-in `node:sqlite` module, which is only stable from Node 24 (it is experimental and
flag-gated on older releases), so running Vitest or `npx` with an older Node can produce
misleading SQLite failures.

```sh
bun run build # Full build (all packages + integrations + examples, via Turbo)
Expand Down Expand Up @@ -68,7 +69,7 @@ Each package builds two runtime targets via `bun build --target=X`:

Types built with `tsc` (composite + incremental). Conditional exports in `package.json` resolve automatically per runtime.

**No `bun` entry unless it differs.** Bun is not a build target by default: with no `"bun"` condition in `exports`, Bun resolves the default `"import"` and loads the node build. Add a `src/bun.ts`, a `--target=bun` build, and a `"bun"` export condition only when the Bun code genuinely differs — a duplicate of `node.ts` is a third bundle and a third `.d.ts` to keep in sync for no behavior change. Only three entries qualify today: `@workglow/util`'s `"."` (`Worker.bun` vs `Worker.node`), `@workglow/util`'s `"./worker"` (`dist/worker-bun.js` vs `dist/worker-node.js`), and `@workglow/sqlite`'s `./storage` (`bun:sqlite` vs the node driver). That set is pinned by `packages/test/src/test/util/BunExportConditions.test.ts` — adding or removing a `"bun"` condition fails it until the fixture and this paragraph are updated together.
**No `bun` entry unless it differs.** Bun is not a build target by default: with no `"bun"` condition in `exports`, Bun resolves the default `"import"` and loads the node build. Add a `src/bun.ts`, a `--target=bun` build, and a `"bun"` export condition only when the Bun code genuinely differs — a duplicate of `node.ts` is a third bundle and a third `.d.ts` to keep in sync for no behavior change. Only two entries qualify today: `@workglow/util`'s `"."` (`Worker.bun` vs `Worker.node`) and `@workglow/util`'s `"./worker"` (`dist/worker-bun.js` vs `dist/worker-node.js`). `@workglow/sqlite`'s `./storage` used to, but both runtimes now share the `node:sqlite` driver. That set is pinned by `packages/test/src/test/util/BunExportConditions.test.ts` — adding or removing a `"bun"` condition fails it until the fixture and this paragraph are updated together.

Exception: vendor packages under `providers/*` (e.g. `@workglow/anthropic`, `@workglow/openai`, `@workglow/google-gemini`) ship `./ai` and `./ai-runtime` sub-paths instead of browser/node.

Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/nightly-typecheck.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# `bun-version: canary` matches `engines.bun` / `packageManager`: no tagged Bun
# release carries `node:sqlite` yet, which @workglow/sqlite/storage requires.
name: Nightly type-drift guard
permissions:
contents: read
Expand All @@ -19,7 +21,7 @@ jobs:
node-version: 24
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
bun-version: canary
- run: bun i
- name: Build type declarations
run: bun run build:types
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-preview.yml-off
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
node-version: 24
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
bun-version: canary
- run: bun i
- run: bun run build
# Publish every workspace under packages/* and providers/* as a PR-
Expand Down
10 changes: 0 additions & 10 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docs/technical/18-multi-runtime-abstraction.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ Bun supports every Node.js API the packages here rely on, so a `bun.ts` that is
copy of `node.ts` buys nothing but a third build target and a third `.d.ts` to keep in sync. With
no `"bun"` condition in `exports`, Bun falls through to the `"import"`/`"types"` default and gets
the Node entry — the same code the duplicated file would have given it. Only two entries in the
monorepo earn a Bun build: `@workglow/util` (`Worker.bun` vs `Worker.node`) and
`@workglow/sqlite`'s `./storage` sub-path (`bun:sqlite` vs the Node driver).
monorepo earn a Bun build, both in `@workglow/util`: its `"."` and `"./worker"` sub-paths
(`Worker.bun` vs `Worker.node`).

Each platform entry point re-exports everything from `common.ts` and then layers on
platform-specific modules. For `@workglow/util`, the entry points look like this:
Expand Down
24 changes: 11 additions & 13 deletions docs/technical/19-build-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,12 @@ Bun is not a third target by default. A package's `exports` carries no `"bun"` c
resolves the default `"import"` and loads `dist/node.js` — which is exactly what a `src/bun.ts`
identical to `src/node.ts` would have produced. Add a `src/bun.ts`, a `--target=bun` build, and a
`"bun"` export condition only when the Bun code genuinely differs; a duplicate is a third bundle
and a third `.d.ts` to keep in sync for no behavior change. Three entries qualify today:
`@workglow/util`'s `"."` (`Worker.bun` vs `Worker.node`), `@workglow/util`'s `"./worker"`
(`dist/worker-bun.js` vs `dist/worker-node.js`), and `@workglow/sqlite`'s `./storage`
(`bun:sqlite` vs the Node driver). That set is pinned by
and a third `.d.ts` to keep in sync for no behavior change. Two entries qualify today, both in
`@workglow/util`: `"."` (`Worker.bun` vs `Worker.node`) and `"./worker"` (`dist/worker-bun.js`
vs `dist/worker-node.js`). `@workglow/sqlite`'s `./storage` used to, but both runtimes now share
the `node:sqlite` driver. That set is pinned by
`packages/test/src/test/util/BunExportConditions.test.ts`, which fails in both directions — on a
redundant `"bun"` condition added back, and on one of the three being deleted.
redundant `"bun"` condition added back, and on one of the two being deleted.

Each build command follows the same template:

Expand All @@ -260,9 +260,8 @@ tree-shaking impossible for downstream consumers.

### Extended Pattern (util)

`@workglow/util` has additional entry points beyond the standard two, and accounts for two of the
three `--target=bun` builds that a surviving `"bun"` export condition still earns (`bun.ts` and
`worker-bun.ts`; the third is `@workglow/sqlite`'s `storage/bun.ts`). Each sub-path export
`@workglow/util` has additional entry points beyond the standard two, and is the only package that
still earns a `--target=bun` build — twice (`bun.ts` and `worker-bun.ts`). Each sub-path export
gets its own build:

```
Expand Down Expand Up @@ -323,15 +322,14 @@ Storage backend packages build one set of entry points per sub-path export:
```
src/storage/browser.ts → dist/storage/browser.js (--target=browser)
src/storage/node.ts → dist/storage/node.js (--target=node)
src/storage/bun.ts → dist/storage/bun.js (--target=bun) # @workglow/sqlite only
src/job-queue/browser.ts → dist/job-queue/browser.js (--target=browser)
src/job-queue/node.ts → dist/job-queue/node.js (--target=node)
```

`@workglow/sqlite`'s `./storage` is the one sub-path with a real Bun build: it selects `bun:sqlite`
where the Node entry selects the Node driver. Its `./job-queue`, and every sub-path of
`@workglow/postgres` / `@workglow/supabase` / `@workglow/aws` / `@workglow/duckdb`, is
runtime-agnostic on the server and serves Bun from the Node build.
No storage backend has a Bun build. Every server sub-path here — including `@workglow/sqlite`'s
`./storage`, which now drives the built-in `node:sqlite` on both runtimes — is runtime-agnostic
and serves Bun from the Node build, as do all sub-paths of `@workglow/postgres` /
`@workglow/supabase` / `@workglow/aws` / `@workglow/duckdb`.

Note that the output directories for sub-paths (`dist/storage/`, `dist/job-queue/`) use
`--outdir ./dist/storage` etc. to place them in nested directories matching the sub-path export
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
"@duckdb/node-api": "^1.5.5-r.4",
"@sqlite.org/sqlite-wasm": "^3.53.0-build1",
"@sqliteai/sqlite-vector": "^1.0.0",
"better-sqlite3": "^13.0.3",
"@aws-sdk/client-sqs": "^3.1111.0",
"@cloudflare/workers-types": "^5.20260815.1",
"fake-indexeddb": "^6.2.4",
Expand Down Expand Up @@ -138,11 +137,11 @@
"vitest": "catalog:"
},
"engines": {
"bun": "^1.3.11"
"bun": "^1.4.0-canary.1",
"node": ">=24"
},
"packageManager": "bun@1.3.11",
"packageManager": "bun@1.4.0-canary.1",
"trustedDependencies": [
"better-sqlite3",
"node-llama-cpp",
"onnxruntime-node",
"protobufjs",
Expand Down
2 changes: 1 addition & 1 deletion packages/storage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ import { InMemoryKvStorage, SqliteTabularStorage } from "@workglow/storage";

### SQLite setup (`@workglow/storage/sqlite`)

Before you open SQLite with a **file path** or construct **`new Sqlite.Database(...)`**, call **`await Sqlite.init()`** once per runtime (Node.js, Bun, or browser). Export is available from **`workglow`** and **`@workglow/storage/sqlite`**. The call is idempotent. On the browser it loads the SQLite WASM build; on Node.js it loads `better-sqlite3`; on Bun it resolves `bun:sqlite`.
Before you open SQLite with a **file path** or construct **`new Sqlite.Database(...)`**, call **`await Sqlite.init()`** once per runtime (Node.js, Bun, or browser). Export is available from **`workglow`** and **`@workglow/storage/sqlite`**. The call is idempotent. On the browser it loads the SQLite WASM build; on Node.js and Bun it loads the built-in `node:sqlite` (Node 24+ / Bun 1.4+).

## Storage Types

Expand Down
2 changes: 1 addition & 1 deletion packages/storage/src/tabular/defineConnectionMutex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { Als } from "./connectionAls.shared";
* Cross-instance connection safety for storage backends that share a single
* underlying database handle across multiple in-process
* {@link BaseSqlTabularStorage} instances (e.g. two SqliteTabularStorage
* repositories wrapping the same `better-sqlite3` `Database`, or two
* repositories wrapping the same `node:sqlite` `DatabaseSync`, or two
* PostgresTabularStorage repositories over one PGlite session).
*
* A per-instance mutex only serializes calls that reach a single storage
Expand Down
Loading
Loading