From 3803b1b2b1165b0989c83d0911fa51ad56aab136 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 01:41:20 +0000 Subject: [PATCH] fix(example-showcase): route external-datasource fixture through the sqlite fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `setupShowcaseExternalDatasource` (run from the showcase app's `onEnable` at boot) built its MANAGED provisioning driver with a raw `new SqlDriver({ client: 'better-sqlite3' })`. `better-sqlite3` loads its native addon lazily at first query, so a `NODE_MODULE_VERSION` ABI mismatch (e.g. after a Node upgrade) threw `ERR_DLOPEN_FAILED` here — which propagated through `onEnable` -> `AppPlugin.start()` and bricked `plugin.app.com.example.showcase`, failing `pnpm dev` entirely, even though the default datasource had already stepped down to wasm SQLite. Every other sqlite construction site was hoisted onto the shared `resolveSqliteDriver` native -> wasm -> in-memory step-down (#2229); this fixture site was missed. Route it through the same helper so a native ABI/load failure degrades to wasm in dev (real SQL + on-disk persistence) instead of crashing boot, and still fails closed in production. Adds `@objectstack/service-datasource` (which exports `resolveSqliteDriver`) as a dependency of the example. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01UUWGgTT5s7XgBb2eLtzhfU --- examples/app-showcase/package.json | 1 + .../system/datasources/external-fixture.ts | 26 ++++++++++++++----- pnpm-lock.yaml | 3 +++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/examples/app-showcase/package.json b/examples/app-showcase/package.json index 164626a030..dc9a20208f 100644 --- a/examples/app-showcase/package.json +++ b/examples/app-showcase/package.json @@ -27,6 +27,7 @@ "@objectstack/connector-slack": "workspace:*", "@objectstack/driver-sql": "workspace:*", "@objectstack/runtime": "workspace:*", + "@objectstack/service-datasource": "workspace:*", "@objectstack/spec": "workspace:*" }, "devDependencies": { diff --git a/examples/app-showcase/src/system/datasources/external-fixture.ts b/examples/app-showcase/src/system/datasources/external-fixture.ts index 5a5cd8e4cf..1d70da11b4 100644 --- a/examples/app-showcase/src/system/datasources/external-fixture.ts +++ b/examples/app-showcase/src/system/datasources/external-fixture.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -import { SqlDriver } from '@objectstack/driver-sql'; +import { resolveSqliteDriver } from '@objectstack/service-datasource'; /** * Fixture provisioning for the external-datasource federation demo @@ -11,6 +11,14 @@ import { SqlDriver } from '@objectstack/driver-sql'; * driver — DDL allowed) so `os dev` needs no external server. It runs from the * stack's `onEnable` hook at boot. * + * The MANAGED driver is built via the shared `resolveSqliteDriver` step-down + * (#2229) rather than a raw `new SqlDriver({ client: 'better-sqlite3' })`: in dev + * a native `better-sqlite3` ABI/load failure (e.g. a `NODE_MODULE_VERSION` + * mismatch after a Node upgrade) steps down to wasm SQLite instead of throwing. + * Without this, an ABI mismatch here crashed the whole `onEnable` hook — + * bricking `plugin.app.` boot even though the default datasource had + * already fallen back to wasm. + * * **It no longer registers a driver or syncs object schemas (ADR-0062 D8).** The * declared `external` datasource (see `showcase-external.datasource.ts`) now * AUTO-CONNECTS: at boot the runtime's `DatasourceConnectionService` builds the @@ -71,11 +79,17 @@ interface OnEnableContext { * datasource auto-connects at boot (ADR-0062 D1/D8). */ export async function setupShowcaseExternalDatasource(ctx: OnEnableContext): Promise { - const fixture = new SqlDriver({ - client: 'better-sqlite3', - connection: { filename: EXTERNAL_DB_FILE }, - useNullAsDefault: true, - }) as unknown as { + // Build the managed provisioning driver through the shared native → wasm → + // in-memory step-down (#2229). In dev, a native better-sqlite3 ABI/load + // failure steps down to wasm SQLite (real SQL + on-disk persistence) so the + // fixture — and therefore `onEnable` / app-plugin boot — never crashes on a + // `NODE_MODULE_VERSION` mismatch; in production it returns the native driver + // unprobed (fail-closed), preserving the historical behavior. + const resolved = await resolveSqliteDriver({ + filename: EXTERNAL_DB_FILE, + warn: (m: string) => ctx.logger?.warn?.(m), + }); + const fixture = resolved.driver as unknown as { name: string; connect: () => Promise; disconnect: () => Promise; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e33b71c554..6fa464c69d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -150,6 +150,9 @@ importers: '@objectstack/runtime': specifier: workspace:* version: link:../../packages/runtime + '@objectstack/service-datasource': + specifier: workspace:* + version: link:../../packages/services/service-datasource '@objectstack/spec': specifier: workspace:* version: link:../../packages/spec