Skip to content

Commit

Permalink
Merge pull request #34 from gregnr/feat/wasm
Browse files Browse the repository at this point in the history
Adds browser (WASM) support
  • Loading branch information
pyramation authored Feb 21, 2024
2 parents f351a42 + 0f42732 commit 1c8617a
Show file tree
Hide file tree
Showing 12 changed files with 2,384 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ libs/
npm-debug.log
libpg_query/**/*.a
libpg_query/**/*.h
wasm/libpg-query.js
*.wasm
.cache
91 changes: 91 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
WASM_OUT_DIR := wasm
WASM_OUT_NAME := libpg-query
WASM_MODULE_NAME := PgQueryModule
LIBPG_QUERY_REPO := https://github.com/pganalyze/libpg_query.git
LIBPG_QUERY_TAG := 15-4.2.4
CACHE_DIR := .cache

OS ?= $(shell uname -s)
ARCH ?= $(shell uname -m)

ifdef EMSCRIPTEN
PLATFORM := emscripten
else ifeq ($(OS),Darwin)
PLATFORM := darwin
else ifeq ($(OS),Linux)
PLATFORM := linux
else
$(error Unsupported platform: $(OS))
endif

ifdef EMSCRIPTEN
ARCH := wasm
endif

PLATFORM_ARCH := $(PLATFORM)-$(ARCH)
SRC_FILES := $(wildcard src/*.cc)
LIBPG_QUERY_DIR := $(CACHE_DIR)/$(PLATFORM_ARCH)/libpg_query/$(LIBPG_QUERY_TAG)
LIBPG_QUERY_ARCHIVE := $(LIBPG_QUERY_DIR)/libpg_query.a
LIBPG_QUERY_HEADER := $(LIBPG_QUERY_DIR)/pg_query.h
CXXFLAGS := -O3

ifdef EMSCRIPTEN
OUT_FILES := $(foreach EXT,.js .wasm,$(WASM_OUT_DIR)/$(WASM_OUT_NAME)$(EXT))
else
OUT_FILES := build/Release/queryparser.node $(wildcard build/*)
endif

# Clone libpg_query source (lives in CACHE_DIR)
$(LIBPG_QUERY_DIR):
mkdir -p $(CACHE_DIR)
git clone -b $(LIBPG_QUERY_TAG) --single-branch $(LIBPG_QUERY_REPO) $(LIBPG_QUERY_DIR)

$(LIBPG_QUERY_HEADER): $(LIBPG_QUERY_DIR)

# Build libpg_query
$(LIBPG_QUERY_ARCHIVE): $(LIBPG_QUERY_DIR)
cd $(LIBPG_QUERY_DIR); $(MAKE) build

# Build libpg-query-node (based on platform)
$(OUT_FILES): $(LIBPG_QUERY_ARCHIVE) $(LIBPG_QUERY_HEADER) $(SRC_FILES)
ifdef EMSCRIPTEN
@ $(CXX) \
$(CXXFLAGS) \
-DNAPI_HAS_THREADS \
-I$(LIBPG_QUERY_DIR) \
-I./node_modules/emnapi/include \
-I./node_modules/node-addon-api \
-L./node_modules/emnapi/lib/wasm32-emscripten \
-L$(LIBPG_QUERY_DIR) \
--js-library=./node_modules/emnapi/dist/library_napi.js \
-sEXPORTED_FUNCTIONS="['_malloc','_free','_napi_register_wasm_v1','_node_api_module_get_api_version_v1']" \
-sEXPORT_NAME="$(WASM_MODULE_NAME)" \
-sENVIRONMENT="web" \
-sMODULARIZE=1 \
-sEXPORT_ES6=1 \
-fexceptions \
-lpg_query \
-lemnapi-basic \
-o $@ \
$(SRC_FILES)
else
# if not wasm, defer to node-gyp
yarn rebuild
endif

# Commands
build: $(OUT_FILES)

build-cache: $(LIBPG_QUERY_ARCHIVE) $(LIBPG_QUERY_HEADER)

rebuild: clean build

rebuild-cache: clean-cache build-cache

clean:
-@ rm -r $(OUT_FILES) > /dev/null 2>&1

clean-cache:
-@ rm -rf $(LIBPG_QUERY_DIR)

.PHONY: build build-cache rebuild rebuild-cache clean clean-cache
8 changes: 4 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const PgQuery = require('./build/Release/queryparser');
const PgQuery = require('./build/Release/queryparser.node');

module.exports = {
parseQuery(query) {
Expand Down Expand Up @@ -26,14 +26,14 @@ module.exports = {
},

fingerprint(query) {
return new Promise((resolve, reject) =>{
return new Promise((resolve, reject) => {
PgQuery.fingerprintAsync(query, (err, result) => {
err ? reject(err) : resolve(result);
})
});
});
},

fingerprintSync(query) {
return PgQuery.fingerprintSync(query);
}
},
};
32 changes: 30 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,36 @@
"publishConfig": {
"access": "public"
},
"files": [
"binding.gyp",
"index.js",
"index.d.ts",
"libpg_query/*",
"script/*",
"src/*",
"wasm/*"
],
"exports": {
".": {
"types": "./index.d.ts",
"browser": "./wasm/index.js",
"node": "./index.js",
"default": "./index.js"
},
"./wasm": {
"types": "./index.d.ts",
"default": "./wasm/index.js"
}
},
"scripts": {
"configure": "node-pre-gyp configure",
"install": "node-pre-gyp install --fallback-to-build",
"rebuild": "node-pre-gyp configure rebuild",
"make:wasm": "docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emmake make",
"build:wasm": "yarn make:wasm build",
"rebuild:wasm": "yarn make:wasm rebuild",
"clean:wasm": "yarn make:wasm clean",
"clean-cache:wasm": "yarn make:wasm clean-cache",
"test": "mocha --timeout 5000",
"binary:build": "node-pre-gyp rebuild package",
"binary:publish": "AWS_PROFILE=supabase-dev node-pre-gyp publish"
Expand All @@ -24,12 +50,14 @@
},
"devDependencies": {
"chai": "^3.5.0",
"emnapi": "^0.43.1",
"lodash": "^4.17.15",
"mocha": "^5.2.0"
},
"dependencies": {
"@emnapi/runtime": "^0.43.1",
"@mapbox/node-pre-gyp": "^1.0.8",
"node-addon-api": "^1.6.3",
"node-addon-api": "^7.0.0",
"node-gyp": "^8.0.0"
},
"keywords": [
Expand All @@ -47,4 +75,4 @@
"host": "https://supabase-public-artifacts-bucket.s3.amazonaws.com",
"remote_path": "./libpg-query-node/"
}
}
}
1 change: 1 addition & 0 deletions test/webpack/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/*.js
14 changes: 14 additions & 0 deletions test/webpack/dist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title>libpg-query web</title>
</head>

<body>
<script src="main.js"></script>
<h2>Check the console for the parsed SQL.</h2>
</body>

</html>
14 changes: 14 additions & 0 deletions test/webpack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "webpack-test",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "webpack serve --open",
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
}
7 changes: 7 additions & 0 deletions test/webpack/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { parseQuery } from '../../../wasm';

const sql = 'select * from customers;';
const result = await parseQuery(sql);

console.log(sql);
console.log(result);
15 changes: 15 additions & 0 deletions test/webpack/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const path = require('path');

module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
devServer: {
static: './dist',
client: {
overlay: false,
},
},
};
Loading

0 comments on commit 1c8617a

Please sign in to comment.