Skip to content

Commit daebe8b

Browse files
committed
Bundle powersync loadable
1 parent 73ed674 commit daebe8b

File tree

9 files changed

+155
-137
lines changed

9 files changed

+155
-137
lines changed

demos/example-electron-node/forge.config.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import OS from 'node:os';
2+
import path from 'node:path';
13
import { createRequire } from 'node:module';
24

35
import type { ForgeConfig } from '@electron-forge/shared-types';
@@ -9,10 +11,12 @@ import { AutoUnpackNativesPlugin } from '@electron-forge/plugin-auto-unpack-nati
911
import { WebpackPlugin } from '@electron-forge/plugin-webpack';
1012
import type { Configuration, ModuleOptions } from 'webpack';
1113
import type IForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
14+
import type ICopyPlugin from 'copy-webpack-plugin';
1215

1316
const require = createRequire(import.meta.url);
1417

1518
const ForkTsCheckerWebpackPlugin: typeof IForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
19+
const CopyPlugin: typeof ICopyPlugin = require('copy-webpack-plugin');
1620

1721
const webpackPlugins = [
1822
new ForkTsCheckerWebpackPlugin({
@@ -52,6 +56,18 @@ const defaultWebpackRules: () => Required<ModuleOptions>['rules'] = () => {
5256
];
5357
};
5458

59+
const platform = OS.platform();
60+
let extensionPath: string;
61+
if (platform === 'win32') {
62+
extensionPath = 'powersync.dll';
63+
} else if (platform === 'linux') {
64+
extensionPath = 'libpowersync.so';
65+
} else if (platform === 'darwin') {
66+
extensionPath = 'libpowersync.dylib';
67+
} else {
68+
throw 'Unknown platform, PowerSync for Node.js currently supports Windows, Linux and macOS.';
69+
}
70+
5571
const mainConfig: Configuration = {
5672
/**
5773
* This is the main entry point for your application, it's the first file
@@ -62,7 +78,15 @@ const mainConfig: Configuration = {
6278
module: {
6379
rules: defaultWebpackRules(),
6480
},
65-
plugins: webpackPlugins,
81+
plugins: [
82+
...webpackPlugins,
83+
new CopyPlugin({
84+
patterns: [{
85+
from: path.resolve(require.resolve('@powersync/node/package.json'), `../lib/${extensionPath}`),
86+
to: extensionPath,
87+
}],
88+
}),
89+
],
6690
resolve: {
6791
extensions: ['.js', '.ts', '.jsx', '.tsx', '.css', '.json']
6892
}

demos/example-electron-node/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"@electron-forge/plugin-auto-unpack-natives": "^7.7.0",
2525
"@electron-forge/plugin-webpack": "^7.7.0",
2626
"@vercel/webpack-asset-relocator-loader": "1.7.3",
27+
"copy-webpack-plugin": "^13.0.0",
2728
"css-loader": "^6.11.0",
2829
"electron": "30.0.2",
2930
"electron-rebuild": "^3.2.9",

demos/example-electron-node/src/main/index.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@ import { default as Logger } from 'js-logger';
88
const logger = Logger.get('PowerSyncDemo');
99
Logger.useDefaults({ defaultLevel: logger.WARN });
1010

11+
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
12+
if (require('electron-squirrel-startup')) {
13+
app.quit();
14+
}
15+
1116
const database = new PowerSyncDatabase({
1217
schema: AppSchema,
1318
database: {
1419
dbFilename: 'test.db',
1520
openWorker(_, options) {
1621
return new Worker(new URL('./worker.ts', import.meta.url), options);
17-
},
22+
}
1823
},
1924
logger
2025
});
@@ -25,11 +30,6 @@ const database = new PowerSyncDatabase({
2530
declare const MAIN_WINDOW_WEBPACK_ENTRY: string;
2631
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string;
2732

28-
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
29-
if (require('electron-squirrel-startup')) {
30-
app.quit();
31-
}
32-
3333
const createWindow = (): void => {
3434
// Create the browser window.
3535
const mainWindow = new BrowserWindow({
@@ -54,6 +54,9 @@ app.whenReady().then(() => {
5454
ipcMain.handle('get', async (_, sql: string, args: any[]) => {
5555
return await database.get(sql, args);
5656
});
57+
ipcMain.handle('getAll', async (_, sql: string, args: any[]) => {
58+
return await database.getAll(sql, args);
59+
});
5760
createWindow();
5861
});
5962

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
import * as path from 'node:path';
2+
import OS from 'node:os';
3+
14
import { startPowerSyncWorker } from '@powersync/node/worker.js';
25

3-
startPowerSyncWorker();
6+
function resolvePowerSyncCoreExtension() {
7+
const platform = OS.platform();
8+
let extensionPath: string;
9+
if (platform === 'win32') {
10+
extensionPath = 'powersync.dll';
11+
} else if (platform === 'linux') {
12+
extensionPath = 'libpowersync.so';
13+
} else if (platform === 'darwin') {
14+
extensionPath = 'libpowersync.dylib';
15+
} else {
16+
throw 'Unknown platform, PowerSync for Node.js currently supports Windows, Linux and macOS.';
17+
}
18+
19+
// This example uses copy-webpack-plugin to copy the prebuilt library over. This ensures that it is
20+
// available in packaged release builds.
21+
return path.resolve(__dirname, extensionPath);
22+
}
23+
24+
startPowerSyncWorker({ extensionPath: resolvePowerSyncCoreExtension });

demos/example-electron-node/src/render/index.html

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22
<html>
33
<head>
44
<meta charset="UTF-8" />
5-
<title>Hello World!</title>
5+
<title>PowerSync Node demo!</title>
66
</head>
77
<body>
8-
<h1>Hello World!</h1>
9-
<p>Welcome to your Electron application.</p>
8+
<h1>PowerSync demo</h1>
9+
<p>
10+
This electron app has a PowerSync database running in its main process.
11+
This database is exposed to web content through an IPC channel. To try it out,
12+
enter <code>await powersync.get('SELECT powersync_rs_version()');</code>
13+
in the DevTools console.
14+
</p>
1015
</body>
1116
</html>
Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1 @@
1-
/**
2-
* This file will automatically be loaded by webpack and run in the "renderer" context.
3-
* To learn more about the differences between the "main" and the "renderer" context in
4-
* Electron, visit:
5-
*
6-
* https://electronjs.org/docs/latest/tutorial/process-model
7-
*
8-
* By default, Node.js integration in this file is disabled. When enabling Node.js integration
9-
* in a renderer process, please be aware of potential security implications. You can read
10-
* more about security risks here:
11-
*
12-
* https://electronjs.org/docs/tutorial/security
13-
*
14-
* To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration`
15-
* flag:
16-
*
17-
* ```
18-
* // Create the browser window.
19-
* mainWindow = new BrowserWindow({
20-
* width: 800,
21-
* height: 600,
22-
* webPreferences: {
23-
* nodeIntegration: true
24-
* }
25-
* });
26-
* ```
27-
*/
28-
291
console.log('👋 This message is being logged by "renderer.js", included via webpack');
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { contextBridge, ipcRenderer } from 'electron';
22

33
contextBridge.exposeInMainWorld('powersync', {
4-
get: (sql: string, variables: any[]) => ipcRenderer.invoke('get', sql, variables),
4+
get: (sql: string, variables: any[]) => ipcRenderer.invoke('get', sql, variables)
55
});

packages/node/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"import": "./lib/worker.js",
3131
"require": "./dist/worker.cjs",
3232
"types": "./lib/worker.d.ts"
33-
}
33+
},
34+
"./package.json": "./package.json"
3435
},
3536
"repository": {
3637
"type": "git",

0 commit comments

Comments
 (0)