Skip to content

Commit e2ab7c3

Browse files
separate static and dynamic builds
1 parent 0b9e625 commit e2ab7c3

22 files changed

+246
-110
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
# PowerSync Rust Core
1313
libpowersync*.wasm
14+
powersync-libs
1415

1516
/cache
1617
/debug

Makefile

Lines changed: 94 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ EXTENSION_FUNCTIONS = extension-functions.c
66
EXTENSION_FUNCTIONS_URL = https://www.sqlite.org/contrib/download/extension-functions.c?get=25
77
EXTENSION_FUNCTIONS_SHA3 = ee39ddf5eaa21e1d0ebcbceeab42822dd0c4f82d8039ce173fd4814807faabfa
88

9-
10-
11-
# source files
9+
# WA-SQLite source files
1210
CFILES = \
1311
sqlite3.c \
1412
extension-functions.c \
@@ -19,6 +17,9 @@ CFILES = \
1917
libvfs.c \
2018
$(CFILES_EXTRA)
2119

20+
POWERSYNC_CFILES = \
21+
setup_powersync.c
22+
2223
JSFILES = \
2324
src/libauthorizer.js \
2425
src/libfunction.js \
@@ -28,8 +29,14 @@ JSFILES = \
2829
vpath %.c src
2930
vpath %.c deps
3031
vpath %.c deps/$(SQLITE_VERSION)
32+
vpath %.c powersync-static
3133

34+
POWERSYNC_EXPORTED_FUNCTIONS = powersync-static/powersync_exported_functions.json
3235
EXPORTED_FUNCTIONS = src/exported_functions.json
36+
37+
# EMCC does not support multiple exports files. Need to combine them temporarily
38+
COMBINED_EXPORTED_FUNCTIONS = tmp/combined_exports.json
39+
3340
EXPORTED_RUNTIME_METHODS = src/extra_exported_runtime_methods.json
3441
ASYNCIFY_IMPORTS = src/asyncify_imports.json
3542
ASYNCIFY_EXPORTS = src/asyncify_exports.json
@@ -38,6 +45,10 @@ ASYNCIFY_EXPORTS = src/asyncify_exports.json
3845
OBJ_FILES_DEBUG = $(patsubst %.c,tmp/obj/debug/%.o,$(CFILES))
3946
OBJ_FILES_DIST = $(patsubst %.c,tmp/obj/dist/%.o,$(CFILES))
4047

48+
POWERSYNC_OBJ_FILES_DEBUG = $(patsubst %.c,tmp/powersync-obj/debug/%.o,$(POWERSYNC_CFILES))
49+
POWERSYNC_OBJ_FILES_DIST = $(patsubst %.c,tmp/powersync-obj/dist/%.o,$(POWERSYNC_CFILES))
50+
POWERSYNC_STATIC_FILES = powersync-libs/libpowersync-wasm.a
51+
4152
# build options
4253
EMCC ?= emcc
4354

@@ -82,6 +93,10 @@ EMFLAGS_INTERFACES = \
8293
-s EXPORTED_FUNCTIONS=@$(EXPORTED_FUNCTIONS) \
8394
-s EXPORTED_RUNTIME_METHODS=@$(EXPORTED_RUNTIME_METHODS)
8495

96+
COMBINED_EMFLAGS_INTERFACES = \
97+
-s EXPORTED_FUNCTIONS=@$(COMBINED_EXPORTED_FUNCTIONS) \
98+
-s EXPORTED_RUNTIME_METHODS=@$(EXPORTED_RUNTIME_METHODS)
99+
85100
EMFLAGS_LIBRARIES = \
86101
--js-library src/libadapters.js \
87102
--js-library src/libtableupdates.js \
@@ -150,12 +165,19 @@ cache/$(EXTENSION_FUNCTIONS):
150165
clean-deps:
151166
rm -rf deps
152167

168+
# Combine WA-SQLite and PowerSync exported functions
169+
$(EXPORTED_FUNCTIONS): $(EXPORTED_FUNCTIONS) $(POWERSYNC_EXPORTED_FUNCTIONS)
170+
jq -s 'add' $(EXPORTED_FUNCTIONS) $(POWERSYNC_EXPORTED_FUNCTIONS) > $(COMBINED_EXPORTED_FUNCTIONS)
171+
153172
deps/$(SQLITE_VERSION)/sqlite3.h deps/$(SQLITE_VERSION)/sqlite3.c:
154173
mkdir -p cache/$(SQLITE_VERSION)
155174
curl -LsS $(SQLITE_TARBALL_URL) | tar -xzf - -C cache/$(SQLITE_VERSION)/ --strip-components=1
156175
mkdir -p deps/$(SQLITE_VERSION)
157176
(cd deps/$(SQLITE_VERSION); ../../cache/$(SQLITE_VERSION)/configure --enable-all && make sqlite3.c)
158177

178+
# Download static files from PowerSync Core repository
179+
$(POWERSYNC_STATIC_FILES):
180+
node ./scripts/download-core-build.js
159181

160182
ifeq ($(shell uname), Darwin)
161183
OPENSSL_CHECK_CMD := openssl dgst -sha3-256 -r cache/$(EXTENSION_FUNCTIONS) | sed -e 's/ .*//' > deps/sha3
@@ -187,6 +209,7 @@ deps/$(EXTENSION_FUNCTIONS): cache/$(EXTENSION_FUNCTIONS)
187209
rm -rf deps/sha3 $@
188210
sed -i '' "/#define COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE/d" cache/$(EXTENSION_FUNCTIONS)
189211
cp cache/$(EXTENSION_FUNCTIONS) $@
212+
190213
## tmp
191214
.PHONY: clean-tmp
192215
clean-tmp:
@@ -200,42 +223,70 @@ tmp/obj/dist/%.o: %.c
200223
mkdir -p tmp/obj/dist
201224
$(EMCC) $(CFLAGS_DIST) $(WASQLITE_DEFINES) $^ -c -o $@
202225

226+
# Build PowerSync specific C files
227+
tmp/powersync-obj/debug/%.o: %.c
228+
mkdir -p tmp/powersync-obj/debug
229+
$(EMCC) $(CFLAGS_DEBUG) $(WASQLITE_DEFINES) $^ -c -o $@
230+
231+
# Build PowerSync specific C files
232+
tmp/powersync-obj/dist/%.o: %.c
233+
mkdir -p tmp/powersync-obj/dist
234+
$(EMCC) $(CFLAGS_DIST) $(WASQLITE_DEFINES) $^ -c -o $@
235+
203236

204237
## debug
205238
.PHONY: clean-debug
206239
clean-debug:
207240
rm -rf debug
208241

209242
.PHONY: debug
210-
debug: debug/wa-sqlite.mjs debug/wa-sqlite-async.mjs debug/wa-sqlite-jspi.mjs debug/wa-sqlite-main.mjs debug/wa-sqlite-main-async.mjs
243+
debug: debug/wa-sqlite.mjs debug/wa-sqlite-async.mjs debug/wa-sqlite-jspi.mjs debug/wa-sqlite-dynamic-main.mjs debug/wa-sqlite-dynamic-main-async.mjs
211244

212-
# TODO link static
213-
debug/wa-sqlite.mjs: $(OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS)
245+
# Statically links PowerSync Core
246+
debug/wa-sqlite.mjs: $(OBJ_FILES_DEBUG) $(POWERSYNC_OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(POWERSYNC_STATIC_FILES)
214247
mkdir -p debug
215248
$(EMCC) $(EMFLAGS_DEBUG) \
216-
$(EMFLAGS_INTERFACES) \
249+
$(COMBINED_EMFLAGS_INTERFACES) \
217250
$(EMFLAGS_LIBRARIES) \
218-
$(OBJ_FILES_DEBUG) -o $@
251+
$(POWERSYNC_STATIC_FILES) \
252+
$(OBJ_FILES_DEBUG) \
253+
$(POWERSYNC_OBJ_FILES_DEBUG) -o $@
219254

220-
# TODO link static
221-
debug/wa-sqlite-async.mjs: $(OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS)
255+
# Statically links PowerSync Core
256+
debug/wa-sqlite-async.mjs: $(OBJ_FILES_DEBUG) $(POWERSYNC_OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS) $(POWERSYNC_STATIC_FILES)
222257
mkdir -p debug
223258
$(EMCC) $(EMFLAGS_DEBUG) \
224-
$(EMFLAGS_INTERFACES) \
259+
$(COMBINED_EMFLAGS_INTERFACES) \
225260
$(EMFLAGS_LIBRARIES) \
226261
$(EMFLAGS_ASYNCIFY_DEBUG) \
262+
$(POWERSYNC_STATIC_FILES) \
263+
$(POWERSYNC_OBJ_FILES_DEBUG) \
264+
$(OBJ_FILES_DEBUG) -o $@
265+
266+
# Statically links PowerSync Core
267+
debug/wa-sqlite-jspi.mjs: $(OBJ_FILES_DEBUG) $(POWERSYNC_OBJ_FILES_DEBUG) $(JSFILES) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS) $(POWERSYNC_STATIC_FILES)
268+
mkdir -p debug
269+
$(EMCC) $(EMFLAGS_DEBUG) $(EMFLAGS_DYNAMIC) \
270+
$(COMBINED_EMFLAGS_INTERFACES) \
271+
$(EMFLAGS_LIBRARIES) \
272+
$(EMFLAGS_JSPI) \
273+
$(POWERSYNC_STATIC_FILES) \
274+
$(POWERSYNC_OBJ_FILES_DEBUG) \
227275
$(OBJ_FILES_DEBUG) -o $@
228276

229-
# Main module distributable
230-
debug/wa-sqlite-main.mjs: $(OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS)
277+
278+
# Dynamic main module
279+
# Exported functions are omitted here since everything is currently exported
280+
debug/wa-sqlite-dynamic-main.mjs: $(OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS)
231281
mkdir -p debug
232282
$(EMCC) $(EMFLAGS_DEBUG) $(EMFLAGS_DYNAMIC) \
233283
$(EMFLAGS_INTERFACES) \
234284
$(EMFLAGS_LIBRARIES) \
235285
$(OBJ_FILES_DEBUG) -o $@
236286

237-
# Main module distributable
238-
debug/wa-sqlite-main-async.mjs: $(OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS)
287+
# Dynamic main module
288+
# Exported functions are omitted here since everything is currently exported
289+
debug/wa-sqlite-dynamic-main-async.mjs: $(OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS)
239290
mkdir -p debug
240291
$(EMCC) $(EMFLAGS_DEBUG) $(EMFLAGS_DYNAMIC) \
241292
$(EMFLAGS_INTERFACES) \
@@ -264,62 +315,65 @@ debug/wa-sqlite-main-async.mjs: $(OBJ_FILES_DEBUG) $(EXPORTED_FUNCTIONS) $(EXPO
264315
# $(RS_WASM_TGT_DIR)/debug/deps/*.bc \
265316
# $(OBJ_FILES_DEBUG_FTS) *.o -o $@
266317

267-
# TODO link static
268-
debug/wa-sqlite-jspi.mjs: $(OBJ_FILES_DEBUG) $(JSFILES) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS)
269-
mkdir -p debug
270-
$(EMCC) $(EMFLAGS_DEBUG) $(EMFLAGS_DYNAMIC) \
271-
$(EMFLAGS_INTERFACES) \
272-
$(EMFLAGS_LIBRARIES) \
273-
$(EMFLAGS_JSPI) \
274-
$(OBJ_FILES_DEBUG) -o $@
275318

276319
## dist
277320
.PHONY: clean-dist
278321
clean-dist:
279322
rm -rf dist
280323

281324
.PHONY: dist
282-
dist: dist/wa-sqlite.mjs dist/wa-sqlite-async.mjs dist/wa-sqlite-jspi.mjs dist/wa-sqlite-main.mjs dist/wa-sqlite-async-main.mjs
325+
dist: dist/wa-sqlite.mjs dist/wa-sqlite-async.mjs dist/wa-sqlite-jspi.mjs dist/wa-sqlite-dynamic-main.mjs dist/wa-sqlite-async-dynamic-main.mjs
283326

284-
# TODO link static
285-
dist/wa-sqlite.mjs: $(OBJ_FILES_DIST) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS)
327+
# Statically links PowerSync Core
328+
dist/wa-sqlite.mjs: $(OBJ_FILES_DIST) $(POWERSYNC_OBJ_FILES_DIST) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(POWERSYNC_STATIC_FILES)
286329
mkdir -p dist
287330
$(EMCC) $(EMFLAGS_DIST) \
288-
$(EMFLAGS_INTERFACES) \
331+
$(COMBINED_EMFLAGS_INTERFACES) \
289332
$(EMFLAGS_LIBRARIES) \
333+
$(POWERSYNC_STATIC_FILES) \
334+
$(POWERSYNC_OBJ_FILES_DIST) \
290335
$(OBJ_FILES_DIST) -o $@
291336

292-
# TODO link static
293-
dist/wa-sqlite-async.mjs: $(OBJ_FILES_DIST) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS)
337+
# Statically links PowerSync Core
338+
dist/wa-sqlite-async.mjs: $(OBJ_FILES_DIST) $(POWERSYNC_OBJ_FILES_DIST) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS) $(POWERSYNC_STATIC_FILES)
294339
mkdir -p dist
295340
$(EMCC) $(EMFLAGS_DIST) \
296-
$(EMFLAGS_INTERFACES) \
341+
$(COMBINED_EMFLAGS_INTERFACES) \
297342
$(EMFLAGS_LIBRARIES) \
298343
$(EMFLAGS_ASYNCIFY_DIST) \
344+
$(POWERSYNC_STATIC_FILES) \
345+
$(POWERSYNC_OBJ_FILES_DIST) \
346+
$(OBJ_FILES_DIST) -o $@
347+
348+
# Statically links PowerSync Core
349+
dist/wa-sqlite-jspi.mjs: $(OBJ_FILES_DIST) $(POWERSYNC_OBJ_FILES_DIST) $(JSFILES) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS) $(POWERSYNC_STATIC_FILES)
350+
mkdir -p dist
351+
$(EMCC) $(EMFLAGS_DIST) \
352+
$(COMBINED_EMFLAGS_INTERFACES) \
353+
$(EMFLAGS_LIBRARIES) \
354+
$(EMFLAGS_JSPI) \
355+
$(POWERSYNC_STATIC_FILES) \
356+
$(POWERSYNC_OBJ_FILES_DIST) \
299357
$(OBJ_FILES_DIST) -o $@
300358

301-
dist/wa-sqlite-main.mjs: $(OBJ_FILES_DIST) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS)
359+
# Dynamic main module
360+
# Exported functions are omitted here since everything is currently exported
361+
dist/wa-sqlite-dynamic-main.mjs: $(OBJ_FILES_DIST) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS)
302362
mkdir -p dist
303363
$(EMCC) $(EMFLAGS_DIST) $(EMFLAGS_DYNAMIC) \
304364
$(EMFLAGS_INTERFACES) \
305365
$(EMFLAGS_LIBRARIES) \
306366
$(OBJ_FILES_DIST) -o $@
307367

308-
dist/wa-sqlite-async-main.mjs: $(OBJ_FILES_DIST) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS)
368+
# Dynamic main module
369+
# Exported functions are omitted here since everything is currently exported
370+
dist/wa-sqlite-async-dynamic-main.mjs: $(OBJ_FILES_DIST) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS)
309371
mkdir -p dist
310372
$(EMCC) $(EMFLAGS_DIST) $(EMFLAGS_DYNAMIC) \
311373
$(EMFLAGS_INTERFACES) \
312374
$(EMFLAGS_LIBRARIES) \
313375
$(EMFLAGS_ASYNCIFY_DIST) \
314376
$(OBJ_FILES_DIST) -o $@
315377

316-
# TODO link static
317-
dist/wa-sqlite-jspi.mjs: $(OBJ_FILES_DIST) $(JSFILES) $(EXPORTED_FUNCTIONS) $(EXPORTED_RUNTIME_METHODS) $(ASYNCIFY_IMPORTS)
318-
mkdir -p dist
319-
$(EMCC) $(EMFLAGS_DIST) \
320-
$(EMFLAGS_INTERFACES) \
321-
$(EMFLAGS_LIBRARIES) \
322-
$(EMFLAGS_JSPI) \
323-
$(OBJ_FILES_DIST) -o $@
324378

325379
FORCE:

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,13 @@ make -B
5151

5252
### PowerSync Core
5353

54-
To update the PowerSync SQLite core see the [script](./scripts/powersync-core.js). Edit the `CORE_VERSION` and run the script with
54+
The PowerSync Rust SQLite extension is used both statically and dynamically in this package. The static core binary is downloaded in the `Makefile` during compilation. The dynamic WASM files are not commited to this repository's `dist` folder, instead the WASM files are downloaded as a `postinstall` script.
5555

56-
```bash
57-
node scripts/powersync-core.js
58-
```
56+
Update the `powersync-version` file in order to update the PowerSync core version.
57+
58+
### Usage with PowerSync
59+
60+
This fork of WA-SQLite can be used with PowerSync either statically or dynamically. See the [demo worker](./demo/demo-worker.js) for usage.
5961

6062
## API
6163
Javascript wrappers for core SQLITE C API functions (and some others) are provided. Some convenience functions are also provided to reduce boilerplate. Here is sample code to load the library and call the API:

demo/demo-worker.js

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ const BUILDS = new Map([
99
// ['default', '../debug/wa-sqlite.mjs'],
1010
// ['asyncify', '../debug/wa-sqlite-async.mjs'],
1111
// ['jspi', '../debug/wa-sqlite-jspi.mjs'],
12+
// Dynamic builds
13+
['default-dynamic', '../dist/wa-sqlite-dynamic-main.mjs'],
14+
['asyncify-dynamic', '../dist/wa-sqlite-async-dynamic-main.mjs'],
1215
]);
1316

1417
const EXT_WASM = new Map([
15-
['default', 'libpowersync.wasm'],
16-
['asyncify', 'libpowersync-async.wasm'],
17-
['jspi', 'libpowersync-jspi.wasm'],
18+
['default-dynamic', 'libpowersync.wasm'],
19+
['asyncify-dynamic', 'libpowersync-async.wasm'],
1820
]);
1921

2022
/**
@@ -83,7 +85,6 @@ maybeReset().then(async () => {
8385
const buildName = searchParams.get('build') || BUILDS.keys().next().value;
8486
const configName = searchParams.get('config') || VFS_CONFIGS.keys().next().value;
8587
const config = VFS_CONFIGS.get(configName);
86-
const extWasm = EXT_WASM.get(buildName);
8788

8889
const dbName = searchParams.get('dbName') ?? 'hello';
8990
const vfsName = searchParams.get('vfsName') ?? config.vfsName ?? 'demo';
@@ -102,17 +103,24 @@ maybeReset().then(async () => {
102103

103104
const sqlite3 = SQLite.Factory(module);
104105

105-
// Load the extension library into this scope
106-
let extScope = {};
107-
await module.loadDynamicLibrary(
108-
extWasm,
109-
{ loadAsync: true },
110-
extScope
111-
);
112106

113-
// This calls sqlite3_auto_extension(sqlite3_powersync_init).
114-
// For generic extensions, we'd need to call sqlite3_auto_extension directly.
115-
extScope.powersync_init_static();
107+
if (buildName.endsWith('-dynamic')) {
108+
const extWasm = EXT_WASM.get(buildName);
109+
// Load the extension library into this scope
110+
let extScope = {};
111+
await module.loadDynamicLibrary(
112+
extWasm,
113+
{ loadAsync: true },
114+
extScope
115+
);
116+
117+
// This calls sqlite3_auto_extension(sqlite3_powersync_init).
118+
// For generic extensions, we'd need to call sqlite3_auto_extension directly.
119+
extScope.powersync_init_static();
120+
} else {
121+
// This is not part of the Sqlite3 API
122+
module.ccall('setup_powersync', 'int', []);
123+
}
116124

117125
if (config.vfsModule) {
118126
// Create the VFS and register it as the default file system.

dist/wa-sqlite-async-dynamic-main.mjs

Lines changed: 16 additions & 0 deletions
Large diffs are not rendered by default.

dist/wa-sqlite-async-main.mjs

Lines changed: 0 additions & 16 deletions
This file was deleted.

dist/wa-sqlite-async.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/wa-sqlite-async.wasm

268 KB
Binary file not shown.

dist/wa-sqlite-dynamic-main.mjs

Lines changed: 16 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)