From 0aba13dab4fb9c5f53cfc391c4a773b5dd498d08 Mon Sep 17 00:00:00 2001
From: James Long <longster@gmail.com>
Date: Tue, 20 Jul 2021 22:38:17 -0400
Subject: [PATCH 1/6] Implement changes required for IndexedDB-backed
 filesystem

---
 Makefile                          | 17 +++++---
 src/api.js                        | 64 ++++++++++++++++++++++++++-----
 src/exported_functions.json       |  6 ++-
 src/exported_runtime_methods.json |  4 +-
 src/fs-externs.js                 | 48 +++++++++++++++++++++++
 src/vfs.c                         | 49 +++++++++++++++++++++++
 6 files changed, 169 insertions(+), 19 deletions(-)
 create mode 100644 src/fs-externs.js
 create mode 100644 src/vfs.c

diff --git a/Makefile b/Makefile
index 45306539..0d229a5d 100644
--- a/Makefile
+++ b/Makefile
@@ -59,7 +59,7 @@ EMFLAGS_DEBUG = \
 	-s ASSERTIONS=2 \
 	-O1
 
-BITCODE_FILES = out/sqlite3.o out/extension-functions.o
+BITCODE_FILES = out/sqlite3.o out/extension-functions.o out/vfs.bc
 
 OUTPUT_WRAPPER_FILES = src/shell-pre.js src/shell-post.js
 
@@ -76,13 +76,13 @@ all: optimized debug worker
 debug: dist/sql-asm-debug.js dist/sql-wasm-debug.js
 
 dist/sql-asm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	$(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
 
 dist/sql-wasm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	$(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
@@ -91,19 +91,19 @@ dist/sql-wasm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FI
 optimized: dist/sql-asm.js dist/sql-wasm.js dist/sql-asm-memory-growth.js
 
 dist/sql-asm.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	$(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
 
 dist/sql-wasm.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	$(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
 
 dist/sql-asm-memory-growth.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	$(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM_MEMORY_GROWTH) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM_MEMORY_GROWTH) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
@@ -153,6 +153,11 @@ out/extension-functions.o: sqlite-src/$(SQLITE_AMALGAMATION)
 	# Generate llvm bitcode
 	$(EMCC) $(SQLITE_COMPILATION_FLAGS) -c sqlite-src/$(SQLITE_AMALGAMATION)/extension-functions.c -o $@
 
+out/vfs.bc: src/vfs.c sqlite-src/$(SQLITE_AMALGAMATION)
+	mkdir -p out
+	# Generate llvm bitcode
+	$(EMCC) $(CFLAGS) -s LINKABLE=1 -I sqlite-src/$(SQLITE_AMALGAMATION) -c src/vfs.c -o $@
+
 # TODO: This target appears to be unused. If we re-instatate it, we'll need to add more files inside of the JS folder
 # module.tar.gz: test package.json AUTHORS README.md dist/sql-asm.js
 # 	tar --create --gzip $^ > $@
diff --git a/src/api.js b/src/api.js
index e1d75dfb..ea0b873c 100644
--- a/src/api.js
+++ b/src/api.js
@@ -829,16 +829,22 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() {
     * @memberof module:SqlJs
     * Open a new database either by creating a new one or opening an existing
     * one stored in the byte array passed in first argument
-    * @param {Array<number>} data An array of bytes representing
-    * an SQLite database file
+    * @param {Array<number>|string} data An array of bytes representing
+    * an SQLite database file or a path
+    * @param {Object} opts Options to specify a filename
     */
-    function Database(data) {
-        this.filename = "dbfile_" + (0xffffffff * Math.random() >>> 0);
-        if (data != null) {
-            FS.createDataFile("/", this.filename, data, true, true);
-        }
-        this.handleError(sqlite3_open(this.filename, apiTemp));
-        this.db = getValue(apiTemp, "i32");
+function Database(data, { filename = false } = {}) {
+    if(filename === false) {
+      this.filename = "dbfile_" + (0xffffffff * Math.random() >>> 0);
+      if (data != null) {
+         FS.createDataFile("/", this.filename, data, true, true);
+      }
+    }
+    else {
+      this.filename = data;
+    }
+    this.handleError(sqlite3_open(this.filename, apiTemp));
+    this.db = getValue(apiTemp, "i32");
         registerExtensionFunctions(this.db);
         // A list of all prepared statements of the database
         this.statements = {};
@@ -1530,4 +1536,44 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() {
 
     // export Database to Module
     Module.Database = Database;
+
+    // Because emscripten doesn't allow us to handle `ioctl`, we need
+    // to manually install lock/unlock methods. Unfortunately we need
+    // to keep track of a mapping of `sqlite_file*` pointers to filename
+    // so that we can tell our filesystem which files to lock/unlock
+    var sqliteFiles = new Map();
+
+    Module["register_for_idb"] = (customFS) => {
+      var SQLITE_BUSY = 5;
+
+      function open(namePtr, file) {
+        var path = UTF8ToString(namePtr);
+        sqliteFiles.set(file, path);
+      }
+
+      function lock(file, lockType) {
+        var path = sqliteFiles.get(file);
+        var success = customFS.lock(path, lockType)
+        return success? 0 : SQLITE_BUSY;
+      }
+
+      function unlock(file,lockType) {
+        var path = sqliteFiles.get(file);
+        customFS.unlock(path, lockType)
+        return 0;
+      }
+
+      let lockPtr = addFunction(lock, 'iii');
+      let unlockPtr = addFunction(unlock, 'iii');
+      let openPtr = addFunction(open, 'vii');
+      Module["_register_for_idb"](lockPtr, unlockPtr, openPtr)
+    }
+
+    // TODO: This isn't called from anywhere yet. We need to
+    // somehow cleanup closed files from `sqliteFiles`
+    Module["cleanup_file"] = (path) => {
+      let filesInfo = [...sqliteFiles.entries()]
+      let fileInfo = filesInfo.find(f => f[1] === path);
+      sqliteFiles.delete(fileInfo[0])
+    }
 };
diff --git a/src/exported_functions.json b/src/exported_functions.json
index 3be25955..8d779181 100644
--- a/src/exported_functions.json
+++ b/src/exported_functions.json
@@ -42,6 +42,8 @@
 "_sqlite3_result_int64",
 "_sqlite3_result_error",
 "_sqlite3_aggregate_context",
-"_RegisterExtensionFunctions",
-"_sqlite3_update_hook"
+"_sqlite3_update_hook",
+"_sqlite3_vfs_find",
+"_register_for_idb",
+"_RegisterExtensionFunctions"
 ]
diff --git a/src/exported_runtime_methods.json b/src/exported_runtime_methods.json
index 245d2078..64893d08 100644
--- a/src/exported_runtime_methods.json
+++ b/src/exported_runtime_methods.json
@@ -4,10 +4,10 @@
 "stackSave",
 "stackRestore",
 "UTF8ToString",
-
 "allocate",
 "ALLOC_NORMAL",
 "allocateUTF8OnStack",
 "removeFunction",
-"addFunction"
+"addFunction",
+"FS"
 ]
diff --git a/src/fs-externs.js b/src/fs-externs.js
new file mode 100644
index 00000000..a82e2463
--- /dev/null
+++ b/src/fs-externs.js
@@ -0,0 +1,48 @@
+/**
+ * @externs
+ */
+
+Module.FS = class {
+  constructor() {
+    this.ErrnoError = class {};
+  }
+  mount() {}
+  isRoot() {}
+  isFile() {}
+  isDir() {}
+  stat() {}
+  /** @return {FSNode} */
+  lookupPath() {}
+  /** @return {FSNode} */
+  lookupNode() {}
+  /** @return {FSNode} */
+  createNode() {}
+  /** @return {FSNode} */
+  mknod() {}
+};
+
+Module.FS.FSNode = class {
+  constructor() {
+    this.node_ops = {
+      getattr: () => {},
+      setattr: () => {},
+      lookup: () => {},
+      mknod: () => {},
+      rename: () => {},
+      unlink: () => {},
+      rmdir: () => {},
+      reaaddir: () => {},
+      symlink: () => {},
+      readlink: () => {}
+    };
+
+    this.stream_ops = {
+      llseek: () => {},
+      read: () => {},
+      write: () => {},
+      allocate: () => {},
+      mmap: () => {},
+      msync: () => {}
+    };
+  }
+};
diff --git a/src/vfs.c b/src/vfs.c
new file mode 100644
index 00000000..30b19ca7
--- /dev/null
+++ b/src/vfs.c
@@ -0,0 +1,49 @@
+#include <sqlite3.h>
+#include <stdio.h>
+
+static int (*defaultOpen)(sqlite3_vfs *vfs, const char *zName, sqlite3_file *file, int flags, int *pOutFlags);
+
+static void (*fsOpen)(const char *, void*);
+static int (*fsLock)(sqlite3_file *file, int);
+static int (*fsUnlock)(sqlite3_file *file, int);
+
+static int blockDeviceCharacteristics(sqlite3_file* file) {
+    return SQLITE_IOCAP_SAFE_APPEND |
+        SQLITE_IOCAP_SEQUENTIAL |
+        SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
+}
+
+static int block_lock(sqlite3_file *file, int lock) {
+    return fsLock(file, lock);
+}
+
+static int block_unlock(sqlite3_file *file, int lock) {
+    return fsUnlock(file, lock);
+}
+
+static int block_open(sqlite3_vfs *vfs, const char *zName, sqlite3_file *file, int flags, int *pOutFlags) {
+    int res = defaultOpen(vfs, zName, file, flags, pOutFlags);
+
+    printf("Opened!\n");
+
+    sqlite3_io_methods* methods = (sqlite3_io_methods*)file->pMethods;
+    methods->xDeviceCharacteristics = blockDeviceCharacteristics;
+    methods->xLock = block_lock;
+    methods->xUnlock = block_unlock;
+
+    fsOpen(zName, (void*)file);
+
+    return res;
+}
+
+void register_for_idb(int(*lockFile)(sqlite3_file*,int), int(*unlockFile)(sqlite3_file*,int), void(*openFile)(const char*, void*)) {
+    sqlite3_vfs *vfs = sqlite3_vfs_find("unix");
+    defaultOpen = vfs->xOpen;
+
+    vfs->xOpen = block_open;
+    sqlite3_vfs_register(vfs, 1);
+
+    fsLock = lockFile;
+    fsUnlock = unlockFile;
+    fsOpen = openFile;
+}

From d197b52147254697589c16d0a15b9fc19ba691e7 Mon Sep 17 00:00:00 2001
From: James Long <longster@gmail.com>
Date: Mon, 2 Aug 2021 10:40:39 -0400
Subject: [PATCH 2/6] Improved exports for testing

---
 src/fs-externs.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/fs-externs.js b/src/fs-externs.js
index a82e2463..c2e1a329 100644
--- a/src/fs-externs.js
+++ b/src/fs-externs.js
@@ -5,8 +5,10 @@
 Module.FS = class {
   constructor() {
     this.ErrnoError = class {};
+    this.filesystems = {}
   }
   mount() {}
+  unmount() {}
   isRoot() {}
   isFile() {}
   isDir() {}

From 1628d53213c6d70e6d1a1ecd61519f0bdb752f02 Mon Sep 17 00:00:00 2001
From: James Long <longster@gmail.com>
Date: Mon, 2 Aug 2021 10:51:12 -0400
Subject: [PATCH 3/6] Add reset_filesystem

---
 src/api.js        | 5 +++++
 src/fs-externs.js | 2 --
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/api.js b/src/api.js
index ea0b873c..2418d4bb 100644
--- a/src/api.js
+++ b/src/api.js
@@ -1576,4 +1576,9 @@ function Database(data, { filename = false } = {}) {
       let fileInfo = filesInfo.find(f => f[1] === path);
       sqliteFiles.delete(fileInfo[0])
     }
+
+    Module["reset_filesystem"] = () => {
+      FS.root = null;
+      FS.staticInit();
+    }
 };
diff --git a/src/fs-externs.js b/src/fs-externs.js
index c2e1a329..a82e2463 100644
--- a/src/fs-externs.js
+++ b/src/fs-externs.js
@@ -5,10 +5,8 @@
 Module.FS = class {
   constructor() {
     this.ErrnoError = class {};
-    this.filesystems = {}
   }
   mount() {}
-  unmount() {}
   isRoot() {}
   isFile() {}
   isDir() {}

From 8a59581f54c626e1d63015e926971cd7b4965110 Mon Sep 17 00:00:00 2001
From: James Long <longster@gmail.com>
Date: Fri, 6 Aug 2021 09:25:58 -0400
Subject: [PATCH 4/6] Don't delete file on close

---
 src/api.js | 50 +++++++++++++++++++++++++++-----------------------
 src/vfs.c  |  2 --
 2 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/src/api.js b/src/api.js
index 2418d4bb..46571d2f 100644
--- a/src/api.js
+++ b/src/api.js
@@ -833,24 +833,26 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() {
     * an SQLite database file or a path
     * @param {Object} opts Options to specify a filename
     */
-function Database(data, { filename = false } = {}) {
-    if(filename === false) {
-      this.filename = "dbfile_" + (0xffffffff * Math.random() >>> 0);
-      if (data != null) {
-         FS.createDataFile("/", this.filename, data, true, true);
-      }
-    }
-    else {
-      this.filename = data;
-    }
-    this.handleError(sqlite3_open(this.filename, apiTemp));
-    this.db = getValue(apiTemp, "i32");
+    function Database(data, { filename = false } = {}) {
+        if(filename === false) {
+          this.filename = "dbfile_" + (0xffffffff * Math.random() >>> 0);
+          this.memoryFile = true;  // Add this line to track if it's a memory file
+          if (data != null) {
+             FS.createDataFile("/", this.filename, data, true, true);
+          }
+        }
+        else {
+          this.filename = data;
+        }
+        this.handleError(sqlite3_open(this.filename, apiTemp));
+        this.db = getValue(apiTemp, "i32");
         registerExtensionFunctions(this.db);
         // A list of all prepared statements of the database
         this.statements = {};
-        // A list of all user function of the database
-        // (created by create_function call)
+        // A list of custom functions registered by this database instance
         this.functions = {};
+        // Callbacks for update hook
+        this.updateHookFunctionPtr = undefined;
     }
 
     /** Execute an SQL query, ignoring the rows it returns.
@@ -1121,23 +1123,25 @@ function Database(data, { filename = false } = {}) {
     * memory consumption will grow forever
      */
     Database.prototype["close"] = function close() {
-        // do nothing if db is null or already closed
-        if (this.db === null) {
-            return;
-        }
-        Object.values(this.statements).forEach(function each(stmt) {
-            stmt["free"]();
+        if (!this.db) return;
+        
+        Object.keys(this.statements).forEach((statementId) => {
+            this["run"](this.statements[statementId], ["--close"]);
         });
         Object.values(this.functions).forEach(removeFunction);
         this.functions = {};
-
+    
         if (this.updateHookFunctionPtr) {
             removeFunction(this.updateHookFunctionPtr);
             this.updateHookFunctionPtr = undefined;
         }
-
+    
         this.handleError(sqlite3_close_v2(this.db));
-        FS.unlink("/" + this.filename);
+        
+        if(this.memoryFile) {
+            FS.unlink("/" + this.filename);
+        }
+        
         this.db = null;
     };
 
diff --git a/src/vfs.c b/src/vfs.c
index 30b19ca7..412bad87 100644
--- a/src/vfs.c
+++ b/src/vfs.c
@@ -24,8 +24,6 @@ static int block_unlock(sqlite3_file *file, int lock) {
 static int block_open(sqlite3_vfs *vfs, const char *zName, sqlite3_file *file, int flags, int *pOutFlags) {
     int res = defaultOpen(vfs, zName, file, flags, pOutFlags);
 
-    printf("Opened!\n");
-
     sqlite3_io_methods* methods = (sqlite3_io_methods*)file->pMethods;
     methods->xDeviceCharacteristics = blockDeviceCharacteristics;
     methods->xLock = block_lock;

From 217e3aad647ec02c99a2505ea0bb73ffbcc9e0ae Mon Sep 17 00:00:00 2001
From: Sergey Popov <quolpr@gmail.com>
Date: Sat, 28 Aug 2021 17:49:46 +0300
Subject: [PATCH 5/6] Fix makefile fs-externs path

---
 Makefile | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index 0d229a5d..a9d62bc0 100644
--- a/Makefile
+++ b/Makefile
@@ -70,19 +70,21 @@ EMFLAGS_PRE_JS_FILES = \
 
 EXPORTED_METHODS_JSON_FILES = src/exported_functions.json src/exported_runtime_methods.json
 
+FS_EXTERN_PATH = "$(realpath -s ./src/fs-externs.js)"
+
 all: optimized debug worker
 
 .PHONY: debug
 debug: dist/sql-asm-debug.js dist/sql-wasm-debug.js
 
 dist/sql-asm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs ${FS_EXTERN_PATH}" $(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
 
 dist/sql-wasm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs ${FS_EXTERN_PATH}" $(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
@@ -91,19 +93,19 @@ dist/sql-wasm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FI
 optimized: dist/sql-asm.js dist/sql-wasm.js dist/sql-asm-memory-growth.js
 
 dist/sql-asm.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs ${FS_EXTERN_PATH}" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
 
 dist/sql-wasm.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs ${FS_EXTERN_PATH}" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js
 
 dist/sql-asm-memory-growth.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
-	EMCC_CLOSURE_ARGS="--externs src/fs-externs.js" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM_MEMORY_GROWTH) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
+	EMCC_CLOSURE_ARGS="--externs ${FS_EXTERN_PATH}" $(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM_MEMORY_GROWTH) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
 	mv $@ out/tmp-raw.js
 	cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
 	rm out/tmp-raw.js

From d9c1b328d678b3c56ed8b2f8a6ea8cecdfc4f53a Mon Sep 17 00:00:00 2001
From: Kacper Kula <kulak@kulak.at>
Date: Wed, 19 Mar 2025 14:13:38 +0000
Subject: [PATCH 6/6] chore: fixing build

---
 Makefile     | 8 ++++----
 README.md    | 8 ++++++++
 package.json | 2 +-
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index a9d62bc0..c227b180 100644
--- a/Makefile
+++ b/Makefile
@@ -59,7 +59,7 @@ EMFLAGS_DEBUG = \
 	-s ASSERTIONS=2 \
 	-O1
 
-BITCODE_FILES = out/sqlite3.o out/extension-functions.o out/vfs.bc
+BITCODE_FILES = out/sqlite3.o out/extension-functions.o out/vfs.o
 
 OUTPUT_WRAPPER_FILES = src/shell-pre.js src/shell-post.js
 
@@ -155,10 +155,10 @@ out/extension-functions.o: sqlite-src/$(SQLITE_AMALGAMATION)
 	# Generate llvm bitcode
 	$(EMCC) $(SQLITE_COMPILATION_FLAGS) -c sqlite-src/$(SQLITE_AMALGAMATION)/extension-functions.c -o $@
 
-out/vfs.bc: src/vfs.c sqlite-src/$(SQLITE_AMALGAMATION)
+out/vfs.o: src/vfs.c sqlite-src/$(SQLITE_AMALGAMATION)
 	mkdir -p out
-	# Generate llvm bitcode
-	$(EMCC) $(CFLAGS) -s LINKABLE=1 -I sqlite-src/$(SQLITE_AMALGAMATION) -c src/vfs.c -o $@
+	# Generate object file
+	$(EMCC) $(CFLAGS) -I sqlite-src/$(SQLITE_AMALGAMATION) -c src/vfs.c -o $@
 
 # TODO: This target appears to be unused. If we re-instatate it, we'll need to add more files inside of the JS folder
 # module.tar.gz: test package.json AUTHORS README.md dist/sql-asm.js
diff --git a/README.md b/README.md
index a42cfa8c..d7e06475 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,11 @@
+> [!IMPORTANT]
+> This is fork of the original sql.js library with extra bits and bobs from the fork of @jlongster/sql.js to enable absurd-sql support
+> It is being used in Obsidian SQLSeal to enable latest SQLite version
+
+
+
+
+
 <img src="https://user-images.githubusercontent.com/552629/76405509-87025300-6388-11ea-86c9-af882abb00bd.png" width="40" height="40" />
 
 # SQLite compiled to JavaScript
diff --git a/package.json b/package.json
index 404fe3a9..cbc811f4 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
 {
-	"name": "sql.js",
+	"name": "@hypersphere/sql.js",
 	"version": "1.13.0",
 	"description": "SQLite library with support for opening and writing databases, prepared statements, and more. This SQLite library is in pure javascript (compiled with emscripten).",
 	"keywords": [
