Skip to content

Commit beb96af

Browse files
vicbpetebacondarwindevin-ai-integration[bot]
authored
feat(unenv-preset): add support for native node:sqlite module (#11841)
* feat(unenv-preset): add support for native node:sqlite module (#11805) * feat(unenv-preset): add support for native node:sqlite module Co-Authored-By: pbacondarwin@cloudflare.com <pete@bacondarwin.com> * fix: improve testSqlite to test both unenv and native cases Co-Authored-By: pbacondarwin@cloudflare.com <pete@bacondarwin.com> * refactor: use assertTypeOfProperties for cleaner test code Co-Authored-By: pbacondarwin@cloudflare.com <pete@bacondarwin.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fixup! do not error when `node:sqlite` is not available on the active Node runtime * fixup! feedback --------- Co-authored-by: Pete Bacon Darwin <pete@bacondarwin.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent fe3e955 commit beb96af

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

.changeset/native-sqlite-module.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/unenv-preset": minor
3+
---
4+
5+
Add support for native `node:sqlite` module when the `enable_nodejs_sqlite_module` compatibility flag is enabled. This feature is currently experimental and requires `nodejs_compat`, `experimental`, and `enable_nodejs_sqlite_module` compatibility flags to be set.

packages/unenv-preset/src/preset.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export function getCloudflarePreset({
8080
const consoleOverrides = getConsoleOverrides(compat);
8181
const vmOverrides = getVmOverrides(compat);
8282
const inspectorOverrides = getInspectorOverrides(compat);
83+
const sqliteOverrides = getSqliteOverrides(compat);
8384

8485
// "dynamic" as they depend on the compatibility date and flags
8586
const dynamicNativeModules = [
@@ -96,6 +97,7 @@ export function getCloudflarePreset({
9697
...consoleOverrides.nativeModules,
9798
...vmOverrides.nativeModules,
9899
...inspectorOverrides.nativeModules,
100+
...sqliteOverrides.nativeModules,
99101
];
100102

101103
// "dynamic" as they depend on the compatibility date and flags
@@ -113,6 +115,7 @@ export function getCloudflarePreset({
113115
...consoleOverrides.hybridModules,
114116
...vmOverrides.hybridModules,
115117
...inspectorOverrides.hybridModules,
118+
...sqliteOverrides.hybridModules,
116119
];
117120

118121
return {
@@ -635,3 +638,39 @@ function getInspectorOverrides({
635638
hybridModules: [],
636639
};
637640
}
641+
642+
/**
643+
* Returns the overrides for `node:sqlite` (unenv or workerd)
644+
*
645+
* The native sqlite implementation:
646+
* - is experimental and has no default enable date
647+
* - can be enabled with the "enable_nodejs_sqlite_module" flag
648+
* - can be disabled with the "disable_nodejs_sqlite_module" flag
649+
*/
650+
function getSqliteOverrides({
651+
compatibilityFlags,
652+
}: {
653+
compatibilityDate: string;
654+
compatibilityFlags: string[];
655+
}): { nativeModules: string[]; hybridModules: string[] } {
656+
const disabledByFlag = compatibilityFlags.includes(
657+
"disable_nodejs_sqlite_module"
658+
);
659+
660+
const enabledByFlag =
661+
compatibilityFlags.includes("enable_nodejs_sqlite_module") &&
662+
compatibilityFlags.includes("experimental");
663+
664+
const enabled = enabledByFlag && !disabledByFlag;
665+
666+
// When enabled, use the native `sqlite` module from workerd
667+
return enabled
668+
? {
669+
nativeModules: ["sqlite"],
670+
hybridModules: [],
671+
}
672+
: {
673+
nativeModules: [],
674+
hybridModules: [],
675+
};
676+
}

packages/wrangler/e2e/unenv-preset/preset.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,28 @@ const localTestConfigs: TestConfig[] = [
429429
},
430430
},
431431
],
432+
// node:sqlite (experimental, no default enable date)
433+
[
434+
// TODO: add test for disabled by date (no date defined yet)
435+
// TODO: add test for enabled by date (no date defined yet)
436+
{
437+
name: "sqlite enabled by flag",
438+
compatibilityDate: "2024-09-23",
439+
compatibilityFlags: ["enable_nodejs_sqlite_module", "experimental"],
440+
expectRuntimeFlags: {
441+
enable_nodejs_sqlite_module: true,
442+
},
443+
},
444+
// TODO: update the date past the default enable date (when defined)
445+
{
446+
name: "sqlite disabled by flag",
447+
compatibilityDate: "2024-09-23",
448+
compatibilityFlags: ["disable_nodejs_sqlite_module", "experimental"],
449+
expectRuntimeFlags: {
450+
enable_nodejs_sqlite_module: false,
451+
},
452+
},
453+
],
432454
].flat() as TestConfig[];
433455

434456
describe.each(localTestConfigs)(

packages/wrangler/e2e/unenv-preset/worker/index.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,55 @@ export const WorkerdTests: Record<string, () => void> = {
783783
assertTypeOf(inspectorPromises.default, "Network", "object");
784784
}
785785
},
786+
787+
async testSqlite() {
788+
let sqlite;
789+
try {
790+
// This source file is imported by the Node runtime (to retrieve the list of tests).
791+
// As `node:sqlite` has only be added in Node 22.5.0, we need to try/catch to not error with older versions.
792+
// Note: This test is not meant to be executed by the Node runtime,
793+
// but only by workerd where `node:sqlite` is available.
794+
// @ts-expect-error TS2307 - node:sqlite is only available in Node 22.5.0+
795+
sqlite = await import("node:sqlite");
796+
} catch {
797+
throw new Error(
798+
"sqlite is not available. This should never happen in workerd."
799+
);
800+
}
801+
802+
// Common exports (both unenv stub and native workerd)
803+
assertTypeOfProperties(sqlite, {
804+
DatabaseSync: "function",
805+
StatementSync: "function",
806+
constants: "object",
807+
default: "object",
808+
});
809+
assertTypeOfProperties(sqlite.default, {
810+
DatabaseSync: "function",
811+
StatementSync: "function",
812+
constants: "object",
813+
});
814+
815+
if (getRuntimeFlagValue("enable_nodejs_sqlite_module")) {
816+
// Native workerd exports `backup` function and non-empty constants
817+
assertTypeOf(sqlite, "backup", "function");
818+
assertTypeOf(sqlite.default, "backup", "function");
819+
assert.strictEqual(
820+
"SQLITE_CHANGESET_OMIT" in sqlite.constants,
821+
true,
822+
"constants should contain SQLITE_CHANGESET_OMIT"
823+
);
824+
} else {
825+
// unenv stub: no backup function and empty constants
826+
assertTypeOf(sqlite, "backup", "undefined");
827+
assertTypeOf(sqlite.default, "backup", "undefined");
828+
assert.deepStrictEqual(
829+
Object.keys(sqlite.constants),
830+
[],
831+
"constants should be empty in unenv stub"
832+
);
833+
}
834+
},
786835
};
787836

788837
/**

0 commit comments

Comments
 (0)