1+ import * as path from 'node:path' ;
12import BetterSQLite3Database , { Database } from '@powersync/better-sqlite3' ;
23import * as Comlink from 'comlink' ;
34import { parentPort , threadId } from 'node:worker_threads' ;
@@ -92,10 +93,16 @@ class BlockingAsyncDatabase implements AsyncDatabase {
9293}
9394
9495class BetterSqliteWorker implements AsyncDatabaseOpener {
96+ options : PowerSyncWorkerOptions ;
97+
98+ constructor ( options : PowerSyncWorkerOptions ) {
99+ this . options = options ;
100+ }
101+
95102 async open ( path : string , isWriter : boolean ) : Promise < AsyncDatabase > {
96103 const baseDB = new BetterSQLite3Database ( path ) ;
97104 baseDB . pragma ( 'journal_mode = WAL' ) ;
98- loadExtension ( baseDB ) ;
105+ baseDB . loadExtension ( this . options . extensionPath ( ) , 'sqlite3_powersync_init' ) ;
99106 if ( ! isWriter ) {
100107 baseDB . pragma ( 'query_only = true' ) ;
101108 }
@@ -107,21 +114,43 @@ class BetterSqliteWorker implements AsyncDatabaseOpener {
107114 }
108115}
109116
110- const loadExtension = ( db : Database ) => {
111- const platform = OS . platform ( ) ;
112- let extensionPath : string ;
113- if ( platform === 'win32' ) {
114- extensionPath = 'powersync.dll' ;
115- } else if ( platform === 'linux' ) {
116- extensionPath = 'libpowersync.so' ;
117- } else if ( platform === 'darwin' ) {
118- extensionPath = 'libpowersync.dylib' ;
119- } else {
120- throw 'Unknown platform, PowerSync for Node.js currently supports Windows, Linux and macOS.' ;
121- }
117+ export interface PowerSyncWorkerOptions {
118+ /**
119+ * A function responsible for finding the powersync DLL/so/dylib file.
120+ *
121+ * @returns The absolute path of the PowerSync SQLite core extensions library.
122+ */
123+ extensionPath : ( ) => string ;
124+ }
122125
123- const resolved = url . fileURLToPath ( new URL ( `../${ extensionPath } ` , import . meta. url ) ) ;
124- db . loadExtension ( resolved , 'sqlite3_powersync_init' ) ;
125- } ;
126+ export function startPowerSyncWorker ( options ?: Partial < PowerSyncWorkerOptions > ) {
127+ const resolvedOptions : PowerSyncWorkerOptions = {
128+ extensionPath ( ) {
129+ const isCommonJsModule = import . meta. isBundlingToCommonJs ?? false ;
130+
131+ const platform = OS . platform ( ) ;
132+ let extensionPath : string ;
133+ if ( platform === 'win32' ) {
134+ extensionPath = 'powersync.dll' ;
135+ } else if ( platform === 'linux' ) {
136+ extensionPath = 'libpowersync.so' ;
137+ } else if ( platform === 'darwin' ) {
138+ extensionPath = 'libpowersync.dylib' ;
139+ } else {
140+ throw 'Unknown platform, PowerSync for Node.js currently supports Windows, Linux and macOS.' ;
141+ }
142+
143+ let resolved : string ;
144+ if ( isCommonJsModule ) {
145+ resolved = path . resolve ( __dirname , '../lib/' , extensionPath ) ;
146+ } else {
147+ resolved = url . fileURLToPath ( new URL ( `../${ extensionPath } ` , import . meta. url ) ) ;
148+ }
126149
127- Comlink . expose ( new BetterSqliteWorker ( ) , parentPort ! as Comlink . Endpoint ) ;
150+ return resolved ;
151+ } ,
152+ ...options ,
153+ } ;
154+
155+ Comlink . expose ( new BetterSqliteWorker ( resolvedOptions ) , parentPort ! as Comlink . Endpoint ) ;
156+ }
0 commit comments