diff --git a/docs-internal/rivetkit-typescript/DYNAMIC_ACTOR_SQLITE_PROXY_SPEC.md b/docs-internal/rivetkit-typescript/DYNAMIC_ACTOR_SQLITE_PROXY_SPEC.md deleted file mode 100644 index 435f1c784d..0000000000 --- a/docs-internal/rivetkit-typescript/DYNAMIC_ACTOR_SQLITE_PROXY_SPEC.md +++ /dev/null @@ -1,275 +0,0 @@ -# Dynamic Actor SQLite Proxy Spec - -## Problem - -Dynamic actors run in sandboxed `secure-exec` / `isolated-vm` processes. The current SQLite path requires `@rivetkit/sqlite` WASM to load inside the isolate, which isn't set up and is the wrong direction — we plan to add a native SQLite extension on the host side. Dynamic actors need a way to use `db()` and `db()` from `rivetkit/db` and `rivetkit/db/drizzle` without running WASM in the isolate. - -## Approach - -Run SQLite on the **host side** and bridge a thin `execute(sql, params) → rows` RPC from isolate → host. The `ActorDriver` already has `overrideRawDatabaseClient()` and `overrideDrizzleDatabaseClient()` hooks designed for this exact purpose. The `DatabaseProvider.createClient()` already checks for overrides before falling back to KV-backed construction. - -``` -Isolate Host -────── ──── -db.execute(sql, args) ──bridge──► host SQLite (per-actor) - ◄────────── { rows, columns } -``` - -One bridge call per query instead of per KV page. - -## Architecture - -### Host side (manager process) - -Each actor gets a dedicated SQLite database file managed by the host. For the file-system driver, this is already done for KV via `#actorKvDatabases` in `FileSystemGlobalState`. The actor's **application database** is a separate SQLite file alongside the KV database. - -The host exposes two bridge callbacks to the isolate: - -1. **`sqliteExec(actorId, sql, params) → string`** — Executes a SQL statement. Returns JSON-encoded `{ rows: unknown[][], columns: string[] }`. Handles both read and write queries. Params are JSON-serialized across the boundary. - -2. **`sqliteBatch(actorId, statements) → string`** — Executes multiple SQL statements in a single bridge call, wrapped in a transaction. Each statement is `{ sql: string, params: unknown[] }`. Returns JSON-encoded array of `{ rows, columns }` per statement. This is critical for migrations and reduces bridge round-trips. - -### Isolate side (dynamic actor process) - -The isolate-side `actorDriver` (defined in `host-runtime.ts` line 1767) gains: - -- `overrideRawDatabaseClient(actorId)` — Returns a `RawDatabaseClient` whose `exec()` method calls through the bridge to `sqliteExec`. -- `overrideDrizzleDatabaseClient(actorId)` — Returns a drizzle `sqlite-proxy` instance whose async callback calls through the bridge to `sqliteExec`. - -Because the overrides are set, `DatabaseProvider.createClient()` in both `db/mod.ts` and `db/drizzle/mod.ts` will use them instead of trying to construct a KV-backed WASM SQLite. No `createSqliteVfs()` is needed in the dynamic actor driver. - -## Detailed Changes - -### 1. Bridge contract (`src/dynamic/runtime-bridge.ts`) - -Add new bridge global keys: - -```typescript -export const DYNAMIC_HOST_BRIDGE_GLOBAL_KEYS = { - // ... existing keys ... - sqliteExec: "__rivetkitDynamicHostSqliteExec", - sqliteBatch: "__rivetkitDynamicHostSqliteBatch", -} as const; -``` - -### 2. Host-side SQLite pool (`src/drivers/file-system/global-state.ts`) - -Add a **per-actor application database** map alongside the existing KV database map: - -```typescript -#actorAppDatabases = new Map(); -``` - -Add methods: - -```typescript -#getOrCreateActorAppDatabase(actorId: string): SqliteRuntimeDatabase -// Opens/creates a SQLite database file at: /app-databases/.db -// Separate from the KV database. Enables WAL mode for concurrency. - -#closeActorAppDatabase(actorId: string): void -// Called during actor teardown, alongside #closeActorKvDatabase. - -sqliteExec(actorId: string, sql: string, params: unknown[]): { rows: unknown[][], columns: string[] } -// Runs a single statement against the actor's app database. -// Uses the same SqliteRuntime (bun:sqlite / better-sqlite3) already loaded. -// Synchronous — native SQLite is sync, the bridge async wrapper handles the rest. - -sqliteBatch(actorId: string, statements: { sql: string, params: unknown[] }[]): { rows: unknown[][], columns: string[] }[] -// Wraps all statements in BEGIN/COMMIT. Returns results per statement. -``` - -Cleanup: extend `#destroyActorData` and actor teardown to also close and delete app databases. - -### 3. Host bridge wiring — `isolated-vm` path (`src/dynamic/isolate-runtime.ts`) - -In `#setIsolateBridge()` (around line 880), add refs for the new bridge callbacks: - -```typescript -const sqliteExecRef = makeRef( - async (actorId: string, sql: string, paramsJson: string): Promise<{ copy(): string }> => { - const params = JSON.parse(paramsJson); - const result = this.#config.globalState.sqliteExec(actorId, sql, params); - return makeExternalCopy(JSON.stringify(result)); - }, -); - -const sqliteBatchRef = makeRef( - async (actorId: string, statementsJson: string): Promise<{ copy(): string }> => { - const statements = JSON.parse(statementsJson); - const results = this.#config.globalState.sqliteBatch(actorId, statements); - return makeExternalCopy(JSON.stringify(results)); - }, -); - -await context.global.set(DYNAMIC_HOST_BRIDGE_GLOBAL_KEYS.sqliteExec, sqliteExecRef); -await context.global.set(DYNAMIC_HOST_BRIDGE_GLOBAL_KEYS.sqliteBatch, sqliteBatchRef); -``` - -### 4. Host bridge wiring — `secure-exec` path (`src/dynamic/host-runtime.ts`) - -In `#setIsolateBridge()` (around line 586), add the same refs using the same base64/JSON bridge pattern already used for KV: - -```typescript -const sqliteExecRef = makeRef( - async (actorId: string, sql: string, paramsJson: string): Promise => { - const params = JSON.parse(paramsJson); - const result = this.#config.globalState.sqliteExec(actorId, sql, params); - return JSON.stringify(result); - }, -); -// ... same for sqliteBatch - -await context.global.set("__dynamicHostSqliteExec", sqliteExecRef); -await context.global.set("__dynamicHostSqliteBatch", sqliteBatchRef); -``` - -And on the isolate-side `actorDriver` object (line 1767), add: - -```typescript -const actorDriver = { - // ... existing methods ... - - async overrideRawDatabaseClient(actorIdValue) { - return { - exec: async (query, ...args) => { - const resultJson = await bridgeCall( - globalThis.__dynamicHostSqliteExec, - [actorIdValue, query, JSON.stringify(args)] - ); - const { rows, columns } = JSON.parse(resultJson); - return rows.map((row) => { - const obj = {}; - for (let i = 0; i < columns.length; i++) { - obj[columns[i]] = row[i]; - } - return obj; - }); - }, - }; - }, - - async overrideDrizzleDatabaseClient(actorIdValue) { - // Return undefined — let the raw override handle it. - // Drizzle provider will fall back to using the raw override path. - return undefined; - }, -}; -``` - -### 5. Drizzle support - -The drizzle `DatabaseProvider` in `db/drizzle/mod.ts` currently does NOT check for overrides — it always constructs a KV-backed WASM database. This needs to change. - -Add an override check at the top of `createClient`: - -```typescript -createClient: async (ctx) => { - // Check for drizzle override first - if (ctx.overrideDrizzleDatabaseClient) { - const override = await ctx.overrideDrizzleDatabaseClient(); - if (override) { - // Wrap with RawAccess execute/close methods and return - return Object.assign(override, { - execute: async (query, ...args) => { /* delegate to override */ }, - close: async () => {}, - }); - } - } - - // Check for raw override — build drizzle sqlite-proxy on top of it - if (ctx.overrideRawDatabaseClient) { - const rawOverride = await ctx.overrideRawDatabaseClient(); - if (rawOverride) { - const callback = async (sql, params, method) => { - const rows = await rawOverride.exec(sql, ...params); - if (method === "run") return { rows: [] }; - if (method === "get") return { rows: rows[0] ? Object.values(rows[0]) : undefined }; - return { rows: rows.map(r => Object.values(r)) }; - }; - const client = proxyDrizzle(callback, config); - return Object.assign(client, { - execute: async (query, ...args) => rawOverride.exec(query, ...args), - close: async () => {}, - }); - } - } - - // Existing KV-backed path... -} -``` - -This lets dynamic actors use `db()` from `rivetkit/db/drizzle` with migrations working through the bridge. The host runs the actual SQL; the isolate just sends strings. - -### 6. Migrations - -Drizzle inline migrations (`runInlineMigrations`) currently operate on the `@rivetkit/sqlite` `Database` WASM instance directly. For the proxy path, migrations need to run through the same `execute()` bridge. - -Option A (simpler): The raw override's `exec()` already supports multi-statement SQL via the host's `db.exec()`. Migrations can use `execute()` directly. The `sqliteBatch` bridge method handles transactional migration application. - -Option B: Add a dedicated `sqliteMigrate(actorId, migrationSql[])` bridge call that runs all migrations in a single transaction on the host. Cleaner but more surface area. - -**Recommendation**: Option A. The `execute()` path is sufficient. The drizzle provider's `onMigrate` can call `client.execute(migrationSql)` for each pending migration, same as it does today but through the bridge. - -### 7. Engine driver (`src/drivers/engine/actor-driver.ts`) - -The engine driver manages dynamic actors the same way. It needs the same `sqliteExec` / `sqliteBatch` bridge wiring, backed by whatever storage the engine provides for actor application databases. - -For now, this can be deferred — the engine driver can continue using the KV-backed path for static actors and throw a clear error for dynamic actors that try to use `db()` until the engine-side SQLite proxy is implemented. - -## Data model - -Each dynamic actor gets TWO SQLite databases on the host: - -| Database | Purpose | Path | Managed by | -|----------|---------|------|------------| -| KV database | Actor KV state (`kvBatchPut`/`kvBatchGet`) | `/databases/.db` | Existing `#actorKvDatabases` | -| App database | User-defined schema via `db()` / drizzle | `/app-databases/.db` | New `#actorAppDatabases` | - -On actor destroy, both databases are deleted. On actor sleep, both databases are closed (and reopened on wake). - -## Serialization format - -All data crosses the bridge as JSON strings: - -- **Params**: `JSON.stringify(args)` — supports `null`, `number`, `string`, `boolean`. Binary (`Uint8Array`) params are base64-encoded. -- **Results**: `JSON.stringify({ rows: unknown[][], columns: string[] })` — column-oriented format, same as `@rivetkit/sqlite`'s `query()` return shape. -- **Batch**: Array of the above per statement. - -## Error handling - -- SQL errors on the host throw through the bridge. The isolate receives the error message and stack trace as a rejected promise. -- If the actor's app database doesn't exist yet, `sqliteExec` creates it on first use (same lazy-open pattern as KV databases). -- Invalid SQL, constraint violations, etc. surface as normal SQLite errors to the actor code. - -## Testing - -Add an engine-focused integration test that: - -1. Creates a dynamic actor that uses `db()` (raw) with a simple schema -2. Runs migrations, inserts rows, queries them back -3. Verifies data persists across actor sleep/wake cycles -4. Creates a dynamic actor that uses `db()` from `rivetkit/db/drizzle` with schema + migrations -5. Verifies drizzle queries work through the proxy - -Add corresponding fixture actors in the shared sandbox-style test fixtures. - -## Files to modify - -| File | Change | -|------|--------| -| `src/dynamic/runtime-bridge.ts` | Add `sqliteExec`, `sqliteBatch` bridge keys | -| `src/drivers/file-system/global-state.ts` | Add `#actorAppDatabases`, `sqliteExec()`, `sqliteBatch()`, cleanup | -| `src/dynamic/isolate-runtime.ts` | Wire `sqliteExec`/`sqliteBatch` refs in `#setIsolateBridge()` | -| `src/dynamic/host-runtime.ts` | Wire bridge refs + add `overrideRawDatabaseClient` to isolate-side `actorDriver` | -| `src/db/drizzle/mod.ts` | Add override check at top of `createClient` | -| `tests/` | New engine-focused integration test for dynamic SQLite proxy | -| shared test fixtures | New fixture actors using `db()` in dynamic actors | -| `docs-internal/rivetkit-typescript/DYNAMIC_ACTORS_ARCHITECTURE.md` | Document SQLite proxy bridge | - -## Non-goals - -- Running WASM SQLite inside the isolate. -- Implementing this for the engine driver (deferred until engine-side app database support exists). -- Shared/cross-actor databases. -- Direct filesystem access from the isolate. diff --git a/docs-internal/rivetkit-typescript/SQLITE_VFS.md b/docs-internal/rivetkit-typescript/SQLITE_VFS.md deleted file mode 100644 index ccc5d23059..0000000000 --- a/docs-internal/rivetkit-typescript/SQLITE_VFS.md +++ /dev/null @@ -1,57 +0,0 @@ -# SQLite VFS (`@rivetkit/sqlite-wasm`) - -## How It Works -- SQLite issues byte-range reads/writes; VFS translates to chunked KV operations -- `CHUNK_SIZE = 4096` — each chunk is one KV key -- `xWrite`: computes touched chunks, read-modify-write for partial updates, `putBatch` -- `xRead`: fetches chunk range, copies bytes, zero-fills gaps -- Metadata (file size) stored alongside chunks via `metaKey` - -## Single-Writer Model -- Actors are single-writer, so `xLock`/`xUnlock` are no-ops -- No need for WAL (its benefit is concurrent readers/writer) -- Double mutex exists: `db/mod.ts` + `vfs.ts` — redundant under single-writer - -## Current Journal/WAL Status -- Actor KV path: DELETE journal mode (SQLite default), no WAL -- File-system driver: uses WAL (standard WAL, not WAL2) -- WAL not recommended for KV-backed VFS due to checkpoint traffic on high-latency KV - -## Caching -- SQLite has its own page cache; VFS-level chunk cache would mostly duplicate it -- VFS cache only helps if KV RTT is very high and pages churn — treat as benchmark-driven, not default - -## Pending TODOs -- Measure `xAccess` KV round-trip overhead during DB open -- Benchmark `journal_mode=PERSIST` + `journal_size_limit` (fewer KV deletes per txn) -- Fast-path delete-on-close: reuse in-memory `file.size` instead of extra `metaKey` read -- Add per-method metrics for `xOpen`/`xAccess`/`xRead`/`xWrite`/`xTruncate`/`xDelete` and KV call counts/latency -- Measure journal-file traffic volume (create/write/delete) before any IOCAP or PRAGMA changes -- Implement `xSectorSize = CHUNK_SIZE` (4096) and benchmark impact -- Reduce `xTruncate` round trips by batching last-chunk rewrite + metadata update in one `putBatch` where possible -- Validate and document page-size alignment expectations (`page_size = CHUNK_SIZE`) - -## Decisions Made -- Do NOT defer metadata writes to `xSync`/`xClose` — crash risk outweighs minimal gain (metadata already batched with chunk data in `putBatch`) -- Do NOT enable `journal_mode=MEMORY`, `journal_mode=OFF`, or `synchronous=OFF` -- `journal_mode=PERSIST` is safe to switch to later (no migration needed) - -## Native SQLite Backend - -The WASM VFS described above has a native Rust counterpart (`@rivetkit/sqlite-native`) that statically links SQLite via napi-rs and routes VFS callbacks over a WebSocket-based KV channel protocol. The native backend shares one SQLite library across all actors (vs. one WASM module instance per actor), reducing memory overhead and removing JS from the I/O hot path. Data is fully compatible between backends. An actor can switch between WASM and native without migration. - -Key implementation files: - -- `rivetkit-typescript/packages/sqlite-native/` — napi-rs addon (Rust): `vfs.rs`, `kv.rs`, `channel.rs`, `protocol.rs`, `lib.rs` -- `engine/sdks/schemas/kv-channel-protocol/` — BARE schema and TypeScript codec -- `engine/packages/pegboard-kv-channel/` — engine-side KV channel WebSocket server -- `rivetkit-typescript/packages/rivetkit/src/manager/kv-channel.ts` — manager-side KV channel handler -- `rivetkit-typescript/packages/rivetkit/src/db/native-sqlite.ts` — integration and WASM fallback logic - -## Future Work -- **PITR / fork**: implement at KV layer (immutable chunk versions, manifests, branch heads, GC) with SQLite layer providing snapshot boundary coordination -- **Remove double mutex** once profiled -- **IOCAP exploration (guarded)**: - - Do not set `SQLITE_IOCAP_BATCH_ATOMIC` unless actor KV `putBatch` atomicity is proven and `xFileControl` atomic-write opcodes are handled correctly. - - `SQLITE_IOCAP_ATOMIC4K` is only safe if single-key KV writes are crash-atomic at 4 KiB granularity. - - Prioritize metrics and correctness proof before enabling either flag. diff --git a/examples/sandbox/package.json b/examples/sandbox/package.json index ce497a69d5..e71fb925e3 100644 --- a/examples/sandbox/package.json +++ b/examples/sandbox/package.json @@ -28,8 +28,7 @@ "drizzle-orm": "^0.44.2", "@hono/node-server": "^1.19.7", "@hono/node-ws": "^1.3.0", - "@rivetkit/react": "^2.3.0-rc.4", - "@rivetkit/sqlite-wasm": "*", + "@rivetkit/react": "*", "ai": "^4.0.38", "fdb-tuple": "^1.0.0", "hono": "^4.11.3", @@ -38,7 +37,7 @@ "prism-react-renderer": "^2.4.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "rivetkit": "^2.3.0-rc.4", + "rivetkit": "*", "srvx": "^0.10.0", "zod": "^3.25.69" }, diff --git a/examples/sandbox/pnpm-lock.yaml b/examples/sandbox/pnpm-lock.yaml deleted file mode 100644 index 1212e38fc3..0000000000 --- a/examples/sandbox/pnpm-lock.yaml +++ /dev/null @@ -1,4030 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@ai-sdk/openai': - specifier: ^0.0.66 - version: 0.0.66(zod@3.25.76) - '@hono/node-server': - specifier: ^1.19.7 - version: 1.19.11(hono@4.12.9) - '@hono/node-ws': - specifier: ^1.3.0 - version: 1.3.0(@hono/node-server@1.19.11(hono@4.12.9))(hono@4.12.9) - '@rivetkit/react': - specifier: 2.1.7 - version: 2.1.7(@standard-schema/spec@1.0.0)(drizzle-kit@0.31.10)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ws@8.20.0) - ai: - specifier: ^4.0.38 - version: 4.3.19(react@18.3.1)(zod@3.25.76) - drizzle-orm: - specifier: ^0.44.2 - version: 0.44.7(@opentelemetry/api@1.9.0) - fdb-tuple: - specifier: ^1.0.0 - version: 1.0.0 - hono: - specifier: ^4.11.3 - version: 4.12.9 - lucide-react: - specifier: ^0.439.0 - version: 0.439.0(react@18.3.1) - mermaid: - specifier: ^11.12.2 - version: 11.13.0 - prism-react-renderer: - specifier: ^2.4.1 - version: 2.4.1(react@18.3.1) - react: - specifier: ^18.2.0 - version: 18.3.1 - react-dom: - specifier: ^18.2.0 - version: 18.3.1(react@18.3.1) - rivetkit: - specifier: 2.1.7 - version: 2.1.7(@standard-schema/spec@1.0.0)(drizzle-kit@0.31.10)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0))(ws@8.20.0) - srvx: - specifier: ^0.10.0 - version: 0.10.1 - zod: - specifier: ^3.25.69 - version: 3.25.76 - devDependencies: - '@types/node': - specifier: ^22.13.9 - version: 22.19.15 - '@types/react': - specifier: ^18.2.0 - version: 18.3.28 - '@types/react-dom': - specifier: ^18.2.0 - version: 18.3.7(@types/react@18.3.28) - '@vitejs/plugin-react': - specifier: ^4.2.0 - version: 4.7.0(vite@5.4.21(@types/node@22.19.15)) - drizzle-kit: - specifier: ^0.31.2 - version: 0.31.10 - tsx: - specifier: ^4.20.6 - version: 4.21.0 - typescript: - specifier: ^5.5.2 - version: 5.9.3 - vite: - specifier: ^5.0.0 - version: 5.4.21(@types/node@22.19.15) - vite-plugin-srvx: - specifier: ^1.0.2 - version: 1.0.2(srvx@0.10.1)(vite@5.4.21(@types/node@22.19.15)) - -packages: - - '@agentclientprotocol/sdk@0.16.1': - resolution: {integrity: sha512-1ad+Sc/0sCtZGHthxxvgEUo5Wsbw16I+aF+YwdiLnPwkZG8KAGUEAPK6LM6Pf69lCyJPt1Aomk1d+8oE3C4ZEw==} - peerDependencies: - zod: ^3.25.0 || ^4.0.0 - - '@ai-sdk/openai@0.0.66': - resolution: {integrity: sha512-V4XeDnlNl5/AY3GB3ozJUjqnBLU5pK3DacKTbCNH3zH8/MggJoH6B8wRGdLUPVFMcsMz60mtvh4DC9JsIVFrKw==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.0.0 - - '@ai-sdk/provider-utils@1.0.20': - resolution: {integrity: sha512-ngg/RGpnA00eNOWEtXHenpX1MsM2QshQh4QJFjUfwcqHpM5kTfG7je7Rc3HcEDP+OkRVv2GF+X4fC1Vfcnl8Ow==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.0.0 - peerDependenciesMeta: - zod: - optional: true - - '@ai-sdk/provider-utils@2.2.8': - resolution: {integrity: sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.23.8 - - '@ai-sdk/provider@0.0.24': - resolution: {integrity: sha512-XMsNGJdGO+L0cxhhegtqZ8+T6nn4EoShS819OvCgI2kLbYTIvk0GWFGD0AXJmxkxs3DrpsJxKAFukFR7bvTkgQ==} - engines: {node: '>=18'} - - '@ai-sdk/provider@1.1.3': - resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==} - engines: {node: '>=18'} - - '@ai-sdk/react@1.2.12': - resolution: {integrity: sha512-jK1IZZ22evPZoQW3vlkZ7wvjYGYF+tRBKXtrcolduIkQ/m/sOAVcVeVDUDvh1T91xCnWCdUGCPZg2avZ90mv3g==} - engines: {node: '>=18'} - peerDependencies: - react: ^18 || ^19 || ^19.0.0-rc - zod: ^3.23.8 - peerDependenciesMeta: - zod: - optional: true - - '@ai-sdk/ui-utils@1.2.11': - resolution: {integrity: sha512-3zcwCc8ezzFlwp3ZD15wAPjf2Au4s3vAbKsXQVyhxODHcmu0iyPO2Eua6D/vicq/AUm/BAo60r97O6HU+EI0+w==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.23.8 - - '@antfu/install-pkg@1.1.0': - resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - - '@asteasolutions/zod-to-openapi@8.5.0': - resolution: {integrity: sha512-SABbKiObg5dLRiTFnqiW1WWwGcg1BJfmHtT2asIBnBHg6Smy/Ms2KHc650+JI4Hw7lSkdiNebEGXpwoxfben8Q==} - peerDependencies: - zod: ^4.0.0 - - '@babel/code-frame@7.29.0': - resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.29.0': - resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-plugin-utils@7.28.6': - resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.29.2': - resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.2': - resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-transform-react-jsx-self@7.27.1': - resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx-source@7.27.1': - resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - - '@braintree/sanitize-url@7.1.2': - resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} - - '@cbor-extract/cbor-extract-darwin-arm64@2.2.2': - resolution: {integrity: sha512-ZKZ/F8US7JR92J4DMct6cLW/Y66o2K576+zjlEN/MevH70bFIsB10wkZEQPLzl2oNh2SMGy55xpJ9JoBRl5DOA==} - cpu: [arm64] - os: [darwin] - - '@cbor-extract/cbor-extract-darwin-x64@2.2.2': - resolution: {integrity: sha512-32b1mgc+P61Js+KW9VZv/c+xRw5EfmOcPx990JbCBSkYJFY0l25VinvyyWfl+3KjibQmAcYwmyzKF9J4DyKP/Q==} - cpu: [x64] - os: [darwin] - - '@cbor-extract/cbor-extract-linux-arm64@2.2.2': - resolution: {integrity: sha512-wfqgzqCAy/Vn8i6WVIh7qZd0DdBFaWBjPdB6ma+Wihcjv0gHqD/mw3ouVv7kbbUNrab6dKEx/w3xQZEdeXIlzg==} - cpu: [arm64] - os: [linux] - - '@cbor-extract/cbor-extract-linux-arm@2.2.2': - resolution: {integrity: sha512-tNg0za41TpQfkhWjptD+0gSD2fggMiDCSacuIeELyb2xZhr7PrhPe5h66Jc67B/5dmpIhI2QOUtv4SBsricyYQ==} - cpu: [arm] - os: [linux] - - '@cbor-extract/cbor-extract-linux-x64@2.2.2': - resolution: {integrity: sha512-rpiLnVEsqtPJ+mXTdx1rfz4RtUGYIUg2rUAZgd1KjiC1SehYUSkJN7Yh+aVfSjvCGtVP0/bfkQkXpPXKbmSUaA==} - cpu: [x64] - os: [linux] - - '@cbor-extract/cbor-extract-win32-x64@2.2.2': - resolution: {integrity: sha512-dI+9P7cfWxkTQ+oE+7Aa6onEn92PHgfWXZivjNheCRmTBDBf2fx6RyTi0cmgpYLnD1KLZK9ZYrMxaPZ4oiXhGA==} - cpu: [x64] - os: [win32] - - '@chevrotain/cst-dts-gen@11.1.2': - resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==} - - '@chevrotain/gast@11.1.2': - resolution: {integrity: sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==} - - '@chevrotain/regexp-to-ast@11.1.2': - resolution: {integrity: sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==} - - '@chevrotain/types@11.1.2': - resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} - - '@chevrotain/utils@11.1.2': - resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==} - - '@drizzle-team/brocli@0.10.2': - resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - - '@esbuild-kit/core-utils@3.3.2': - resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} - deprecated: 'Merged into tsx: https://tsx.is' - - '@esbuild-kit/esm-loader@2.6.5': - resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} - deprecated: 'Merged into tsx: https://tsx.is' - - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.27.4': - resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.27.4': - resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.27.4': - resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.27.4': - resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.27.4': - resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.27.4': - resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.27.4': - resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.4': - resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.27.4': - resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.27.4': - resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.27.4': - resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.27.4': - resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.27.4': - resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.27.4': - resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.27.4': - resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.27.4': - resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.27.4': - resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-arm64@0.27.4': - resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.27.4': - resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-arm64@0.27.4': - resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.4': - resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/openharmony-arm64@0.27.4': - resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.27.4': - resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.27.4': - resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.27.4': - resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.27.4': - resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@hono/node-server@1.19.11': - resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==} - engines: {node: '>=18.14.1'} - peerDependencies: - hono: ^4 - - '@hono/node-ws@1.3.0': - resolution: {integrity: sha512-ju25YbbvLuXdqBCmLZLqnNYu1nbHIQjoyUqA8ApZOeL1k4skuiTcw5SW77/5SUYo2Xi2NVBJoVlfQurnKEp03Q==} - engines: {node: '>=18.14.1'} - peerDependencies: - '@hono/node-server': ^1.19.2 - hono: ^4.6.0 - - '@hono/standard-validator@0.1.5': - resolution: {integrity: sha512-EIyZPPwkyLn6XKwFj5NBEWHXhXbgmnVh2ceIFo5GO7gKI9WmzTjPDKnppQB0KrqKeAkq3kpoW4SIbu5X1dgx3w==} - peerDependencies: - '@standard-schema/spec': 1.0.0 - hono: '>=3.9.0' - - '@hono/zod-openapi@1.2.3': - resolution: {integrity: sha512-zAviC3ApRAYGUiGWZiW/mrK/UBqkTi9BKQxn1IvwYyp2kS+k1tlnwut59DfEInpcsq1347zAYOqYI+obMy4vzQ==} - engines: {node: '>=16.0.0'} - peerDependencies: - hono: '>=4.3.6' - zod: ^4.0.0 - - '@hono/zod-validator@0.7.6': - resolution: {integrity: sha512-Io1B6d011Gj1KknV4rXYz4le5+5EubcWEU/speUjuw9XMMIaP3n78yXLhjd2A3PXaXaUwEAluOiAyLqhBEJgsw==} - peerDependencies: - hono: '>=3.9.0' - zod: ^3.25.0 || ^4.0.0 - - '@iconify/types@2.0.0': - resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - - '@iconify/utils@3.1.0': - resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} - - '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@mermaid-js/parser@1.0.1': - resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==} - - '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} - engines: {node: '>=8.0.0'} - - '@pinojs/redact@0.4.0': - resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} - - '@rivetkit/bare-ts@0.6.2': - resolution: {integrity: sha512-3qndQUQXLdwafMEqfhz24hUtDPcsf1Bu3q52Kb8MqeH8JUh3h6R4HYW3ZJXiQsLcyYyFM68PuIwlLRlg1xDEpg==} - engines: {node: ^14.18.0 || >=16.0.0} - - '@rivetkit/engine-runner-protocol@2.1.7': - resolution: {integrity: sha512-fbp+faQcECs07/q6wjgB+GCZPMyOq6D8tm8ZreVBKqtvMoQ2KKmjMLZOZhGPewYa8VScptnO+F6QXdZd0r1ymQ==} - - '@rivetkit/engine-runner@2.1.7': - resolution: {integrity: sha512-JxYtwSku2yImG7I0ndMgyYM79XGBkgfyYLIxnq1aM6dNx76h1LTTQwzKg3rEadHqPCr/7UsIPioxhjt37Z4ZdQ==} - - '@rivetkit/fast-json-patch@3.1.2': - resolution: {integrity: sha512-CtA50xgsSSzICQduF/NDShPRzvucnNvsW/lQO0WgMTT1XAj9Lfae4pm7r3llFwilgG+9iq76Hv1LUqNy72v6yw==} - - '@rivetkit/framework-base@2.1.7': - resolution: {integrity: sha512-+5wUc3/I3kBetq9GdZIiGwFHx8Vl+4Qq7teA0S3AIFVc8uhUeSDMJfhM4X0d2C3uPl10MUpvUdZn3A0l37UAXQ==} - - '@rivetkit/on-change@6.0.2-rc.1': - resolution: {integrity: sha512-5RC9Ze/wTKqSlJvopdCgr+EfyV93+iiH8Thog0QXrl8PT1unuBNw/jadXNMtwgAxrIaCJL+JLaHQH9w7rqpMDw==} - engines: {node: '>=20'} - - '@rivetkit/react@2.1.7': - resolution: {integrity: sha512-oO1WGhUkx3ApAZSQeaRsaLC25/Zm4Ulhsqq+/dCSDS/z3L+hf0OuBLeozpYUtKB7Ik3xJHryYqz7qwJwU3hDEA==} - peerDependencies: - react: ^18 || ^19 - react-dom: ^18 || ^19 - - '@rivetkit/sqlite-vfs@2.1.7': - resolution: {integrity: sha512-eSMRfdLK9LsDAUyDNOhu+GdP6YnmZidziEBgt7yrvrYo2g5E6si+wZcDFe1P8/FocrIn631OpvQiZoInozMzfQ==} - engines: {node: '>=20.0.0'} - - '@rivetkit/sqlite@0.1.1': - resolution: {integrity: sha512-NE7ZBy/hQhOrWzMZFjkHX9SoXxf+ILcDvVV+mNbUYPgiy/fsDzlXdK0+JDTGnko5f4Xl6/KVCoCozz9gkwkq8A==} - - '@rivetkit/traces@2.1.7': - resolution: {integrity: sha512-/r+pBcYOHUaMYnzVejwiHLjRdCtiFq22SLfXrp1OqIfPE0ikhZ6IIv/LFVQMfgELKPqpCLvYia765DwV/Hn3KQ==} - engines: {node: '>=18.0.0'} - - '@rivetkit/virtual-websocket@2.0.33': - resolution: {integrity: sha512-sMoHZgBy9WDW76pv+ML3LPgf7TWk5vXdu3ZpPO20j6n+rB3fLacnnmzjt5xD6tZcJ/x5qINyEywGgcxA7MTMuQ==} - - '@rivetkit/workflow-engine@2.1.7': - resolution: {integrity: sha512-xDpSnv+8KKJIq6yt6u3c25BIkItLYshTMTgHuB0y+Y4Df3w3f76f7NFR4srkbd+GmYysTGGMR2ZkYYNpZX1iQg==} - engines: {node: '>=18.0.0'} - - '@rolldown/pluginutils@1.0.0-beta.27': - resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - - '@rollup/rollup-android-arm-eabi@4.60.0': - resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.60.0': - resolution: {integrity: sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.60.0': - resolution: {integrity: sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.60.0': - resolution: {integrity: sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.60.0': - resolution: {integrity: sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.60.0': - resolution: {integrity: sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.60.0': - resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.60.0': - resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.60.0': - resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.60.0': - resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loong64-gnu@4.60.0': - resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-loong64-musl@4.60.0': - resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.60.0': - resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-ppc64-musl@4.60.0': - resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.60.0': - resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.60.0': - resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.60.0': - resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.60.0': - resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.60.0': - resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-openbsd-x64@4.60.0': - resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.60.0': - resolution: {integrity: sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.60.0': - resolution: {integrity: sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.60.0': - resolution: {integrity: sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.60.0': - resolution: {integrity: sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.60.0': - resolution: {integrity: sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==} - cpu: [x64] - os: [win32] - - '@sandbox-agent/cli-darwin-arm64@0.4.0': - resolution: {integrity: sha512-AaMd2h2OPG5k5DFxfc7jNtmYu3S1PS1BZjXGbXZ2NfAScwVCSeBuN0vvmSxP23CqPrEpf1m7PnruFrFh67Khhw==} - cpu: [arm64] - os: [darwin] - - '@sandbox-agent/cli-darwin-x64@0.4.0': - resolution: {integrity: sha512-dnr9xpiVXGbOqolukyLy1NNV+1w97yFh2zJL6TRuXg86eQbHSQRXVm/PqRMlr8KyVYdaLPQJeR8s4ofGvoa6Rg==} - cpu: [x64] - os: [darwin] - - '@sandbox-agent/cli-linux-arm64@0.4.0': - resolution: {integrity: sha512-217tEQU/47aNG7BFC27apZ51jEZgLfU7J3i5R52b+w3aI3khDyfJ/UHvkd1tsMztp59UjZTxwuY7xXSRkaTSGQ==} - cpu: [arm64] - os: [linux] - - '@sandbox-agent/cli-linux-x64@0.4.0': - resolution: {integrity: sha512-j39uNei4/dnX3Oy3hwqzrndZwPRE2SraahhfCGycymlFqN/p4Xii004QQ0WOP/vibQSGq+lPYR3faSevmjMZig==} - cpu: [x64] - os: [linux] - - '@sandbox-agent/cli-shared@0.4.0': - resolution: {integrity: sha512-hSNNIZJlnGlL0yVfp+d1N97qimO0dz6QB24vmfO4pviiBICcoIcoxnOv9l3aj8Z4nT8A3WTy/6cypYHUpoLxkQ==} - - '@sandbox-agent/cli-win32-x64@0.4.0': - resolution: {integrity: sha512-8OyIgsr/jMzMhAj5Fyz9VHj0ZEkGkaxAAELg4U0y5632Vkae8jcJRZyZ8bv6fBJp3zG2sgj47UJFfmHHh4pfMg==} - cpu: [x64] - os: [win32] - - '@sandbox-agent/cli@0.4.0': - resolution: {integrity: sha512-1xoLnr0ZAEgvGtVpBGkyGuACwI3Th4D2i218K1pr+YlBRclsps7TjRjddkEuTXZgQj4wjQ4uUjlDsvUBhvHMQQ==} - hasBin: true - - '@standard-schema/spec@1.0.0': - resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - - '@tanstack/react-store@0.7.7': - resolution: {integrity: sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - '@tanstack/store@0.7.7': - resolution: {integrity: sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==} - - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - - '@types/d3-array@3.2.2': - resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} - - '@types/d3-axis@3.0.6': - resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} - - '@types/d3-brush@3.0.6': - resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} - - '@types/d3-chord@3.0.6': - resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} - - '@types/d3-color@3.1.3': - resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} - - '@types/d3-contour@3.0.6': - resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} - - '@types/d3-delaunay@6.0.4': - resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} - - '@types/d3-dispatch@3.0.7': - resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} - - '@types/d3-drag@3.0.7': - resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} - - '@types/d3-dsv@3.0.7': - resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} - - '@types/d3-ease@3.0.2': - resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} - - '@types/d3-fetch@3.0.7': - resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} - - '@types/d3-force@3.0.10': - resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} - - '@types/d3-format@3.0.4': - resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} - - '@types/d3-geo@3.1.0': - resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} - - '@types/d3-hierarchy@3.1.7': - resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} - - '@types/d3-interpolate@3.0.4': - resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} - - '@types/d3-path@3.1.1': - resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} - - '@types/d3-polygon@3.0.2': - resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} - - '@types/d3-quadtree@3.0.6': - resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} - - '@types/d3-random@3.0.3': - resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} - - '@types/d3-scale-chromatic@3.1.0': - resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} - - '@types/d3-scale@4.0.9': - resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} - - '@types/d3-selection@3.0.11': - resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} - - '@types/d3-shape@3.1.8': - resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} - - '@types/d3-time-format@4.0.3': - resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} - - '@types/d3-time@3.0.4': - resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} - - '@types/d3-timer@3.0.2': - resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} - - '@types/d3-transition@3.0.9': - resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} - - '@types/d3-zoom@3.0.8': - resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} - - '@types/d3@7.4.3': - resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} - - '@types/diff-match-patch@1.0.36': - resolution: {integrity: sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/geojson@7946.0.16': - resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} - - '@types/node@22.19.15': - resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} - - '@types/prismjs@1.26.6': - resolution: {integrity: sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==} - - '@types/prop-types@15.7.15': - resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - - '@types/react-dom@18.3.7': - resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} - peerDependencies: - '@types/react': ^18.0.0 - - '@types/react@18.3.28': - resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} - - '@types/retry@0.12.2': - resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} - - '@types/trusted-types@2.0.7': - resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - - '@upsetjs/venn.js@2.0.0': - resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} - - '@vitejs/plugin-react@4.7.0': - resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - acp-http-client@0.4.0: - resolution: {integrity: sha512-RxXaX7hLyxYVpOwmzwc6FIud7icdcPfYqTsVoqJFkI/G5qE7feiac4jSB5SC6P6awy4FMHpFogYEp92vzZTKJA==} - - ai@4.3.19: - resolution: {integrity: sha512-dIE2bfNpqHN3r6IINp9znguYdhIOheKW2LDigAMrgt/upT3B8eBGPSCblENvaZGoq+hxaN9fSMzjWpbqloP+7Q==} - engines: {node: '>=18'} - peerDependencies: - react: ^18 || ^19 || ^19.0.0-rc - zod: ^3.23.8 - peerDependenciesMeta: - react: - optional: true - - atomic-sleep@1.0.0: - resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} - engines: {node: '>=8.0.0'} - - baseline-browser-mapping@2.10.10: - resolution: {integrity: sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==} - engines: {node: '>=6.0.0'} - hasBin: true - - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - caniuse-lite@1.0.30001781: - resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==} - - cbor-extract@2.2.2: - resolution: {integrity: sha512-hlSxxI9XO2yQfe9g6msd3g4xCfDqK5T5P0fRMLuaLHhxn4ViPrm+a+MUfhrvH2W962RGxcBwEGzLQyjbDG1gng==} - hasBin: true - - cbor-x@1.6.4: - resolution: {integrity: sha512-UGKHjp6RHC6QuZ2yy5LCKm7MojM4716DwoSaqwQpaH4DvZvbBTGcoDNTiG9Y2lByXZYFEs9WRkS5tLl96IrF1Q==} - - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - chevrotain-allstar@0.3.1: - resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} - peerDependencies: - chevrotain: ^11.0.0 - - chevrotain@11.1.2: - resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} - - chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - commander@7.2.0: - resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} - engines: {node: '>= 10'} - - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cose-base@1.0.3: - resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} - - cose-base@2.2.0: - resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - cytoscape-cose-bilkent@4.1.0: - resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} - peerDependencies: - cytoscape: ^3.2.0 - - cytoscape-fcose@2.2.0: - resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} - peerDependencies: - cytoscape: ^3.2.0 - - cytoscape@3.33.1: - resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} - engines: {node: '>=0.10'} - - d3-array@2.12.1: - resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} - - d3-array@3.2.4: - resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} - engines: {node: '>=12'} - - d3-axis@3.0.0: - resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} - engines: {node: '>=12'} - - d3-brush@3.0.0: - resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} - engines: {node: '>=12'} - - d3-chord@3.0.1: - resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} - engines: {node: '>=12'} - - d3-color@3.1.0: - resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} - engines: {node: '>=12'} - - d3-contour@4.0.2: - resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} - engines: {node: '>=12'} - - d3-delaunay@6.0.4: - resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} - engines: {node: '>=12'} - - d3-dispatch@3.0.1: - resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} - engines: {node: '>=12'} - - d3-drag@3.0.0: - resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} - engines: {node: '>=12'} - - d3-dsv@3.0.1: - resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} - engines: {node: '>=12'} - hasBin: true - - d3-ease@3.0.1: - resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} - engines: {node: '>=12'} - - d3-fetch@3.0.1: - resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} - engines: {node: '>=12'} - - d3-force@3.0.0: - resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} - engines: {node: '>=12'} - - d3-format@3.1.2: - resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} - engines: {node: '>=12'} - - d3-geo@3.1.1: - resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} - engines: {node: '>=12'} - - d3-hierarchy@3.1.2: - resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} - engines: {node: '>=12'} - - d3-interpolate@3.0.1: - resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} - engines: {node: '>=12'} - - d3-path@1.0.9: - resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} - - d3-path@3.1.0: - resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} - engines: {node: '>=12'} - - d3-polygon@3.0.1: - resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} - engines: {node: '>=12'} - - d3-quadtree@3.0.1: - resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} - engines: {node: '>=12'} - - d3-random@3.0.1: - resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} - engines: {node: '>=12'} - - d3-sankey@0.12.3: - resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} - - d3-scale-chromatic@3.1.0: - resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} - engines: {node: '>=12'} - - d3-scale@4.0.2: - resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} - engines: {node: '>=12'} - - d3-selection@3.0.0: - resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} - engines: {node: '>=12'} - - d3-shape@1.3.7: - resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} - - d3-shape@3.2.0: - resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} - engines: {node: '>=12'} - - d3-time-format@4.1.0: - resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} - engines: {node: '>=12'} - - d3-time@3.1.0: - resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} - engines: {node: '>=12'} - - d3-timer@3.0.1: - resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} - engines: {node: '>=12'} - - d3-transition@3.0.1: - resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} - engines: {node: '>=12'} - peerDependencies: - d3-selection: 2 - 3 - - d3-zoom@3.0.0: - resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} - engines: {node: '>=12'} - - d3@7.9.0: - resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} - engines: {node: '>=12'} - - dagre-d3-es@7.0.14: - resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} - - dayjs@1.11.20: - resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - delaunator@5.1.0: - resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} - - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - diff-match-patch@1.0.5: - resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} - - dompurify@3.3.3: - resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==} - - drizzle-kit@0.31.10: - resolution: {integrity: sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw==} - hasBin: true - - drizzle-orm@0.44.7: - resolution: {integrity: sha512-quIpnYznjU9lHshEOAYLoZ9s3jweleHlZIAWR/jX9gAWNg/JhQ1wj0KGRf7/Zm+obRrYd9GjPVJg790QY9N5AQ==} - peerDependencies: - '@aws-sdk/client-rds-data': '>=3' - '@cloudflare/workers-types': '>=4' - '@electric-sql/pglite': '>=0.2.0' - '@libsql/client': '>=0.10.0' - '@libsql/client-wasm': '>=0.10.0' - '@neondatabase/serverless': '>=0.10.0' - '@op-engineering/op-sqlite': '>=2' - '@opentelemetry/api': ^1.4.1 - '@planetscale/database': '>=1.13' - '@prisma/client': '*' - '@tidbcloud/serverless': '*' - '@types/better-sqlite3': '*' - '@types/pg': '*' - '@types/sql.js': '*' - '@upstash/redis': '>=1.34.7' - '@vercel/postgres': '>=0.8.0' - '@xata.io/client': '*' - better-sqlite3: '>=7' - bun-types: '*' - expo-sqlite: '>=14.0.0' - gel: '>=2' - knex: '*' - kysely: '*' - mysql2: '>=2' - pg: '>=8' - postgres: '>=3' - prisma: '*' - sql.js: '>=1' - sqlite3: '>=5' - peerDependenciesMeta: - '@aws-sdk/client-rds-data': - optional: true - '@cloudflare/workers-types': - optional: true - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - '@libsql/client-wasm': - optional: true - '@neondatabase/serverless': - optional: true - '@op-engineering/op-sqlite': - optional: true - '@opentelemetry/api': - optional: true - '@planetscale/database': - optional: true - '@prisma/client': - optional: true - '@tidbcloud/serverless': - optional: true - '@types/better-sqlite3': - optional: true - '@types/pg': - optional: true - '@types/sql.js': - optional: true - '@upstash/redis': - optional: true - '@vercel/postgres': - optional: true - '@xata.io/client': - optional: true - better-sqlite3: - optional: true - bun-types: - optional: true - expo-sqlite: - optional: true - gel: - optional: true - knex: - optional: true - kysely: - optional: true - mysql2: - optional: true - pg: - optional: true - postgres: - optional: true - prisma: - optional: true - sql.js: - optional: true - sqlite3: - optional: true - - electron-to-chromium@1.5.322: - resolution: {integrity: sha512-vFU34OcrvMcH66T+dYC3G4nURmgfDVewMIu6Q2urXpumAPSMmzvcn04KVVV8Opikq8Vs5nUbO/8laNhNRqSzYw==} - - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} - engines: {node: '>=18'} - hasBin: true - - esbuild@0.27.4: - resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - eventsource-parser@1.1.2: - resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==} - engines: {node: '>=14.18'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fdb-tuple@1.0.0: - resolution: {integrity: sha512-8jSvKPCYCgTpi9Pt87qlfTk6griyMx4Gk3Xv31Dp72Qp8b6XgIyFsMm8KzPmFJ9iJ8K4pGvRxvOS8D0XGnrkjw==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-port@7.2.0: - resolution: {integrity: sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==} - engines: {node: '>=16'} - - get-tsconfig@4.13.7: - resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} - - hachure-fill@0.5.2: - resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} - - hono@4.12.9: - resolution: {integrity: sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==} - engines: {node: '>=16.9.0'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - internmap@1.0.1: - resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} - - internmap@2.0.3: - resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} - engines: {node: '>=12'} - - invariant@2.2.4: - resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} - - is-network-error@1.3.1: - resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} - engines: {node: '>=16'} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsondiffpatch@0.6.0: - resolution: {integrity: sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - - katex@0.16.42: - resolution: {integrity: sha512-sZ4jqyEXfHTLEFK+qsFYToa3UZ0rtFcPGwKpyiRYh2NJn8obPWOQ+/u7ux0F6CAU/y78+Mksh1YkxTPXTh47TQ==} - hasBin: true - - khroma@2.1.0: - resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} - - langium@4.2.1: - resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} - engines: {node: '>=20.10.0', npm: '>=10.2.3'} - - layout-base@1.0.2: - resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} - - layout-base@2.0.1: - resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} - - lodash-es@4.17.23: - resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} - - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - lucide-react@0.439.0: - resolution: {integrity: sha512-PafSWvDTpxdtNEndS2HIHxcNAbd54OaqSYJO90/b63rab2HWYqDbH194j0i82ZFdWOAcf0AHinRykXRRK2PJbw==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc - - marked@16.4.2: - resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} - engines: {node: '>= 20'} - hasBin: true - - mermaid@11.13.0: - resolution: {integrity: sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==} - - minipass@7.1.3: - resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} - engines: {node: '>=16 || 14 >=14.17'} - - minizlib@3.1.0: - resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} - engines: {node: '>= 18'} - - mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - nanoevents@9.1.0: - resolution: {integrity: sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==} - engines: {node: ^18.0.0 || >=20.0.0} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - node-gyp-build-optional-packages@5.1.1: - resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} - hasBin: true - - node-releases@2.0.36: - resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} - - on-exit-leak-free@2.1.2: - resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} - engines: {node: '>=14.0.0'} - - openapi3-ts@4.5.0: - resolution: {integrity: sha512-jaL+HgTq2Gj5jRcfdutgRGLosCy/hT8sQf6VOy+P+g36cZOjI1iukdPnijC+4CmeRzg/jEllJUboEic2FhxhtQ==} - - p-retry@6.2.1: - resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} - engines: {node: '>=16.17'} - - package-manager-detector@1.6.0: - resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} - - path-data-parser@0.1.0: - resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - pino-abstract-transport@2.0.0: - resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} - - pino-std-serializers@7.1.0: - resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} - - pino@9.14.0: - resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} - hasBin: true - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - points-on-curve@0.2.0: - resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} - - points-on-path@0.2.1: - resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} - - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} - engines: {node: ^10 || ^12 || >=14} - - prism-react-renderer@2.4.1: - resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} - peerDependencies: - react: '>=16.0.0' - - process-warning@5.0.0: - resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} - - quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} - peerDependencies: - react: ^18.3.1 - - react-refresh@0.17.0: - resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} - engines: {node: '>=0.10.0'} - - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} - engines: {node: '>=0.10.0'} - - real-require@0.2.0: - resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} - engines: {node: '>= 12.13.0'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - retry@0.13.1: - resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} - engines: {node: '>= 4'} - - rivetkit@2.1.7: - resolution: {integrity: sha512-ToHx1ECe4ruIpkVtPhHooWxT5VSrM/QH5ws4gzq+bJafEuSr5k1xQS5i3JzBwvj/nD953RKq8SG2bsP8DWL2Sg==} - engines: {node: '>=22.0.0'} - peerDependencies: - '@daytonaio/sdk': ^0.150.0 - '@e2b/code-interpreter': ^2.3.3 - dockerode: ^4.0.9 - drizzle-kit: ^0.31.2 - drizzle-orm: ^0.44.2 - eventsource: ^4.0.0 - ws: ^8.0.0 - peerDependenciesMeta: - '@daytonaio/sdk': - optional: true - '@e2b/code-interpreter': - optional: true - dockerode: - optional: true - drizzle-kit: - optional: true - drizzle-orm: - optional: true - eventsource: - optional: true - ws: - optional: true - - robust-predicates@3.0.3: - resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} - - rollup@4.60.0: - resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - roughjs@4.6.6: - resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} - - rw@1.3.3: - resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} - - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} - engines: {node: '>=10'} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - sandbox-agent@0.4.0: - resolution: {integrity: sha512-vm/+LB/3dtGVjZkSI5w3fsCrJwF7mQr8f0FE7vSAy1elp1qgaHtpCRqBeCVeYv7zGAtjuXZzO42/kZbFZX/h+A==} - peerDependencies: - '@cloudflare/sandbox': '>=0.1.0' - '@daytonaio/sdk': '>=0.12.0' - '@e2b/code-interpreter': '>=1.0.0' - '@vercel/sandbox': '>=0.1.0' - computesdk: '>=0.1.0' - dockerode: '>=4.0.0' - get-port: '>=7.0.0' - modal: '>=0.1.0' - peerDependenciesMeta: - '@cloudflare/sandbox': - optional: true - '@daytonaio/sdk': - optional: true - '@e2b/code-interpreter': - optional: true - '@vercel/sandbox': - optional: true - computesdk: - optional: true - dockerode: - optional: true - get-port: - optional: true - modal: - optional: true - - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} - - secure-json-parse@2.7.0: - resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - sonic-boom@4.2.1: - resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - srvx@0.10.1: - resolution: {integrity: sha512-A//xtfak4eESMWWydSRFUVvCTQbSwivnGCEf8YGPe2eHU0+Z6znfUTCPF0a7oV3sObSOcrXHlL6Bs9vVctfXdg==} - engines: {node: '>=20.16.0'} - hasBin: true - - stylis@4.3.6: - resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} - - swr@2.4.1: - resolution: {integrity: sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA==} - peerDependencies: - react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - tar@7.5.13: - resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} - engines: {node: '>=18'} - - thread-stream@3.1.0: - resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} - - throttleit@2.1.0: - resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} - engines: {node: '>=18'} - - tinyexec@1.0.4: - resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} - engines: {node: '>=18'} - - ts-dedent@2.2.0: - resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} - engines: {node: '>=6.10'} - - tsx@4.21.0: - resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} - engines: {node: '>=18.0.0'} - hasBin: true - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.6.3: - resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - use-sync-external-store@1.6.0: - resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} - hasBin: true - - uuid@12.0.0: - resolution: {integrity: sha512-USe1zesMYh4fjCA8ZH5+X5WIVD0J4V1Jksm1bFTVBX2F/cwSXt0RO5w/3UXbdLKmZX65MiWV+hwhSS8p6oBTGA==} - hasBin: true - - vbare@0.0.4: - resolution: {integrity: sha512-QsxSVw76NqYUWYPVcQmOnQPX8buIVjgn+yqldTHlWISulBTB9TJ9rnzZceDu+GZmycOtzsmuPbPN1YNxvK12fg==} - engines: {node: '>=18.0.0'} - - vite-plugin-srvx@1.0.2: - resolution: {integrity: sha512-y11gH+CBkbQvfbFE14TJcl7HAkjqaZbGEb3CXnEdu0fXlsPzHJST7Khyq021WKOWbDYb8PaCabjzMQ+pS1oDPw==} - peerDependencies: - srvx: '>=0.9.0' - vite: ^5.0.0 || ^6.0.0 - - vite@5.4.21: - resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vscode-jsonrpc@8.2.0: - resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} - engines: {node: '>=14.0.0'} - - vscode-languageserver-protocol@3.17.5: - resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} - - vscode-languageserver-textdocument@1.0.12: - resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} - - vscode-languageserver-types@3.17.5: - resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} - - vscode-languageserver@9.0.1: - resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} - hasBin: true - - vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - - ws@8.20.0: - resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} - - yaml@2.8.3: - resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} - engines: {node: '>= 14.6'} - hasBin: true - - zod-to-json-schema@3.25.1: - resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} - peerDependencies: - zod: ^3.25 || ^4 - - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - -snapshots: - - '@agentclientprotocol/sdk@0.16.1(zod@4.3.6)': - dependencies: - zod: 4.3.6 - - '@ai-sdk/openai@0.0.66(zod@3.25.76)': - dependencies: - '@ai-sdk/provider': 0.0.24 - '@ai-sdk/provider-utils': 1.0.20(zod@3.25.76) - zod: 3.25.76 - - '@ai-sdk/provider-utils@1.0.20(zod@3.25.76)': - dependencies: - '@ai-sdk/provider': 0.0.24 - eventsource-parser: 1.1.2 - nanoid: 3.3.6 - secure-json-parse: 2.7.0 - optionalDependencies: - zod: 3.25.76 - - '@ai-sdk/provider-utils@2.2.8(zod@3.25.76)': - dependencies: - '@ai-sdk/provider': 1.1.3 - nanoid: 3.3.11 - secure-json-parse: 2.7.0 - zod: 3.25.76 - - '@ai-sdk/provider@0.0.24': - dependencies: - json-schema: 0.4.0 - - '@ai-sdk/provider@1.1.3': - dependencies: - json-schema: 0.4.0 - - '@ai-sdk/react@1.2.12(react@18.3.1)(zod@3.25.76)': - dependencies: - '@ai-sdk/provider-utils': 2.2.8(zod@3.25.76) - '@ai-sdk/ui-utils': 1.2.11(zod@3.25.76) - react: 18.3.1 - swr: 2.4.1(react@18.3.1) - throttleit: 2.1.0 - optionalDependencies: - zod: 3.25.76 - - '@ai-sdk/ui-utils@1.2.11(zod@3.25.76)': - dependencies: - '@ai-sdk/provider': 1.1.3 - '@ai-sdk/provider-utils': 2.2.8(zod@3.25.76) - zod: 3.25.76 - zod-to-json-schema: 3.25.1(zod@3.25.76) - - '@antfu/install-pkg@1.1.0': - dependencies: - package-manager-detector: 1.6.0 - tinyexec: 1.0.4 - - '@asteasolutions/zod-to-openapi@8.5.0(zod@4.3.6)': - dependencies: - openapi3-ts: 4.5.0 - zod: 4.3.6 - - '@babel/code-frame@7.29.0': - dependencies: - '@babel/helper-validator-identifier': 7.28.5 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.29.0': {} - - '@babel/core@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.29.2 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.29.1': - dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/helper-compilation-targets@7.28.6': - dependencies: - '@babel/compat-data': 7.29.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-module-imports@7.28.6': - dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-plugin-utils@7.28.6': {} - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/helper-validator-option@7.27.1': {} - - '@babel/helpers@7.29.2': - dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - - '@babel/parser@7.29.2': - dependencies: - '@babel/types': 7.29.0 - - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/template@7.28.6': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - - '@babel/traverse@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - - '@braintree/sanitize-url@7.1.2': {} - - '@cbor-extract/cbor-extract-darwin-arm64@2.2.2': - optional: true - - '@cbor-extract/cbor-extract-darwin-x64@2.2.2': - optional: true - - '@cbor-extract/cbor-extract-linux-arm64@2.2.2': - optional: true - - '@cbor-extract/cbor-extract-linux-arm@2.2.2': - optional: true - - '@cbor-extract/cbor-extract-linux-x64@2.2.2': - optional: true - - '@cbor-extract/cbor-extract-win32-x64@2.2.2': - optional: true - - '@chevrotain/cst-dts-gen@11.1.2': - dependencies: - '@chevrotain/gast': 11.1.2 - '@chevrotain/types': 11.1.2 - lodash-es: 4.17.23 - - '@chevrotain/gast@11.1.2': - dependencies: - '@chevrotain/types': 11.1.2 - lodash-es: 4.17.23 - - '@chevrotain/regexp-to-ast@11.1.2': {} - - '@chevrotain/types@11.1.2': {} - - '@chevrotain/utils@11.1.2': {} - - '@drizzle-team/brocli@0.10.2': {} - - '@esbuild-kit/core-utils@3.3.2': - dependencies: - esbuild: 0.18.20 - source-map-support: 0.5.21 - - '@esbuild-kit/esm-loader@2.6.5': - dependencies: - '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.13.7 - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/aix-ppc64@0.25.12': - optional: true - - '@esbuild/aix-ppc64@0.27.4': - optional: true - - '@esbuild/android-arm64@0.18.20': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.25.12': - optional: true - - '@esbuild/android-arm64@0.27.4': - optional: true - - '@esbuild/android-arm@0.18.20': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-arm@0.25.12': - optional: true - - '@esbuild/android-arm@0.27.4': - optional: true - - '@esbuild/android-x64@0.18.20': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/android-x64@0.25.12': - optional: true - - '@esbuild/android-x64@0.27.4': - optional: true - - '@esbuild/darwin-arm64@0.18.20': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.25.12': - optional: true - - '@esbuild/darwin-arm64@0.27.4': - optional: true - - '@esbuild/darwin-x64@0.18.20': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.25.12': - optional: true - - '@esbuild/darwin-x64@0.27.4': - optional: true - - '@esbuild/freebsd-arm64@0.18.20': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.25.12': - optional: true - - '@esbuild/freebsd-arm64@0.27.4': - optional: true - - '@esbuild/freebsd-x64@0.18.20': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.25.12': - optional: true - - '@esbuild/freebsd-x64@0.27.4': - optional: true - - '@esbuild/linux-arm64@0.18.20': - optional: true - - '@esbuild/linux-arm64@0.21.5': - optional: true - - '@esbuild/linux-arm64@0.25.12': - optional: true - - '@esbuild/linux-arm64@0.27.4': - optional: true - - '@esbuild/linux-arm@0.18.20': - optional: true - - '@esbuild/linux-arm@0.21.5': - optional: true - - '@esbuild/linux-arm@0.25.12': - optional: true - - '@esbuild/linux-arm@0.27.4': - optional: true - - '@esbuild/linux-ia32@0.18.20': - optional: true - - '@esbuild/linux-ia32@0.21.5': - optional: true - - '@esbuild/linux-ia32@0.25.12': - optional: true - - '@esbuild/linux-ia32@0.27.4': - optional: true - - '@esbuild/linux-loong64@0.18.20': - optional: true - - '@esbuild/linux-loong64@0.21.5': - optional: true - - '@esbuild/linux-loong64@0.25.12': - optional: true - - '@esbuild/linux-loong64@0.27.4': - optional: true - - '@esbuild/linux-mips64el@0.18.20': - optional: true - - '@esbuild/linux-mips64el@0.21.5': - optional: true - - '@esbuild/linux-mips64el@0.25.12': - optional: true - - '@esbuild/linux-mips64el@0.27.4': - optional: true - - '@esbuild/linux-ppc64@0.18.20': - optional: true - - '@esbuild/linux-ppc64@0.21.5': - optional: true - - '@esbuild/linux-ppc64@0.25.12': - optional: true - - '@esbuild/linux-ppc64@0.27.4': - optional: true - - '@esbuild/linux-riscv64@0.18.20': - optional: true - - '@esbuild/linux-riscv64@0.21.5': - optional: true - - '@esbuild/linux-riscv64@0.25.12': - optional: true - - '@esbuild/linux-riscv64@0.27.4': - optional: true - - '@esbuild/linux-s390x@0.18.20': - optional: true - - '@esbuild/linux-s390x@0.21.5': - optional: true - - '@esbuild/linux-s390x@0.25.12': - optional: true - - '@esbuild/linux-s390x@0.27.4': - optional: true - - '@esbuild/linux-x64@0.18.20': - optional: true - - '@esbuild/linux-x64@0.21.5': - optional: true - - '@esbuild/linux-x64@0.25.12': - optional: true - - '@esbuild/linux-x64@0.27.4': - optional: true - - '@esbuild/netbsd-arm64@0.25.12': - optional: true - - '@esbuild/netbsd-arm64@0.27.4': - optional: true - - '@esbuild/netbsd-x64@0.18.20': - optional: true - - '@esbuild/netbsd-x64@0.21.5': - optional: true - - '@esbuild/netbsd-x64@0.25.12': - optional: true - - '@esbuild/netbsd-x64@0.27.4': - optional: true - - '@esbuild/openbsd-arm64@0.25.12': - optional: true - - '@esbuild/openbsd-arm64@0.27.4': - optional: true - - '@esbuild/openbsd-x64@0.18.20': - optional: true - - '@esbuild/openbsd-x64@0.21.5': - optional: true - - '@esbuild/openbsd-x64@0.25.12': - optional: true - - '@esbuild/openbsd-x64@0.27.4': - optional: true - - '@esbuild/openharmony-arm64@0.25.12': - optional: true - - '@esbuild/openharmony-arm64@0.27.4': - optional: true - - '@esbuild/sunos-x64@0.18.20': - optional: true - - '@esbuild/sunos-x64@0.21.5': - optional: true - - '@esbuild/sunos-x64@0.25.12': - optional: true - - '@esbuild/sunos-x64@0.27.4': - optional: true - - '@esbuild/win32-arm64@0.18.20': - optional: true - - '@esbuild/win32-arm64@0.21.5': - optional: true - - '@esbuild/win32-arm64@0.25.12': - optional: true - - '@esbuild/win32-arm64@0.27.4': - optional: true - - '@esbuild/win32-ia32@0.18.20': - optional: true - - '@esbuild/win32-ia32@0.21.5': - optional: true - - '@esbuild/win32-ia32@0.25.12': - optional: true - - '@esbuild/win32-ia32@0.27.4': - optional: true - - '@esbuild/win32-x64@0.18.20': - optional: true - - '@esbuild/win32-x64@0.21.5': - optional: true - - '@esbuild/win32-x64@0.25.12': - optional: true - - '@esbuild/win32-x64@0.27.4': - optional: true - - '@hono/node-server@1.19.11(hono@4.12.9)': - dependencies: - hono: 4.12.9 - - '@hono/node-ws@1.3.0(@hono/node-server@1.19.11(hono@4.12.9))(hono@4.12.9)': - dependencies: - '@hono/node-server': 1.19.11(hono@4.12.9) - hono: 4.12.9 - ws: 8.20.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - '@hono/standard-validator@0.1.5(@standard-schema/spec@1.0.0)(hono@4.12.9)': - dependencies: - '@standard-schema/spec': 1.0.0 - hono: 4.12.9 - - '@hono/zod-openapi@1.2.3(hono@4.12.9)(zod@4.3.6)': - dependencies: - '@asteasolutions/zod-to-openapi': 8.5.0(zod@4.3.6) - '@hono/zod-validator': 0.7.6(hono@4.12.9)(zod@4.3.6) - hono: 4.12.9 - openapi3-ts: 4.5.0 - zod: 4.3.6 - - '@hono/zod-validator@0.7.6(hono@4.12.9)(zod@4.3.6)': - dependencies: - hono: 4.12.9 - zod: 4.3.6 - - '@iconify/types@2.0.0': {} - - '@iconify/utils@3.1.0': - dependencies: - '@antfu/install-pkg': 1.1.0 - '@iconify/types': 2.0.0 - mlly: 1.8.2 - - '@isaacs/fs-minipass@4.0.1': - dependencies: - minipass: 7.1.3 - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@mermaid-js/parser@1.0.1': - dependencies: - langium: 4.2.1 - - '@opentelemetry/api@1.9.0': {} - - '@pinojs/redact@0.4.0': {} - - '@rivetkit/bare-ts@0.6.2': {} - - '@rivetkit/engine-runner-protocol@2.1.7': - dependencies: - '@rivetkit/bare-ts': 0.6.2 - - '@rivetkit/engine-runner@2.1.7': - dependencies: - '@rivetkit/engine-runner-protocol': 2.1.7 - '@rivetkit/virtual-websocket': 2.0.33 - pino: 9.14.0 - uuid: 12.0.0 - ws: 8.20.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - '@rivetkit/fast-json-patch@3.1.2': {} - - '@rivetkit/framework-base@2.1.7(@standard-schema/spec@1.0.0)(drizzle-kit@0.31.10)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0))(ws@8.20.0)': - dependencies: - '@tanstack/store': 0.7.7 - fast-deep-equal: 3.1.3 - rivetkit: 2.1.7(@standard-schema/spec@1.0.0)(drizzle-kit@0.31.10)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0))(ws@8.20.0) - transitivePeerDependencies: - - '@cloudflare/sandbox' - - '@daytonaio/sdk' - - '@e2b/code-interpreter' - - '@standard-schema/spec' - - '@vercel/sandbox' - - bufferutil - - computesdk - - dockerode - - drizzle-kit - - drizzle-orm - - eventsource - - modal - - utf-8-validate - - ws - - '@rivetkit/on-change@6.0.2-rc.1': {} - - '@rivetkit/react@2.1.7(@standard-schema/spec@1.0.0)(drizzle-kit@0.31.10)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ws@8.20.0)': - dependencies: - '@rivetkit/framework-base': 2.1.7(@standard-schema/spec@1.0.0)(drizzle-kit@0.31.10)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0))(ws@8.20.0) - '@tanstack/react-store': 0.7.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - rivetkit: 2.1.7(@standard-schema/spec@1.0.0)(drizzle-kit@0.31.10)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0))(ws@8.20.0) - transitivePeerDependencies: - - '@cloudflare/sandbox' - - '@daytonaio/sdk' - - '@e2b/code-interpreter' - - '@standard-schema/spec' - - '@vercel/sandbox' - - bufferutil - - computesdk - - dockerode - - drizzle-kit - - drizzle-orm - - eventsource - - modal - - utf-8-validate - - ws - - '@rivetkit/sqlite-vfs@2.1.7': - dependencies: - '@rivetkit/bare-ts': 0.6.2 - '@rivetkit/sqlite': 0.1.1 - vbare: 0.0.4 - - '@rivetkit/sqlite@0.1.1': {} - - '@rivetkit/traces@2.1.7': - dependencies: - '@rivetkit/bare-ts': 0.6.2 - cbor-x: 1.6.4 - fdb-tuple: 1.0.0 - vbare: 0.0.4 - - '@rivetkit/virtual-websocket@2.0.33': {} - - '@rivetkit/workflow-engine@2.1.7': - dependencies: - '@rivetkit/bare-ts': 0.6.2 - cbor-x: 1.6.4 - fdb-tuple: 1.0.0 - pino: 9.14.0 - vbare: 0.0.4 - - '@rolldown/pluginutils@1.0.0-beta.27': {} - - '@rollup/rollup-android-arm-eabi@4.60.0': - optional: true - - '@rollup/rollup-android-arm64@4.60.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.60.0': - optional: true - - '@rollup/rollup-darwin-x64@4.60.0': - optional: true - - '@rollup/rollup-freebsd-arm64@4.60.0': - optional: true - - '@rollup/rollup-freebsd-x64@4.60.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.60.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.60.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.60.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.60.0': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.60.0': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.60.0': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.60.0': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.60.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.60.0': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.60.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.60.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.60.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.60.0': - optional: true - - '@rollup/rollup-openbsd-x64@4.60.0': - optional: true - - '@rollup/rollup-openharmony-arm64@4.60.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.60.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.60.0': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.60.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.60.0': - optional: true - - '@sandbox-agent/cli-darwin-arm64@0.4.0': - optional: true - - '@sandbox-agent/cli-darwin-x64@0.4.0': - optional: true - - '@sandbox-agent/cli-linux-arm64@0.4.0': - optional: true - - '@sandbox-agent/cli-linux-x64@0.4.0': - optional: true - - '@sandbox-agent/cli-shared@0.4.0': {} - - '@sandbox-agent/cli-win32-x64@0.4.0': - optional: true - - '@sandbox-agent/cli@0.4.0': - dependencies: - '@sandbox-agent/cli-shared': 0.4.0 - optionalDependencies: - '@sandbox-agent/cli-darwin-arm64': 0.4.0 - '@sandbox-agent/cli-darwin-x64': 0.4.0 - '@sandbox-agent/cli-linux-arm64': 0.4.0 - '@sandbox-agent/cli-linux-x64': 0.4.0 - '@sandbox-agent/cli-win32-x64': 0.4.0 - optional: true - - '@standard-schema/spec@1.0.0': {} - - '@tanstack/react-store@0.7.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@tanstack/store': 0.7.7 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - use-sync-external-store: 1.6.0(react@18.3.1) - - '@tanstack/store@0.7.7': {} - - '@types/babel__core@7.20.5': - dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 - - '@types/babel__generator@7.27.0': - dependencies: - '@babel/types': 7.29.0 - - '@types/babel__template@7.4.4': - dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - - '@types/babel__traverse@7.28.0': - dependencies: - '@babel/types': 7.29.0 - - '@types/d3-array@3.2.2': {} - - '@types/d3-axis@3.0.6': - dependencies: - '@types/d3-selection': 3.0.11 - - '@types/d3-brush@3.0.6': - dependencies: - '@types/d3-selection': 3.0.11 - - '@types/d3-chord@3.0.6': {} - - '@types/d3-color@3.1.3': {} - - '@types/d3-contour@3.0.6': - dependencies: - '@types/d3-array': 3.2.2 - '@types/geojson': 7946.0.16 - - '@types/d3-delaunay@6.0.4': {} - - '@types/d3-dispatch@3.0.7': {} - - '@types/d3-drag@3.0.7': - dependencies: - '@types/d3-selection': 3.0.11 - - '@types/d3-dsv@3.0.7': {} - - '@types/d3-ease@3.0.2': {} - - '@types/d3-fetch@3.0.7': - dependencies: - '@types/d3-dsv': 3.0.7 - - '@types/d3-force@3.0.10': {} - - '@types/d3-format@3.0.4': {} - - '@types/d3-geo@3.1.0': - dependencies: - '@types/geojson': 7946.0.16 - - '@types/d3-hierarchy@3.1.7': {} - - '@types/d3-interpolate@3.0.4': - dependencies: - '@types/d3-color': 3.1.3 - - '@types/d3-path@3.1.1': {} - - '@types/d3-polygon@3.0.2': {} - - '@types/d3-quadtree@3.0.6': {} - - '@types/d3-random@3.0.3': {} - - '@types/d3-scale-chromatic@3.1.0': {} - - '@types/d3-scale@4.0.9': - dependencies: - '@types/d3-time': 3.0.4 - - '@types/d3-selection@3.0.11': {} - - '@types/d3-shape@3.1.8': - dependencies: - '@types/d3-path': 3.1.1 - - '@types/d3-time-format@4.0.3': {} - - '@types/d3-time@3.0.4': {} - - '@types/d3-timer@3.0.2': {} - - '@types/d3-transition@3.0.9': - dependencies: - '@types/d3-selection': 3.0.11 - - '@types/d3-zoom@3.0.8': - dependencies: - '@types/d3-interpolate': 3.0.4 - '@types/d3-selection': 3.0.11 - - '@types/d3@7.4.3': - dependencies: - '@types/d3-array': 3.2.2 - '@types/d3-axis': 3.0.6 - '@types/d3-brush': 3.0.6 - '@types/d3-chord': 3.0.6 - '@types/d3-color': 3.1.3 - '@types/d3-contour': 3.0.6 - '@types/d3-delaunay': 6.0.4 - '@types/d3-dispatch': 3.0.7 - '@types/d3-drag': 3.0.7 - '@types/d3-dsv': 3.0.7 - '@types/d3-ease': 3.0.2 - '@types/d3-fetch': 3.0.7 - '@types/d3-force': 3.0.10 - '@types/d3-format': 3.0.4 - '@types/d3-geo': 3.1.0 - '@types/d3-hierarchy': 3.1.7 - '@types/d3-interpolate': 3.0.4 - '@types/d3-path': 3.1.1 - '@types/d3-polygon': 3.0.2 - '@types/d3-quadtree': 3.0.6 - '@types/d3-random': 3.0.3 - '@types/d3-scale': 4.0.9 - '@types/d3-scale-chromatic': 3.1.0 - '@types/d3-selection': 3.0.11 - '@types/d3-shape': 3.1.8 - '@types/d3-time': 3.0.4 - '@types/d3-time-format': 4.0.3 - '@types/d3-timer': 3.0.2 - '@types/d3-transition': 3.0.9 - '@types/d3-zoom': 3.0.8 - - '@types/diff-match-patch@1.0.36': {} - - '@types/estree@1.0.8': {} - - '@types/geojson@7946.0.16': {} - - '@types/node@22.19.15': - dependencies: - undici-types: 6.21.0 - - '@types/prismjs@1.26.6': {} - - '@types/prop-types@15.7.15': {} - - '@types/react-dom@18.3.7(@types/react@18.3.28)': - dependencies: - '@types/react': 18.3.28 - - '@types/react@18.3.28': - dependencies: - '@types/prop-types': 15.7.15 - csstype: 3.2.3 - - '@types/retry@0.12.2': {} - - '@types/trusted-types@2.0.7': - optional: true - - '@upsetjs/venn.js@2.0.0': - optionalDependencies: - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) - - '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@22.19.15))': - dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) - '@rolldown/pluginutils': 1.0.0-beta.27 - '@types/babel__core': 7.20.5 - react-refresh: 0.17.0 - vite: 5.4.21(@types/node@22.19.15) - transitivePeerDependencies: - - supports-color - - acorn@8.16.0: {} - - acp-http-client@0.4.0(zod@4.3.6): - dependencies: - '@agentclientprotocol/sdk': 0.16.1(zod@4.3.6) - transitivePeerDependencies: - - zod - - ai@4.3.19(react@18.3.1)(zod@3.25.76): - dependencies: - '@ai-sdk/provider': 1.1.3 - '@ai-sdk/provider-utils': 2.2.8(zod@3.25.76) - '@ai-sdk/react': 1.2.12(react@18.3.1)(zod@3.25.76) - '@ai-sdk/ui-utils': 1.2.11(zod@3.25.76) - '@opentelemetry/api': 1.9.0 - jsondiffpatch: 0.6.0 - zod: 3.25.76 - optionalDependencies: - react: 18.3.1 - - atomic-sleep@1.0.0: {} - - baseline-browser-mapping@2.10.10: {} - - browserslist@4.28.1: - dependencies: - baseline-browser-mapping: 2.10.10 - caniuse-lite: 1.0.30001781 - electron-to-chromium: 1.5.322 - node-releases: 2.0.36 - update-browserslist-db: 1.2.3(browserslist@4.28.1) - - buffer-from@1.1.2: {} - - caniuse-lite@1.0.30001781: {} - - cbor-extract@2.2.2: - dependencies: - node-gyp-build-optional-packages: 5.1.1 - optionalDependencies: - '@cbor-extract/cbor-extract-darwin-arm64': 2.2.2 - '@cbor-extract/cbor-extract-darwin-x64': 2.2.2 - '@cbor-extract/cbor-extract-linux-arm': 2.2.2 - '@cbor-extract/cbor-extract-linux-arm64': 2.2.2 - '@cbor-extract/cbor-extract-linux-x64': 2.2.2 - '@cbor-extract/cbor-extract-win32-x64': 2.2.2 - optional: true - - cbor-x@1.6.4: - optionalDependencies: - cbor-extract: 2.2.2 - - chalk@5.6.2: {} - - chevrotain-allstar@0.3.1(chevrotain@11.1.2): - dependencies: - chevrotain: 11.1.2 - lodash-es: 4.17.23 - - chevrotain@11.1.2: - dependencies: - '@chevrotain/cst-dts-gen': 11.1.2 - '@chevrotain/gast': 11.1.2 - '@chevrotain/regexp-to-ast': 11.1.2 - '@chevrotain/types': 11.1.2 - '@chevrotain/utils': 11.1.2 - lodash-es: 4.17.23 - - chownr@3.0.0: {} - - clsx@2.1.1: {} - - commander@7.2.0: {} - - commander@8.3.0: {} - - confbox@0.1.8: {} - - convert-source-map@2.0.0: {} - - cose-base@1.0.3: - dependencies: - layout-base: 1.0.2 - - cose-base@2.2.0: - dependencies: - layout-base: 2.0.1 - - csstype@3.2.3: {} - - cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): - dependencies: - cose-base: 1.0.3 - cytoscape: 3.33.1 - - cytoscape-fcose@2.2.0(cytoscape@3.33.1): - dependencies: - cose-base: 2.2.0 - cytoscape: 3.33.1 - - cytoscape@3.33.1: {} - - d3-array@2.12.1: - dependencies: - internmap: 1.0.1 - - d3-array@3.2.4: - dependencies: - internmap: 2.0.3 - - d3-axis@3.0.0: {} - - d3-brush@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) - - d3-chord@3.0.1: - dependencies: - d3-path: 3.1.0 - - d3-color@3.1.0: {} - - d3-contour@4.0.2: - dependencies: - d3-array: 3.2.4 - - d3-delaunay@6.0.4: - dependencies: - delaunator: 5.1.0 - - d3-dispatch@3.0.1: {} - - d3-drag@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-selection: 3.0.0 - - d3-dsv@3.0.1: - dependencies: - commander: 7.2.0 - iconv-lite: 0.6.3 - rw: 1.3.3 - - d3-ease@3.0.1: {} - - d3-fetch@3.0.1: - dependencies: - d3-dsv: 3.0.1 - - d3-force@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-quadtree: 3.0.1 - d3-timer: 3.0.1 - - d3-format@3.1.2: {} - - d3-geo@3.1.1: - dependencies: - d3-array: 3.2.4 - - d3-hierarchy@3.1.2: {} - - d3-interpolate@3.0.1: - dependencies: - d3-color: 3.1.0 - - d3-path@1.0.9: {} - - d3-path@3.1.0: {} - - d3-polygon@3.0.1: {} - - d3-quadtree@3.0.1: {} - - d3-random@3.0.1: {} - - d3-sankey@0.12.3: - dependencies: - d3-array: 2.12.1 - d3-shape: 1.3.7 - - d3-scale-chromatic@3.1.0: - dependencies: - d3-color: 3.1.0 - d3-interpolate: 3.0.1 - - d3-scale@4.0.2: - dependencies: - d3-array: 3.2.4 - d3-format: 3.1.2 - d3-interpolate: 3.0.1 - d3-time: 3.1.0 - d3-time-format: 4.1.0 - - d3-selection@3.0.0: {} - - d3-shape@1.3.7: - dependencies: - d3-path: 1.0.9 - - d3-shape@3.2.0: - dependencies: - d3-path: 3.1.0 - - d3-time-format@4.1.0: - dependencies: - d3-time: 3.1.0 - - d3-time@3.1.0: - dependencies: - d3-array: 3.2.4 - - d3-timer@3.0.1: {} - - d3-transition@3.0.1(d3-selection@3.0.0): - dependencies: - d3-color: 3.1.0 - d3-dispatch: 3.0.1 - d3-ease: 3.0.1 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-timer: 3.0.1 - - d3-zoom@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) - - d3@7.9.0: - dependencies: - d3-array: 3.2.4 - d3-axis: 3.0.0 - d3-brush: 3.0.0 - d3-chord: 3.0.1 - d3-color: 3.1.0 - d3-contour: 4.0.2 - d3-delaunay: 6.0.4 - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-dsv: 3.0.1 - d3-ease: 3.0.1 - d3-fetch: 3.0.1 - d3-force: 3.0.0 - d3-format: 3.1.2 - d3-geo: 3.1.1 - d3-hierarchy: 3.1.2 - d3-interpolate: 3.0.1 - d3-path: 3.1.0 - d3-polygon: 3.0.1 - d3-quadtree: 3.0.1 - d3-random: 3.0.1 - d3-scale: 4.0.2 - d3-scale-chromatic: 3.1.0 - d3-selection: 3.0.0 - d3-shape: 3.2.0 - d3-time: 3.1.0 - d3-time-format: 4.1.0 - d3-timer: 3.0.1 - d3-transition: 3.0.1(d3-selection@3.0.0) - d3-zoom: 3.0.0 - - dagre-d3-es@7.0.14: - dependencies: - d3: 7.9.0 - lodash-es: 4.17.23 - - dayjs@1.11.20: {} - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - delaunator@5.1.0: - dependencies: - robust-predicates: 3.0.3 - - dequal@2.0.3: {} - - detect-libc@2.1.2: - optional: true - - diff-match-patch@1.0.5: {} - - dompurify@3.3.3: - optionalDependencies: - '@types/trusted-types': 2.0.7 - - drizzle-kit@0.31.10: - dependencies: - '@drizzle-team/brocli': 0.10.2 - '@esbuild-kit/esm-loader': 2.6.5 - esbuild: 0.25.12 - tsx: 4.21.0 - - drizzle-orm@0.44.7(@opentelemetry/api@1.9.0): - optionalDependencies: - '@opentelemetry/api': 1.9.0 - - electron-to-chromium@1.5.322: {} - - esbuild@0.18.20: - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - - esbuild@0.25.12: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.12 - '@esbuild/android-arm': 0.25.12 - '@esbuild/android-arm64': 0.25.12 - '@esbuild/android-x64': 0.25.12 - '@esbuild/darwin-arm64': 0.25.12 - '@esbuild/darwin-x64': 0.25.12 - '@esbuild/freebsd-arm64': 0.25.12 - '@esbuild/freebsd-x64': 0.25.12 - '@esbuild/linux-arm': 0.25.12 - '@esbuild/linux-arm64': 0.25.12 - '@esbuild/linux-ia32': 0.25.12 - '@esbuild/linux-loong64': 0.25.12 - '@esbuild/linux-mips64el': 0.25.12 - '@esbuild/linux-ppc64': 0.25.12 - '@esbuild/linux-riscv64': 0.25.12 - '@esbuild/linux-s390x': 0.25.12 - '@esbuild/linux-x64': 0.25.12 - '@esbuild/netbsd-arm64': 0.25.12 - '@esbuild/netbsd-x64': 0.25.12 - '@esbuild/openbsd-arm64': 0.25.12 - '@esbuild/openbsd-x64': 0.25.12 - '@esbuild/openharmony-arm64': 0.25.12 - '@esbuild/sunos-x64': 0.25.12 - '@esbuild/win32-arm64': 0.25.12 - '@esbuild/win32-ia32': 0.25.12 - '@esbuild/win32-x64': 0.25.12 - - esbuild@0.27.4: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.4 - '@esbuild/android-arm': 0.27.4 - '@esbuild/android-arm64': 0.27.4 - '@esbuild/android-x64': 0.27.4 - '@esbuild/darwin-arm64': 0.27.4 - '@esbuild/darwin-x64': 0.27.4 - '@esbuild/freebsd-arm64': 0.27.4 - '@esbuild/freebsd-x64': 0.27.4 - '@esbuild/linux-arm': 0.27.4 - '@esbuild/linux-arm64': 0.27.4 - '@esbuild/linux-ia32': 0.27.4 - '@esbuild/linux-loong64': 0.27.4 - '@esbuild/linux-mips64el': 0.27.4 - '@esbuild/linux-ppc64': 0.27.4 - '@esbuild/linux-riscv64': 0.27.4 - '@esbuild/linux-s390x': 0.27.4 - '@esbuild/linux-x64': 0.27.4 - '@esbuild/netbsd-arm64': 0.27.4 - '@esbuild/netbsd-x64': 0.27.4 - '@esbuild/openbsd-arm64': 0.27.4 - '@esbuild/openbsd-x64': 0.27.4 - '@esbuild/openharmony-arm64': 0.27.4 - '@esbuild/sunos-x64': 0.27.4 - '@esbuild/win32-arm64': 0.27.4 - '@esbuild/win32-ia32': 0.27.4 - '@esbuild/win32-x64': 0.27.4 - - escalade@3.2.0: {} - - eventsource-parser@1.1.2: {} - - fast-deep-equal@3.1.3: {} - - fdb-tuple@1.0.0: {} - - fsevents@2.3.3: - optional: true - - gensync@1.0.0-beta.2: {} - - get-port@7.2.0: {} - - get-tsconfig@4.13.7: - dependencies: - resolve-pkg-maps: 1.0.0 - - hachure-fill@0.5.2: {} - - hono@4.12.9: {} - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - internmap@1.0.1: {} - - internmap@2.0.3: {} - - invariant@2.2.4: - dependencies: - loose-envify: 1.4.0 - - is-network-error@1.3.1: {} - - js-tokens@4.0.0: {} - - jsesc@3.1.0: {} - - json-schema@0.4.0: {} - - json5@2.2.3: {} - - jsondiffpatch@0.6.0: - dependencies: - '@types/diff-match-patch': 1.0.36 - chalk: 5.6.2 - diff-match-patch: 1.0.5 - - katex@0.16.42: - dependencies: - commander: 8.3.0 - - khroma@2.1.0: {} - - langium@4.2.1: - dependencies: - chevrotain: 11.1.2 - chevrotain-allstar: 0.3.1(chevrotain@11.1.2) - vscode-languageserver: 9.0.1 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.1.0 - - layout-base@1.0.2: {} - - layout-base@2.0.1: {} - - lodash-es@4.17.23: {} - - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - lucide-react@0.439.0(react@18.3.1): - dependencies: - react: 18.3.1 - - marked@16.4.2: {} - - mermaid@11.13.0: - dependencies: - '@braintree/sanitize-url': 7.1.2 - '@iconify/utils': 3.1.0 - '@mermaid-js/parser': 1.0.1 - '@types/d3': 7.4.3 - '@upsetjs/venn.js': 2.0.0 - cytoscape: 3.33.1 - cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) - cytoscape-fcose: 2.2.0(cytoscape@3.33.1) - d3: 7.9.0 - d3-sankey: 0.12.3 - dagre-d3-es: 7.0.14 - dayjs: 1.11.20 - dompurify: 3.3.3 - katex: 0.16.42 - khroma: 2.1.0 - lodash-es: 4.17.23 - marked: 16.4.2 - roughjs: 4.6.6 - stylis: 4.3.6 - ts-dedent: 2.2.0 - uuid: 11.1.0 - - minipass@7.1.3: {} - - minizlib@3.1.0: - dependencies: - minipass: 7.1.3 - - mlly@1.8.2: - dependencies: - acorn: 8.16.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.3 - - ms@2.1.3: {} - - nanoevents@9.1.0: {} - - nanoid@3.3.11: {} - - nanoid@3.3.6: {} - - node-gyp-build-optional-packages@5.1.1: - dependencies: - detect-libc: 2.1.2 - optional: true - - node-releases@2.0.36: {} - - on-exit-leak-free@2.1.2: {} - - openapi3-ts@4.5.0: - dependencies: - yaml: 2.8.3 - - p-retry@6.2.1: - dependencies: - '@types/retry': 0.12.2 - is-network-error: 1.3.1 - retry: 0.13.1 - - package-manager-detector@1.6.0: {} - - path-data-parser@0.1.0: {} - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - pino-abstract-transport@2.0.0: - dependencies: - split2: 4.2.0 - - pino-std-serializers@7.1.0: {} - - pino@9.14.0: - dependencies: - '@pinojs/redact': 0.4.0 - atomic-sleep: 1.0.0 - on-exit-leak-free: 2.1.2 - pino-abstract-transport: 2.0.0 - pino-std-serializers: 7.1.0 - process-warning: 5.0.0 - quick-format-unescaped: 4.0.4 - real-require: 0.2.0 - safe-stable-stringify: 2.5.0 - sonic-boom: 4.2.1 - thread-stream: 3.1.0 - - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.2 - pathe: 2.0.3 - - points-on-curve@0.2.0: {} - - points-on-path@0.2.1: - dependencies: - path-data-parser: 0.1.0 - points-on-curve: 0.2.0 - - postcss@8.5.8: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prism-react-renderer@2.4.1(react@18.3.1): - dependencies: - '@types/prismjs': 1.26.6 - clsx: 2.1.1 - react: 18.3.1 - - process-warning@5.0.0: {} - - quick-format-unescaped@4.0.4: {} - - react-dom@18.3.1(react@18.3.1): - dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 - - react-refresh@0.17.0: {} - - react@18.3.1: - dependencies: - loose-envify: 1.4.0 - - real-require@0.2.0: {} - - resolve-pkg-maps@1.0.0: {} - - retry@0.13.1: {} - - rivetkit@2.1.7(@standard-schema/spec@1.0.0)(drizzle-kit@0.31.10)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0))(ws@8.20.0): - dependencies: - '@hono/node-server': 1.19.11(hono@4.12.9) - '@hono/node-ws': 1.3.0(@hono/node-server@1.19.11(hono@4.12.9))(hono@4.12.9) - '@hono/standard-validator': 0.1.5(@standard-schema/spec@1.0.0)(hono@4.12.9) - '@hono/zod-openapi': 1.2.3(hono@4.12.9)(zod@4.3.6) - '@rivetkit/bare-ts': 0.6.2 - '@rivetkit/engine-runner': 2.1.7 - '@rivetkit/fast-json-patch': 3.1.2 - '@rivetkit/on-change': 6.0.2-rc.1 - '@rivetkit/sqlite': 0.1.1 - '@rivetkit/sqlite-vfs': 2.1.7 - '@rivetkit/traces': 2.1.7 - '@rivetkit/virtual-websocket': 2.0.33 - '@rivetkit/workflow-engine': 2.1.7 - cbor-x: 1.6.4 - get-port: 7.2.0 - hono: 4.12.9 - invariant: 2.2.4 - nanoevents: 9.1.0 - p-retry: 6.2.1 - pino: 9.14.0 - sandbox-agent: 0.4.0(get-port@7.2.0)(zod@4.3.6) - tar: 7.5.13 - uuid: 12.0.0 - vbare: 0.0.4 - zod: 4.3.6 - optionalDependencies: - drizzle-kit: 0.31.10 - drizzle-orm: 0.44.7(@opentelemetry/api@1.9.0) - ws: 8.20.0 - transitivePeerDependencies: - - '@cloudflare/sandbox' - - '@standard-schema/spec' - - '@vercel/sandbox' - - bufferutil - - computesdk - - modal - - utf-8-validate - - robust-predicates@3.0.3: {} - - rollup@4.60.0: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.0 - '@rollup/rollup-android-arm64': 4.60.0 - '@rollup/rollup-darwin-arm64': 4.60.0 - '@rollup/rollup-darwin-x64': 4.60.0 - '@rollup/rollup-freebsd-arm64': 4.60.0 - '@rollup/rollup-freebsd-x64': 4.60.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.0 - '@rollup/rollup-linux-arm-musleabihf': 4.60.0 - '@rollup/rollup-linux-arm64-gnu': 4.60.0 - '@rollup/rollup-linux-arm64-musl': 4.60.0 - '@rollup/rollup-linux-loong64-gnu': 4.60.0 - '@rollup/rollup-linux-loong64-musl': 4.60.0 - '@rollup/rollup-linux-ppc64-gnu': 4.60.0 - '@rollup/rollup-linux-ppc64-musl': 4.60.0 - '@rollup/rollup-linux-riscv64-gnu': 4.60.0 - '@rollup/rollup-linux-riscv64-musl': 4.60.0 - '@rollup/rollup-linux-s390x-gnu': 4.60.0 - '@rollup/rollup-linux-x64-gnu': 4.60.0 - '@rollup/rollup-linux-x64-musl': 4.60.0 - '@rollup/rollup-openbsd-x64': 4.60.0 - '@rollup/rollup-openharmony-arm64': 4.60.0 - '@rollup/rollup-win32-arm64-msvc': 4.60.0 - '@rollup/rollup-win32-ia32-msvc': 4.60.0 - '@rollup/rollup-win32-x64-gnu': 4.60.0 - '@rollup/rollup-win32-x64-msvc': 4.60.0 - fsevents: 2.3.3 - - roughjs@4.6.6: - dependencies: - hachure-fill: 0.5.2 - path-data-parser: 0.1.0 - points-on-curve: 0.2.0 - points-on-path: 0.2.1 - - rw@1.3.3: {} - - safe-stable-stringify@2.5.0: {} - - safer-buffer@2.1.2: {} - - sandbox-agent@0.4.0(get-port@7.2.0)(zod@4.3.6): - dependencies: - '@sandbox-agent/cli-shared': 0.4.0 - acp-http-client: 0.4.0(zod@4.3.6) - optionalDependencies: - '@sandbox-agent/cli': 0.4.0 - get-port: 7.2.0 - transitivePeerDependencies: - - zod - - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 - - secure-json-parse@2.7.0: {} - - semver@6.3.1: {} - - sonic-boom@4.2.1: - dependencies: - atomic-sleep: 1.0.0 - - source-map-js@1.2.1: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - split2@4.2.0: {} - - srvx@0.10.1: {} - - stylis@4.3.6: {} - - swr@2.4.1(react@18.3.1): - dependencies: - dequal: 2.0.3 - react: 18.3.1 - use-sync-external-store: 1.6.0(react@18.3.1) - - tar@7.5.13: - dependencies: - '@isaacs/fs-minipass': 4.0.1 - chownr: 3.0.0 - minipass: 7.1.3 - minizlib: 3.1.0 - yallist: 5.0.0 - - thread-stream@3.1.0: - dependencies: - real-require: 0.2.0 - - throttleit@2.1.0: {} - - tinyexec@1.0.4: {} - - ts-dedent@2.2.0: {} - - tsx@4.21.0: - dependencies: - esbuild: 0.27.4 - get-tsconfig: 4.13.7 - optionalDependencies: - fsevents: 2.3.3 - - typescript@5.9.3: {} - - ufo@1.6.3: {} - - undici-types@6.21.0: {} - - update-browserslist-db@1.2.3(browserslist@4.28.1): - dependencies: - browserslist: 4.28.1 - escalade: 3.2.0 - picocolors: 1.1.1 - - use-sync-external-store@1.6.0(react@18.3.1): - dependencies: - react: 18.3.1 - - uuid@11.1.0: {} - - uuid@12.0.0: {} - - vbare@0.0.4: {} - - vite-plugin-srvx@1.0.2(srvx@0.10.1)(vite@5.4.21(@types/node@22.19.15)): - dependencies: - srvx: 0.10.1 - vite: 5.4.21(@types/node@22.19.15) - - vite@5.4.21(@types/node@22.19.15): - dependencies: - esbuild: 0.21.5 - postcss: 8.5.8 - rollup: 4.60.0 - optionalDependencies: - '@types/node': 22.19.15 - fsevents: 2.3.3 - - vscode-jsonrpc@8.2.0: {} - - vscode-languageserver-protocol@3.17.5: - dependencies: - vscode-jsonrpc: 8.2.0 - vscode-languageserver-types: 3.17.5 - - vscode-languageserver-textdocument@1.0.12: {} - - vscode-languageserver-types@3.17.5: {} - - vscode-languageserver@9.0.1: - dependencies: - vscode-languageserver-protocol: 3.17.5 - - vscode-uri@3.1.0: {} - - ws@8.20.0: {} - - yallist@3.1.1: {} - - yallist@5.0.0: {} - - yaml@2.8.3: {} - - zod-to-json-schema@3.25.1(zod@3.25.76): - dependencies: - zod: 3.25.76 - - zod@3.25.76: {} - - zod@4.3.6: {} diff --git a/frontend/cloud.Dockerfile b/frontend/cloud.Dockerfile index 9668faa682..fae37f616d 100644 --- a/frontend/cloud.Dockerfile +++ b/frontend/cloud.Dockerfile @@ -23,7 +23,6 @@ COPY rivetkit-typescript/packages/engine-runner-protocol/ rivetkit-typescript/pa COPY rivetkit-typescript/packages/rivetkit/ rivetkit-typescript/packages/rivetkit/ COPY rivetkit-typescript/packages/traces/ rivetkit-typescript/packages/traces/ COPY rivetkit-typescript/packages/workflow-engine/ rivetkit-typescript/packages/workflow-engine/ -COPY rivetkit-typescript/packages/sqlite-vfs/ rivetkit-typescript/packages/sqlite-vfs/ # Copy shared libraries COPY shared/typescript/virtual-websocket/ shared/typescript/virtual-websocket/ diff --git a/frontend/inspector.Dockerfile b/frontend/inspector.Dockerfile index c72d934035..2b3fcfcc78 100644 --- a/frontend/inspector.Dockerfile +++ b/frontend/inspector.Dockerfile @@ -23,7 +23,6 @@ COPY rivetkit-typescript/packages/engine-runner-protocol/ rivetkit-typescript/pa COPY rivetkit-typescript/packages/rivetkit/ rivetkit-typescript/packages/rivetkit/ COPY rivetkit-typescript/packages/traces/ rivetkit-typescript/packages/traces/ COPY rivetkit-typescript/packages/workflow-engine/ rivetkit-typescript/packages/workflow-engine/ -COPY rivetkit-typescript/packages/sqlite-vfs/ rivetkit-typescript/packages/sqlite-vfs/ # Copy shared libraries COPY shared/typescript/virtual-websocket/ shared/typescript/virtual-websocket/ diff --git a/frontend/ladle.Dockerfile b/frontend/ladle.Dockerfile index 64e5cc1af0..e79bd9a662 100644 --- a/frontend/ladle.Dockerfile +++ b/frontend/ladle.Dockerfile @@ -26,9 +26,6 @@ COPY rivetkit-typescript/packages/engine-runner-protocol/ rivetkit-typescript/pa COPY rivetkit-typescript/packages/rivetkit/ rivetkit-typescript/packages/rivetkit/ COPY rivetkit-typescript/packages/traces/ rivetkit-typescript/packages/traces/ COPY rivetkit-typescript/packages/workflow-engine/ rivetkit-typescript/packages/workflow-engine/ -COPY rivetkit-typescript/packages/sqlite-vfs/ rivetkit-typescript/packages/sqlite-vfs/ -COPY rivetkit-typescript/packages/sqlite-vfs-linux-arm64/ rivetkit-typescript/packages/sqlite-vfs-linux-arm64/ -COPY rivetkit-typescript/packages/sqlite-vfs-linux-x64/ rivetkit-typescript/packages/sqlite-vfs-linux-x64/ # Copy shared libraries COPY shared/typescript/virtual-websocket/ shared/typescript/virtual-websocket/ diff --git a/package.json b/package.json index 951f504a7c..f4aff35580 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@rivetkit/react": "workspace:*", "@rivetkit/next-js": "workspace:*", "@rivetkit/db": "workspace:*", - "@rivetkit/sqlite-wasm": "workspace:*", "@rivetkit/engine-api-full": "workspace:*", "@rivetkit/rivetkit-native": "workspace:*", "@rivetkit/engine-cli": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 49a71ec126..9a004e3bd7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,7 @@ overrides: '@rivetkit/react': workspace:* '@rivetkit/next-js': workspace:* '@rivetkit/db': workspace:* - '@rivetkit/sqlite-wasm': workspace:* - '@rivetkit/engine-api-full': workspace:* + '@rivetkit/engine-api-full': https://pkg.pr.new/rivet-dev/engine-ee/@rivetkit/engine-api-full@011e389 '@rivetkit/rivetkit-native': workspace:* '@rivetkit/engine-cli': workspace:* '@types/react': ^19 @@ -2686,9 +2685,6 @@ importers: '@rivetkit/react': specifier: workspace:* version: link:../../rivetkit-typescript/packages/react - '@rivetkit/sqlite-wasm': - specifier: workspace:* - version: link:../../rivetkit-typescript/packages/sqlite-vfs ai: specifier: ^4.0.38 version: 4.3.19(react@19.1.0)(zod@3.25.76) @@ -4379,12 +4375,6 @@ importers: '@rivetkit/rivetkit-native': specifier: workspace:* version: link:../rivetkit-native - '@rivetkit/sqlite': - specifier: ^0.1.1 - version: 0.1.1 - '@rivetkit/sqlite-wasm': - specifier: workspace:* - version: link:../sqlite-vfs '@rivetkit/traces': specifier: workspace:* version: link:../traces @@ -4546,59 +4536,6 @@ importers: specifier: ^2.18.0 version: 2.18.4 - rivetkit-typescript/packages/sqlite-vfs: - dependencies: - '@rivetkit/bare-ts': - specifier: ^0.6.2 - version: 0.6.2 - '@rivetkit/sqlite': - specifier: ^0.1.1 - version: 0.1.1 - vbare: - specifier: ^0.0.4 - version: 0.0.4 - devDependencies: - '@bare-ts/tools': - specifier: ^0.13.0 - version: 0.13.0(@bare-ts/lib@0.6.0) - '@types/node': - specifier: ^22.13.1 - version: 22.19.10 - commander: - specifier: ^12.0.0 - version: 12.1.0 - tsup: - specifier: ^8.4.0 - version: 8.5.1(@microsoft/api-extractor@7.53.2(@types/node@22.19.10))(@swc/core@1.15.11(@swc/helpers@0.5.17))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) - tsx: - specifier: ^4.7.0 - version: 4.21.0 - typescript: - specifier: ^5.7.3 - version: 5.9.3 - vitest: - specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) - - rivetkit-typescript/packages/sqlite-vfs-test: - dependencies: - '@rivetkit/sqlite-wasm': - specifier: workspace:* - version: link:../sqlite-vfs - devDependencies: - '@types/node': - specifier: ^22.13.1 - version: 22.19.15 - tsx: - specifier: ^4.7.0 - version: 4.21.0 - typescript: - specifier: ^5.7.3 - version: 5.9.3 - vitest: - specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.15)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.15)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) - rivetkit-typescript/packages/traces: dependencies: '@rivetkit/bare-ts': @@ -9605,9 +9542,6 @@ packages: resolution: {integrity: sha512-5RC9Ze/wTKqSlJvopdCgr+EfyV93+iiH8Thog0QXrl8PT1unuBNw/jadXNMtwgAxrIaCJL+JLaHQH9w7rqpMDw==} engines: {node: '>=20'} - '@rivetkit/sqlite@0.1.1': - resolution: {integrity: sha512-NE7ZBy/hQhOrWzMZFjkHX9SoXxf+ILcDvVV+mNbUYPgiy/fsDzlXdK0+JDTGnko5f4Xl6/KVCoCozz9gkwkq8A==} - '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} @@ -25521,8 +25455,6 @@ snapshots: '@rivetkit/on-change@6.0.2-rc.1': {} - '@rivetkit/sqlite@0.1.1': {} - '@rolldown/pluginutils@1.0.0-beta.27': {} '@rollup/pluginutils@5.3.0(rollup@4.57.1)': diff --git a/rivetkit-rust/Cargo.lock b/rivetkit-rust/Cargo.lock index 2ffbb347dd..86a22c717a 100644 --- a/rivetkit-rust/Cargo.lock +++ b/rivetkit-rust/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "atomic-waker" @@ -37,9 +37,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "block-buffer" @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bytes" @@ -64,9 +64,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.55" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", "shlex", @@ -79,19 +79,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] -name = "convert_case" -version = "0.6.0" +name = "core-foundation" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "unicode-segmentation", + "core-foundation-sys", + "libc", ] [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -122,16 +123,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "ctor" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "data-encoding" version = "2.10.0" @@ -203,9 +194,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "find-msvc-tools" @@ -219,6 +210,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -251,9 +248,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -266,9 +263,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -276,15 +273,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -293,15 +290,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", @@ -310,21 +307,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -334,7 +331,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -367,10 +363,23 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + [[package]] name = "h2" version = "0.3.27" @@ -417,9 +426,24 @@ checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "http" @@ -514,9 +538,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", @@ -528,7 +552,6 @@ dependencies = [ "httparse", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -552,15 +575,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "c2b52f86d1d4bc0d6b4e6826d960b1b333217e07d36b882dca570a5e1c48895b" dependencies = [ "http 1.4.0", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", - "rustls 0.23.36", - "rustls-pki-types", + "rustls 0.23.38", "tokio", "tokio-rustls 0.26.4", "tower-service", @@ -586,7 +608,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", "native-tls", "tokio", @@ -606,12 +628,12 @@ dependencies = [ "futures-util", "http 1.4.0", "http-body 1.0.1", - "hyper 1.8.1", + "hyper 1.9.0", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.2", + "socket2 0.6.3", "system-configuration", "tokio", "tower-service", @@ -621,12 +643,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -634,9 +657,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -647,9 +670,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -661,15 +684,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -681,15 +704,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -700,6 +723,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "idna" version = "1.1.0" @@ -723,25 +752,27 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.17.0", + "serde", + "serde_core", ] [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" dependencies = [ "memchr", "serde", @@ -749,16 +780,18 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -770,43 +803,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "libc" -version = "0.2.180" +name = "leb128fmt" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] -name = "libloading" -version = "0.8.9" +name = "libc" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "libsqlite3-sys" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" @@ -834,9 +852,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "mime" @@ -846,85 +864,28 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", "windows-sys 0.61.2", ] -[[package]] -name = "napi" -version = "2.16.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" -dependencies = [ - "bitflags", - "ctor", - "napi-derive", - "napi-sys", - "once_cell", -] - -[[package]] -name = "napi-build" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d376940fd5b723c6893cd1ee3f33abbfd86acb1cd1ec079f3ab04a2a3bc4d3b1" - -[[package]] -name = "napi-derive" -version = "2.16.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c" -dependencies = [ - "cfg-if", - "convert_case", - "napi-derive-backend", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "napi-derive-backend" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf" -dependencies = [ - "convert_case", - "once_cell", - "proc-macro2", - "quote", - "regex", - "semver", - "syn", -] - -[[package]] -name = "napi-sys" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3" -dependencies = [ - "libloading", -] - [[package]] name = "native-tls" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" dependencies = [ "libc", "log", "openssl", - "openssl-probe", + "openssl-probe 0.2.1", "openssl-sys", "schannel", - "security-framework", + "security-framework 3.7.0", "security-framework-sys", "tempfile", ] @@ -940,15 +901,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "openssl" -version = "0.10.75" +version = "0.10.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +checksum = "bfe4646e360ec77dff7dde40ed3d6c5fee52d156ef4a62f53973d38294dad87f" dependencies = [ "bitflags", "cfg-if", @@ -976,11 +937,17 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "openssl-sys" -version = "0.9.111" +version = "0.9.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +checksum = "ad2f2c0eba47118757e4c6d2bff2838f3e0523380021356e7875e858372ce644" dependencies = [ "cc", "libc", @@ -1019,18 +986,18 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", "quote", @@ -1039,21 +1006,15 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "portpicker" @@ -1066,9 +1027,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -1082,6 +1043,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.106" @@ -1093,9 +1064,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -1106,6 +1077,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" version = "0.8.5" @@ -1119,9 +1096,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -1174,18 +1151,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - [[package]] name = "regex-automata" version = "0.4.14" @@ -1199,9 +1164,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" @@ -1217,8 +1182,8 @@ dependencies = [ "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", - "hyper-rustls 0.27.7", + "hyper 1.9.0", + "hyper-rustls 0.27.8", "hyper-tls", "hyper-util", "js-sys", @@ -1281,31 +1246,11 @@ dependencies = [ "urlencoding", ] -[[package]] -name = "rivetkit-sqlite-vfs-core" -version = "0.0.1" - -[[package]] -name = "rivetkit-sqlite-vfs-native" -version = "0.0.1" -dependencies = [ - "libsqlite3-sys", - "napi", - "napi-build", - "napi-derive", - "tempfile", - "thiserror 1.0.69", -] - -[[package]] -name = "rivetkit-sqlite-vfs-wasm" -version = "0.0.1" - [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags", "errno", @@ -1328,13 +1273,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" dependencies = [ "once_cell", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.11", "subtle", "zeroize", ] @@ -1345,10 +1290,10 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ - "openssl-probe", + "openssl-probe 0.1.6", "rustls-pemfile", "schannel", - "security-framework", + "security-framework 2.11.1", ] [[package]] @@ -1381,9 +1326,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "20a6af516fea4b20eccceaf166e8aa666ac996208e8a644ce3ef5aa783bc7cd4" dependencies = [ "ring", "rustls-pki-types", @@ -1398,15 +1343,15 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -1434,7 +1379,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -1442,9 +1400,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -1452,9 +1410,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" @@ -1581,12 +1539,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1603,9 +1561,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.114" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -1639,7 +1597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -1655,44 +1613,24 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.24.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", ] -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.18", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "thiserror-impl", ] [[package]] @@ -1717,9 +1655,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -1727,9 +1665,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.49.0" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ "bytes", "libc", @@ -1737,7 +1675,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.2", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] @@ -1754,9 +1692,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -1789,7 +1727,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.36", + "rustls 0.23.38", "tokio", ] @@ -1932,9 +1870,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -1966,9 +1904,9 @@ dependencies = [ "httparse", "log", "native-tls", - "rand 0.9.2", + "rand 0.9.3", "sha1", - "thiserror 2.0.18", + "thiserror", "utf-8", ] @@ -1980,15 +1918,15 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] -name = "unicode-segmentation" -version = "1.12.0" +name = "unicode-xid" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "untrusted" @@ -2068,11 +2006,20 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", "once_cell", @@ -2083,23 +2030,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" dependencies = [ - "cfg-if", - "futures-util", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2107,9 +2050,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ "bumpalo", "proc-macro2", @@ -2120,18 +2063,52 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" dependencies = [ "js-sys", "wasm-bindgen", @@ -2178,16 +2155,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -2205,31 +2173,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -2238,60 +2189,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -2299,52 +2220,116 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_x86_64_gnullvm" +name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" +name = "wit-bindgen" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] [[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" +name = "wit-bindgen-core" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] [[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" +name = "wit-bindgen-rust" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] [[package]] -name = "wit-bindgen" +name = "wit-bindgen-rust-macro" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -2353,9 +2338,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -2365,18 +2350,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.38" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57cf3aa6855b23711ee9852dfc97dfaa51c45feaba5b645d0c777414d494a961" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.38" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a616990af1a287837c4fe6596ad77ef57948f787e46ce28e166facc0cc1cb75" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -2385,18 +2370,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -2412,9 +2397,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -2423,9 +2408,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -2434,9 +2419,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", @@ -2445,6 +2430,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.19" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/rivetkit-typescript/packages/sqlite-vfs-test/package.json b/rivetkit-typescript/packages/sqlite-vfs-test/package.json deleted file mode 100644 index 8787c9cff4..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs-test/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@rivetkit/sqlite-wasm-test", - "version": "2.2.1", - "description": "Vitest wrapper for sqlite-vfs backends", - "license": "Apache-2.0", - "type": "module", - "private": true, - "scripts": { - "test": "pnpm --filter @rivetkit/sqlite-wasm build && RIVETKIT_SQLITE_BACKEND=wasm vitest run && pnpm --filter @rivetkit/sqlite-wasm build:native && RIVETKIT_SQLITE_BACKEND=native vitest run" - }, - "dependencies": { - "@rivetkit/sqlite-wasm": "workspace:*" - }, - "devDependencies": { - "@types/node": "^22.13.1", - "tsx": "^4.7.0", - "typescript": "^5.7.3", - "vitest": "^3.1.1" - } -} diff --git a/rivetkit-typescript/packages/sqlite-vfs-test/src/backend.ts b/rivetkit-typescript/packages/sqlite-vfs-test/src/backend.ts deleted file mode 100644 index 567e57772e..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs-test/src/backend.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { SqliteVfs } from "@rivetkit/sqlite-wasm"; - -export async function createSqliteVfs() { - return new SqliteVfs(); -} diff --git a/rivetkit-typescript/packages/sqlite-vfs-test/tests/pool.test.ts b/rivetkit-typescript/packages/sqlite-vfs-test/tests/pool.test.ts deleted file mode 100644 index d873fed397..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs-test/tests/pool.test.ts +++ /dev/null @@ -1,321 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { SqliteVfsPool } from "@rivetkit/sqlite-wasm"; -import type { KvVfsOptions } from "@rivetkit/sqlite-wasm"; - -function keyToString(key: Uint8Array): string { - return Buffer.from(key).toString("hex"); -} - -function createKvStore(): KvVfsOptions { - const store = new Map(); - - return { - get: async (key) => { - const value = store.get(keyToString(key)); - return value ? new Uint8Array(value) : null; - }, - getBatch: async (keys) => { - return keys.map((key) => { - const value = store.get(keyToString(key)); - return value ? new Uint8Array(value) : null; - }); - }, - put: async (key, value) => { - store.set(keyToString(key), new Uint8Array(value)); - }, - putBatch: async (entries) => { - for (const [key, value] of entries) { - store.set(keyToString(key), new Uint8Array(value)); - } - }, - deleteBatch: async (keys) => { - for (const key of keys) { - store.delete(keyToString(key)); - } - }, - }; -} - -describe("SqliteVfsPool", () => { - it("acquire returns a handle that can open and close a database", async () => { - const pool = new SqliteVfsPool({ actorsPerInstance: 50 }); - const handle = await pool.acquire("actor-a"); - - const kvStore = createKvStore(); - const db = await handle.open("ignored-filename", kvStore); - - await db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"); - await db.exec("INSERT INTO test (value) VALUES ('hello')"); - - const result = await db.query("SELECT value FROM test"); - expect(result.rows.length).toBe(1); - expect(String(result.rows[0]?.[0])).toBe("hello"); - - await db.close(); - await handle.destroy(); - await pool.shutdown(); - }); - - it("acquire with same actorId returns the same handle (sticky assignment)", async () => { - const pool = new SqliteVfsPool({ actorsPerInstance: 50 }); - - const handle1 = await pool.acquire("actor-sticky"); - const handle2 = await pool.acquire("actor-sticky"); - - expect(handle1).toBe(handle2); - - await handle1.destroy(); - await pool.shutdown(); - }); - - it("release then re-acquire gets a new handle", async () => { - const pool = new SqliteVfsPool({ actorsPerInstance: 50 }); - - const handle1 = await pool.acquire("actor-reacquire"); - await handle1.destroy(); - - const handle2 = await pool.acquire("actor-reacquire"); - expect(handle2).not.toBe(handle1); - - // The new handle should still work. - const kvStore = createKvStore(); - const db = await handle2.open("test", kvStore); - await db.exec("CREATE TABLE t (id INTEGER PRIMARY KEY)"); - await db.close(); - - await handle2.destroy(); - await pool.shutdown(); - }); - - it("releasing short name '1' does not close short name '10'", async () => { - const pool = new SqliteVfsPool({ actorsPerInstance: 50 }); - - // Acquire 11 actors so short names '0' through '10' are assigned. - const handles = []; - const actorIds = []; - for (let i = 0; i < 11; i++) { - const actorId = `actor-${i}`; - actorIds.push(actorId); - handles.push(await pool.acquire(actorId)); - } - - // Open databases for actor with short name '1' (actor-1) and - // short name '10' (actor-10). Each gets its own KV store. - const kvStore1 = createKvStore(); - const kvStore10 = createKvStore(); - - const db1 = await handles[1]!.open("db", kvStore1); - await db1.exec("CREATE TABLE t1 (id INTEGER PRIMARY KEY, v TEXT)"); - await db1.exec("INSERT INTO t1 (v) VALUES ('from-actor-1')"); - - const db10 = await handles[10]!.open("db", kvStore10); - await db10.exec("CREATE TABLE t10 (id INTEGER PRIMARY KEY, v TEXT)"); - await db10.exec("INSERT INTO t10 (v) VALUES ('from-actor-10')"); - - // Release actor-1 (short name '1'). This should force-close only - // databases with fileName exactly '1', not '10'. - await handles[1]!.destroy(); - - // Actor-10's database should still be usable. - await db10.exec("INSERT INTO t10 (v) VALUES ('after-release-1')"); - const result = await db10.query("SELECT v FROM t10 ORDER BY id"); - expect(result.rows.length).toBe(2); - expect(String(result.rows[0]?.[0])).toBe("from-actor-10"); - expect(String(result.rows[1]?.[0])).toBe("after-release-1"); - - // Clean up. - await db10.close(); - for (let i = 0; i < 11; i++) { - if (i !== 1) { - await handles[i]!.destroy(); - } - } - await pool.shutdown(); - }); - - it("double destroy() on PooledSqliteHandle is idempotent", async () => { - const pool = new SqliteVfsPool({ actorsPerInstance: 50 }); - const handle = await pool.acquire("actor-double-destroy"); - - // First destroy should succeed. - await handle.destroy(); - - // Second destroy should be a no-op (no error). - await handle.destroy(); - - await pool.shutdown(); - }); - - it("acquire after shutdown throws", async () => { - const pool = new SqliteVfsPool({ actorsPerInstance: 50 }); - - // Acquire and release one actor to exercise the pool. - const handle = await pool.acquire("actor-before-shutdown"); - await handle.destroy(); - - await pool.shutdown(); - - await expect(pool.acquire("actor-after-shutdown")).rejects.toThrow( - "SqliteVfsPool is shutting down", - ); - }); - - it("actorsPerInstance limit triggers new instance creation", async () => { - const pool = new SqliteVfsPool({ actorsPerInstance: 2 }); - - // Acquire 2 actors to fill the first instance. - const handle1 = await pool.acquire("actor-limit-1"); - const handle2 = await pool.acquire("actor-limit-2"); - - // The third actor should trigger a new instance. - const handle3 = await pool.acquire("actor-limit-3"); - - // All three handles should work independently. - const kvStore1 = createKvStore(); - const kvStore2 = createKvStore(); - const kvStore3 = createKvStore(); - - const db1 = await handle1.open("db", kvStore1); - const db2 = await handle2.open("db", kvStore2); - const db3 = await handle3.open("db", kvStore3); - - await db1.exec("CREATE TABLE t (v TEXT)"); - await db2.exec("CREATE TABLE t (v TEXT)"); - await db3.exec("CREATE TABLE t (v TEXT)"); - - await db1.exec("INSERT INTO t (v) VALUES ('one')"); - await db2.exec("INSERT INTO t (v) VALUES ('two')"); - await db3.exec("INSERT INTO t (v) VALUES ('three')"); - - const r1 = await db1.query("SELECT v FROM t"); - const r2 = await db2.query("SELECT v FROM t"); - const r3 = await db3.query("SELECT v FROM t"); - - expect(String(r1.rows[0]?.[0])).toBe("one"); - expect(String(r2.rows[0]?.[0])).toBe("two"); - expect(String(r3.rows[0]?.[0])).toBe("three"); - - await db1.close(); - await db2.close(); - await db3.close(); - await handle1.destroy(); - await handle2.destroy(); - await handle3.destroy(); - await pool.shutdown(); - }); - - it("pool scales up, scales down on idle, and scales back up", async () => { - const pool = new SqliteVfsPool({ - actorsPerInstance: 2, - idleDestroyMs: 100, - }); - - // -- Scale up: 6 actors with limit 2 → 3 instances -- - const handles = []; - const kvStores = []; - for (let i = 0; i < 6; i++) { - handles.push(await pool.acquire(`scale-actor-${i}`)); - kvStores.push(createKvStore()); - } - expect(pool.instanceCount).toBe(3); - expect(pool.actorCount).toBe(6); - - // Verify all 6 actors work with isolated data - for (let i = 0; i < 6; i++) { - const db = await handles[i]!.open("db", kvStores[i]!); - await db.exec("CREATE TABLE t (v TEXT)"); - await db.exec(`INSERT INTO t (v) VALUES ('actor-${i}')`); - const result = await db.query("SELECT v FROM t"); - expect(String(result.rows[0]?.[0])).toBe(`actor-${i}`); - await db.close(); - } - - // -- Scale down: release all actors, wait for idle destroy -- - for (const handle of handles) { - await handle.destroy(); - } - expect(pool.actorCount).toBe(0); - - // Wait for idle timers to fire and destroy instances - await new Promise((r) => setTimeout(r, 250)); - expect(pool.instanceCount).toBe(0); - - // -- Scale back up: 6 new actors → 3 new instances -- - const handles2 = []; - const kvStores2 = []; - for (let i = 0; i < 6; i++) { - handles2.push(await pool.acquire(`scale-actor-new-${i}`)); - kvStores2.push(createKvStore()); - } - expect(pool.instanceCount).toBe(3); - expect(pool.actorCount).toBe(6); - - // Verify all new actors work - for (let i = 0; i < 6; i++) { - const db = await handles2[i]!.open("db", kvStores2[i]!); - await db.exec("CREATE TABLE t (v TEXT)"); - await db.exec(`INSERT INTO t (v) VALUES ('new-${i}')`); - const result = await db.query("SELECT v FROM t"); - expect(String(result.rows[0]?.[0])).toBe(`new-${i}`); - await db.close(); - } - - for (const handle of handles2) { - await handle.destroy(); - } - await pool.shutdown(); - }); - - it("partial scale down keeps correct instance count", async () => { - const pool = new SqliteVfsPool({ - actorsPerInstance: 2, - idleDestroyMs: 100, - }); - - // Fill 3 instances with 6 actors - const handles = []; - for (let i = 0; i < 6; i++) { - handles.push(await pool.acquire(`partial-${i}`)); - } - expect(pool.instanceCount).toBe(3); - - // Release 4 actors (leaving 2 in one instance) - for (let i = 0; i < 4; i++) { - await handles[i]!.destroy(); - } - expect(pool.actorCount).toBe(2); - - // Wait for idle timers on empty instances - await new Promise((r) => setTimeout(r, 250)); - - // Only the instance with 2 remaining actors should survive - expect(pool.instanceCount).toBe(1); - expect(pool.actorCount).toBe(2); - - // Scale back up to 6 actors → should create 2 new instances - const handles2 = []; - for (let i = 0; i < 4; i++) { - handles2.push(await pool.acquire(`partial-new-${i}`)); - } - expect(pool.instanceCount).toBe(3); - expect(pool.actorCount).toBe(6); - - // Clean up - for (const h of [...handles.slice(4), ...handles2]) { - await h!.destroy(); - } - await pool.shutdown(); - }); - - it("constructor rejects actorsPerInstance < 1", () => { - expect(() => new SqliteVfsPool({ actorsPerInstance: 0 })).toThrow( - "actorsPerInstance must be a positive integer", - ); - expect(() => new SqliteVfsPool({ actorsPerInstance: -1 })).toThrow( - "actorsPerInstance must be a positive integer", - ); - expect(() => new SqliteVfsPool({ actorsPerInstance: 1.5 })).toThrow( - "actorsPerInstance must be a positive integer", - ); - }); -}); diff --git a/rivetkit-typescript/packages/sqlite-vfs-test/tests/sqlite-lock-repro.test.ts b/rivetkit-typescript/packages/sqlite-vfs-test/tests/sqlite-lock-repro.test.ts deleted file mode 100644 index 9d0dd97bd2..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs-test/tests/sqlite-lock-repro.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { afterEach, describe, expect, it } from "vitest"; -import { mkdtempSync, rmSync } from "node:fs"; -import { join } from "node:path"; -import { tmpdir } from "node:os"; - -interface SqliteLockError extends Error { - code?: string; - errcode?: number; - errstr?: string; -} - -const nodeMajorVersion = Number(process.versions.node.split(".")[0] ?? "0"); -const supportsNodeSqlite = - Number.isFinite(nodeMajorVersion) && nodeMajorVersion >= 22; -const lockReproTest = supportsNodeSqlite ? it : it.skip; - -describe("sqlite lock repro", () => { - let tempDir: string | undefined; - - afterEach(() => { - if (tempDir) { - rmSync(tempDir, { recursive: true, force: true }); - tempDir = undefined; - } - }); - - lockReproTest( - "throws database is locked on stmt.get when another handle holds an exclusive txn", - async () => { - const { DatabaseSync } = await import("node:sqlite"); - - tempDir = mkdtempSync(join(tmpdir(), "sqlite-lock-repro-")); - const dbPath = join(tempDir, "actor.db"); - - const writer = new DatabaseSync(dbPath); - const reader = new DatabaseSync(dbPath); - - try { - writer.exec( - "CREATE TABLE IF NOT EXISTS kv (key BLOB PRIMARY KEY NOT NULL, value BLOB NOT NULL)", - ); - writer - .prepare( - "INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)", - ) - .run(new Uint8Array([1]), new Uint8Array([2])); - - // Prepare the statement before the lock to match the failing runtime stack. - const readerStmt = reader.prepare( - "SELECT value FROM kv WHERE key = ?", - ); - - writer.exec("BEGIN EXCLUSIVE"); - writer - .prepare( - "INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)", - ) - .run(new Uint8Array([3]), new Uint8Array([4])); - - let thrown: unknown; - try { - readerStmt.get(new Uint8Array([1])); - } catch (error) { - thrown = error; - } - - expect(thrown).toBeDefined(); - const sqliteError = thrown as SqliteLockError; - expect(sqliteError.code).toBe("ERR_SQLITE_ERROR"); - expect(sqliteError.errcode).toBe(5); - expect(sqliteError.errstr).toBe("database is locked"); - } finally { - try { - writer.exec("ROLLBACK"); - } catch { - // Ignore rollback failures when setup failed before BEGIN EXCLUSIVE. - } - writer.close(); - reader.close(); - } - }, - ); -}); diff --git a/rivetkit-typescript/packages/sqlite-vfs-test/tests/sqlite-vfs.test.ts b/rivetkit-typescript/packages/sqlite-vfs-test/tests/sqlite-vfs.test.ts deleted file mode 100644 index d27e8e0641..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs-test/tests/sqlite-vfs.test.ts +++ /dev/null @@ -1,386 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { createSqliteVfs } from "../src/backend"; -import type { KvVfsOptions } from "@rivetkit/sqlite-wasm"; - -const CHUNK_SIZE = 4096; - -function keyToString(key: Uint8Array): string { - return Buffer.from(key).toString("hex"); -} - -function createKvStore(): KvVfsOptions { - const store = new Map(); - - return { - get: async (key) => { - const value = store.get(keyToString(key)); - return value ? new Uint8Array(value) : null; - }, - getBatch: async (keys) => { - return keys.map((key) => { - const value = store.get(keyToString(key)); - return value ? new Uint8Array(value) : null; - }); - }, - put: async (key, value) => { - store.set(keyToString(key), new Uint8Array(value)); - }, - putBatch: async (entries) => { - for (const [key, value] of entries) { - store.set(keyToString(key), new Uint8Array(value)); - } - }, - deleteBatch: async (keys) => { - for (const key of keys) { - store.delete(keyToString(key)); - } - }, - deleteRange: async (start, end) => { - const startHex = keyToString(start); - const endHex = keyToString(end); - for (const key of store.keys()) { - if (key >= startHex && key < endHex) { - store.delete(key); - } - } - }, - }; -} - -function toBlobValue(value: unknown): Uint8Array { - if (value instanceof Uint8Array) { - return new Uint8Array(value); - } - if (value instanceof ArrayBuffer) { - return new Uint8Array(value); - } - if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) { - return new Uint8Array(value); - } - throw new Error(`Expected blob value, got ${typeof value}`); -} - -function createPattern(size: number, seed = 17): Uint8Array { - const out = new Uint8Array(size); - for (let i = 0; i < out.length; i++) { - out[i] = (seed + i * 31) % 251; - } - return out; -} - -function assertBytesEqual(actual: Uint8Array, expected: Uint8Array): void { - expect(actual.length).toBe(expected.length); - for (let i = 0; i < expected.length; i++) { - if (actual[i] !== expected[i]) { - throw new Error( - `byte mismatch at offset ${i}: ${actual[i]} != ${expected[i]}`, - ); - } - } -} - -function applyPatch( - base: Uint8Array, - offset: number, - patch: Uint8Array, -): Uint8Array { - const next = new Uint8Array(base); - next.set(patch, offset); - return next; -} - -async function createBlobTable(db: { - exec: (sql: string) => Promise; -}): Promise { - await db.exec(` - CREATE TABLE IF NOT EXISTS blob_data ( - id INTEGER PRIMARY KEY, - payload BLOB NOT NULL - ) - `); -} - -describe("sqlite-vfs", () => { - it("persists data across VFS instances", async () => { - const kvStore = createKvStore(); - - const vfs = await createSqliteVfs(); - const db = await vfs.open("actor-1", kvStore); - await db.exec( - "CREATE TABLE IF NOT EXISTS test_data (id INTEGER PRIMARY KEY AUTOINCREMENT, value TEXT NOT NULL)", - ); - await db.exec("INSERT INTO test_data (value) VALUES ('alpha')"); - await db.exec("INSERT INTO test_data (value) VALUES ('beta')"); - await db.close(); - - const vfsReloaded = await createSqliteVfs(); - const dbReloaded = await vfsReloaded.open("actor-1", kvStore); - - const values: string[] = []; - await dbReloaded.exec( - "SELECT value FROM test_data ORDER BY id", - (row) => { - values.push(String(row[0])); - }, - ); - - expect(values).toEqual(["alpha", "beta"]); - - await dbReloaded.close(); - }); - - it("handles chunk boundary payload sizes", async () => { - const kvStore = createKvStore(); - const vfs = await createSqliteVfs(); - const db = await vfs.open("actor-chunk-boundary", kvStore); - - try { - await createBlobTable(db); - const sizes = [ - CHUNK_SIZE - 1, - CHUNK_SIZE, - CHUNK_SIZE + 1, - 2 * CHUNK_SIZE - 1, - 2 * CHUNK_SIZE, - 2 * CHUNK_SIZE + 1, - 4 * CHUNK_SIZE - 1, - 4 * CHUNK_SIZE, - 4 * CHUNK_SIZE + 1, - ]; - - for (const [index, size] of sizes.entries()) { - const payload = createPattern(size, index + 7); - await db.run( - "INSERT INTO blob_data (id, payload) VALUES (?, ?)", - [index + 1, payload], - ); - - const result = await db.query( - "SELECT payload FROM blob_data WHERE id = ?", - [index + 1], - ); - expect(result.rows.length).toBe(1); - const readBack = toBlobValue(result.rows[0]?.[0]); - assertBytesEqual(readBack, payload); - } - } finally { - await db.close(); - } - }); - - it("handles unaligned overwrite across chunk boundaries", async () => { - const kvStore = createKvStore(); - const vfs = await createSqliteVfs(); - const db = await vfs.open("actor-unaligned-overwrite", kvStore); - - try { - await createBlobTable(db); - - const initial = createPattern(3 * CHUNK_SIZE + 211, 23); - await db.run("INSERT INTO blob_data (id, payload) VALUES (?, ?)", [ - 1, - initial, - ]); - - const patchOffset = CHUNK_SIZE - 137; - const patch = createPattern(CHUNK_SIZE + 503, 91); - const expected = applyPatch(initial, patchOffset, patch); - await db.run("UPDATE blob_data SET payload = ? WHERE id = 1", [ - expected, - ]); - - const result = await db.query( - "SELECT payload FROM blob_data WHERE id = 1", - ); - expect(result.rows.length).toBe(1); - const readBack = toBlobValue(result.rows[0]?.[0]); - assertBytesEqual(readBack, expected); - } finally { - await db.close(); - } - }); - - it("supports shrink and regrow workloads", async () => { - const kvStore = createKvStore(); - const vfs = await createSqliteVfs(); - const db = await vfs.open("actor-shrink-regrow", kvStore); - - try { - await db.exec("PRAGMA auto_vacuum = NONE"); - await createBlobTable(db); - await db.exec("DELETE FROM blob_data"); - await db.exec("VACUUM"); - - for (let i = 0; i < 40; i++) { - await db.run( - "INSERT INTO blob_data (id, payload) VALUES (?, ?)", - [i + 1, createPattern(8192, i + 11)], - ); - } - - const grown = await db.query("PRAGMA page_count"); - const grownPages = Number(grown.rows[0]?.[0] ?? 0); - expect(grownPages).toBeGreaterThan(0); - - await db.exec("DELETE FROM blob_data"); - await db.exec("VACUUM"); - const shrunk = await db.query("PRAGMA page_count"); - const shrunkPages = Number(shrunk.rows[0]?.[0] ?? 0); - expect(shrunkPages).toBeLessThanOrEqual(grownPages); - - for (let i = 0; i < 25; i++) { - await db.run( - "INSERT INTO blob_data (id, payload) VALUES (?, ?)", - [i + 100, createPattern(12288, i + 41)], - ); - } - const regrown = await db.query("PRAGMA page_count"); - const regrownPages = Number(regrown.rows[0]?.[0] ?? 0); - expect(regrownPages).toBeGreaterThan(shrunkPages); - } finally { - await db.close(); - } - }); - - it("reads sparse-like zeroblob regions as zeros", async () => { - const kvStore = createKvStore(); - const vfs = await createSqliteVfs(); - const db = await vfs.open("actor-sparse-like", kvStore); - - try { - await createBlobTable(db); - const totalSize = 3 * CHUNK_SIZE; - const patchOffset = 2 * CHUNK_SIZE + 97; - const patch = createPattern(321, 171); - - await db.run( - "INSERT INTO blob_data (id, payload) VALUES (1, zeroblob(?))", - [totalSize], - ); - const zeroBlobResult = await db.query( - "SELECT payload FROM blob_data WHERE id = 1", - ); - const baseBlob = toBlobValue(zeroBlobResult.rows[0]?.[0]); - const expected = applyPatch(baseBlob, patchOffset, patch); - await db.run("UPDATE blob_data SET payload = ? WHERE id = 1", [ - expected, - ]); - - const result = await db.query( - "SELECT payload FROM blob_data WHERE id = 1", - ); - const blob = toBlobValue(result.rows[0]?.[0]); - expect(blob.length).toBe(totalSize); - - for (let i = 0; i < patchOffset; i++) { - if (blob[i] !== 0) { - throw new Error( - `expected zero at offset ${i}, got ${blob[i]}`, - ); - } - } - for (let i = 0; i < patch.length; i++) { - expect(blob[patchOffset + i]).toBe(patch[i]); - } - } finally { - await db.close(); - } - }); - - it("handles many small writes to hot and scattered rows", async () => { - const kvStore = createKvStore(); - const vfs = await createSqliteVfs(); - const db = await vfs.open("actor-many-small-writes", kvStore); - - try { - await db.exec( - "CREATE TABLE IF NOT EXISTS kv_like (id INTEGER PRIMARY KEY, value TEXT NOT NULL)", - ); - for (let i = 1; i <= 10; i++) { - await db.run("INSERT INTO kv_like (id, value) VALUES (?, ?)", [ - i, - "init", - ]); - } - - for (let i = 0; i < 500; i++) { - const id = (i % 10) + 1; - await db.run("UPDATE kv_like SET value = ? WHERE id = ?", [ - `v-${i}`, - id, - ]); - } - - const results = await db.query( - "SELECT id, value FROM kv_like ORDER BY id", - ); - expect(results.rows.length).toBe(10); - for (let i = 0; i < results.rows.length; i++) { - const row = results.rows[i]; - expect(Number(row?.[0])).toBe(i + 1); - expect(String(row?.[1])).toMatch(/^v-\d+$/); - } - } finally { - await db.close(); - } - }); - - it("passes integrity checks after mixed workload and reopen", async () => { - const kvStore = createKvStore(); - const vfs = await createSqliteVfs(); - const db = await vfs.open("actor-integrity", kvStore); - - try { - await db.exec( - "CREATE TABLE IF NOT EXISTS integrity_data (id INTEGER PRIMARY KEY, value TEXT NOT NULL, payload BLOB NOT NULL)", - ); - for (let i = 0; i < 150; i++) { - await db.run( - "INSERT OR REPLACE INTO integrity_data (id, value, payload) VALUES (?, ?, ?)", - [ - i + 1, - `seed-${i}`, - createPattern(2048 + (i % 7) * 97, i + 5), - ], - ); - } - for (let i = 0; i < 200; i++) { - const id = (i % 150) + 1; - if (i % 9 === 0) { - await db.run("DELETE FROM integrity_data WHERE id = ?", [ - id, - ]); - } else { - await db.run( - "INSERT OR REPLACE INTO integrity_data (id, value, payload) VALUES (?, ?, ?)", - [ - id, - `upd-${i}`, - createPattern(1024 + (i % 11) * 131, 100 + i), - ], - ); - } - } - - const integrityBefore = await db.query("PRAGMA integrity_check"); - expect(String(integrityBefore.rows[0]?.[0]).toLowerCase()).toBe( - "ok", - ); - } finally { - await db.close(); - } - - const vfsReloaded = await createSqliteVfs(); - const dbReloaded = await vfsReloaded.open("actor-integrity", kvStore); - try { - const integrityAfter = await dbReloaded.query( - "PRAGMA integrity_check", - ); - expect(String(integrityAfter.rows[0]?.[0]).toLowerCase()).toBe( - "ok", - ); - } finally { - await dbReloaded.close(); - } - }); -}); diff --git a/rivetkit-typescript/packages/sqlite-vfs-test/tsconfig.json b/rivetkit-typescript/packages/sqlite-vfs-test/tsconfig.json deleted file mode 100644 index c99638e62d..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs-test/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "types": ["node"] - }, - "include": ["src/**/*", "tests/**/*"] -} diff --git a/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/mod.ts b/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/mod.ts deleted file mode 100644 index cc5ca385c7..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/mod.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./versioned"; -export * from "../../dist/schemas/file-meta/v1"; diff --git a/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/v1.bare b/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/v1.bare deleted file mode 100644 index 4836c09e89..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/v1.bare +++ /dev/null @@ -1,7 +0,0 @@ -# File Meta BARE Schema v1 - -# File metadata for KV-backed SQLite storage - -type FileMeta struct { - size: u64 -} diff --git a/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/versioned.ts b/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/versioned.ts deleted file mode 100644 index 4565390c1f..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/schemas/file-meta/versioned.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { createVersionedDataHandler } from "vbare"; -import * as v1 from "../../dist/schemas/file-meta/v1"; - -export const CURRENT_VERSION = 1; - -export const FILE_META_VERSIONED = createVersionedDataHandler({ - deserializeVersion: (bytes, version) => { - switch (version) { - case 1: - return v1.decodeFileMeta(bytes); - default: - throw new Error(`Unknown version ${version}`); - } - }, - serializeVersion: (data, version) => { - switch (version) { - case 1: - return v1.encodeFileMeta(data as v1.FileMeta); - default: - throw new Error(`Unknown version ${version}`); - } - }, - deserializeConverters: () => [], - serializeConverters: () => [], -}); diff --git a/rivetkit-typescript/packages/sqlite-vfs/scripts/build-native.js b/rivetkit-typescript/packages/sqlite-vfs/scripts/build-native.js deleted file mode 100644 index faa0743fbb..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/scripts/build-native.js +++ /dev/null @@ -1,53 +0,0 @@ -import { execFileSync } from "node:child_process"; -import { copyFileSync, existsSync, mkdirSync } from "node:fs"; -import { dirname, join, resolve, delimiter } from "node:path"; -import { fileURLToPath } from "node:url"; -import { arch, platform } from "node:process"; - -const __dirname = dirname(fileURLToPath(import.meta.url)); -const repoRoot = resolve(__dirname, "../../../.."); -const rustRoot = resolve(repoRoot, "rivetkit-rust"); -const targetDir = resolve(rustRoot, "target", "debug"); - -const candidates = []; -if (process.env.CARGO) { - candidates.push(process.env.CARGO); -} -if (process.env.HOME) { - candidates.push(resolve(process.env.HOME, ".cargo", "bin", "cargo")); -} -const pathEntries = (process.env.PATH ?? "").split(delimiter); -for (const entry of pathEntries) { - if (entry) { - candidates.push(resolve(entry, "cargo")); - } -} - -const cargoPath = candidates.find((candidate) => existsSync(candidate)); -if (!cargoPath) { - throw new Error("cargo not found in PATH or default locations"); -} - -execFileSync(cargoPath, ["build", "-p", "rivetkit-sqlite-vfs-native"], { - cwd: rustRoot, - stdio: "inherit", -}); - -let libName = "librivetkit_sqlite_vfs_native.so"; -if (platform === "darwin") { - libName = "librivetkit_sqlite_vfs_native.dylib"; -} else if (platform === "win32") { - libName = "rivetkit_sqlite_vfs_native.dll"; -} - -const packageDir = resolve( - repoRoot, - "rivetkit-typescript", - "packages", - `sqlite-vfs-${platform}-${arch}`, -); -const destDir = join(packageDir, "bin"); -const destFile = join(destDir, "rivetkit_sqlite_vfs_native.node"); - -mkdirSync(destDir, { recursive: true }); -copyFileSync(join(targetDir, libName), destFile); diff --git a/rivetkit-typescript/packages/sqlite-vfs/scripts/compile-bare.ts b/rivetkit-typescript/packages/sqlite-vfs/scripts/compile-bare.ts deleted file mode 100644 index 2f674cbf66..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/scripts/compile-bare.ts +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env -S tsx - -/** - * BARE schema compiler for TypeScript - * - * This script compiles .bare schema files to TypeScript using @bare-ts/tools, - * then post-processes the output to: - * 1. Replace @bare-ts/lib import with @rivetkit/bare-ts - * 2. Replace Node.js assert import with a custom assert function - */ - -import * as fs from "node:fs/promises"; -import * as path from "node:path"; -import { type Config, transform } from "@bare-ts/tools"; -import { Command } from "commander"; - -const program = new Command(); - -program - .name("bare-compiler") - .description("Compile BARE schemas to TypeScript") - .version("0.0.1"); - -program - .command("compile") - .description("Compile a BARE schema file") - .argument("", "Input BARE schema file") - .option("-o, --output ", "Output file path") - .option("--pedantic", "Enable pedantic mode", false) - .option("--generator ", "Generator type (ts, js, dts, bare)", "ts") - .action(async (input: string, options) => { - try { - const schemaPath = path.resolve(input); - const outputPath = options.output - ? path.resolve(options.output) - : schemaPath.replace(/\.bare$/, ".ts"); - - await compileSchema({ - schemaPath, - outputPath, - config: { - pedantic: options.pedantic, - generator: options.generator, - }, - }); - - console.log(`Successfully compiled ${input} to ${outputPath}`); - } catch (error) { - console.error("Failed to compile schema:", error); - process.exit(1); - } - }); - -program.parse(); - -export interface CompileOptions { - schemaPath: string; - outputPath: string; - config?: Partial; -} - -export async function compileSchema(options: CompileOptions): Promise { - const { schemaPath, outputPath, config = {} } = options; - - const schema = await fs.readFile(schemaPath, "utf-8"); - const outputDir = path.dirname(outputPath); - - await fs.mkdir(outputDir, { recursive: true }); - - const defaultConfig: Partial = { - pedantic: true, - generator: "ts", - ...config, - }; - - let result = transform(schema, defaultConfig); - - result = postProcess(result); - - await fs.writeFile(outputPath, result); -} - -const POST_PROCESS_MARKER = - "// @generated - post-processed by compile-bare.ts\n"; - -const ASSERT_FUNCTION = ` -function assert(condition: boolean, message?: string): asserts condition { - if (!condition) throw new Error(message ?? "Assertion failed") -} -`; - -/** - * Post-process the generated TypeScript file to: - * 1. Replace @bare-ts/lib import with @rivetkit/bare-ts - * 2. Replace Node.js assert import with a custom assert function - */ -function postProcess(code: string): string { - if (code.startsWith(POST_PROCESS_MARKER)) { - return code; - } - - code = code.replace(/@bare-ts\/lib/g, "@rivetkit/bare-ts"); - code = code.replace(/^import assert from "assert"/m, ""); - code = POST_PROCESS_MARKER + code + `\n${ASSERT_FUNCTION}`; - - if (code.includes("@bare-ts/lib")) { - throw new Error("Failed to replace @bare-ts/lib import"); - } - if (code.includes("import assert from")) { - throw new Error("Failed to remove Node.js assert import"); - } - - return code; -} - -export type { Config } from "@bare-ts/tools"; diff --git a/rivetkit-typescript/packages/sqlite-vfs/scripts/generate-empty-db-page.ts b/rivetkit-typescript/packages/sqlite-vfs/scripts/generate-empty-db-page.ts deleted file mode 100644 index 7a97c453db..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/scripts/generate-empty-db-page.ts +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Generates the empty SQLite database page 1 using the same wa-sqlite WASM - * binary that ships in production. This ensures the pre-written page always - * matches the exact SQLite build we use at runtime. - * - * The output is written to src/generated/empty-db-page.ts as a Uint8Array - * constant. The VFS uses this to pre-populate new databases so that - * SQLite sees dbSize > 0 on first open, enabling BATCH_ATOMIC from the - * very first write transaction. - * - * Run via: pnpm run generate:empty-db-page - */ - -import { readFileSync, writeFileSync } from "node:fs"; -import { createRequire } from "node:module"; -import { dirname, join } from "node:path"; -import { fileURLToPath } from "node:url"; - -const __dirname = dirname(fileURLToPath(import.meta.url)); -const require = createRequire(import.meta.url); - -// Load wa-sqlite the same way vfs.ts does at runtime. -const specifier = ["@rivetkit/sqlite", "dist", "wa-sqlite-async.mjs"].join("/"); -const sqliteModule = await import(specifier); -const sqliteEsmFactory = sqliteModule.default; -const wasmPath = require.resolve("@rivetkit/sqlite/dist/wa-sqlite-async.wasm"); -const wasmBinary = readFileSync(wasmPath); -const module = await sqliteEsmFactory({ wasmBinary }); - -// Import Factory and MemoryVFS from @rivetkit/sqlite. -const { Factory } = await import("@rivetkit/sqlite"); -const { MemoryVFS } = await import( - "@rivetkit/sqlite/src/examples/MemoryVFS.js" -); - -const sqlite3 = Factory(module as any); - -// Create a MemoryVFS and register it with the SQLite runtime. -const vfs = await MemoryVFS.create("header-gen", module); -sqlite3.vfs_register(vfs, false); - -// Open a fresh database on the MemoryVFS. -const db = await sqlite3.open_v2( - "empty.db", - 0x00000002 | 0x00000004, // SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE - "header-gen", -); - -// Set the exact same PRAGMAs our production VFS uses. These determine the -// header field values (page_size, journal format version, encoding, etc.). -await sqlite3.exec(db, "PRAGMA page_size = 4096"); -await sqlite3.exec(db, "PRAGMA journal_mode = DELETE"); -await sqlite3.exec(db, "PRAGMA synchronous = NORMAL"); -await sqlite3.exec(db, "PRAGMA temp_store = MEMORY"); -await sqlite3.exec(db, "PRAGMA auto_vacuum = NONE"); - -// Force SQLite to write page 1 by creating a table, then clean up to -// leave an empty database with only the header. -await sqlite3.exec(db, "CREATE TABLE _header_gen (x)"); -await sqlite3.exec(db, "DROP TABLE _header_gen"); -await sqlite3.exec(db, "VACUUM"); - -await sqlite3.close(db); - -// Extract page 1 (4096 bytes) from the MemoryVFS file store. -const file = vfs.mapNameToFile.get("/empty.db"); -if (!file) { - throw new Error("Database file not found in MemoryVFS"); -} -if (file.size < 4096) { - throw new Error( - `Database file too small: ${file.size} bytes, expected >= 4096`, - ); -} -const page1 = new Uint8Array(file.data, 0, 4096); - -// Validate the header magic. -const magic = new TextDecoder().decode(page1.slice(0, 15)); -if (magic !== "SQLite format 3") { - throw new Error(`Invalid header magic: ${magic}`); -} - -// Validate page size field matches 4096. -const pageSize = (page1[16] << 8) | page1[17]; -if (pageSize !== 4096) { - throw new Error(`Header page size is ${pageSize}, expected 4096`); -} - -// Validate dbSize = 1 page. -const dbSizePages = - (page1[28] << 24) | (page1[29] << 16) | (page1[30] << 8) | page1[31]; -if (dbSizePages !== 1) { - throw new Error(`Header dbSize is ${dbSizePages} pages, expected 1`); -} - -// Format as TypeScript source. -// We emit the full 4096-byte page. Bytes 108-4095 are always zero for an -// empty database, so we only hard-code the 108-byte prefix and fill the -// rest at runtime. -const headerBytes = Array.from(page1.slice(0, 108)); - -const source = `// Auto-generated by scripts/generate-empty-db-page.ts -// DO NOT EDIT. Re-generate with: pnpm run generate:empty-db-page -// -// This is page 1 of a valid empty SQLite database (page_size=4096, -// journal_mode=DELETE, encoding=UTF-8, auto_vacuum=NONE). The VFS -// pre-writes this page into KV for new databases so that SQLite sees -// dbSize > 0 on first open. This enables BATCH_ATOMIC from the first -// write transaction and eliminates the need for a dummy table workaround. -// -// Only the first 108 bytes are non-zero (100-byte database header + -// 8-byte b-tree leaf page header for the empty sqlite_master table). - -const HEADER_PREFIX = new Uint8Array(${JSON.stringify(headerBytes)}); - -/** - * A complete 4096-byte page 1 for an empty SQLite database. - * Generated from wa-sqlite with our production PRAGMAs. - */ -export const EMPTY_DB_PAGE: Uint8Array = (() => { -\tconst page = new Uint8Array(4096); -\tpage.set(HEADER_PREFIX); -\treturn page; -})(); -`; - -const outPath = join(__dirname, "..", "src", "generated", "empty-db-page.ts"); -writeFileSync(outPath, source); -console.log(`Wrote ${outPath}`); -console.log( - `Header prefix (${headerBytes.length} bytes): [${headerBytes.slice(0, 20).join(", ")}...]`, -); -console.log(`Page size: ${pageSize}, DB pages: ${dbSizePages}`); - -vfs.close(); diff --git a/rivetkit-typescript/packages/sqlite-vfs/src/generated/empty-db-page.ts b/rivetkit-typescript/packages/sqlite-vfs/src/generated/empty-db-page.ts deleted file mode 100644 index 5e7ab96aa5..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/src/generated/empty-db-page.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Auto-generated by scripts/generate-empty-db-page.ts -// DO NOT EDIT. Re-generate with: pnpm run generate:empty-db-page -// -// This is page 1 of a valid empty SQLite database (page_size=4096, -// journal_mode=DELETE, encoding=UTF-8, auto_vacuum=NONE). The VFS -// pre-writes this page into KV for new databases so that SQLite sees -// dbSize > 0 on first open. This enables BATCH_ATOMIC from the first -// write transaction and eliminates the need for a dummy table workaround. -// -// Only the first 108 bytes are non-zero (100-byte database header + -// 8-byte b-tree leaf page header for the empty sqlite_master table). - -const HEADER_PREFIX = new Uint8Array([83,81,76,105,116,101,32,102,111,114,109,97,116,32,51,0,16,0,1,1,0,64,32,32,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,46,138,17,13,0,0,0,0,16,0,0]); - -/** - * A complete 4096-byte page 1 for an empty SQLite database. - * Generated from wa-sqlite with our production PRAGMAs. - */ -export const EMPTY_DB_PAGE: Uint8Array = (() => { - const page = new Uint8Array(4096); - page.set(HEADER_PREFIX); - return page; -})(); diff --git a/rivetkit-typescript/packages/sqlite-vfs/src/index.ts b/rivetkit-typescript/packages/sqlite-vfs/src/index.ts deleted file mode 100644 index e7eb8451af..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { SqliteVfs, Database } from "./vfs"; -export type { ISqliteVfs, IDatabase } from "./vfs"; -export type { KvVfsOptions } from "./types"; -export { SqliteVfsPool, PooledSqliteHandle } from "./pool"; -export type { SqliteVfsPoolConfig } from "./pool"; diff --git a/rivetkit-typescript/packages/sqlite-vfs/src/kv.ts b/rivetkit-typescript/packages/sqlite-vfs/src/kv.ts deleted file mode 100644 index 6dcfc5ff72..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/src/kv.ts +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Key management for SQLite VFS storage - * - * This module contains constants and utilities for building keys used in the - * key-value store for SQLite file storage. - * - * Keep in sync with rivetkit-typescript/packages/sqlite-native/src/kv.rs - * (native VFS). Both must produce byte-identical keys. - */ - -/** - * Size of each file chunk stored in KV. - * - * Set to 4096 to match SQLite's default page size so that one SQLite page - * maps to exactly one KV value. This avoids partial-chunk reads on page - * boundaries. - * - * Larger chunk sizes (e.g. 32 KiB) would reduce the number of KV keys per - * database and fit within FDB's recommended 10 KB value chunks (the engine - * splits values >10 KB internally, see VALUE_CHUNK_SIZE in - * engine/packages/pegboard/src/actor_kv/mod.rs). However, 4 KiB is kept - * because: - * - * - It matches SQLite's default page_size, avoiding alignment overhead. - * - At 128 keys per batch and 4 KiB per chunk, a single putBatch can flush - * up to 512 KiB of dirty pages, which covers most actor databases. - * - Changing chunk size is a breaking change for existing persisted databases. - * - KV max value size is 128 KiB, so 4 KiB is well within limits. - * - * If page_size is ever changed via PRAGMA, CHUNK_SIZE must be updated to - * match so the 1:1 page-to-chunk mapping is preserved. - */ -export const CHUNK_SIZE = 4096; - -/** Top-level SQLite prefix (must match SQLITE_PREFIX in actor KV system) */ -export const SQLITE_PREFIX = 8; - -/** Schema version namespace byte after SQLITE_PREFIX */ -export const SQLITE_SCHEMA_VERSION = 1; - -/** Key prefix byte for file metadata (after SQLITE_PREFIX + version) */ -export const META_PREFIX = 0; - -/** Key prefix byte for file chunks (after SQLITE_PREFIX + version) */ -export const CHUNK_PREFIX = 1; - -/** File kind tag for the actor's main database file */ -export const FILE_TAG_MAIN = 0; - -/** File kind tag for the actor's rollback journal sidecar */ -export const FILE_TAG_JOURNAL = 1; - -/** File kind tag for the actor's WAL sidecar */ -export const FILE_TAG_WAL = 2; - -/** File kind tag for the actor's SHM sidecar */ -export const FILE_TAG_SHM = 3; - -export type SqliteFileTag = - | typeof FILE_TAG_MAIN - | typeof FILE_TAG_JOURNAL - | typeof FILE_TAG_WAL - | typeof FILE_TAG_SHM; - -/** - * Gets the key for file metadata - * Format: [SQLITE_PREFIX (1 byte), version (1 byte), META_PREFIX (1 byte), file tag (1 byte)] - */ -export function getMetaKey(fileTag: SqliteFileTag): Uint8Array { - const key = new Uint8Array(4); - key[0] = SQLITE_PREFIX; - key[1] = SQLITE_SCHEMA_VERSION; - key[2] = META_PREFIX; - key[3] = fileTag; - return key; -} - -/** - * Gets the key for one chunk of file data. - * Format: [SQLITE_PREFIX, SCHEMA_VERSION, CHUNK_PREFIX, file tag, chunk index (u32 big-endian)] - * - * The chunk index is derived from byte offset as floor(offset / CHUNK_SIZE), - * which is how SQLite byte ranges map onto KV keys. - */ -export function getChunkKey( - fileTag: SqliteFileTag, - chunkIndex: number, -): Uint8Array { - const key = new Uint8Array(8); - key[0] = SQLITE_PREFIX; - key[1] = SQLITE_SCHEMA_VERSION; - key[2] = CHUNK_PREFIX; - key[3] = fileTag; - key[4] = (chunkIndex >>> 24) & 0xff; - key[5] = (chunkIndex >>> 16) & 0xff; - key[6] = (chunkIndex >>> 8) & 0xff; - key[7] = chunkIndex & 0xff; - return key; -} - -/** - * Returns a key that is lexicographically just past all chunk keys for the - * given file tag. Useful as the exclusive end bound for deleteRange. - * - * The key is [SQLITE_PREFIX, SCHEMA_VERSION, CHUNK_PREFIX, fileTag + 1], - * which is shorter than a chunk key but lexicographically greater than any - * 8-byte chunk key with the same fileTag prefix. - */ -export function getChunkKeyRangeEnd(fileTag: SqliteFileTag): Uint8Array { - const key = new Uint8Array(4); - key[0] = SQLITE_PREFIX; - key[1] = SQLITE_SCHEMA_VERSION; - key[2] = CHUNK_PREFIX; - key[3] = fileTag + 1; - return key; -} diff --git a/rivetkit-typescript/packages/sqlite-vfs/src/pool.ts b/rivetkit-typescript/packages/sqlite-vfs/src/pool.ts deleted file mode 100644 index 102778826c..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/src/pool.ts +++ /dev/null @@ -1,502 +0,0 @@ -/** - * SQLite VFS Pool - shares WASM SQLite instances across actors to reduce - * memory overhead. Instead of one WASM module per actor, multiple actors - * share a single instance, with short file names routing to separate KV - * namespaces. - */ - -import { readFileSync } from "node:fs"; -import { createRequire } from "node:module"; -import path from "node:path"; -import { SqliteVfs } from "./vfs"; -import type { ISqliteVfs, IDatabase } from "./vfs"; -import type { KvVfsOptions } from "./types"; - -function createNodeRequire(): NodeJS.Require { - return createRequire( - path.join(process.cwd(), "__rivetkit_sqlite_require__.cjs"), - ); -} - -export interface SqliteVfsPoolConfig { - actorsPerInstance: number; - idleDestroyMs?: number; -} - -/** - * Internal state for a single WASM SQLite instance shared by multiple actors. - */ -interface PoolInstance { - vfs: SqliteVfs; - /** Actor IDs currently assigned to this instance. */ - actors: Set; - /** Monotonically increasing counter for generating short file names. */ - shortNameCounter: number; - /** Maps actorId to the short name assigned within this instance. */ - actorShortNames: Map; - /** Short names released by actors that closed successfully, available for reuse. */ - availableShortNames: Set; - /** Short names that failed to close cleanly. Not reused until instance is destroyed. */ - poisonedShortNames: Set; - /** Number of in-flight operations (e.g. open calls) on this instance. */ - opsInFlight: number; - /** Handle for the idle destruction timer, or null if not scheduled. */ - idleTimer: ReturnType | null; - /** True once destruction has started. Prevents double-destroy. */ - destroying: boolean; -} - -/** - * Manages a pool of SqliteVfs instances, assigning actors to instances using - * bin-packing to maximize density. The WASM module is compiled once and - * reused across all instances. - */ -export class SqliteVfsPool { - readonly #config: SqliteVfsPoolConfig; - #modulePromise: Promise | null = null; - readonly #instances: Set = new Set(); - readonly #actorToInstance: Map = new Map(); - readonly #actorToHandle: Map = new Map(); - #shuttingDown = false; - - constructor(config: SqliteVfsPoolConfig) { - if ( - !Number.isInteger(config.actorsPerInstance) || - config.actorsPerInstance < 1 - ) { - throw new Error( - `actorsPerInstance must be a positive integer, got ${config.actorsPerInstance}`, - ); - } - this.#config = config; - } - - /** - * Compile the WASM module once and cache the promise. Subsequent calls - * return the same promise, avoiding redundant compilation. - */ - #getModule(): Promise { - if (!this.#modulePromise) { - this.#modulePromise = (async () => { - const require = createNodeRequire(); - const wasmPath = require.resolve( - "@rivetkit/sqlite/dist/wa-sqlite-async.wasm", - ); - const wasmBinary = readFileSync(wasmPath); - return WebAssembly.compile(wasmBinary); - })(); - // Clear the cached promise on rejection so subsequent calls retry - // compilation instead of returning the same rejected promise forever. - this.#modulePromise.catch(() => { - this.#modulePromise = null; - }); - } - return this.#modulePromise; - } - - /** Number of live WASM instances in the pool. */ - get instanceCount(): number { - return this.#instances.size; - } - - /** Number of actors currently assigned to pool instances. */ - get actorCount(): number { - return this.#actorToInstance.size; - } - - /** - * Acquire a pooled VFS handle for the given actor. Returns a - * PooledSqliteHandle with sticky assignment. If the actor is already - * assigned, the existing handle is returned. - * - * Bin-packing: picks the instance with the most actors that still has - * capacity. If all instances are full, creates a new one using the - * cached WASM module. - */ - async acquire(actorId: string): Promise { - if (this.#shuttingDown) { - throw new Error("SqliteVfsPool is shutting down"); - } - - // Sticky assignment: return existing handle. - const existingHandle = this.#actorToHandle.get(actorId); - if (existingHandle) { - return existingHandle; - } - - // Bin-packing: pick instance with most actors that still has capacity. - // Skip instances that are being destroyed. - let bestInstance: PoolInstance | null = null; - let bestCount = -1; - for (const instance of this.#instances) { - if (instance.destroying) continue; - const count = instance.actors.size; - if (count < this.#config.actorsPerInstance && count > bestCount) { - bestInstance = instance; - bestCount = count; - } - } - - // If all instances are full, compile the module and re-check capacity. - // Multiple concurrent acquire() calls may all reach this point. After - // awaiting the module, re-scan for capacity that another caller may - // have created during the await, to avoid creating duplicate instances. - if (!bestInstance) { - const wasmModule = await this.#getModule(); - if (this.#shuttingDown) { - throw new Error("SqliteVfsPool is shutting down"); - } - - // Re-check sticky assignment: another concurrent acquire() for the - // same actorId may have completed during the await. - const existingHandleAfterAwait = this.#actorToHandle.get(actorId); - if (existingHandleAfterAwait) { - return existingHandleAfterAwait; - } - - // Re-scan for an instance with available capacity that was created - // by another concurrent acquire() during the module compilation. - for (const instance of this.#instances) { - if (instance.destroying) continue; - const count = instance.actors.size; - if ( - count < this.#config.actorsPerInstance && - count > bestCount - ) { - bestInstance = instance; - bestCount = count; - } - } - - if (!bestInstance) { - const vfs = new SqliteVfs(wasmModule); - bestInstance = { - vfs, - actors: new Set(), - shortNameCounter: 0, - actorShortNames: new Map(), - availableShortNames: new Set(), - poisonedShortNames: new Set(), - opsInFlight: 0, - idleTimer: null, - destroying: false, - }; - this.#instances.add(bestInstance); - } - } - - // Cancel idle timer synchronously since this instance is getting a - // new actor and should not be destroyed. - this.#cancelIdleTimer(bestInstance); - - // Assign actor to instance with a short file name. Prefer recycled - // names from the available set before generating a new one. - let shortName: string; - const recycled = bestInstance.availableShortNames.values().next(); - if (!recycled.done) { - shortName = recycled.value; - bestInstance.availableShortNames.delete(shortName); - } else { - shortName = String(bestInstance.shortNameCounter++); - } - bestInstance.actors.add(actorId); - bestInstance.actorShortNames.set(actorId, shortName); - this.#actorToInstance.set(actorId, bestInstance); - - const handle = new PooledSqliteHandle(shortName, actorId, this); - this.#actorToHandle.set(actorId, handle); - - return handle; - } - - /** - * Release an actor's assignment from the pool. Force-closes all database - * handles for the actor, recycles or poisons the short name, and - * decrements the instance refcount. - */ - async release(actorId: string): Promise { - const instance = this.#actorToInstance.get(actorId); - if (!instance) { - return; - } - - const shortName = instance.actorShortNames.get(actorId); - if (shortName === undefined) { - return; - } - - // Force-close all Database handles for this actor's short name. - const { allSucceeded } = - await instance.vfs.forceCloseByFileName(shortName); - - if (allSucceeded) { - instance.availableShortNames.add(shortName); - } else { - instance.poisonedShortNames.add(shortName); - } - - // Remove actor from instance tracking. - instance.actors.delete(actorId); - instance.actorShortNames.delete(actorId); - this.#actorToInstance.delete(actorId); - this.#actorToHandle.delete(actorId); - - // Start idle timer if instance has no actors and no in-flight ops. - // Skip if shutting down to avoid leaking timers after shutdown - // completes. - if ( - instance.actors.size === 0 && - instance.opsInFlight === 0 && - !this.#shuttingDown - ) { - this.#startIdleTimer(instance); - } - } - - /** - * Track an in-flight operation on an instance. Increments opsInFlight - * before running fn, decrements after using try/finally to prevent - * drift from exceptions. If the decrement brings opsInFlight to 0 - * with refcount also 0, starts the idle timer. - */ - async #trackOp( - instance: PoolInstance, - fn: () => Promise, - ): Promise { - instance.opsInFlight++; - try { - return await fn(); - } finally { - instance.opsInFlight--; - if ( - instance.actors.size === 0 && - instance.opsInFlight === 0 && - !instance.destroying && - !this.#shuttingDown - ) { - this.#startIdleTimer(instance); - } - } - } - - /** - * Open a database on behalf of an actor, tracked as an in-flight - * operation. Used by PooledSqliteHandle to avoid exposing PoolInstance. - */ - async openForActor( - actorId: string, - shortName: string, - options: KvVfsOptions, - ): Promise { - const instance = this.#actorToInstance.get(actorId); - if (!instance) { - throw new Error( - `Actor ${actorId} is not assigned to any pool instance`, - ); - } - return this.#trackOp(instance, () => - instance.vfs.open(shortName, options), - ); - } - - /** - * Track an in-flight database operation for the given actor. Resolves the - * actor's pool instance and wraps the operation with opsInFlight tracking. - * If the actor has already been released, the operation runs without - * tracking since the instance may already be destroyed. - */ - async trackOpForActor( - actorId: string, - fn: () => Promise, - ): Promise { - const instance = this.#actorToInstance.get(actorId); - if (!instance) { - return fn(); - } - return this.#trackOp(instance, fn); - } - - #startIdleTimer(instance: PoolInstance): void { - if (instance.idleTimer || instance.destroying) return; - const idleDestroyMs = this.#config.idleDestroyMs ?? 30_000; - instance.idleTimer = setTimeout(() => { - instance.idleTimer = null; - // Check opsInFlight in addition to actors.size. With tracked - // database operations (TrackedDatabase), opsInFlight can be >0 - // while actors.size is 0 if the last operation is still in-flight - // after release. The #trackOp finally block will re-start the - // idle timer when ops drain to 0. - if ( - instance.actors.size === 0 && - instance.opsInFlight === 0 && - !instance.destroying - ) { - this.#destroyInstance(instance); - } - }, idleDestroyMs); - } - - #cancelIdleTimer(instance: PoolInstance): void { - if (instance.idleTimer) { - clearTimeout(instance.idleTimer); - instance.idleTimer = null; - } - } - - async #destroyInstance(instance: PoolInstance): Promise { - instance.destroying = true; - this.#cancelIdleTimer(instance); - // Remove from pool map first so no new actors can be assigned. - this.#instances.delete(instance); - try { - await instance.vfs.forceCloseAll(); - await instance.vfs.destroy(); - } catch (error) { - console.warn("SqliteVfsPool: failed to destroy instance", error); - } - } - - /** - * Graceful shutdown. Rejects new acquire() calls, cancels idle timers, - * force-closes all databases, destroys all VFS instances, and clears pool - * state. - */ - async shutdown(): Promise { - this.#shuttingDown = true; - - // Snapshot instances to array since we mutate the set during iteration. - const instances = [...this.#instances]; - - for (const instance of instances) { - this.#cancelIdleTimer(instance); - this.#instances.delete(instance); - - // Check for in-flight operations (e.g. a concurrent release() call - // mid-forceCloseByFileName). Database.close() is idempotent - // (US-019), so concurrent close from shutdown + release is safe, - // but log a warning for observability. - if (instance.opsInFlight > 0) { - console.warn( - `SqliteVfsPool: shutting down instance with ${instance.opsInFlight} in-flight operation(s). ` + - "Concurrent close is safe due to Database.close() idempotency.", - ); - } - - try { - await instance.vfs.forceCloseAll(); - await instance.vfs.destroy(); - } catch (error) { - console.warn( - "SqliteVfsPool: failed to destroy instance during shutdown", - error, - ); - } - } - - this.#actorToInstance.clear(); - this.#actorToHandle.clear(); - } -} - -/** - * Wraps a Database with opsInFlight tracking so the pool's idle timer - * does not destroy instances while database operations are in-flight. - * The unwrapped Database remains in SqliteVfs's #openDatabases set - * for force-close purposes. - */ -class TrackedDatabase implements IDatabase { - readonly #inner: IDatabase; - readonly #pool: SqliteVfsPool; - readonly #actorId: string; - - constructor(inner: IDatabase, pool: SqliteVfsPool, actorId: string) { - this.#inner = inner; - this.#pool = pool; - this.#actorId = actorId; - } - - async exec( - ...args: Parameters - ): ReturnType { - return this.#pool.trackOpForActor(this.#actorId, () => - this.#inner.exec(...args), - ); - } - - async run( - ...args: Parameters - ): ReturnType { - return this.#pool.trackOpForActor(this.#actorId, () => - this.#inner.run(...args), - ); - } - - async query( - ...args: Parameters - ): ReturnType { - return this.#pool.trackOpForActor(this.#actorId, () => - this.#inner.query(...args), - ); - } - - async close(): ReturnType { - return this.#pool.trackOpForActor(this.#actorId, () => - this.#inner.close(), - ); - } - - get fileName(): string { - return this.#inner.fileName; - } -} - -/** - * A pooled VFS handle for a single actor. Implements ISqliteVfs so callers - * can use it interchangeably with a standalone SqliteVfs. The short name - * assigned by the pool is used as the VFS file path, while the caller's - * KvVfsOptions routes data to the correct KV namespace. - */ -export class PooledSqliteHandle implements ISqliteVfs { - readonly #shortName: string; - readonly #actorId: string; - readonly #pool: SqliteVfsPool; - #released = false; - - constructor(shortName: string, actorId: string, pool: SqliteVfsPool) { - this.#shortName = shortName; - this.#actorId = actorId; - this.#pool = pool; - } - - /** - * Open a database on the shared instance. Uses the pool-assigned short - * name as the VFS file path, with the caller's KvVfsOptions for KV - * routing. The open call itself is tracked as an in-flight operation, - * and the returned Database is wrapped so that exec(), run(), query(), - * and close() are also tracked via opsInFlight. - */ - async open(_fileName: string, options: KvVfsOptions): Promise { - if (this.#released) { - throw new Error("PooledSqliteHandle has been released"); - } - const db = await this.#pool.openForActor( - this.#actorId, - this.#shortName, - options, - ); - return new TrackedDatabase(db, this.#pool, this.#actorId); - } - - /** - * Release this actor's assignment back to the pool. Idempotent: calling - * destroy() more than once is a no-op, preventing double-release from - * decrementing the instance refcount below actual. - */ - async destroy(): Promise { - if (this.#released) { - return; - } - this.#released = true; - await this.#pool.release(this.#actorId); - } -} diff --git a/rivetkit-typescript/packages/sqlite-vfs/src/types.ts b/rivetkit-typescript/packages/sqlite-vfs/src/types.ts deleted file mode 100644 index cd34b6fbc8..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/src/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface KvVfsOptions { - /** Get a single value by key. Returns null if missing. */ - get: (key: Uint8Array) => Promise; - /** Get multiple values by keys. Returns null for missing keys. */ - getBatch: (keys: Uint8Array[]) => Promise<(Uint8Array | null)[]>; - /** Put a single key-value pair */ - put: (key: Uint8Array, value: Uint8Array) => Promise; - /** Put multiple key-value pairs */ - putBatch: (entries: [Uint8Array, Uint8Array][]) => Promise; - /** Delete multiple keys */ - deleteBatch: (keys: Uint8Array[]) => Promise; - /** - * Called when a KV operation fails inside a VFS callback. The VFS must - * return a generic SQLite error code to the pager, so the original error - * is lost unless the caller captures it through this callback. - */ - onError?: (error: unknown) => void; - /** Delete all keys in the half-open range [start, end). */ - deleteRange: (start: Uint8Array, end: Uint8Array) => Promise; -} diff --git a/rivetkit-typescript/packages/sqlite-vfs/src/vfs.ts b/rivetkit-typescript/packages/sqlite-vfs/src/vfs.ts deleted file mode 100644 index b4dbfca8d5..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/src/vfs.ts +++ /dev/null @@ -1,1641 +0,0 @@ -/** - * SQLite raw database with KV storage backend - * - * This module provides a SQLite API that uses a KV-backed VFS - * for storage. Each SqliteVfs instance is independent and can be - * used concurrently with other instances. - * - * Keep this VFS on direct VFS.Base callbacks for minimal wrapper overhead. - * Use @rivetkit/sqlite/src/FacadeVFS.js as the reference implementation for - * callback ABI and pointer/data conversion behavior. - * This implementation is optimized for single-writer semantics because each - * actor owns one SQLite database. - * SQLite invokes this VFS with byte-range file operations. This VFS maps those - * ranges onto fixed-size KV chunks keyed by file tag and chunk index. - * We intentionally rely on SQLite's pager cache for hot page reuse and do not - * add a second cache in this VFS. This avoids duplicate cache invalidation - * logic and keeps memory usage predictable for each actor. - */ - -import * as VFS from "@rivetkit/sqlite/src/VFS.js"; -import { - Factory, - SQLITE_OPEN_CREATE, - SQLITE_OPEN_READWRITE, - SQLITE_ROW, -} from "@rivetkit/sqlite"; -import { readFileSync } from "node:fs"; -import { createRequire } from "node:module"; -import path from "node:path"; -import { pathToFileURL } from "node:url"; -import { - CHUNK_SIZE, - FILE_TAG_JOURNAL, - FILE_TAG_MAIN, - FILE_TAG_SHM, - FILE_TAG_WAL, - getChunkKey, - getChunkKeyRangeEnd, - getMetaKey, - type SqliteFileTag, -} from "./kv"; -import { EMPTY_DB_PAGE } from "./generated/empty-db-page"; -import { - FILE_META_VERSIONED, - CURRENT_VERSION, -} from "../schemas/file-meta/versioned"; -import type { FileMeta } from "../schemas/file-meta/mod"; -import type { KvVfsOptions } from "./types"; - -function createNodeRequire(): NodeJS.Require { - return createRequire( - path.join(process.cwd(), "__rivetkit_sqlite_require__.cjs"), - ); -} - -/** - * Common interface for database handles returned by ISqliteVfs.open(). - * Both the concrete Database class and the pool's TrackedDatabase wrapper - * implement this, so consumers can use either interchangeably. - */ -export interface IDatabase { - exec( - sql: string, - callback?: (row: unknown[], columns: string[]) => void, - ): Promise; - run(sql: string, params?: SqliteBindings): Promise; - query( - sql: string, - params?: SqliteBindings, - ): Promise<{ rows: unknown[][]; columns: string[] }>; - close(): Promise; - readonly fileName: string; -} - -/** - * Common interface for SQLite VFS backends. Both standalone SqliteVfs and - * PooledSqliteHandle implement this so callers can use either interchangeably. - */ -export interface ISqliteVfs { - open(fileName: string, options: KvVfsOptions): Promise; - destroy(): Promise; -} - -type SqliteEsmFactory = (config?: { - wasmBinary?: ArrayBuffer | Uint8Array; - instantiateWasm?: ( - imports: WebAssembly.Imports, - receiveInstance: (instance: WebAssembly.Instance) => void, - ) => WebAssembly.Exports; -}) => Promise; -type SQLite3Api = ReturnType; -type SqliteBindings = Parameters[1]; -type SqliteVfsRegistration = Parameters[0]; - -interface SQLiteModule { - UTF8ToString: (ptr: number) => string; - HEAPU8: Uint8Array; -} - -const TEXT_ENCODER = new TextEncoder(); -const TEXT_DECODER = new TextDecoder(); -const SQLITE_MAX_PATHNAME_BYTES = 64; - -// Chunk keys encode the chunk index in 32 bits, so a file can span at most -// 2^32 chunks. At 4 KiB/chunk this yields a hard limit of 16 TiB. -const UINT32_SIZE = 0x100000000; -const MAX_CHUNK_INDEX = 0xffffffff; -const MAX_FILE_SIZE_BYTES = (MAX_CHUNK_INDEX + 1) * CHUNK_SIZE; -const MAX_FILE_SIZE_HI32 = Math.floor(MAX_FILE_SIZE_BYTES / UINT32_SIZE); -const MAX_FILE_SIZE_LO32 = MAX_FILE_SIZE_BYTES % UINT32_SIZE; - -// Maximum number of keys the KV backend accepts in a single deleteBatch or putBatch call. -const KV_MAX_BATCH_KEYS = 128; - -// -- BATCH_ATOMIC and KV round trip documentation -- -// -// KV round trips per actor database lifecycle: -// -// Open (new database): -// 1 putBatch -- xOpen pre-writes EMPTY_DB_PAGE + metadata (2 keys) -// PRAGMAs are in-memory, 0 KV ops -// -// Open (existing database / wake from sleep): -// 1 get -- xOpen reads metadata to determine file size -// PRAGMAs are in-memory, 0 KV ops -// -// First SQL operation (e.g., migration CREATE TABLE): -// 1 getBatch -- pager reads page 1 (database header) -// N getBatch -- pager reads additional pages as needed by the schema -// 1 putBatch -- BATCH_ATOMIC commit (all dirty pages + metadata) -// -// Subsequent writes (warm pager cache): -// 0 reads -- pages served from pager cache -// 1 putBatch -- BATCH_ATOMIC commit -// -// Subsequent reads (warm pager cache): -// 0 reads -- pages served from pager cache -// 0 writes -- SELECT-only, no dirty pages -// -// Large writes (> 127 dirty pages): -// BATCH_ATOMIC COMMIT returns SQLITE_IOERR, SQLite falls back to -// journal mode with multiple putBatch calls (each <= 128 keys). -// -// BATCH_ATOMIC requires SQLite's pager to use an in-memory journal. -// The pager only does this when dbSize > 0. For new databases, xOpen -// pre-writes a valid empty page (EMPTY_DB_PAGE) so dbSize is 1 from -// the start. Without this, the first transaction opens a real journal -// file, and locking_mode=EXCLUSIVE prevents it from ever being closed, -// permanently disabling BATCH_ATOMIC. -// -// See scripts/generate-empty-db-page.ts for how EMPTY_DB_PAGE is built. - -// BATCH_ATOMIC capability flag returned by xDeviceCharacteristics. -const SQLITE_IOCAP_BATCH_ATOMIC = 0x4000; - -// xFileControl opcodes for atomic write bracketing. -const SQLITE_FCNTL_BEGIN_ATOMIC_WRITE = 31; -const SQLITE_FCNTL_COMMIT_ATOMIC_WRITE = 32; -const SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE = 33; - -// libvfs captures this async/sync mask at registration time. Any VFS callback -// that returns a Promise must be listed here so SQLite uses async relays. -const SQLITE_ASYNC_METHODS = new Set([ - "xOpen", - "xClose", - "xRead", - "xWrite", - "xTruncate", - "xSync", - "xFileSize", - "xDelete", - "xAccess", - "xFileControl", -]); - -interface LoadedSqliteRuntime { - sqlite3: SQLite3Api; - module: SQLiteModule; -} - -function isSqliteEsmFactory(value: unknown): value is SqliteEsmFactory { - return typeof value === "function"; -} - -function isSQLiteModule(value: unknown): value is SQLiteModule { - if (!value || typeof value !== "object") { - return false; - } - const candidate = value as { - UTF8ToString?: unknown; - HEAPU8?: unknown; - }; - return ( - typeof candidate.UTF8ToString === "function" && - candidate.HEAPU8 instanceof Uint8Array - ); -} - -/** - * Lazily load and instantiate the async SQLite module for this VFS instance. - * We do this on first open so actors that do not use SQLite do not pay module - * parse and wasm initialization cost at startup, and we pass wasmBinary - * explicitly so this works consistently in both ESM and CJS bundles. - */ -async function loadSqliteRuntime( - wasmModule?: WebAssembly.Module, -): Promise { - const require = createNodeRequire(); - const sqliteModulePath = require.resolve( - ["@rivetkit/sqlite", "dist", "wa-sqlite-async.mjs"].join("/"), - ); - const sqliteModule = await nativeDynamicImport<{ default?: unknown }>( - pathToFileURL(sqliteModulePath).href, - ); - if (!isSqliteEsmFactory(sqliteModule.default)) { - throw new Error("Invalid SQLite ESM factory export"); - } - const sqliteEsmFactory = sqliteModule.default; - - let module: unknown; - if (wasmModule) { - // Use the pre-compiled WebAssembly.Module directly, skipping - // WebAssembly.compile. The Emscripten instantiateWasm callback lets us - // provide a module that has already been compiled and cached by the pool. - module = await sqliteEsmFactory({ - instantiateWasm( - imports: WebAssembly.Imports, - receiveInstance: (instance: WebAssembly.Instance) => void, - ) { - WebAssembly.instantiate(wasmModule, imports).then( - (instance) => { - receiveInstance(instance); - }, - ); - return {} as WebAssembly.Exports; - }, - }); - } else { - const sqliteDistPath = "@rivetkit/sqlite/dist/"; - const wasmPath = require.resolve( - sqliteDistPath + "wa-sqlite-async.wasm", - ); - const wasmBinary = readFileSync(wasmPath); - module = await sqliteEsmFactory({ wasmBinary }); - } - - if (!isSQLiteModule(module)) { - throw new Error("Invalid SQLite runtime module"); - } - return { - sqlite3: Factory(module), - module, - }; -} - -async function nativeDynamicImport(specifier: string): Promise { - try { - return (await import(specifier)) as T; - } catch (directError) { - const importer = new Function( - "moduleSpecifier", - "return import(moduleSpecifier);", - ) as (moduleSpecifier: string) => Promise; - try { - return await importer(specifier); - } catch { - throw directError; - } - } -} - -/** - * Represents an open file - */ -interface OpenFile { - /** File path */ - path: string; - /** File kind tag used by compact key layout */ - fileTag: SqliteFileTag; - /** Precomputed metadata key */ - metaKey: Uint8Array; - /** File size in bytes */ - size: number; - /** True when in-memory size has not been persisted yet */ - metaDirty: boolean; - /** Open flags */ - flags: number; - /** KV options for this file */ - options: KvVfsOptions; - /** True while inside a BATCH_ATOMIC write bracket */ - batchMode: boolean; - /** Buffered dirty pages during batch mode. Key is the chunk index. */ - dirtyBuffer: Map | null; - /** File size saved at BEGIN_ATOMIC_WRITE for rollback */ - savedFileSize: number; -} - -interface ResolvedFile { - options: KvVfsOptions; - fileTag: SqliteFileTag; -} - -/** - * Encodes file metadata to a Uint8Array using BARE schema - */ -function encodeFileMeta(size: number): Uint8Array { - const meta: FileMeta = { size: BigInt(size) }; - return FILE_META_VERSIONED.serializeWithEmbeddedVersion( - meta, - CURRENT_VERSION, - ); -} - -/** - * Decodes file metadata from a Uint8Array using BARE schema - */ -function decodeFileMeta(data: Uint8Array): number { - const meta = FILE_META_VERSIONED.deserializeWithEmbeddedVersion(data); - return Number(meta.size); -} - -function isValidFileSize(size: number): boolean { - return ( - Number.isSafeInteger(size) && size >= 0 && size <= MAX_FILE_SIZE_BYTES - ); -} - -/** - * Simple async mutex for serializing database operations - * @rivetkit/sqlite calls are not safe to run concurrently on one module instance - */ -class AsyncMutex { - #locked = false; - #waiting: (() => void)[] = []; - - async acquire(): Promise { - while (this.#locked) { - await new Promise((resolve) => this.#waiting.push(resolve)); - } - this.#locked = true; - } - - release(): void { - this.#locked = false; - const next = this.#waiting.shift(); - if (next) { - next(); - } - } - - async run(fn: () => Promise): Promise { - await this.acquire(); - try { - return await fn(); - } finally { - this.release(); - } - } -} - -/** - * Database wrapper that provides a simplified SQLite API - */ -export class Database implements IDatabase { - readonly #sqlite3: SQLite3Api; - readonly #handle: number; - readonly #fileName: string; - readonly #onClose: () => Promise; - readonly #sqliteMutex: AsyncMutex; - #closed = false; - - constructor( - sqlite3: SQLite3Api, - handle: number, - fileName: string, - onClose: () => Promise, - sqliteMutex: AsyncMutex, - ) { - this.#sqlite3 = sqlite3; - this.#handle = handle; - this.#fileName = fileName; - this.#onClose = onClose; - this.#sqliteMutex = sqliteMutex; - } - - /** - * Execute SQL with optional row callback - * @param sql - SQL statement to execute - * @param callback - Called for each result row with (row, columns) - */ - async exec( - sql: string, - callback?: (row: unknown[], columns: string[]) => void, - ): Promise { - await this.#sqliteMutex.run(async () => { - await this.#sqlite3.exec(this.#handle, sql, callback); - }); - } - - /** - * Execute a parameterized SQL statement (no result rows) - * @param sql - SQL statement with ? placeholders - * @param params - Parameter values to bind - */ - async run(sql: string, params?: SqliteBindings): Promise { - await this.#sqliteMutex.run(async () => { - for await (const stmt of this.#sqlite3.statements( - this.#handle, - sql, - )) { - if (params) { - this.#sqlite3.bind_collection(stmt, params); - } - while ((await this.#sqlite3.step(stmt)) === SQLITE_ROW) { - // Consume rows for statements that return results. - } - } - }); - } - - /** - * Execute a parameterized SQL query and return results - * @param sql - SQL query with ? placeholders - * @param params - Parameter values to bind - * @returns Object with rows (array of arrays) and columns (column names) - */ - async query( - sql: string, - params?: SqliteBindings, - ): Promise<{ rows: unknown[][]; columns: string[] }> { - return this.#sqliteMutex.run(async () => { - const rows: unknown[][] = []; - let columns: string[] = []; - for await (const stmt of this.#sqlite3.statements( - this.#handle, - sql, - )) { - if (params) { - this.#sqlite3.bind_collection(stmt, params); - } - - while ((await this.#sqlite3.step(stmt)) === SQLITE_ROW) { - if (columns.length === 0) { - columns = this.#sqlite3.column_names(stmt); - } - rows.push(this.#sqlite3.row(stmt)); - } - } - - return { rows, columns }; - }); - } - - /** - * Close the database - */ - async close(): Promise { - if (this.#closed) { - return; - } - this.#closed = true; - - await this.#sqliteMutex.run(async () => { - await this.#sqlite3.close(this.#handle); - }); - await this.#onClose(); - } - - /** - * Get the database file name - */ - get fileName(): string { - return this.#fileName; - } - - /** - * Get the raw @rivetkit/sqlite API (for advanced usage) - */ - get sqlite3(): SQLite3Api { - return this.#sqlite3; - } - - /** - * Get the raw database handle (for advanced usage) - */ - get handle(): number { - return this.#handle; - } -} - -/** - * SQLite VFS backed by KV storage. - * - * Each instance is independent and has its own @rivetkit/sqlite WASM module. - * This allows multiple instances to operate concurrently without interference. - */ -export class SqliteVfs implements ISqliteVfs { - #sqlite3: SQLite3Api | null = null; - #sqliteSystem: SqliteSystem | null = null; - #initPromise: Promise | null = null; - #openMutex = new AsyncMutex(); - #sqliteMutex = new AsyncMutex(); - #instanceId: string; - #destroyed = false; - #openDatabases: Set = new Set(); - #wasmModule?: WebAssembly.Module; - - constructor(wasmModule?: WebAssembly.Module) { - // Generate unique instance ID for VFS name - this.#instanceId = crypto.randomUUID().replace(/-/g, "").slice(0, 8); - this.#wasmModule = wasmModule; - } - - /** - * Initialize @rivetkit/sqlite and VFS (called once per instance) - */ - async #ensureInitialized(): Promise { - if (this.#destroyed) { - throw new Error("SqliteVfs is closed"); - } - - // Fast path: already initialized - if (this.#sqlite3 && this.#sqliteSystem) { - return; - } - - // Synchronously create the promise if not started - if (!this.#initPromise) { - this.#initPromise = (async () => { - const { sqlite3, module } = await loadSqliteRuntime( - this.#wasmModule, - ); - if (this.#destroyed) { - return; - } - this.#sqlite3 = sqlite3; - this.#sqliteSystem = new SqliteSystem( - sqlite3, - module, - `kv-vfs-${this.#instanceId}`, - ); - this.#sqliteSystem.register(); - })(); - } - - // Wait for initialization - try { - await this.#initPromise; - } catch (error) { - this.#initPromise = null; - throw error; - } - } - - /** - * Open a SQLite database using KV storage backend - * - * @param fileName - The database file name (typically the actor ID) - * @param options - KV storage operations for this database - * @returns A Database instance - */ - async open(fileName: string, options: KvVfsOptions): Promise { - if (this.#destroyed) { - throw new Error("SqliteVfs is closed"); - } - - // Serialize all open operations within this instance - await this.#openMutex.acquire(); - try { - // Reject double-open of the same fileName. Two handles to the same - // file would have separate pager caches and no real locking - // (xLock/xUnlock are no-ops), causing silent data corruption. - for (const db of this.#openDatabases) { - if (db.fileName === fileName) { - throw new Error( - `SqliteVfs: fileName "${fileName}" is already open on this instance`, - ); - } - } - - // Initialize @rivetkit/sqlite and SqliteSystem on first call - await this.#ensureInitialized(); - - if (!this.#sqlite3 || !this.#sqliteSystem) { - throw new Error("Failed to initialize SQLite"); - } - const sqlite3 = this.#sqlite3; - const sqliteSystem = this.#sqliteSystem; - - // Register this filename with its KV options - sqliteSystem.registerFile(fileName, options); - - // Open database - const db = await this.#sqliteMutex.run(async () => - sqlite3.open_v2( - fileName, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, - sqliteSystem.name, - ), - ); - // Single-writer optimizations for KV-backed SQLite. Each actor owns - // its database exclusively. BATCH_ATOMIC batches dirty pages into a - // single putBatch call instead of 5-7 individual KV round trips per - // write transaction. - // - // BATCH_ATOMIC requires an in-memory journal, which SQLite only uses - // when dbSize > 0. The xOpen handler pre-writes a valid empty page 1 - // for new databases so this condition is satisfied from the start. - // See xOpen and scripts/generate-empty-db-page.ts for details. - await this.#sqliteMutex.run(async () => { - await sqlite3.exec(db, "PRAGMA page_size = 4096"); - await sqlite3.exec(db, "PRAGMA journal_mode = DELETE"); - await sqlite3.exec(db, "PRAGMA synchronous = NORMAL"); - await sqlite3.exec(db, "PRAGMA temp_store = MEMORY"); - await sqlite3.exec(db, "PRAGMA auto_vacuum = NONE"); - await sqlite3.exec(db, "PRAGMA locking_mode = EXCLUSIVE"); - }); - - // Wrap unregistration under #openMutex so it serializes with - // registerFile and prevents interleaving when short names recycle. - const onClose = async () => { - this.#openDatabases.delete(database); - await this.#openMutex.run(async () => { - sqliteSystem.unregisterFile(fileName); - }); - }; - - const database = new Database( - sqlite3, - db, - fileName, - onClose, - this.#sqliteMutex, - ); - this.#openDatabases.add(database); - - return database; - } finally { - this.#openMutex.release(); - } - } - - /** - * Force-close all Database handles whose fileName exactly matches the - * given name. Snapshots the set to an array before iterating to avoid - * mutation during async iteration. - * - * Uses exact file name match because short names are numeric strings - * ('0', '1', ..., '10', '11', ...) and a prefix match like - * startsWith('1') would incorrectly match '10', '11', etc., causing - * cross-actor corruption. Sidecar files (-journal, -wal, -shm) are not - * tracked as separate Database handles, so prefix matching for sidecars - * is not needed. - */ - async forceCloseByFileName( - fileName: string, - ): Promise<{ allSucceeded: boolean }> { - const snapshot = [...this.#openDatabases]; - let allSucceeded = true; - for (const db of snapshot) { - if (db.fileName === fileName) { - try { - await db.close(); - } catch { - allSucceeded = false; - // When close fails, onClose never fires, leaving orphaned - // entries in #openDatabases and #registeredFiles. Clean up - // manually so stale registrations don't accumulate. - this.#openDatabases.delete(db); - const sqliteSystem = this.#sqliteSystem; - if (sqliteSystem) { - await this.#openMutex.run(async () => { - sqliteSystem.unregisterFile(db.fileName); - }); - } - } - } - } - return { allSucceeded }; - } - - /** - * Force-close all open Database handles. Best-effort: errors are - * swallowed so this is safe to call during instance teardown. - */ - async forceCloseAll(): Promise { - const snapshot = [...this.#openDatabases]; - for (const db of snapshot) { - try { - await db.close(); - } catch { - // Best-effort teardown. Swallow errors. - } - } - } - - /** - * Tears down this VFS instance and releases internal references. - */ - async destroy(): Promise { - if (this.#destroyed) { - return; - } - this.#destroyed = true; - - const initPromise = this.#initPromise; - if (initPromise) { - try { - await initPromise; - } catch { - // Initialization failure already surfaced to caller. - } - } - - if (this.#sqliteSystem) { - await this.#sqliteSystem.close(); - } - - this.#sqliteSystem = null; - this.#sqlite3 = null; - this.#initPromise = null; - } - - /** - * Alias for destroy to align with DB-style lifecycle naming. - */ - async close(): Promise { - await this.destroy(); - } -} - -/** - * Internal VFS implementation - */ -class SqliteSystem implements SqliteVfsRegistration { - readonly name: string; - readonly mxPathName = SQLITE_MAX_PATHNAME_BYTES; - readonly mxPathname = SQLITE_MAX_PATHNAME_BYTES; - readonly #registeredFiles: Map = new Map(); - readonly #openFiles: Map = new Map(); - readonly #sqlite3: SQLite3Api; - readonly #module: SQLiteModule; - #heapDataView: DataView; - #heapDataViewBuffer: ArrayBufferLike; - - constructor(sqlite3: SQLite3Api, module: SQLiteModule, name: string) { - this.name = name; - this.#sqlite3 = sqlite3; - this.#module = module; - this.#heapDataViewBuffer = module.HEAPU8.buffer; - this.#heapDataView = new DataView(this.#heapDataViewBuffer); - } - - async close(): Promise { - this.#openFiles.clear(); - this.#registeredFiles.clear(); - } - - isReady(): boolean { - return true; - } - - hasAsyncMethod(methodName: string): boolean { - return SQLITE_ASYNC_METHODS.has(methodName); - } - - /** - * Registers the VFS with SQLite - */ - register(): void { - this.#sqlite3.vfs_register(this, false); - } - - /** - * Registers a file with its KV options (before opening). - */ - registerFile(fileName: string, options: KvVfsOptions): void { - this.#registeredFiles.set(fileName, options); - } - - /** - * Unregisters a file's KV options (after closing). - */ - unregisterFile(fileName: string): void { - this.#registeredFiles.delete(fileName); - } - - /** - * Resolve file path to a registered database file or one of its SQLite - * sidecars (-journal, -wal, -shm). File tags are reused across files - * because each file's KvVfsOptions routes to a separate KV namespace. - */ - #resolveFile(path: string): ResolvedFile | null { - // Direct match: O(1) lookup for main database file. - const directOptions = this.#registeredFiles.get(path); - if (directOptions) { - return { options: directOptions, fileTag: FILE_TAG_MAIN }; - } - - // Sidecar match: strip each known suffix and check the base name. - if (path.endsWith("-journal")) { - const baseName = path.slice(0, -8); - const options = this.#registeredFiles.get(baseName); - if (options) { - return { options, fileTag: FILE_TAG_JOURNAL }; - } - } else if (path.endsWith("-wal")) { - const baseName = path.slice(0, -4); - const options = this.#registeredFiles.get(baseName); - if (options) { - return { options, fileTag: FILE_TAG_WAL }; - } - } else if (path.endsWith("-shm")) { - const baseName = path.slice(0, -4); - const options = this.#registeredFiles.get(baseName); - if (options) { - return { options, fileTag: FILE_TAG_SHM }; - } - } - - return null; - } - - #resolveFileOrThrow(path: string): ResolvedFile { - const resolved = this.#resolveFile(path); - if (resolved) { - return resolved; - } - - if (this.#registeredFiles.size === 0) { - throw new Error(`No KV options registered for file: ${path}`); - } - - const registered = Array.from(this.#registeredFiles.keys()).join(", "); - throw new Error( - `Unsupported SQLite file path ${path}. Registered base names: ${registered}.`, - ); - } - - #chunkKey(file: OpenFile, chunkIndex: number): Uint8Array { - return getChunkKey(file.fileTag, chunkIndex); - } - - async xOpen( - _pVfs: number, - zName: number, - fileId: number, - flags: number, - pOutFlags: number, - ): Promise { - const path = this.#decodeFilename(zName, flags); - if (!path) { - return VFS.SQLITE_CANTOPEN; - } - - // Get the registered KV options for this file - // For journal/wal files, use the main database's options - const { options, fileTag } = this.#resolveFileOrThrow(path); - const metaKey = getMetaKey(fileTag); - - // Get existing file size if the file exists - let sizeData: Uint8Array | null; - try { - sizeData = await options.get(metaKey); - } catch (error) { - options.onError?.(error); - return VFS.SQLITE_CANTOPEN; - } - - let size: number; - - if (sizeData) { - // File exists, use existing size - size = decodeFileMeta(sizeData); - if (!isValidFileSize(size)) { - return VFS.SQLITE_IOERR; - } - } else if (flags & VFS.SQLITE_OPEN_CREATE) { - if (fileTag === FILE_TAG_MAIN) { - // Pre-write a valid empty database page so SQLite sees - // dbSize > 0 on first read. This enables BATCH_ATOMIC - // from the very first write transaction. Without this, - // SQLite's pager opens a real journal file for the first - // write (because jrnlBufferSize returns a positive value - // when dbSize == 0), and with locking_mode=EXCLUSIVE that - // real journal is never closed, permanently disabling - // batch atomic writes. - // - // The page is generated by scripts/generate-empty-header.ts - // using the same wa-sqlite WASM binary we ship. - const chunkKey = getChunkKey(fileTag, 0); - size = EMPTY_DB_PAGE.length; - try { - await options.putBatch([ - [chunkKey, EMPTY_DB_PAGE], - [metaKey, encodeFileMeta(size)], - ]); - } catch (error) { - options.onError?.(error); - return VFS.SQLITE_CANTOPEN; - } - } else { - // Sidecar files (journal, WAL, SHM) start empty. - size = 0; - try { - await options.put(metaKey, encodeFileMeta(size)); - } catch (error) { - options.onError?.(error); - return VFS.SQLITE_CANTOPEN; - } - } - } else { - // File doesn't exist and we're not creating it - return VFS.SQLITE_CANTOPEN; - } - - // Store open file info with options - this.#openFiles.set(fileId, { - path, - fileTag, - metaKey, - size, - metaDirty: false, - flags, - options, - batchMode: false, - dirtyBuffer: null, - savedFileSize: 0, - }); - - // Set output flags to the actual flags used. - this.#writeInt32(pOutFlags, flags); - - return VFS.SQLITE_OK; - } - - async xClose(fileId: number): Promise { - const file = this.#openFiles.get(fileId); - if (!file) { - return VFS.SQLITE_OK; - } - - try { - // Delete-on-close files should skip metadata flush because the file - // will be removed immediately. - if (file.flags & VFS.SQLITE_OPEN_DELETEONCLOSE) { - await this.#delete(file.path); - } else if (file.metaDirty) { - await file.options.put(file.metaKey, encodeFileMeta(file.size)); - file.metaDirty = false; - } - } catch (error) { - // Always clean up the file handle even if the KV operation fails. - file.options.onError?.(error); - this.#openFiles.delete(fileId); - return VFS.SQLITE_IOERR; - } - - this.#openFiles.delete(fileId); - return VFS.SQLITE_OK; - } - - async xRead( - fileId: number, - pData: number, - iAmt: number, - iOffsetLo: number, - iOffsetHi: number, - ): Promise { - if (iAmt === 0) { - return VFS.SQLITE_OK; - } - - const file = this.#openFiles.get(fileId); - if (!file) { - return VFS.SQLITE_IOERR_READ; - } - - let data = this.#module.HEAPU8.subarray(pData, pData + iAmt); - const options = file.options; - const requestedLength = iAmt; - const iOffset = delegalize(iOffsetLo, iOffsetHi); - if (iOffset < 0) { - return VFS.SQLITE_IOERR_READ; - } - const fileSize = file.size; - - // If offset is beyond file size, return short read with zeroed buffer - if (iOffset >= fileSize) { - data.fill(0); - return VFS.SQLITE_IOERR_SHORT_READ; - } - - // Calculate which chunks we need to read - const startChunk = Math.floor(iOffset / CHUNK_SIZE); - const endChunk = Math.floor( - (iOffset + requestedLength - 1) / CHUNK_SIZE, - ); - - // Fetch needed chunks, checking dirty buffer first in batch mode. - const chunkKeys: Uint8Array[] = []; - const chunkIndexToBuffered: Map = new Map(); - for (let i = startChunk; i <= endChunk; i++) { - // In batch mode, serve from dirty buffer if available. - if (file.batchMode && file.dirtyBuffer) { - const buffered = file.dirtyBuffer.get(i); - if (buffered) { - chunkIndexToBuffered.set(i, buffered); - continue; - } - } - chunkKeys.push(this.#chunkKey(file, i)); - } - - let kvChunks: (Uint8Array | null)[]; - try { - kvChunks = - chunkKeys.length > 0 ? await options.getBatch(chunkKeys) : []; - } catch (error) { - options.onError?.(error); - return VFS.SQLITE_IOERR_READ; - } - - // Re-read HEAPU8 after await to defend against buffer detachment - // from memory.grow() that may have occurred during getBatch. - data = this.#module.HEAPU8.subarray(pData, pData + iAmt); - - // Copy data from chunks to output buffer - let kvIdx = 0; - for (let i = startChunk; i <= endChunk; i++) { - const chunkData = chunkIndexToBuffered.get(i) ?? kvChunks[kvIdx++]; - const chunkOffset = i * CHUNK_SIZE; - - // Calculate the range within this chunk - const readStart = Math.max(0, iOffset - chunkOffset); - const readEnd = Math.min( - CHUNK_SIZE, - iOffset + requestedLength - chunkOffset, - ); - - if (chunkData) { - // Copy available data - const sourceStart = readStart; - const sourceEnd = Math.min(readEnd, chunkData.length); - const destStart = chunkOffset + readStart - iOffset; - - if (sourceEnd > sourceStart) { - data.set( - chunkData.subarray(sourceStart, sourceEnd), - destStart, - ); - } - - // Zero-fill if chunk is smaller than expected - if (sourceEnd < readEnd) { - const zeroStart = destStart + (sourceEnd - sourceStart); - const zeroEnd = destStart + (readEnd - readStart); - data.fill(0, zeroStart, zeroEnd); - } - } else { - // Chunk doesn't exist, zero-fill - const destStart = chunkOffset + readStart - iOffset; - const destEnd = destStart + (readEnd - readStart); - data.fill(0, destStart, destEnd); - } - } - - // If we read less than requested (past EOF), return short read - const actualBytes = Math.min(requestedLength, fileSize - iOffset); - if (actualBytes < requestedLength) { - data.fill(0, actualBytes); - return VFS.SQLITE_IOERR_SHORT_READ; - } - - return VFS.SQLITE_OK; - } - - async xWrite( - fileId: number, - pData: number, - iAmt: number, - iOffsetLo: number, - iOffsetHi: number, - ): Promise { - if (iAmt === 0) { - return VFS.SQLITE_OK; - } - - const file = this.#openFiles.get(fileId); - if (!file) { - return VFS.SQLITE_IOERR_WRITE; - } - - let data = this.#module.HEAPU8.subarray(pData, pData + iAmt); - const iOffset = delegalize(iOffsetLo, iOffsetHi); - if (iOffset < 0) { - return VFS.SQLITE_IOERR_WRITE; - } - const options = file.options; - const writeLength = iAmt; - const writeEndOffset = iOffset + writeLength; - if (writeEndOffset > MAX_FILE_SIZE_BYTES) { - return VFS.SQLITE_IOERR_WRITE; - } - - // Calculate which chunks we need to modify - const startChunk = Math.floor(iOffset / CHUNK_SIZE); - const endChunk = Math.floor((iOffset + writeLength - 1) / CHUNK_SIZE); - - // Batch mode: buffer pages in dirtyBuffer instead of writing to KV. - // COMMIT_ATOMIC_WRITE flushes the buffer in a single putBatch. - if (file.batchMode && file.dirtyBuffer) { - for (let i = startChunk; i <= endChunk; i++) { - const chunkOffset = i * CHUNK_SIZE; - const sourceStart = Math.max(0, chunkOffset - iOffset); - const sourceEnd = Math.min( - writeLength, - chunkOffset + CHUNK_SIZE - iOffset, - ); - // .slice() creates an independent copy that won't be - // invalidated by memory.grow() after an await. - file.dirtyBuffer.set( - i, - data.subarray(sourceStart, sourceEnd).slice(), - ); - } - - // Update file size if write extends the file - const newSize = Math.max(file.size, writeEndOffset); - if (newSize !== file.size) { - file.size = newSize; - file.metaDirty = true; - } - - return VFS.SQLITE_OK; - } - - interface WritePlan { - chunkKey: Uint8Array; - chunkOffset: number; - writeStart: number; - writeEnd: number; - existingChunkIndex: number; - } - - // Only fetch chunks where we must preserve existing prefix/suffix bytes. - const plans: WritePlan[] = []; - const chunkKeysToFetch: Uint8Array[] = []; - for (let i = startChunk; i <= endChunk; i++) { - const chunkOffset = i * CHUNK_SIZE; - const writeStart = Math.max(0, iOffset - chunkOffset); - const writeEnd = Math.min( - CHUNK_SIZE, - iOffset + writeLength - chunkOffset, - ); - const existingBytesInChunk = Math.max( - 0, - Math.min(CHUNK_SIZE, file.size - chunkOffset), - ); - const needsExisting = - writeStart > 0 || existingBytesInChunk > writeEnd; - const chunkKey = this.#chunkKey(file, i); - let existingChunkIndex = -1; - if (needsExisting) { - existingChunkIndex = chunkKeysToFetch.length; - chunkKeysToFetch.push(chunkKey); - } - plans.push({ - chunkKey, - chunkOffset, - writeStart, - writeEnd, - existingChunkIndex, - }); - } - - let existingChunks: (Uint8Array | null)[]; - try { - existingChunks = - chunkKeysToFetch.length > 0 - ? await options.getBatch(chunkKeysToFetch) - : []; - } catch (error) { - options.onError?.(error); - return VFS.SQLITE_IOERR_WRITE; - } - - // Re-read HEAPU8 after await to defend against buffer detachment - // from memory.grow() that may have occurred during getBatch. - data = this.#module.HEAPU8.subarray(pData, pData + iAmt); - - // Prepare new chunk data - const entriesToWrite: [Uint8Array, Uint8Array][] = []; - - for (const plan of plans) { - const existingChunk = - plan.existingChunkIndex >= 0 - ? existingChunks[plan.existingChunkIndex] - : null; - // Create new chunk data - let newChunk: Uint8Array; - if (existingChunk) { - newChunk = new Uint8Array( - Math.max(existingChunk.length, plan.writeEnd), - ); - newChunk.set(existingChunk); - } else { - newChunk = new Uint8Array(plan.writeEnd); - } - - // Copy data from input buffer to chunk - const sourceStart = plan.chunkOffset + plan.writeStart - iOffset; - const sourceEnd = sourceStart + (plan.writeEnd - plan.writeStart); - newChunk.set( - data.subarray(sourceStart, sourceEnd), - plan.writeStart, - ); - - entriesToWrite.push([plan.chunkKey, newChunk]); - } - - // Update file size if we wrote past the end - const previousSize = file.size; - const previousMetaDirty = file.metaDirty; - const newSize = Math.max(file.size, writeEndOffset); - if (newSize !== previousSize) { - file.size = newSize; - file.metaDirty = true; - } - if (file.metaDirty) { - entriesToWrite.push([file.metaKey, encodeFileMeta(file.size)]); - } - - // Write all chunks and metadata - try { - await options.putBatch(entriesToWrite); - } catch (error) { - options.onError?.(error); - file.size = previousSize; - file.metaDirty = previousMetaDirty; - return VFS.SQLITE_IOERR_WRITE; - } - if (file.metaDirty) { - file.metaDirty = false; - } - file.metaDirty = false; - - return VFS.SQLITE_OK; - } - - async xTruncate( - fileId: number, - sizeLo: number, - sizeHi: number, - ): Promise { - const file = this.#openFiles.get(fileId); - if (!file) { - return VFS.SQLITE_IOERR_TRUNCATE; - } - - const size = delegalize(sizeLo, sizeHi); - if (size < 0 || size > MAX_FILE_SIZE_BYTES) { - return VFS.SQLITE_IOERR_TRUNCATE; - } - const options = file.options; - - // If truncating to larger size, just update metadata - if (size >= file.size) { - if (size > file.size) { - const previousSize = file.size; - const previousMetaDirty = file.metaDirty; - file.size = size; - file.metaDirty = true; - try { - await options.put(file.metaKey, encodeFileMeta(file.size)); - } catch (error) { - options.onError?.(error); - file.size = previousSize; - file.metaDirty = previousMetaDirty; - return VFS.SQLITE_IOERR_TRUNCATE; - } - file.metaDirty = false; - } - return VFS.SQLITE_OK; - } - - // Calculate which chunks to delete - // Note: When size=0, lastChunkToKeep = floor(-1/4096) = -1, which means - // all chunks (starting from index 0) will be deleted in the loop below. - const lastChunkToKeep = Math.floor((size - 1) / CHUNK_SIZE); - const lastExistingChunk = Math.floor((file.size - 1) / CHUNK_SIZE); - - // Update metadata first so a crash leaves orphaned chunks (wasted - // space) rather than metadata pointing at missing chunks (corruption). - const previousSize = file.size; - const previousMetaDirty = file.metaDirty; - file.size = size; - file.metaDirty = true; - try { - await options.put(file.metaKey, encodeFileMeta(file.size)); - } catch (error) { - options.onError?.(error); - file.size = previousSize; - file.metaDirty = previousMetaDirty; - return VFS.SQLITE_IOERR_TRUNCATE; - } - file.metaDirty = false; - - // Remaining operations clean up old chunk data. Metadata already - // reflects the new size, so failures here leave orphaned/oversized - // chunks that are invisible to SQLite (xRead clips to file.size). - try { - // Truncate the last kept chunk if needed - if (size > 0 && size % CHUNK_SIZE !== 0) { - const lastChunkKey = this.#chunkKey(file, lastChunkToKeep); - const lastChunkData = await options.get(lastChunkKey); - - if (lastChunkData && lastChunkData.length > size % CHUNK_SIZE) { - const truncatedChunk = lastChunkData.subarray( - 0, - size % CHUNK_SIZE, - ); - await options.put(lastChunkKey, truncatedChunk); - } - } - - if (lastChunkToKeep < lastExistingChunk) { - await options.deleteRange( - this.#chunkKey(file, lastChunkToKeep + 1), - getChunkKeyRangeEnd(file.fileTag), - ); - } - } catch (error) { - options.onError?.(error); - return VFS.SQLITE_IOERR_TRUNCATE; - } - - return VFS.SQLITE_OK; - } - - async xSync(fileId: number, _flags: number): Promise { - const file = this.#openFiles.get(fileId); - if (!file || !file.metaDirty) { - return VFS.SQLITE_OK; - } - - try { - await file.options.put(file.metaKey, encodeFileMeta(file.size)); - } catch (error) { - file.options.onError?.(error); - return VFS.SQLITE_IOERR_FSYNC; - } - file.metaDirty = false; - return VFS.SQLITE_OK; - } - - async xFileSize(fileId: number, pSize: number): Promise { - const file = this.#openFiles.get(fileId); - if (!file) { - return VFS.SQLITE_IOERR_FSTAT; - } - - // Set size as 64-bit integer. - this.#writeBigInt64(pSize, BigInt(file.size)); - return VFS.SQLITE_OK; - } - - async xDelete( - _pVfs: number, - zName: number, - _syncDir: number, - ): Promise { - try { - await this.#delete(this.#module.UTF8ToString(zName)); - } catch (error) { - // xDelete doesn't have a file handle, so we can't resolve - // options.onError here. The error is still surfaced by - // SQLite as SQLITE_IOERR_DELETE. - return VFS.SQLITE_IOERR_DELETE; - } - return VFS.SQLITE_OK; - } - - /** - * Internal delete implementation. - * Uses deleteRange for O(1) chunk deletion instead of enumerating - * individual chunk keys. The chunk keys for a file tag are - * lexicographically contiguous, so range deletion is always safe. - */ - async #delete(path: string): Promise { - const { options, fileTag } = this.#resolveFileOrThrow(path); - const metaKey = getMetaKey(fileTag); - - // Get file size to check if the file exists - const sizeData = await options.get(metaKey); - - if (!sizeData) { - // File doesn't exist, that's OK - return; - } - - // Delete all chunks via range delete and the metadata key. - await options.deleteRange( - getChunkKey(fileTag, 0), - getChunkKeyRangeEnd(fileTag), - ); - await options.deleteBatch([metaKey]); - } - - async xAccess( - _pVfs: number, - zName: number, - _flags: number, - pResOut: number, - ): Promise { - // TODO: Measure how often xAccess runs during open and whether these - // existence checks add meaningful KV round-trip overhead. If they do, - // consider serving file existence from in-memory state. - const path = this.#module.UTF8ToString(zName); - const resolved = this.#resolveFile(path); - if (!resolved) { - // File not registered, doesn't exist - this.#writeInt32(pResOut, 0); - return VFS.SQLITE_OK; - } - - const compactMetaKey = getMetaKey(resolved.fileTag); - let metaData: Uint8Array | null; - try { - metaData = await resolved.options.get(compactMetaKey); - } catch (error) { - resolved.options.onError?.(error); - return VFS.SQLITE_IOERR_ACCESS; - } - - // Set result: 1 if file exists, 0 otherwise - this.#writeInt32(pResOut, metaData ? 1 : 0); - return VFS.SQLITE_OK; - } - - xCheckReservedLock(_fileId: number, pResOut: number): number { - // This VFS is actor-scoped with one writer, so there is no external - // reserved lock state to report. - this.#writeInt32(pResOut, 0); - return VFS.SQLITE_OK; - } - - xLock(_fileId: number, _flags: number): number { - return VFS.SQLITE_OK; - } - - xUnlock(_fileId: number, _flags: number): number { - return VFS.SQLITE_OK; - } - - async xFileControl( - fileId: number, - flags: number, - _pArg: number, - ): Promise { - switch (flags) { - case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: { - const file = this.#openFiles.get(fileId); - if (!file) return VFS.SQLITE_NOTFOUND; - file.savedFileSize = file.size; - file.batchMode = true; - file.metaDirty = false; - file.dirtyBuffer = new Map(); - return VFS.SQLITE_OK; - } - - case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: { - const file = this.#openFiles.get(fileId); - if (!file) return VFS.SQLITE_NOTFOUND; - const { dirtyBuffer, options } = file; - - // Dynamic limit: if metadata is dirty, we need one slot for it. - // If metadata is not dirty (file.size unchanged), all slots are available for pages. - const maxDirtyPages = file.metaDirty - ? KV_MAX_BATCH_KEYS - 1 - : KV_MAX_BATCH_KEYS; - if (dirtyBuffer && dirtyBuffer.size > maxDirtyPages) { - dirtyBuffer.clear(); - file.dirtyBuffer = null; - file.size = file.savedFileSize; - file.metaDirty = false; - file.batchMode = false; - return VFS.SQLITE_IOERR; - } - - // Build entries array from dirty buffer + metadata. - const entries: [Uint8Array, Uint8Array][] = []; - if (dirtyBuffer) { - for (const [chunkIndex, data] of dirtyBuffer) { - entries.push([this.#chunkKey(file, chunkIndex), data]); - } - dirtyBuffer.clear(); - } - if (file.metaDirty) { - entries.push([file.metaKey, encodeFileMeta(file.size)]); - } - - try { - await options.putBatch(entries); - } catch (error) { - options.onError?.(error); - file.dirtyBuffer = null; - file.size = file.savedFileSize; - file.metaDirty = false; - file.batchMode = false; - return VFS.SQLITE_IOERR; - } - - file.dirtyBuffer = null; - file.metaDirty = false; - file.batchMode = false; - return VFS.SQLITE_OK; - } - - case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: { - const file = this.#openFiles.get(fileId); - if (!file || !file.batchMode) return VFS.SQLITE_OK; - if (file.dirtyBuffer) { - file.dirtyBuffer.clear(); - file.dirtyBuffer = null; - } - file.size = file.savedFileSize; - file.metaDirty = false; - file.batchMode = false; - return VFS.SQLITE_OK; - } - - default: - return VFS.SQLITE_NOTFOUND; - } - } - - // Return CHUNK_SIZE so SQLite aligns journal I/O to chunk boundaries. - // Must match the native VFS (kv_io_sector_size in sqlite-native/src/vfs.rs). - xSectorSize(_fileId: number): number { - return CHUNK_SIZE; - } - - xDeviceCharacteristics(_fileId: number): number { - return SQLITE_IOCAP_BATCH_ATOMIC; - } - - xFullPathname( - _pVfs: number, - zName: number, - nOut: number, - zOut: number, - ): number { - const path = this.#module.UTF8ToString(zName); - const bytes = TEXT_ENCODER.encode(path); - const out = this.#module.HEAPU8.subarray(zOut, zOut + nOut); - if (bytes.length >= out.length) { - return VFS.SQLITE_IOERR; - } - out.set(bytes, 0); - out[bytes.length] = 0; - return VFS.SQLITE_OK; - } - - #decodeFilename(zName: number, flags: number): string | null { - if (!zName) { - return null; - } - - if (flags & VFS.SQLITE_OPEN_URI) { - // Decode SQLite URI filename layout: path\0key\0value\0...\0 - let pName = zName; - let state: 1 | 2 | 3 | null = 1; - const charCodes: number[] = []; - while (state) { - const charCode = this.#module.HEAPU8[pName++]; - if (charCode) { - charCodes.push(charCode); - continue; - } - - if (!this.#module.HEAPU8[pName]) { - state = null; - } - switch (state) { - case 1: - charCodes.push("?".charCodeAt(0)); - state = 2; - break; - case 2: - charCodes.push("=".charCodeAt(0)); - state = 3; - break; - case 3: - charCodes.push("&".charCodeAt(0)); - state = 2; - break; - } - } - return TEXT_DECODER.decode(new Uint8Array(charCodes)); - } - - return this.#module.UTF8ToString(zName); - } - - #heapView(): DataView { - const heapBuffer = this.#module.HEAPU8.buffer; - if (heapBuffer !== this.#heapDataViewBuffer) { - this.#heapDataViewBuffer = heapBuffer; - this.#heapDataView = new DataView(heapBuffer); - } - return this.#heapDataView; - } - - #writeInt32(pointer: number, value: number): void { - const heapByteOffset = this.#module.HEAPU8.byteOffset + pointer; - this.#heapView().setInt32(heapByteOffset, value, true); - } - - #writeBigInt64(pointer: number, value: bigint): void { - const heapByteOffset = this.#module.HEAPU8.byteOffset + pointer; - this.#heapView().setBigInt64(heapByteOffset, value, true); - } -} - -/** - * Rebuild an i64 from Emscripten's legalized (lo32, hi32) pair. - * SQLite passes file offsets and sizes this way. We decode into unsigned words - * and reject values above the VFS max file size. - */ -function delegalize(lo32: number, hi32: number): number { - const hi = hi32 >>> 0; - const lo = lo32 >>> 0; - if (hi > MAX_FILE_SIZE_HI32) { - return -1; - } - if (hi === MAX_FILE_SIZE_HI32 && lo > MAX_FILE_SIZE_LO32) { - return -1; - } - return hi * UINT32_SIZE + lo; -} diff --git a/rivetkit-typescript/packages/sqlite-vfs/src/wasm.d.ts b/rivetkit-typescript/packages/sqlite-vfs/src/wasm.d.ts deleted file mode 100644 index 112d181d88..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/src/wasm.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Minimal WebAssembly type declarations for Node.js environments where - * lib.dom.d.ts is not included. Only the types needed by the VFS pool - * module caching are declared here. - */ -declare namespace WebAssembly { - class Module { - constructor(bytes: BufferSource); - } - - class Instance { - readonly exports: Exports; - constructor(module: Module, importObject?: Imports); - } - - type Imports = Record>; - type ImportValue = Function | Global | Memory | Table | number; - type Exports = Record; - - class Global { - constructor(descriptor: GlobalDescriptor, value?: number); - value: number; - } - - interface GlobalDescriptor { - value: string; - mutable?: boolean; - } - - class Memory { - constructor(descriptor: MemoryDescriptor); - readonly buffer: ArrayBuffer; - } - - interface MemoryDescriptor { - initial: number; - maximum?: number; - } - - class Table { - constructor(descriptor: TableDescriptor); - readonly length: number; - } - - interface TableDescriptor { - element: string; - initial: number; - maximum?: number; - } - - function compile(bytes: BufferSource): Promise; - function instantiate( - module: Module, - importObject?: Imports, - ): Promise; - function instantiate( - bytes: BufferSource, - importObject?: Imports, - ): Promise<{ module: Module; instance: Instance }>; -} diff --git a/rivetkit-typescript/packages/sqlite-vfs/tsconfig.json b/rivetkit-typescript/packages/sqlite-vfs/tsconfig.json deleted file mode 100644 index 2767f744b3..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "paths": { - "@/*": ["./src/*"] - } - }, - "include": ["src/**/*", "schemas/**/*", "dist/schemas/**/*", "tests/**/*"] -} diff --git a/rivetkit-typescript/packages/sqlite-vfs/tsup.config.ts b/rivetkit-typescript/packages/sqlite-vfs/tsup.config.ts deleted file mode 100644 index d8652c0151..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/tsup.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from "tsup"; -import defaultConfig from "../../../tsup.base.ts"; - -export default defineConfig({ - ...defaultConfig, - outDir: "dist/tsup/", -}); diff --git a/rivetkit-typescript/packages/sqlite-vfs/turbo.json b/rivetkit-typescript/packages/sqlite-vfs/turbo.json deleted file mode 100644 index 29d4cb2625..0000000000 --- a/rivetkit-typescript/packages/sqlite-vfs/turbo.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "extends": ["//"] -} diff --git a/website/src/content/internal/sqlite-batch-atomic-write.md b/website/src/content/internal/sqlite-batch-atomic-write.md deleted file mode 100644 index 13eceb5976..0000000000 --- a/website/src/content/internal/sqlite-batch-atomic-write.md +++ /dev/null @@ -1,214 +0,0 @@ -# SQLite BATCH_ATOMIC_WRITE: Internal Reference - -This document covers the internals of SQLite's `SQLITE_IOCAP_BATCH_ATOMIC` -mechanism and its fallback behavior. It is intended as a reference for anyone -working on the KV-backed SQLite VFS. - -## Overview - -`SQLITE_IOCAP_BATCH_ATOMIC` is a VFS device characteristic flag that tells -SQLite the underlying storage can atomically write multiple pages in one -operation. When a VFS declares this capability, SQLite changes its commit -strategy to eliminate external journal file I/O. - -The feature was introduced in SQLite 3.21.0 (2017-10-24) for Android's F2FS -filesystem. It is compiled into the wa-sqlite WASM binary used by -`@rivetkit/sqlite` via the `SQLITE_ENABLE_BATCH_ATOMIC_WRITE` compile flag. - -## The protocol - -Three `xFileControl` opcodes define the VFS contract: - -| Opcode | Value | VFS action | -|--------|-------|------------| -| `SQLITE_FCNTL_BEGIN_ATOMIC_WRITE` | 31 | Enter batch mode. Buffer subsequent xWrite calls. | -| `SQLITE_FCNTL_COMMIT_ATOMIC_WRITE` | 32 | Atomically persist all buffered writes. | -| `SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE` | 33 | Discard all buffered writes. | - -### Batch eligibility - -SQLite uses the batch-atomic path only when all of these conditions are met -(checked in `sqlite3PagerCommitPhaseOne()` in pager.c): - -1. The transaction involves a single database (no super-journal / multi-db tx). -2. `xDeviceCharacteristics()` includes `SQLITE_IOCAP_BATCH_ATOMIC`. -3. `pPager->noSync` is false (i.e., `synchronous` is not OFF). -4. The journal is still in memory (hasn't been spilled to disk due to memory - pressure). - -If any condition fails, SQLite uses the standard journal-to-disk path. - -**Important**: condition 3 means `PRAGMA synchronous = OFF` disables -BATCH_ATOMIC. The VFS must use `synchronous = NORMAL` or higher. With -BATCH_ATOMIC active, `synchronous = NORMAL` does not add extra xSync calls -because the batch write path bypasses the sync logic entirely. - -### Commit sequence (happy path) - -Inside `sqlite3PagerCommitPhaseOne()`: - -``` -1. pager_incr_changecounter() Update the change counter in page 1 (in cache). -2. syncJournal() No-op: journal is in memory. -3. sqlite3PcacheDirtyList() Collect all dirty pages into a linked list. -4. xFileControl(BEGIN_ATOMIC_WRITE) Tell VFS to start buffering. -5. pager_write_pagelist(pList) Call xWrite() for each dirty page. VFS buffers. -6. xWrite (file extension) If file grew, write trailing zeros. VFS buffers. -7. xFileControl(COMMIT_ATOMIC_WRITE) Tell VFS to persist everything atomically. -8. Continue normal cleanup. Clear page cache dirty flags, etc. -``` - -The journal file is never created on disk/KV. It exists only in memory as a -backup of original page contents in case ROLLBACK is needed before commit. - -### Commit sequence (failure + fallback) - -If any step between BEGIN_ATOMIC_WRITE and COMMIT_ATOMIC_WRITE fails (including -COMMIT itself returning an error), SQLite executes a fallback: - -``` -1-4. Same as happy path. -5. pager_write_pagelist() xWrite calls → VFS buffers. (May succeed or fail.) -6. (file extension write) May succeed or fail. -7. xFileControl(COMMIT_ATOMIC) Returns SQLITE_IOERR (e.g., buffer too large). - - SQLite detects the error: - -8. xFileControl(ROLLBACK_ATOMIC) VFS discards the buffer. Called as a "hint" - (return value ignored). - -9. Error class check: - - If (rc & 0xFF) == SQLITE_IOERR and rc != SQLITE_IOERR_NOMEM: - → sqlite3JournalCreate() Spill the in-memory journal to a real file. - This calls xOpen(journal) + xWrite for each - original page that was saved in memory. - → bBatch = 0 Disable batch mode for the rest of this commit. - - Otherwise: - → Hard failure. No retry. Error propagates to application. - -10. if bBatch == 0: - pager_write_pagelist(pList) Re-write all dirty pages via xWrite, this time - NOT inside a BEGIN/COMMIT bracket. Each xWrite - goes directly to storage (no buffering). - -11. Normal commit continues: - - Extend file if needed. - - xSync (database file). - - Delete/truncate journal file (the commit point). -``` - -### Source code references - -All line numbers refer to the SQLite 3.49.2 amalgamation (`sqlite3.c`). - -- `sqlite3PagerCommitPhaseOne()`: ~line 63769. The main commit function. -- Batch eligibility check: ~line 63829-63832. -- BEGIN_ATOMIC_WRITE call: ~line 63921. -- COMMIT_ATOMIC_WRITE call: ~line 63929. -- ROLLBACK_ATOMIC_WRITE on failure: ~line 63935. -- IOERR retry decision: ~line 63940-63949. -- Journal spill via `sqlite3JournalCreate()`: ~line 63941. -- Non-batch page write retry: ~line 63953. - -## The in-memory journal - -When BATCH_ATOMIC is eligible, SQLite stores the rollback journal entirely in -memory using a `MemJournal` structure. This is controlled by -`jrnlBufferSize()` returning -1 when batch-atomic conditions are met (the -1 -tells SQLite to use unbounded in-memory buffering). - -The in-memory journal holds the **original** page contents (before -modification). If a ROLLBACK occurs, SQLite reads these original pages back -from the MemJournal to restore the database to its pre-transaction state. - -During the fallback (step 9 above), `sqlite3JournalCreate()` converts the -MemJournal into a real file: -1. Opens the journal file via `xOpen` with `SQLITE_OPEN_MAIN_JOURNAL` flags. -2. Writes all buffered journal chunks from the MemJournal to the real file via - `xWrite`. -3. Replaces the MemJournal I/O methods with the real file I/O methods. - -After this, SQLite proceeds with the normal DELETE-mode journal commit: write -dirty pages to the main database file, sync, then delete the journal file. - -## Error code requirements - -The fallback ONLY triggers for `SQLITE_IOERR` family errors. Specifically, the -check in the source is: - -```c -if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){ - // retry with journal -} -``` - -This means: -- `SQLITE_IOERR` (10): triggers retry. -- `SQLITE_IOERR_WRITE` (778): triggers retry. -- `SQLITE_IOERR_FSYNC` (1034): triggers retry. -- Any other `SQLITE_IOERR_*` variant: triggers retry (except NOMEM). -- `SQLITE_IOERR_NOMEM` (3082): hard failure, no retry. -- `SQLITE_FULL` (13): hard failure, no retry. -- `SQLITE_NOMEM` (7): hard failure, no retry. -- Any non-IOERR error: hard failure, no retry. - -**For our VFS**: when the dirty buffer exceeds 128 entries, return -`SQLITE_IOERR` from `COMMIT_ATOMIC_WRITE` to trigger the retry path. - -## Documentation status - -The BATCH_ATOMIC feature has fragmented documentation: - -- **Official FCNTL docs** (`sqlite.org/c3ref/c_fcntl_begin_atomic_write.html`): - Documents the three opcodes and their contracts. Does not document the - fallback behavior. - -- **Tech note** (2017, `sqlite3.org/cgi/src/technote/714f6cbb...`): - Design document written before the feature was fully implemented. States: - "a failed batch-atomic transaction is a hard failure which is not retried. - Future versions of SQLite might retry a failed batch-atomic transaction as a - normal transaction." The retry was implemented in a later version but the - tech note was never updated. - -- **Source code**: The only authoritative documentation of the fallback - behavior is the source code in `pager.c` (`sqlite3PagerCommitPhaseOne()`). - -- **Atomic commit docs** (`sqlite.org/atomiccommit.html`): Describes the - general journal commit protocol but does not mention BATCH_ATOMIC. - -## The synchronous=OFF bug - -Roy Hashimoto (wa-sqlite author) reported a corruption window when combining -`PRAGMA synchronous = OFF` with `SQLITE_IOCAP_BATCH_ATOMIC`. The issue is that -`synchronous = OFF` sets `pPager->noSync = 1`, which is one of the batch -eligibility conditions (condition 3 above). When noSync is true, SQLite skips -the batch-atomic path and falls through to the normal commit path, but the -journal is still in memory (because the VFS declared BATCH_ATOMIC). This can -lead to a state where dirty pages are written without journal protection. - -Richard Hipp (SQLite author) fixed this on the SQLite trunk. The fix ensures -the journal is spilled to disk when noSync is true and batch-atomic is not -used. However, the fix may not be present in all wa-sqlite builds. - -**Recommendation**: Use `PRAGMA synchronous = NORMAL` to avoid this issue -entirely. With BATCH_ATOMIC active, NORMAL adds zero overhead because the -batch write path bypasses all sync operations. - -## Industry usage - -| Implementation | Backend | Approach | -|----------------|---------|----------| -| Android F2FS | Filesystem | `F2FS_IOC_START_ATOMIC_WRITE` / `F2FS_IOC_COMMIT_ATOMIC_WRITE` ioctls. Kernel buffers writes and commits atomically. First production use of BATCH_ATOMIC. | -| wa-sqlite IDBBatchAtomicVFS | IndexedDB | Declares BATCH_ATOMIC. BEGIN/COMMIT are no-ops because IDB transactions are inherently atomic. Actual commit happens at IDB transaction boundary. | -| Gazette store_sqlite | RocksDB | Uses BATCH_ATOMIC to collect dirty pages, commits via RocksDB WriteBatch. | -| gRPSQLite | gRPC remote store | Uses BATCH_ATOMIC with `journal_mode=MEMORY`. Sends all dirty pages in a single `AtomicWriteBatch` gRPC call at commit. | - -## References - -- SQLite FCNTL constants: https://sqlite.org/c3ref/c_fcntl_begin_atomic_write.html -- SQLite atomic commit: https://sqlite.org/atomiccommit.html -- Batch atomic write tech note: https://www3.sqlite.org/cgi/src/technote/714f6cbbf78c8a1351cbd48af2b438f7f824b336 -- wa-sqlite IDBBatchAtomicVFS source: `@rivetkit/sqlite/src/examples/IDBBatchAtomicVFS.js` -- wa-sqlite BATCH_ATOMIC discussion: https://github.com/rhashimoto/wa-sqlite/discussions/78 -- F2FS atomic writes: https://www.kernel.org/doc/html/latest/filesystems/f2fs.html -- SQLite forum on synchronous=OFF + BATCH_ATOMIC: https://sqlite.org/forum/forumpost/7ceaee2262e52377