diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 31b1e26..244d015 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -69,7 +69,7 @@ jobs:
>> $GITHUB_OUTPUT
- name: Cache Playwright browsers
- uses: actions/cache@v4
+ uses: actions/cache@v5
id: playwright-cache
with:
path: ~/.cache/ms-playwright
diff --git a/.gitignore b/.gitignore
index b26da1b..c77346e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,5 @@ Thumbs.db
node_modules
dist/
bundle
+
+.parcel-cache
diff --git a/.oxfmtrc.json b/.oxfmtrc.json
deleted file mode 100644
index 49c1123..0000000
--- a/.oxfmtrc.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "$schema": "./node_modules/oxfmt/configuration_schema.json",
- "insertPragma": false,
- "printWidth": 100,
- "proseWrap": "always",
- "requirePragma": false,
- "singleQuote": true,
- "tabWidth": 2,
- "trailingComma": "all",
- "ignorePatterns": ["/src/bin", "/dist", "/node_modules", "package.json"]
-}
diff --git a/demos/in-worker-demo/package.json b/demos/in-worker-demo/package.json
index e0b4861..384719d 100644
--- a/demos/in-worker-demo/package.json
+++ b/demos/in-worker-demo/package.json
@@ -7,6 +7,6 @@
"preview": "vite preview"
},
"devDependencies": {
- "vite": "^8.0.8"
+ "vite": "^8.0.9"
}
}
diff --git a/demos/in-worker-demo/vite.config.ts b/demos/in-worker-demo/vite.config.ts
deleted file mode 100644
index 8a8bcb6..0000000
--- a/demos/in-worker-demo/vite.config.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { defineConfig, type UserConfig } from 'vite';
-
-const viteConfig: UserConfig = defineConfig({
- server: {
- port: 5173,
- },
-});
-
-export default viteConfig;
diff --git a/demos/kvvfs-demo/index.html b/demos/kvvfs-demo/index.html
new file mode 100644
index 0000000..b29499b
--- /dev/null
+++ b/demos/kvvfs-demo/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ kvvfs Demo
+
+
+
+
+
+
diff --git a/demos/kvvfs-demo/package.json b/demos/kvvfs-demo/package.json
new file mode 100644
index 0000000..0b34955
--- /dev/null
+++ b/demos/kvvfs-demo/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "@sqlite.org/kvvfs-demo",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "vite": "^8.0.9"
+ }
+}
diff --git a/demos/kvvfs-demo/src/main.ts b/demos/kvvfs-demo/src/main.ts
new file mode 100644
index 0000000..8572df0
--- /dev/null
+++ b/demos/kvvfs-demo/src/main.ts
@@ -0,0 +1,37 @@
+import sqlite3InitModule from '../../../src/index.js';
+
+const runDemo = async () => {
+ const sqlite3 = await sqlite3InitModule();
+ const dbName = 'kvvfs-demo';
+
+ sqlite3.kvvfs.unlink(dbName);
+
+ const db = new sqlite3.oo1.JsStorageDb('session');
+ db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
+ db.exec({
+ sql: 'INSERT INTO test (name) VALUES (?), (?)',
+ bind: ['kvvfs 1', 'kvvfs 2'],
+ });
+
+ const rows = db.selectObjects('SELECT * FROM test ORDER BY id');
+ const size = db.storageSize();
+
+ const app = document.getElementById('app');
+ if (app) {
+ const sizeInfo = document.createElement('p');
+ sizeInfo.textContent = `Stored in kvvfs as ${dbName} (${size} bytes)`;
+ app.appendChild(sizeInfo);
+
+ const ul = document.createElement('ul');
+ rows.forEach((row: any) => {
+ const li = document.createElement('li');
+ li.textContent = `${row.id}: ${row.name}`;
+ ul.appendChild(li);
+ });
+ app.appendChild(ul);
+ }
+
+ db.close();
+};
+
+runDemo().catch(console.error);
diff --git a/demos/kvvfs-demo/tsconfig.json b/demos/kvvfs-demo/tsconfig.json
new file mode 100644
index 0000000..596e2cf
--- /dev/null
+++ b/demos/kvvfs-demo/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../tsconfig.json",
+ "include": ["src"]
+}
diff --git a/demos/main-thread-demo/package.json b/demos/main-thread-demo/package.json
index 9517334..0604efa 100644
--- a/demos/main-thread-demo/package.json
+++ b/demos/main-thread-demo/package.json
@@ -7,6 +7,6 @@
"preview": "vite preview"
},
"devDependencies": {
- "vite": "^8.0.8"
+ "vite": "^8.0.9"
}
}
diff --git a/demos/main-thread-demo/vite.config.ts b/demos/main-thread-demo/vite.config.ts
deleted file mode 100644
index bcd854c..0000000
--- a/demos/main-thread-demo/vite.config.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { defineConfig, type UserConfig } from 'vite';
-
-const viteConfig: UserConfig = defineConfig({
- server: {
- port: 5174,
- },
-});
-
-export default viteConfig;
diff --git a/demos/opfs-demo/index.html b/demos/opfs-demo/index.html
new file mode 100644
index 0000000..6eea9f8
--- /dev/null
+++ b/demos/opfs-demo/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ OPFS Demo
+
+
+
+
+
+
diff --git a/demos/opfs-demo/package.json b/demos/opfs-demo/package.json
new file mode 100644
index 0000000..b603dfa
--- /dev/null
+++ b/demos/opfs-demo/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "@sqlite.org/opfs-demo",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "vite": "^8.0.9"
+ }
+}
diff --git a/demos/opfs-demo/src/main.ts b/demos/opfs-demo/src/main.ts
new file mode 100644
index 0000000..a74bb78
--- /dev/null
+++ b/demos/opfs-demo/src/main.ts
@@ -0,0 +1,26 @@
+const worker = new Worker(new URL('./workers/worker.ts', import.meta.url), {
+ type: 'module',
+});
+
+worker.onmessage = (e) => {
+ if (e.data.type === 'success') {
+ const app = document.getElementById('app');
+ if (app) {
+ const file = document.createElement('p');
+ file.textContent = `Stored in OPFS file ${e.data.filename}`;
+ app.appendChild(file);
+
+ const ul = document.createElement('ul');
+ e.data.rows.forEach((row: any) => {
+ const li = document.createElement('li');
+ li.textContent = `${row.id}: ${row.name}`;
+ ul.appendChild(li);
+ });
+ app.appendChild(ul);
+ }
+ } else if (e.data.type === 'error') {
+ console.error(e.data.message);
+ }
+};
+
+worker.postMessage({ type: 'start' });
diff --git a/demos/opfs-demo/src/workers/worker.ts b/demos/opfs-demo/src/workers/worker.ts
new file mode 100644
index 0000000..e8155f4
--- /dev/null
+++ b/demos/opfs-demo/src/workers/worker.ts
@@ -0,0 +1,25 @@
+import sqlite3InitModule from '../../../../src/index.js';
+
+self.onmessage = async (e) => {
+ if (e.data.type === 'start') {
+ try {
+ const sqlite3 = await sqlite3InitModule();
+ const filename = '/opfs-demo.sqlite3';
+ const db = new sqlite3.oo1.OpfsDb(filename, 'ct');
+
+ db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
+ db.exec({
+ sql: 'INSERT INTO test (name) VALUES (?), (?)',
+ bind: ['OPFS 1', 'OPFS 2'],
+ });
+
+ const rows = db.selectObjects('SELECT * FROM test ORDER BY id');
+
+ db.close();
+
+ self.postMessage({ type: 'success', filename, rows });
+ } catch (err: any) {
+ self.postMessage({ type: 'error', message: err.message });
+ }
+ }
+};
diff --git a/demos/opfs-demo/tsconfig.json b/demos/opfs-demo/tsconfig.json
new file mode 100644
index 0000000..596e2cf
--- /dev/null
+++ b/demos/opfs-demo/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../tsconfig.json",
+ "include": ["src"]
+}
diff --git a/demos/opfs-demo/vite.config.ts b/demos/opfs-demo/vite.config.ts
new file mode 100644
index 0000000..965e27f
--- /dev/null
+++ b/demos/opfs-demo/vite.config.ts
@@ -0,0 +1,21 @@
+import { defineConfig, type UserConfig } from 'vite';
+
+const viteConfig: UserConfig = defineConfig({
+ server: {
+ port: 5173,
+ },
+ plugins: [
+ {
+ name: 'configure-response-headers',
+ configureServer: (server) => {
+ server.middlewares.use((_req, res, next) => {
+ res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
+ res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
+ next();
+ });
+ },
+ },
+ ],
+});
+
+export default viteConfig;
diff --git a/demos/opfs-wl-demo/index.html b/demos/opfs-wl-demo/index.html
new file mode 100644
index 0000000..be4477b
--- /dev/null
+++ b/demos/opfs-wl-demo/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ OPFS Web Locks Demo
+
+
+
+
+
+
diff --git a/demos/opfs-wl-demo/package.json b/demos/opfs-wl-demo/package.json
new file mode 100644
index 0000000..57580ed
--- /dev/null
+++ b/demos/opfs-wl-demo/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "@sqlite.org/opfs-wl-demo",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "vite": "^8.0.9"
+ }
+}
diff --git a/demos/opfs-wl-demo/src/main.ts b/demos/opfs-wl-demo/src/main.ts
new file mode 100644
index 0000000..0e76340
--- /dev/null
+++ b/demos/opfs-wl-demo/src/main.ts
@@ -0,0 +1,26 @@
+const worker = new Worker(new URL('./workers/worker.ts', import.meta.url), {
+ type: 'module',
+});
+
+worker.onmessage = (e) => {
+ if (e.data.type === 'success') {
+ const app = document.getElementById('app');
+ if (app) {
+ const file = document.createElement('p');
+ file.textContent = `Stored in OPFS Web Locks file ${e.data.filename}`;
+ app.appendChild(file);
+
+ const ul = document.createElement('ul');
+ e.data.rows.forEach((row: any) => {
+ const li = document.createElement('li');
+ li.textContent = `${row.id}: ${row.name}`;
+ ul.appendChild(li);
+ });
+ app.appendChild(ul);
+ }
+ } else if (e.data.type === 'error') {
+ console.error(e.data.message);
+ }
+};
+
+worker.postMessage({ type: 'start' });
diff --git a/demos/opfs-wl-demo/src/workers/worker.ts b/demos/opfs-wl-demo/src/workers/worker.ts
new file mode 100644
index 0000000..f256c76
--- /dev/null
+++ b/demos/opfs-wl-demo/src/workers/worker.ts
@@ -0,0 +1,25 @@
+import sqlite3InitModule from '../../../../src/index.js';
+
+self.onmessage = async (e) => {
+ if (e.data.type === 'start') {
+ try {
+ const sqlite3 = await sqlite3InitModule();
+ const filename = '/opfs-wl-demo.sqlite3';
+ const db = new sqlite3.oo1.OpfsWlDb(filename, 'ct');
+
+ db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
+ db.exec({
+ sql: 'INSERT INTO test (name) VALUES (?), (?)',
+ bind: ['OPFS-WL 1', 'OPFS-WL 2'],
+ });
+
+ const rows = db.selectObjects('SELECT * FROM test ORDER BY id');
+
+ db.close();
+
+ self.postMessage({ type: 'success', filename, rows });
+ } catch (err: any) {
+ self.postMessage({ type: 'error', message: err.message });
+ }
+ }
+};
diff --git a/demos/opfs-wl-demo/tsconfig.json b/demos/opfs-wl-demo/tsconfig.json
new file mode 100644
index 0000000..596e2cf
--- /dev/null
+++ b/demos/opfs-wl-demo/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../tsconfig.json",
+ "include": ["src"]
+}
diff --git a/demos/opfs-wl-demo/vite.config.ts b/demos/opfs-wl-demo/vite.config.ts
new file mode 100644
index 0000000..965e27f
--- /dev/null
+++ b/demos/opfs-wl-demo/vite.config.ts
@@ -0,0 +1,21 @@
+import { defineConfig, type UserConfig } from 'vite';
+
+const viteConfig: UserConfig = defineConfig({
+ server: {
+ port: 5173,
+ },
+ plugins: [
+ {
+ name: 'configure-response-headers',
+ configureServer: (server) => {
+ server.middlewares.use((_req, res, next) => {
+ res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
+ res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
+ next();
+ });
+ },
+ },
+ ],
+});
+
+export default viteConfig;
diff --git a/demos/sahpool-demo/package.json b/demos/sahpool-demo/package.json
index 6d143b6..e342b7e 100644
--- a/demos/sahpool-demo/package.json
+++ b/demos/sahpool-demo/package.json
@@ -7,6 +7,6 @@
"preview": "vite preview"
},
"devDependencies": {
- "vite": "^8.0.8"
+ "vite": "^8.0.9"
}
}
diff --git a/demos/sahpool-demo/src/main.ts b/demos/sahpool-demo/src/main.ts
index fc4955d..8c762e3 100644
--- a/demos/sahpool-demo/src/main.ts
+++ b/demos/sahpool-demo/src/main.ts
@@ -3,6 +3,7 @@ const worker = new Worker(new URL('./workers/worker.ts', import.meta.url), {
});
worker.onmessage = (e) => {
+ console.log(e);
if (e.data.type === 'success') {
const rows = e.data.rows;
const app = document.getElementById('app');
diff --git a/demos/sahpool-demo/src/workers/worker.ts b/demos/sahpool-demo/src/workers/worker.ts
index 3f0579b..74fe10b 100644
--- a/demos/sahpool-demo/src/workers/worker.ts
+++ b/demos/sahpool-demo/src/workers/worker.ts
@@ -6,6 +6,7 @@ self.onmessage = async (e) => {
const sqlite3 = await sqlite3InitModule();
const opfsSahPool = await sqlite3.installOpfsSAHPoolVfs({
directory: '/sqlite-wasm-sahpool-demo',
+ clearOnInit: true,
});
const db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3');
diff --git a/demos/sahpool-demo/vite.config.ts b/demos/sahpool-demo/vite.config.ts
index 0152081..965e27f 100644
--- a/demos/sahpool-demo/vite.config.ts
+++ b/demos/sahpool-demo/vite.config.ts
@@ -2,8 +2,20 @@ import { defineConfig, type UserConfig } from 'vite';
const viteConfig: UserConfig = defineConfig({
server: {
- port: 5175,
+ port: 5173,
},
+ plugins: [
+ {
+ name: 'configure-response-headers',
+ configureServer: (server) => {
+ server.middlewares.use((_req, res, next) => {
+ res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
+ res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
+ next();
+ });
+ },
+ },
+ ],
});
export default viteConfig;
diff --git a/demos/sahpool-parcel-demo/index.html b/demos/sahpool-parcel-demo/index.html
new file mode 100644
index 0000000..17a2fa3
--- /dev/null
+++ b/demos/sahpool-parcel-demo/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ SAHPOOL Parcel Demo
+
+
+
+
+
+
diff --git a/demos/sahpool-parcel-demo/package.json b/demos/sahpool-parcel-demo/package.json
new file mode 100644
index 0000000..03739e3
--- /dev/null
+++ b/demos/sahpool-parcel-demo/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@sqlite.org/sahpool-parcel-demo",
+ "type": "module",
+ "scripts": {
+ "dev": "parcel serve index.html --port 5174 --dist-dir dist",
+ "build": "parcel build index.html --dist-dir dist"
+ },
+ "targets": {
+ "default": {
+ "outputFormat": "esmodule"
+ }
+ },
+ "devDependencies": {
+ "parcel": "^2.16.1"
+ }
+}
diff --git a/demos/sahpool-parcel-demo/src/main.js b/demos/sahpool-parcel-demo/src/main.js
new file mode 100644
index 0000000..0b697dc
--- /dev/null
+++ b/demos/sahpool-parcel-demo/src/main.js
@@ -0,0 +1,23 @@
+const worker = new Worker(new URL('./workers/worker.js', import.meta.url), {
+ type: 'module',
+});
+
+worker.onmessage = (e) => {
+ if (e.data.type === 'success') {
+ const app = document.getElementById('app');
+ if (app) {
+ const ul = document.createElement('ul');
+ e.data.rows.forEach((row) => {
+ const li = document.createElement('li');
+ li.textContent = `${row.id}: ${row.name}`;
+ ul.appendChild(li);
+ });
+ app.appendChild(ul);
+ }
+ return;
+ }
+
+ console.error(e.data.message);
+};
+
+worker.postMessage({ type: 'start' });
diff --git a/demos/sahpool-parcel-demo/src/workers/worker.js b/demos/sahpool-parcel-demo/src/workers/worker.js
new file mode 100644
index 0000000..955822b
--- /dev/null
+++ b/demos/sahpool-parcel-demo/src/workers/worker.js
@@ -0,0 +1,26 @@
+import sqlite3InitModule from '../../../../dist/index.mjs';
+
+self.onmessage = async (e) => {
+ if (e.data.type !== 'start') return;
+
+ try {
+ const sqlite3 = await sqlite3InitModule();
+ const opfsSahPool = await sqlite3.installOpfsSAHPoolVfs({
+ directory: '/sqlite-wasm-sahpool-parcel-demo',
+ clearOnInit: true,
+ });
+
+ const db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-parcel-worker.sqlite3');
+ db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
+ db.exec({
+ sql: 'INSERT INTO test (name) VALUES (?), (?)',
+ bind: ['Alice', 'Bob'],
+ });
+
+ const rows = db.selectObjects('SELECT * FROM test ORDER BY id');
+ db.close();
+ self.postMessage({ type: 'success', rows });
+ } catch (err) {
+ self.postMessage({ type: 'error', message: err.message });
+ }
+};
diff --git a/demos/sahpool-rsbuild-demo/package.json b/demos/sahpool-rsbuild-demo/package.json
new file mode 100644
index 0000000..6923966
--- /dev/null
+++ b/demos/sahpool-rsbuild-demo/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@sqlite.org/sahpool-rsbuild-demo",
+ "type": "module",
+ "scripts": {
+ "dev": "rsbuild dev --port 5175",
+ "build": "rsbuild build"
+ },
+ "devDependencies": {
+ "@rsbuild/core": "^1.5.13"
+ }
+}
diff --git a/demos/sahpool-rsbuild-demo/rsbuild.config.mjs b/demos/sahpool-rsbuild-demo/rsbuild.config.mjs
new file mode 100644
index 0000000..51537e7
--- /dev/null
+++ b/demos/sahpool-rsbuild-demo/rsbuild.config.mjs
@@ -0,0 +1,13 @@
+import { defineConfig } from '@rsbuild/core';
+
+export default defineConfig({
+ server: {
+ headers: {
+ 'Cross-Origin-Embedder-Policy': 'require-corp',
+ 'Cross-Origin-Opener-Policy': 'same-origin',
+ },
+ },
+ html: {
+ title: 'SAHPOOL Rsbuild Demo',
+ },
+});
diff --git a/demos/sahpool-rsbuild-demo/src/index.js b/demos/sahpool-rsbuild-demo/src/index.js
new file mode 100644
index 0000000..859ecc3
--- /dev/null
+++ b/demos/sahpool-rsbuild-demo/src/index.js
@@ -0,0 +1 @@
+import './main.js';
diff --git a/demos/sahpool-rsbuild-demo/src/main.js b/demos/sahpool-rsbuild-demo/src/main.js
new file mode 100644
index 0000000..0b697dc
--- /dev/null
+++ b/demos/sahpool-rsbuild-demo/src/main.js
@@ -0,0 +1,23 @@
+const worker = new Worker(new URL('./workers/worker.js', import.meta.url), {
+ type: 'module',
+});
+
+worker.onmessage = (e) => {
+ if (e.data.type === 'success') {
+ const app = document.getElementById('app');
+ if (app) {
+ const ul = document.createElement('ul');
+ e.data.rows.forEach((row) => {
+ const li = document.createElement('li');
+ li.textContent = `${row.id}: ${row.name}`;
+ ul.appendChild(li);
+ });
+ app.appendChild(ul);
+ }
+ return;
+ }
+
+ console.error(e.data.message);
+};
+
+worker.postMessage({ type: 'start' });
diff --git a/demos/sahpool-rsbuild-demo/src/workers/worker.js b/demos/sahpool-rsbuild-demo/src/workers/worker.js
new file mode 100644
index 0000000..f8ab23d
--- /dev/null
+++ b/demos/sahpool-rsbuild-demo/src/workers/worker.js
@@ -0,0 +1,26 @@
+import sqlite3InitModule from '../../../../dist/index.mjs';
+
+self.onmessage = async (e) => {
+ if (e.data.type !== 'start') return;
+
+ try {
+ const sqlite3 = await sqlite3InitModule();
+ const opfsSahPool = await sqlite3.installOpfsSAHPoolVfs({
+ directory: '/sqlite-wasm-sahpool-rsbuild-demo',
+ clearOnInit: true,
+ });
+
+ const db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-rsbuild-worker.sqlite3');
+ db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
+ db.exec({
+ sql: 'INSERT INTO test (name) VALUES (?), (?)',
+ bind: ['Alice', 'Bob'],
+ });
+
+ const rows = db.selectObjects('SELECT * FROM test ORDER BY id');
+ db.close();
+ self.postMessage({ type: 'success', rows });
+ } catch (err) {
+ self.postMessage({ type: 'error', message: err.message });
+ }
+};
diff --git a/demos/sahpool-webpack-demo/index.html b/demos/sahpool-webpack-demo/index.html
new file mode 100644
index 0000000..b6852c0
--- /dev/null
+++ b/demos/sahpool-webpack-demo/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+ SAHPOOL Webpack Demo
+
+
+
+
+
diff --git a/demos/sahpool-webpack-demo/package.json b/demos/sahpool-webpack-demo/package.json
new file mode 100644
index 0000000..4eb492a
--- /dev/null
+++ b/demos/sahpool-webpack-demo/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "@sqlite.org/sahpool-webpack-demo",
+ "type": "module",
+ "scripts": {
+ "dev": "webpack serve --config webpack.config.js --mode development",
+ "build": "webpack --config webpack.config.js --mode production"
+ },
+ "devDependencies": {
+ "webpack": "^5.102.1",
+ "webpack-cli": "^7.0.2",
+ "webpack-dev-server": "^5.2.2"
+ }
+}
diff --git a/demos/sahpool-webpack-demo/src/main.js b/demos/sahpool-webpack-demo/src/main.js
new file mode 100644
index 0000000..0b697dc
--- /dev/null
+++ b/demos/sahpool-webpack-demo/src/main.js
@@ -0,0 +1,23 @@
+const worker = new Worker(new URL('./workers/worker.js', import.meta.url), {
+ type: 'module',
+});
+
+worker.onmessage = (e) => {
+ if (e.data.type === 'success') {
+ const app = document.getElementById('app');
+ if (app) {
+ const ul = document.createElement('ul');
+ e.data.rows.forEach((row) => {
+ const li = document.createElement('li');
+ li.textContent = `${row.id}: ${row.name}`;
+ ul.appendChild(li);
+ });
+ app.appendChild(ul);
+ }
+ return;
+ }
+
+ console.error(e.data.message);
+};
+
+worker.postMessage({ type: 'start' });
diff --git a/demos/sahpool-webpack-demo/src/workers/worker.js b/demos/sahpool-webpack-demo/src/workers/worker.js
new file mode 100644
index 0000000..421fbd4
--- /dev/null
+++ b/demos/sahpool-webpack-demo/src/workers/worker.js
@@ -0,0 +1,26 @@
+import sqlite3InitModule from '../../../../dist/index.mjs';
+
+self.onmessage = async (e) => {
+ if (e.data.type !== 'start') return;
+
+ try {
+ const sqlite3 = await sqlite3InitModule();
+ const opfsSahPool = await sqlite3.installOpfsSAHPoolVfs({
+ directory: '/sqlite-wasm-sahpool-webpack-demo',
+ clearOnInit: true,
+ });
+
+ const db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-webpack-worker.sqlite3');
+ db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
+ db.exec({
+ sql: 'INSERT INTO test (name) VALUES (?), (?)',
+ bind: ['Alice', 'Bob'],
+ });
+
+ const rows = db.selectObjects('SELECT * FROM test ORDER BY id');
+ db.close();
+ self.postMessage({ type: 'success', rows });
+ } catch (err) {
+ self.postMessage({ type: 'error', message: err.message });
+ }
+};
diff --git a/demos/sahpool-webpack-demo/webpack.config.js b/demos/sahpool-webpack-demo/webpack.config.js
new file mode 100644
index 0000000..498398e
--- /dev/null
+++ b/demos/sahpool-webpack-demo/webpack.config.js
@@ -0,0 +1,31 @@
+import { fileURLToPath } from 'node:url';
+import { dirname, resolve } from 'node:path';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
+
+export default {
+ entry: './src/main.js',
+ output: {
+ filename: 'bundle.js',
+ path: resolve(__dirname, 'dist'),
+ clean: true,
+ },
+ stats: {
+ errorDetails: true,
+ },
+ devtool: 'source-map',
+ experiments: {
+ asyncWebAssembly: true,
+ },
+ devServer: {
+ port: 5173,
+ static: {
+ directory: __dirname,
+ },
+ headers: {
+ 'Cross-Origin-Embedder-Policy': 'require-corp',
+ 'Cross-Origin-Opener-Policy': 'same-origin',
+ },
+ },
+};
diff --git a/oxfmt.config.ts b/oxfmt.config.ts
new file mode 100644
index 0000000..69b5724
--- /dev/null
+++ b/oxfmt.config.ts
@@ -0,0 +1,12 @@
+import { defineConfig, type OxfmtConfig } from 'oxfmt';
+
+const oxfmtConfig: OxfmtConfig = defineConfig({
+ printWidth: 100,
+ proseWrap: 'always',
+ singleQuote: true,
+ tabWidth: 2,
+ trailingComma: 'all',
+ ignorePatterns: ['/src/bin', '/dist', '/node_modules', 'package.json'],
+});
+
+export default oxfmtConfig;
diff --git a/package-lock.json b/package-lock.json
index dee0a90..fd638bd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,30 +1,29 @@
{
"name": "@sqlite.org/sqlite-wasm",
- "version": "3.51.2-build9",
+ "version": "3.53.0-build1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@sqlite.org/sqlite-wasm",
- "version": "3.51.2-build9",
+ "version": "3.53.0-build1",
"license": "Apache-2.0",
"workspaces": [
"demos/*"
],
"devDependencies": {
"@types/node": "^25.6.0",
- "@typescript/native-preview": "^7.0.0-dev.20260414.1",
- "@vitest/browser": "^4.1.4",
- "@vitest/browser-playwright": "^4.1.4",
+ "@typescript/native-preview": "^7.0.0-dev.20260421.2",
+ "@vitest/browser": "^4.1.5",
+ "@vitest/browser-playwright": "^4.1.5",
"happy-dom": "20.9.0",
- "http-server": "^14.1.1",
- "lefthook": "2.1.5",
- "oxfmt": "^0.45.0",
+ "lefthook": "2.1.6",
+ "oxfmt": "^0.46.0",
"playwright": "^1.59.1",
"publint": "^0.3.18",
- "tsdown": "^0.21.8",
- "typescript": "^6.0.2",
- "vitest": "^4.1.4"
+ "tsdown": "^0.21.9",
+ "typescript": "^6.0.3",
+ "vitest": "^4.1.5"
},
"engines": {
"node": ">=22"
@@ -33,19 +32,57 @@
"demos/in-worker-demo": {
"name": "@sqlite.org/in-worker-demo",
"devDependencies": {
- "vite": "^8.0.8"
+ "vite": "^8.0.9"
+ }
+ },
+ "demos/kvvfs-demo": {
+ "name": "@sqlite.org/kvvfs-demo",
+ "devDependencies": {
+ "vite": "^8.0.9"
}
},
"demos/main-thread-demo": {
"name": "@sqlite.org/main-thread-demo",
"devDependencies": {
- "vite": "^8.0.8"
+ "vite": "^8.0.9"
+ }
+ },
+ "demos/opfs-demo": {
+ "name": "@sqlite.org/opfs-demo",
+ "devDependencies": {
+ "vite": "^8.0.9"
+ }
+ },
+ "demos/opfs-wl-demo": {
+ "name": "@sqlite.org/opfs-wl-demo",
+ "devDependencies": {
+ "vite": "^8.0.9"
}
},
"demos/sahpool-demo": {
"name": "@sqlite.org/sahpool-demo",
"devDependencies": {
- "vite": "^8.0.8"
+ "vite": "^8.0.9"
+ }
+ },
+ "demos/sahpool-parcel-demo": {
+ "name": "@sqlite.org/sahpool-parcel-demo",
+ "devDependencies": {
+ "parcel": "^2.16.1"
+ }
+ },
+ "demos/sahpool-rsbuild-demo": {
+ "name": "@sqlite.org/sahpool-rsbuild-demo",
+ "devDependencies": {
+ "@rsbuild/core": "^1.5.13"
+ }
+ },
+ "demos/sahpool-webpack-demo": {
+ "name": "@sqlite.org/sahpool-webpack-demo",
+ "devDependencies": {
+ "webpack": "^5.102.1",
+ "webpack-cli": "^7.0.2",
+ "webpack-dev-server": "^5.2.2"
}
},
"node_modules/@babel/generator": {
@@ -123,6 +160,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@discoveryjs/json-ext": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-1.0.0.tgz",
+ "integrity": "sha512-dDlz3W405VMFO4w5kIP9DOmELBcvFQGmLoKSdIRstBDubKFYwaNHV1NnlzMCQpXQFGWVALmeMORAuiLx18AvZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.17.0"
+ }
+ },
"node_modules/@emnapi/core": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz",
@@ -178,6 +225,17 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
@@ -196,335 +254,506 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz",
- "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==",
+ "node_modules/@jsonjoy.com/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==",
"dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@tybys/wasm-util": "^0.10.1"
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
},
"funding": {
"type": "github",
- "url": "https://github.com/sponsors/Brooooooklyn"
+ "url": "https://github.com/sponsors/streamich"
},
"peerDependencies": {
- "@emnapi/core": "^1.7.1",
- "@emnapi/runtime": "^1.7.1"
+ "tslib": "2"
}
},
- "node_modules/@oxc-project/types": {
- "version": "0.124.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz",
- "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==",
+ "node_modules/@jsonjoy.com/buffers": {
+ "version": "17.67.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz",
+ "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==",
"dev": true,
- "license": "MIT",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
+ },
"funding": {
- "url": "https://github.com/sponsors/Boshen"
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-android-arm-eabi": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.45.0.tgz",
- "integrity": "sha512-A/UMxFob1fefCuMeGxQBulGfFE38g2Gm23ynr3u6b+b7fY7/ajGbNsa3ikMIkGMLJW/TRoQaMoP1kME7S+815w==",
- "cpu": [
- "arm"
- ],
+ "node_modules/@jsonjoy.com/codegen": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz",
+ "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==",
"dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "license": "Apache-2.0",
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-android-arm64": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.45.0.tgz",
- "integrity": "sha512-L63z4uZmHjgvvqvMJD7mwff8aSBkM0+X4uFr6l6U5t6+Qc9DCLVZWIunJ7Gm4fn4zHPdSq6FFQnhu9yqqobxIg==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@jsonjoy.com/fs-core": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.2.tgz",
+ "integrity": "sha512-SVjwklkpIV5wrynpYtuYnfYH1QF4/nDuLBX7VXdb+3miglcAgBVZb/5y0cOsehRV/9Vb+3UqhkMq3/NR3ztdkQ==",
"dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/fs-node-builtins": "4.57.2",
+ "@jsonjoy.com/fs-node-utils": "4.57.2",
+ "thingies": "^2.5.0"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-darwin-arm64": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.45.0.tgz",
- "integrity": "sha512-UV34dd623FzqT+outIGndsCA/RBB+qgB3XVQhgmmJ9PJwa37NzPC9qzgKeOhPKxVk2HW+JKldQrVL54zs4Noww==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@jsonjoy.com/fs-fsa": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.2.tgz",
+ "integrity": "sha512-fhO8+iR2I+OCw668ISDJdn1aArc9zx033sWejIyzQ8RBeXa9bDSaUeA3ix0poYOfrj1KdOzytmYNv2/uLDfV6g==",
"dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/fs-core": "4.57.2",
+ "@jsonjoy.com/fs-node-builtins": "4.57.2",
+ "@jsonjoy.com/fs-node-utils": "4.57.2",
+ "thingies": "^2.5.0"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-darwin-x64": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.45.0.tgz",
- "integrity": "sha512-pMNJv0CMa1pDefVPeNbuQxibh8ITpWDFEhMC/IBB9Zlu76EbgzYwrzI4Cb11mqX2+rIYN70UTrh3z06TM59ptQ==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@jsonjoy.com/fs-node": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.2.tgz",
+ "integrity": "sha512-nX2AdL6cOFwLdju9G4/nbRnYevmCJbh7N7hvR3gGm97Cs60uEjyd0rpR+YBS7cTg175zzl22pGKXR5USaQMvKg==",
"dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/fs-core": "4.57.2",
+ "@jsonjoy.com/fs-node-builtins": "4.57.2",
+ "@jsonjoy.com/fs-node-utils": "4.57.2",
+ "@jsonjoy.com/fs-print": "4.57.2",
+ "@jsonjoy.com/fs-snapshot": "4.57.2",
+ "glob-to-regex.js": "^1.0.0",
+ "thingies": "^2.5.0"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-freebsd-x64": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.45.0.tgz",
- "integrity": "sha512-xTcRoxbbo61sW2+ZRPeH+vp/o9G8gkdhiVumFU+TpneiPm14c79l6GFlxPXlCE9bNWikigbsrvJw46zCVAQFfg==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@jsonjoy.com/fs-node-builtins": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.2.tgz",
+ "integrity": "sha512-xhiegylRmhw43Ki2HO1ZBL7DQ5ja/qpRsL29VtQ2xuUHiuDGbgf2uD4p9Qd8hJI5P6RCtGYD50IXHXVq/Ocjcg==",
"dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
+ "license": "Apache-2.0",
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-arm-gnueabihf": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.45.0.tgz",
- "integrity": "sha512-hWL8Hdni+3U1mPFx1UtWeGp3tNb6EhBAUHRMbKUxVkOp3WwoJbpVO2bfUVbS4PfpledviXXNHSTl1veTa6FhkQ==",
- "cpu": [
- "arm"
- ],
+ "node_modules/@jsonjoy.com/fs-node-to-fsa": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.2.tgz",
+ "integrity": "sha512-18LmWTSONhoAPW+IWRuf8w/+zRolPFGPeGwMxlAhhfY11EKzX+5XHDBPAw67dBF5dxDErHJbl40U+3IXSDRXSQ==",
"dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/fs-fsa": "4.57.2",
+ "@jsonjoy.com/fs-node-builtins": "4.57.2",
+ "@jsonjoy.com/fs-node-utils": "4.57.2"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-arm-musleabihf": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.45.0.tgz",
- "integrity": "sha512-6Blt/0OBT7vvfQpqYuYbpbFLPqSiaYpEJzUUWhinPEuADypDbtV1+LdjM0vYBNGPvnj85ex7lTerEX6JGcPt9w==",
- "cpu": [
- "arm"
- ],
+ "node_modules/@jsonjoy.com/fs-node-utils": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.2.tgz",
+ "integrity": "sha512-rsPSJgekz43IlNbLyAM/Ab+ouYLWGp5DDBfYBNNEqDaSpsbXfthBn29Q4muFA9L0F+Z3mKo+CWlgSCXrf+mOyQ==",
"dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/fs-node-builtins": "4.57.2"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-arm64-gnu": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.45.0.tgz",
- "integrity": "sha512-jLjoLfe+hGfjhA8hNBSdw85yCA8ePKq7ME4T+g6P9caQXvmt6IhE2X7iVjnVdkmYUWEzZrxlh4p6RkDmAMJY/A==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@jsonjoy.com/fs-print": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.2.tgz",
+ "integrity": "sha512-wK9NSow48i4DbDl9F1CQE5TqnyZOJ04elU3WFG5aJ76p+YxO/ulyBBQvKsessPxdo381Bc2pcEoyPujMOhcRqQ==",
"dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/fs-node-utils": "4.57.2",
+ "tree-dump": "^1.1.0"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-arm64-musl": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.45.0.tgz",
- "integrity": "sha512-XQKXZIKYJC3GQJ8FnD3iMntpw69Wd9kDDK/Xt79p6xnFYlGGxSNv2vIBvRTDg5CKByWFWWZLCRDOXoP/m6YN4g==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@jsonjoy.com/fs-snapshot": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.2.tgz",
+ "integrity": "sha512-GdduDZuoP5V/QCgJkx9+BZ6SC0EZ/smXAdTS7PfMqgMTGXLlt/bH/FqMYaqB9JmLf05sJPtO0XRbAwwkEEPbVw==",
"dev": true,
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/buffers": "^17.65.0",
+ "@jsonjoy.com/fs-node-utils": "4.57.2",
+ "@jsonjoy.com/json-pack": "^17.65.0",
+ "@jsonjoy.com/util": "^17.65.0"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-ppc64-gnu": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.45.0.tgz",
- "integrity": "sha512-+g5RiG+xOkdrCWkKodv407nTvMq4vYM18Uox2MhZBm/YoqFxxJpWKsloskFFG5NU13HGPw1wzYjjOVcyd9moCA==",
- "cpu": [
- "ppc64"
- ],
+ "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": {
+ "version": "17.67.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz",
+ "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==",
"dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "Apache-2.0",
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-riscv64-gnu": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.45.0.tgz",
- "integrity": "sha512-V7dXKoSyEbWAkkSF4JJNtF+NJZDmJoSarSoP30WCsB3X636Rehd3CvxBj49FIJxEBFWhvcUjGSHVeU8Erck1bQ==",
- "cpu": [
- "riscv64"
- ],
+ "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": {
+ "version": "17.67.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz",
+ "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==",
"dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "Apache-2.0",
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-riscv64-musl": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.45.0.tgz",
- "integrity": "sha512-Vdelft1sAEYojVGgcODEFXSWYQYlIvoyIGWebKCuUibd1tvS1TjTx413xG2ZLuHpYj45CkN/ztMLMX6jrgqpgg==",
- "cpu": [
- "riscv64"
- ],
+ "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": {
+ "version": "17.67.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz",
+ "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==",
"dev": true,
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/base64": "17.67.0",
+ "@jsonjoy.com/buffers": "17.67.0",
+ "@jsonjoy.com/codegen": "17.67.0",
+ "@jsonjoy.com/json-pointer": "17.67.0",
+ "@jsonjoy.com/util": "17.67.0",
+ "hyperdyperid": "^1.2.0",
+ "thingies": "^2.5.0",
+ "tree-dump": "^1.1.0"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-s390x-gnu": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.45.0.tgz",
- "integrity": "sha512-RR7xKgNpqwENnK0aYCGYg0JycY2n93J0reNjHyes+I9Gq52dH95x+CBlnlAQHCPfz6FGnKA9HirgUl14WO6o7w==",
- "cpu": [
- "s390x"
- ],
+ "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": {
+ "version": "17.67.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz",
+ "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==",
"dev": true,
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/util": "17.67.0"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
}
},
- "node_modules/@oxfmt/binding-linux-x64-gnu": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.45.0.tgz",
- "integrity": "sha512-U/QQ0+BQNSHxjuXR/utvXnQ50Vu5kUuqEomZvQ1/3mhgbBiMc2WU9q5kZ5WwLp3gnFIx9ibkveoRSe2EZubkqg==",
+ "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": {
+ "version": "17.67.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz",
+ "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/buffers": "17.67.0",
+ "@jsonjoy.com/codegen": "17.67.0"
+ },
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@jsonjoy.com/json-pack": {
+ "version": "1.21.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz",
+ "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/base64": "^1.1.2",
+ "@jsonjoy.com/buffers": "^1.2.0",
+ "@jsonjoy.com/codegen": "^1.0.0",
+ "@jsonjoy.com/json-pointer": "^1.0.2",
+ "@jsonjoy.com/util": "^1.9.0",
+ "hyperdyperid": "^1.2.0",
+ "thingies": "^2.5.0",
+ "tree-dump": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz",
+ "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@jsonjoy.com/json-pointer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz",
+ "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/codegen": "^1.0.0",
+ "@jsonjoy.com/util": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@jsonjoy.com/util": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz",
+ "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/buffers": "^1.0.0",
+ "@jsonjoy.com/codegen": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz",
+ "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@leichtgewicht/ip-codec": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
+ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@lezer/common": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz",
+ "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@lezer/lr": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz",
+ "integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@lezer/common": "^1.0.0"
+ }
+ },
+ "node_modules/@lmdb/lmdb-darwin-arm64": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.8.5.tgz",
+ "integrity": "sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw==",
"cpu": [
- "x64"
+ "arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
+ "darwin"
+ ]
},
- "node_modules/@oxfmt/binding-linux-x64-musl": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.45.0.tgz",
- "integrity": "sha512-o5TLOUCF0RWQjsIS06yVC+kFgp092/yLe6qBGSUvtnmTVw9gxjpdQSXc3VN5Cnive4K11HNstEZF8ROKHfDFSw==",
+ "node_modules/@lmdb/lmdb-darwin-x64": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.8.5.tgz",
+ "integrity": "sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug==",
"cpu": [
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
+ "darwin"
+ ]
},
- "node_modules/@oxfmt/binding-openharmony-arm64": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.45.0.tgz",
- "integrity": "sha512-RnGcV3HgPuOjsGx/k9oyRNKmOp+NBLGzZTdPDYbc19r7NGeYPplnUU/BfU35bX2Y/O4ejvHxcfkvW2WoYL/gsg==",
+ "node_modules/@lmdb/lmdb-linux-arm": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.8.5.tgz",
+ "integrity": "sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg==",
"cpu": [
- "arm64"
+ "arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "openharmony"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
+ "linux"
+ ]
},
- "node_modules/@oxfmt/binding-win32-arm64-msvc": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.45.0.tgz",
- "integrity": "sha512-v3Vj7iKKsUFwt9w5hsqIIoErKVoENC6LoqfDlteOQ5QMDCXihlqLoxpmviUhXnNncg4zV6U9BPwlBbwa+qm4wg==",
+ "node_modules/@lmdb/lmdb-linux-arm64": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.8.5.tgz",
+ "integrity": "sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww==",
"cpu": [
"arm64"
],
@@ -532,33 +761,27 @@
"license": "MIT",
"optional": true,
"os": [
- "win32"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
+ "linux"
+ ]
},
- "node_modules/@oxfmt/binding-win32-ia32-msvc": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.45.0.tgz",
- "integrity": "sha512-N8yotPBX6ph0H3toF4AEpdCeVPrdcSetj+8eGiZGsrLsng3bs/Q5HPu4bbSxip5GBPx5hGbGHrZwH4+rcrjhHA==",
+ "node_modules/@lmdb/lmdb-linux-x64": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.8.5.tgz",
+ "integrity": "sha512-Xkc8IUx9aEhP0zvgeKy7IQ3ReX2N8N1L0WPcQwnZweWmOuKfwpS3GRIYqLtK5za/w3E60zhFfNdS+3pBZPytqQ==",
"cpu": [
- "ia32"
+ "x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "win32"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
+ "linux"
+ ]
},
- "node_modules/@oxfmt/binding-win32-x64-msvc": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.45.0.tgz",
- "integrity": "sha512-w5MMTRCK1dpQeRA+HHqXQXyN33DlG/N2LOYxJmaT4fJjcmZrbNnqw7SmIk7I2/a2493PPLZ+2E/Ar6t2iKVMug==",
+ "node_modules/@lmdb/lmdb-win32-x64": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.8.5.tgz",
+ "integrity": "sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ==",
"cpu": [
"x64"
],
@@ -567,65 +790,86 @@
"optional": true,
"os": [
"win32"
- ],
+ ]
+ },
+ "node_modules/@mischnic/json-sourcemap": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz",
+ "integrity": "sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@lezer/common": "^1.0.0",
+ "@lezer/lr": "^1.0.0",
+ "json5": "^2.2.1"
+ },
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">=12.0.0"
}
},
- "node_modules/@polka/url": {
- "version": "1.0.0-next.29",
- "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
- "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+ "node_modules/@module-federation/error-codes": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz",
+ "integrity": "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==",
"dev": true,
"license": "MIT"
},
- "node_modules/@publint/pack": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/@publint/pack/-/pack-0.1.4.tgz",
- "integrity": "sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==",
+ "node_modules/@module-federation/runtime": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.22.0.tgz",
+ "integrity": "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://bjornlu.com/sponsor"
+ "dependencies": {
+ "@module-federation/error-codes": "0.22.0",
+ "@module-federation/runtime-core": "0.22.0",
+ "@module-federation/sdk": "0.22.0"
}
},
- "node_modules/@quansync/fs": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz",
- "integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==",
+ "node_modules/@module-federation/runtime-core": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz",
+ "integrity": "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "quansync": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sxzz"
+ "@module-federation/error-codes": "0.22.0",
+ "@module-federation/sdk": "0.22.0"
}
},
- "node_modules/@rolldown/binding-android-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@module-federation/runtime-tools": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz",
+ "integrity": "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "dependencies": {
+ "@module-federation/runtime": "0.22.0",
+ "@module-federation/webpack-bundler-runtime": "0.22.0"
}
},
- "node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==",
+ "node_modules/@module-federation/sdk": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.22.0.tgz",
+ "integrity": "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@module-federation/webpack-bundler-runtime": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz",
+ "integrity": "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@module-federation/runtime": "0.22.0",
+ "@module-federation/sdk": "0.22.0"
+ }
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
+ "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==",
"cpu": [
"arm64"
],
@@ -634,15 +878,12 @@
"optional": true,
"os": [
"darwin"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
+ ]
},
- "node_modules/@rolldown/binding-darwin-x64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz",
- "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==",
+ "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz",
+ "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==",
"cpu": [
"x64"
],
@@ -651,49 +892,229 @@
"optional": true,
"os": [
"darwin"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
+ ]
},
- "node_modules/@rolldown/binding-freebsd-x64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz",
- "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==",
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz",
+ "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==",
"cpu": [
- "x64"
+ "arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "freebsd"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
+ "linux"
+ ]
},
- "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz",
- "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==",
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz",
+ "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==",
"cpu": [
- "arm"
+ "arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
+ ]
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz",
+ "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz",
+ "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
+ "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
}
},
- "node_modules/@rolldown/binding-linux-arm64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==",
+ "node_modules/@noble/hashes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
+ "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@oxc-project/types": {
+ "version": "0.126.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.126.0.tgz",
+ "integrity": "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
+ "node_modules/@oxfmt/binding-android-arm-eabi": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.46.0.tgz",
+ "integrity": "sha512-b1doV4WRcJU+BESSlCvCjV+5CEr/T6h0frArAdV26Nir+gGNFNaylvDiiMPfF1pxeV0txZEs38ojzJaxBYg+ng==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-android-arm64": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.46.0.tgz",
+ "integrity": "sha512-v6+HhjsoV3GO0u2u9jLSAZrvWfTraDxKofUIQ7/ktS7tzS+epVsxdHmeM+XxuNcAY/nWxxU1Sg4JcGTNRXraBA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-darwin-arm64": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.46.0.tgz",
+ "integrity": "sha512-3eeooJGrqGIlI5MyryDZsAcKXSmKIgAD4yYtfRrRJzXZ0UTFZtiSveIur56YPrGMYZwT4XyVhHsMqrNwr1XeFA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-darwin-x64": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.46.0.tgz",
+ "integrity": "sha512-QG8BDM0CXWbu84k2SKmCqfEddPQPFiBicwtYnLqHRWZZl57HbtOLRMac/KTq2NO4AEc4ICCBpFxJIV9zcqYfkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-freebsd-x64": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.46.0.tgz",
+ "integrity": "sha512-9DdCqS/n2ncu/Chazvt3cpgAjAmIGQDz7hFKSrNItMApyV/Ja9mz3hD4JakIE3nS8PW9smEbPWnb389QLBY4nw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-linux-arm-gnueabihf": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.46.0.tgz",
+ "integrity": "sha512-Dgs7VeE2jT0LHMhw6tPEt0xQYe54kBqHEovmWsv4FVQlegCOvlIJNx0S8n4vj8WUtpT+Z6BD2HhKJPLglLxvZg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-linux-arm-musleabihf": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.46.0.tgz",
+ "integrity": "sha512-Zxn3adhTH13JKnU4xXJj8FeEfF680XjXh3gSShKl57HCMBRde2tUJTgogV/1MSHA80PJEVrDa7r66TLVq3Ia7Q==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-linux-arm64-gnu": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.46.0.tgz",
+ "integrity": "sha512-+TWipjrgVM8D7aIdDD0tlr3teLTTvQTn7QTE5BpT10H1Fj82gfdn9X6nn2sDgx/MepuSCfSnzFNJq2paLL0OiA==",
"cpu": [
"arm64"
],
@@ -710,10 +1131,10 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-linux-arm64-musl": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz",
- "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==",
+ "node_modules/@oxfmt/binding-linux-arm64-musl": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.46.0.tgz",
+ "integrity": "sha512-aAUPBWJ1lGwwnxZUEDLJ94+Iy6MuwJwPxUgO4sCA5mEEyDk7b+cDQ+JpX1VR150Zoyd+D49gsrUzpUK5h587Eg==",
"cpu": [
"arm64"
],
@@ -730,10 +1151,10 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-linux-ppc64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==",
+ "node_modules/@oxfmt/binding-linux-ppc64-gnu": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.46.0.tgz",
+ "integrity": "sha512-ufBCJukyFX/UDrokP/r6BGDoTInnsDs7bxyzKAgMiZlt2Qu8GPJSJ6Zm6whIiJzKk0naxA8ilwmbO1LMw6Htxw==",
"cpu": [
"ppc64"
],
@@ -750,10 +1171,50 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-linux-s390x-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==",
+ "node_modules/@oxfmt/binding-linux-riscv64-gnu": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.46.0.tgz",
+ "integrity": "sha512-eqtlC2YmPqjun76R1gVfGLuKWx7NuEnLEAudZ7n6ipSKbCZTqIKSs1b5Y8K/JHZsRpLkeSmAAjig5HOIg8fQzQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-linux-riscv64-musl": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.46.0.tgz",
+ "integrity": "sha512-yccVOO2nMXkQLGgy0He3EQEwKD7NF0zEk+/OWmroznkqXyJdN6bfK0LtNnr6/14Bh3FjpYq7bP33l/VloCnxpA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxfmt/binding-linux-s390x-gnu": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.46.0.tgz",
+ "integrity": "sha512-aAf7fG23OQCey6VRPj9IeCraoYtpgtx0ZyJ1CXkPyT1wjzBE7c3xtuxHe/AdHaJfVVb/SXpSk8Gl1LzyQupSqw==",
"cpu": [
"s390x"
],
@@ -770,10 +1231,10 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-linux-x64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==",
+ "node_modules/@oxfmt/binding-linux-x64-gnu": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.46.0.tgz",
+ "integrity": "sha512-q0JPsTMyJNjYrBvYFDz4WbVsafNZaPCZv4RnFypRotLqpKROtBZcEaXQW4eb9YmvLU3NckVemLJnzkSZSdmOxw==",
"cpu": [
"x64"
],
@@ -790,10 +1251,10 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-linux-x64-musl": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz",
- "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==",
+ "node_modules/@oxfmt/binding-linux-x64-musl": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.46.0.tgz",
+ "integrity": "sha512-7LsLY9Cw57GPkhSR+duI3mt9baRczK/DtHYSldQ4BEU92da9igBQNl4z7Vq5U9NNPsh1FmpKvv1q9WDtiUQR1A==",
"cpu": [
"x64"
],
@@ -810,10 +1271,10 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-openharmony-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==",
+ "node_modules/@oxfmt/binding-openharmony-arm64": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.46.0.tgz",
+ "integrity": "sha512-lHiBOz8Duaku7JtRNLlps3j++eOaICPZSd8FCVmTDM4DFOPT71Bjn7g6iar1z7StXlKRweUKxWUs4sA+zWGDXg==",
"cpu": [
"arm64"
],
@@ -827,31 +1288,29 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-wasm32-wasi": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz",
- "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==",
+ "node_modules/@oxfmt/binding-win32-arm64-msvc": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.46.0.tgz",
+ "integrity": "sha512-/5ktYUliP89RhgC37DBH1x20U5zPSZMy3cMEcO0j3793rbHP9MWsknBwQB6eozRzWmYrh0IFM/p20EbPvDlYlg==",
"cpu": [
- "wasm32"
+ "arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
- "dependencies": {
- "@emnapi/core": "1.9.2",
- "@emnapi/runtime": "1.9.2",
- "@napi-rs/wasm-runtime": "^1.1.3"
- },
+ "os": [
+ "win32"
+ ],
"engines": {
- "node": ">=14.0.0"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-win32-arm64-msvc": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz",
- "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==",
+ "node_modules/@oxfmt/binding-win32-ia32-msvc": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.46.0.tgz",
+ "integrity": "sha512-3WTnoiuIr8XvV0DIY7SN+1uJSwKf4sPpcbHfobcRT9JutGcLaef/miyBB87jxd3aqH+mS0+G5lsgHuXLUwjjpQ==",
"cpu": [
- "arm64"
+ "ia32"
],
"dev": true,
"license": "MIT",
@@ -863,10 +1322,10 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/binding-win32-x64-msvc": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz",
- "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==",
+ "node_modules/@oxfmt/binding-win32-x64-msvc": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.46.0.tgz",
+ "integrity": "sha512-IXxiQpkYnOwNfP23vzwSfhdpxJzyiPTY7eTn6dn3DsriKddESzM8i6kfq9R7CD/PUJwCvQT22NgtygBeug3KoA==",
"cpu": [
"x64"
],
@@ -880,1307 +1339,1542 @@
"node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz",
- "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@sqlite.org/in-worker-demo": {
- "resolved": "demos/in-worker-demo",
- "link": true
- },
- "node_modules/@sqlite.org/main-thread-demo": {
- "resolved": "demos/main-thread-demo",
- "link": true
- },
- "node_modules/@sqlite.org/sahpool-demo": {
- "resolved": "demos/sahpool-demo",
- "link": true
- },
- "node_modules/@standard-schema/spec": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
- "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tybys/wasm-util": {
- "version": "0.10.1",
- "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
- "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "node_modules/@parcel/bundler-default": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.16.4.tgz",
+ "integrity": "sha512-Nb8peNvhfm1+660CLwssWh4weY+Mv6vEGS6GPKqzJmTMw50udi0eS1YuWFzvmhSiu1KsYcUD37mqQ1LuIDtWoA==",
"dev": true,
"license": "MIT",
- "optional": true,
"dependencies": {
- "tslib": "^2.4.0"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/graph": "3.6.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@types/chai": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
- "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
+ "node_modules/@parcel/cache": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.16.4.tgz",
+ "integrity": "sha512-+uCyeElSga2MBbmbXpIj/WVKH7TByCrKaxtHbelfKKIJpYMgEHVjO4cuc7GUfTrUAmRUS8ZGvnX7Etgq6/jQhw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/deep-eql": "*",
- "assertion-error": "^2.0.1"
+ "@parcel/fs": "2.16.4",
+ "@parcel/logger": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "lmdb": "2.8.5"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "peerDependencies": {
+ "@parcel/core": "^2.16.4"
}
},
- "node_modules/@types/deep-eql": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
- "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/estree": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/jsesc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@types/jsesc/-/jsesc-2.5.1.tgz",
- "integrity": "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "25.6.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz",
- "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
+ "node_modules/@parcel/codeframe": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.16.4.tgz",
+ "integrity": "sha512-s64aMfOJoPrXhKH+Y98ahX0O8aXWvTR+uNlOaX4yFkpr4FFDnviLcGngDe/Yo4Qq2FJZ0P6dNswbJTUH9EGxkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "undici-types": "~7.19.0"
+ "chalk": "^4.1.2"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@types/whatwg-mimetype": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz",
- "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/ws": {
- "version": "8.18.1",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
- "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
+ "node_modules/@parcel/compressor-raw": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.16.4.tgz",
+ "integrity": "sha512-IK8IpNhw61B2HKgA1JhGhO9y+ZJFRZNTEmvhN1NdLdPqvgEXm2EunT+m6D9z7xeoeT6XnUKqM0eRckEdD0OXbA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@typescript/native-preview": {
- "version": "7.0.0-dev.20260414.1",
- "resolved": "https://registry.npmjs.org/@typescript/native-preview/-/native-preview-7.0.0-dev.20260414.1.tgz",
- "integrity": "sha512-b9C7ZVKSGCF1VFvA8UdAKHCGmKOrmm44UwmGgICSQmWg6vseLdElx0F8UvuNsA6risIOXh5hs7Buif+QRrCYuA==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsgo": "bin/tsgo.js"
+ "@parcel/plugin": "2.16.4"
},
- "optionalDependencies": {
- "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260414.1",
- "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260414.1",
- "@typescript/native-preview-linux-arm": "7.0.0-dev.20260414.1",
- "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260414.1",
- "@typescript/native-preview-linux-x64": "7.0.0-dev.20260414.1",
- "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260414.1",
- "@typescript/native-preview-win32-x64": "7.0.0-dev.20260414.1"
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@typescript/native-preview-darwin-arm64": {
- "version": "7.0.0-dev.20260414.1",
- "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-arm64/-/native-preview-darwin-arm64-7.0.0-dev.20260414.1.tgz",
- "integrity": "sha512-O7h9lNcE9YMA2TKw1YX9GZO3K/Kb1FUmxjEJAfBFvjQhGydIk4oNsuoOQ3RQHVvebCdFjNroZzoIXNeR3ceCdA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@typescript/native-preview-darwin-x64": {
- "version": "7.0.0-dev.20260414.1",
- "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-x64/-/native-preview-darwin-x64-7.0.0-dev.20260414.1.tgz",
- "integrity": "sha512-ax7OUrIaIIay+yI9EhavXmsnO+79AdFVv/N3ZibC11LBixJXaYhfTyFikQL5IyMkfoKm3oBQ0tHyI0xMkS+9tA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@typescript/native-preview-linux-arm": {
- "version": "7.0.0-dev.20260414.1",
- "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm/-/native-preview-linux-arm-7.0.0-dev.20260414.1.tgz",
- "integrity": "sha512-0gYz37o/hr5PAlsABXbai2D1sPioB9pMy2Ft4leF/Rc6qq4QVuyLPE+QbXgu/2k4I0YWud2On6k4+kEobXK9qA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@typescript/native-preview-linux-arm64": {
- "version": "7.0.0-dev.20260414.1",
- "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm64/-/native-preview-linux-arm64-7.0.0-dev.20260414.1.tgz",
- "integrity": "sha512-oGAWMCw6JZ27+LBZlLEg8NGHZyIFPx9YUNYCaDcX3Z9dGh6ZPeD7uIaBiw7JZ0fh05sgK6DZBsAz5nWnnSvc7Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@typescript/native-preview-linux-x64": {
- "version": "7.0.0-dev.20260414.1",
- "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-x64/-/native-preview-linux-x64-7.0.0-dev.20260414.1.tgz",
- "integrity": "sha512-9YnVwJoiu6w8m7g+Q7AQECz9nxieKGIRFeibmQ1MnF+lEtnXFZMLJWkNzE+Jt2UXIkKZBvVT3VDgmpExzeHGBA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@typescript/native-preview-win32-arm64": {
- "version": "7.0.0-dev.20260414.1",
- "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-arm64/-/native-preview-win32-arm64-7.0.0-dev.20260414.1.tgz",
- "integrity": "sha512-Sjm40DJk62e+aR8EblKwlX/KsTJlYgg+EwSi9FPGsi3YY+BSoM6kQ6NF7FmE41FEOqRyuWom0ap9CqXIwosBOg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@typescript/native-preview-win32-x64": {
- "version": "7.0.0-dev.20260414.1",
- "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-x64/-/native-preview-win32-x64-7.0.0-dev.20260414.1.tgz",
- "integrity": "sha512-TMgYk82tvehQjze0mdo2CUSXYkh7ZOqxewLVqGAHsAG5QFPEZ+8qSbGwTytznOs9wL4V2rrbziL6psGonJoBxw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@vitest/browser": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.4.tgz",
- "integrity": "sha512-TrNaY/yVOwxtrxNsDUC/wQ56xSwplpytTeRAqF/197xV/ZddxxulBsxR6TrhVMyniJmp9in8d5u0AcDaNRY30w==",
+ "node_modules/@parcel/config-default": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.16.4.tgz",
+ "integrity": "sha512-kBxuTY/5trEVnvXk92l7LVkYjNuz3SaqWymFhPjEnc8GY4ZVdcWrWdXWTB9hUhpmRYJctFCyGvM0nN05JTiM2g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@blazediff/core": "1.9.1",
- "@vitest/mocker": "4.1.4",
- "@vitest/utils": "4.1.4",
- "magic-string": "^0.30.21",
- "pngjs": "^7.0.0",
- "sirv": "^3.0.2",
- "tinyrainbow": "^3.1.0",
- "ws": "^8.19.0"
+ "@parcel/bundler-default": "2.16.4",
+ "@parcel/compressor-raw": "2.16.4",
+ "@parcel/namer-default": "2.16.4",
+ "@parcel/optimizer-css": "2.16.4",
+ "@parcel/optimizer-html": "2.16.4",
+ "@parcel/optimizer-image": "2.16.4",
+ "@parcel/optimizer-svg": "2.16.4",
+ "@parcel/optimizer-swc": "2.16.4",
+ "@parcel/packager-css": "2.16.4",
+ "@parcel/packager-html": "2.16.4",
+ "@parcel/packager-js": "2.16.4",
+ "@parcel/packager-raw": "2.16.4",
+ "@parcel/packager-svg": "2.16.4",
+ "@parcel/packager-wasm": "2.16.4",
+ "@parcel/reporter-dev-server": "2.16.4",
+ "@parcel/resolver-default": "2.16.4",
+ "@parcel/runtime-browser-hmr": "2.16.4",
+ "@parcel/runtime-js": "2.16.4",
+ "@parcel/runtime-rsc": "2.16.4",
+ "@parcel/runtime-service-worker": "2.16.4",
+ "@parcel/transformer-babel": "2.16.4",
+ "@parcel/transformer-css": "2.16.4",
+ "@parcel/transformer-html": "2.16.4",
+ "@parcel/transformer-image": "2.16.4",
+ "@parcel/transformer-js": "2.16.4",
+ "@parcel/transformer-json": "2.16.4",
+ "@parcel/transformer-node": "2.16.4",
+ "@parcel/transformer-postcss": "2.16.4",
+ "@parcel/transformer-posthtml": "2.16.4",
+ "@parcel/transformer-raw": "2.16.4",
+ "@parcel/transformer-react-refresh-wrap": "2.16.4",
+ "@parcel/transformer-svg": "2.16.4"
},
"funding": {
- "url": "https://opencollective.com/vitest"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
},
"peerDependencies": {
- "vitest": "4.1.4"
+ "@parcel/core": "^2.16.4"
}
},
- "node_modules/@vitest/browser-playwright": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.4.tgz",
- "integrity": "sha512-q3PchVhZINX23Pv+RERgAtDlp6wzVkID/smOPnZ5YGWpeWUe3jMNYppeVh15j4il3G7JIJty1d1Kicpm0HSMig==",
+ "node_modules/@parcel/core": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.16.4.tgz",
+ "integrity": "sha512-a0CgrW5A5kwuSu5J1RFRoMQaMs9yagvfH2jJMYVw56+/7NRI4KOtu612SG9Y1ERWfY55ZwzyFxtLWvD6LO+Anw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/browser": "4.1.4",
- "@vitest/mocker": "4.1.4",
- "tinyrainbow": "^3.1.0"
+ "@mischnic/json-sourcemap": "^0.1.1",
+ "@parcel/cache": "2.16.4",
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/events": "2.16.4",
+ "@parcel/feature-flags": "2.16.4",
+ "@parcel/fs": "2.16.4",
+ "@parcel/graph": "3.6.4",
+ "@parcel/logger": "2.16.4",
+ "@parcel/package-manager": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/profiler": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/types": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "@parcel/workers": "2.16.4",
+ "base-x": "^3.0.11",
+ "browserslist": "^4.24.5",
+ "clone": "^2.1.2",
+ "dotenv": "^16.5.0",
+ "dotenv-expand": "^11.0.7",
+ "json5": "^2.2.3",
+ "msgpackr": "^1.11.2",
+ "nullthrows": "^1.1.1",
+ "semver": "^7.7.1"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "playwright": "*",
- "vitest": "4.1.4"
- },
- "peerDependenciesMeta": {
- "playwright": {
- "optional": false
- }
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@vitest/expect": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.4.tgz",
- "integrity": "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==",
+ "node_modules/@parcel/diagnostic": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.16.4.tgz",
+ "integrity": "sha512-YN5CfX7lFd6yRLxyZT4Sj3sR6t7nnve4TdXSIqapXzQwL7Bw+sj79D95wTq2rCm3mzk5SofGxFAXul2/nG6gcQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@standard-schema/spec": "^1.1.0",
- "@types/chai": "^5.2.2",
- "@vitest/spy": "4.1.4",
- "@vitest/utils": "4.1.4",
- "chai": "^6.2.2",
- "tinyrainbow": "^3.1.0"
+ "@mischnic/json-sourcemap": "^0.1.1",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://opencollective.com/vitest"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@vitest/mocker": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.4.tgz",
- "integrity": "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==",
+ "node_modules/@parcel/error-overlay": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/error-overlay/-/error-overlay-2.16.4.tgz",
+ "integrity": "sha512-e8KYKnMsfmQnqIhsUWBUZAXlDK30wkxsAGle1tZ0gOdoplaIdVq/WjGPatHLf6igLM76c3tRn2vw8jZFput0jw==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@vitest/spy": "4.1.4",
- "estree-walker": "^3.0.3",
- "magic-string": "^0.30.21"
+ "engines": {
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "msw": "^2.4.9",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "msw": {
- "optional": true
- },
- "vite": {
- "optional": true
- }
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@vitest/pretty-format": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.4.tgz",
- "integrity": "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==",
+ "node_modules/@parcel/events": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.16.4.tgz",
+ "integrity": "sha512-slWQkBRAA7o0cN0BLEd+yCckPmlVRVhBZn5Pn6ktm4EzEtrqoMzMeJOxxH8TXaRzrQDYnTcnYIHFgXWd4kkUfg==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "tinyrainbow": "^3.1.0"
+ "engines": {
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://opencollective.com/vitest"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@vitest/runner": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.4.tgz",
- "integrity": "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==",
+ "node_modules/@parcel/feature-flags": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/feature-flags/-/feature-flags-2.16.4.tgz",
+ "integrity": "sha512-nYdx53siKPLYikHHxfzgjzzgxdrjquK6DMnuSgOTyIdRG4VHdEN0+NqKijRLuVgiUFo/dtxc2h+amwqFENMw8w==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@vitest/utils": "4.1.4",
- "pathe": "^2.0.3"
+ "engines": {
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://opencollective.com/vitest"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@vitest/snapshot": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.4.tgz",
- "integrity": "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==",
+ "node_modules/@parcel/fs": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.16.4.tgz",
+ "integrity": "sha512-maCMOiVn7oJYZlqlfxgLne8n6tSktIT1k0AeyBp4UGWCXyeJUJ+nL7QYShFpKNLtMLeF0cEtgwRAknWzbcDS1g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.4",
- "@vitest/utils": "4.1.4",
- "magic-string": "^0.30.21",
- "pathe": "^2.0.3"
+ "@parcel/feature-flags": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/types-internal": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "@parcel/watcher": "^2.0.7",
+ "@parcel/workers": "2.16.4"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://opencollective.com/vitest"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "peerDependencies": {
+ "@parcel/core": "^2.16.4"
}
},
- "node_modules/@vitest/spy": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.4.tgz",
- "integrity": "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==",
+ "node_modules/@parcel/graph": {
+ "version": "3.6.4",
+ "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-3.6.4.tgz",
+ "integrity": "sha512-Cj9yV+/k88kFhE+D+gz0YuNRpvNOCVDskO9pFqkcQhGbsGq6kg2XpZ9V7HlYraih31xf8Vb589bZOwjKIiHixQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/feature-flags": "2.16.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
+ },
"funding": {
- "url": "https://opencollective.com/vitest"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@vitest/utils": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.4.tgz",
- "integrity": "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==",
+ "node_modules/@parcel/logger": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.16.4.tgz",
+ "integrity": "sha512-QR8QLlKo7xAy9JBpPDAh0RvluaixqPCeyY7Fvo2K7hrU3r85vBNNi06pHiPbWoDmB4x1+QoFwMaGnJOHR+/fMA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.4",
- "convert-source-map": "^2.0.0",
- "tinyrainbow": "^3.1.0"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/events": "2.16.4"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://opencollective.com/vitest"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "node_modules/@parcel/markdown-ansi": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.16.4.tgz",
+ "integrity": "sha512-0+oQApAVF3wMcQ6d1ZfZ0JsRzaMUYj9e4U+naj6YEsFsFGOPp+pQYKXBf1bobQeeB7cPKPT3SUHxFqced722Hw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "color-convert": "^2.0.1"
+ "chalk": "^4.1.2"
},
"engines": {
- "node": ">=8"
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/ansis": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz",
- "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==",
+ "node_modules/@parcel/namer-default": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.16.4.tgz",
+ "integrity": "sha512-CE+0lFg881sJq575EXxj2lKUn81tsS5itpNUUErHxit195m3PExyAhoXM6ed/SXxwi+uv+T5FS/jjDLBNuUFDA==",
"dev": true,
- "license": "ISC",
+ "license": "MIT",
+ "dependencies": {
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "nullthrows": "^1.1.1"
+ },
"engines": {
- "node": ">=14"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/assertion-error": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
- "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "node_modules/@parcel/node-resolver-core": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-3.7.4.tgz",
+ "integrity": "sha512-b3VDG+um6IWW5CTod6M9hQsTX5mdIelKmam7mzxzgqg4j5hnycgTWqPMc9UxhYoUY/Q/PHfWepccNcKtvP5JiA==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@mischnic/json-sourcemap": "^0.1.1",
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/fs": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "nullthrows": "^1.1.1",
+ "semver": "^7.7.1"
+ },
"engines": {
- "node": ">=12"
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/ast-kit": {
- "version": "3.0.0-beta.1",
- "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-3.0.0-beta.1.tgz",
- "integrity": "sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw==",
+ "node_modules/@parcel/optimizer-css": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.16.4.tgz",
+ "integrity": "sha512-aqdXCtmvpcXYgJFGk2DtXF34wuM2TD1fZorKMrJdKB9sSkWVRs1tq6RAXQrbi0ZPDH9wfE/9An3YdkTex7RHuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^8.0.0-beta.4",
- "estree-walker": "^3.0.3",
- "pathe": "^2.0.3"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/utils": "2.16.4",
+ "browserslist": "^4.24.5",
+ "lightningcss": "^1.30.1",
+ "nullthrows": "^1.1.1"
},
"engines": {
- "node": ">=20.19.0"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
},
"funding": {
- "url": "https://github.com/sponsors/sxzz"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/async": {
- "version": "2.6.4",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
- "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "node_modules/@parcel/optimizer-html": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/optimizer-html/-/optimizer-html-2.16.4.tgz",
+ "integrity": "sha512-vg/R2uuSni+NYYUUV8m+5bz8p5zBv8wc/nNleoBnGuCDwn7uaUwTZ8Gt9CjZO8jjG0xCLILoc/TW+e2FF3pfgQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "lodash": "^4.17.14"
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/utils": "2.16.4"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/basic-auth": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
- "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "node_modules/@parcel/optimizer-image": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.16.4.tgz",
+ "integrity": "sha512-2RV54WnvMYr18lxSx7Zlx/DXpJwMzOiPxDnoFyvaUoYutvgHO6chtcgFgh1Bvw/PoI95vYzlTkZ8QfUOk5A0JA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "safe-buffer": "5.1.2"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "@parcel/workers": "2.16.4"
},
"engines": {
- "node": ">= 0.8"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "peerDependencies": {
+ "@parcel/core": "^2.16.4"
}
},
- "node_modules/birpc": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/birpc/-/birpc-4.0.0.tgz",
- "integrity": "sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==",
+ "node_modules/@parcel/optimizer-svg": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/optimizer-svg/-/optimizer-svg-2.16.4.tgz",
+ "integrity": "sha512-22+BqIffCrVErg8y2XwhasbTaFNn75OKXZ3KTDBIfOSAZKLUKs1iHfDXETzTRN7cVcS+Q36/6EHd7N/RA8i1fg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/utils": "2.16.4"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
"funding": {
- "url": "https://github.com/sponsors/antfu"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/cac": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz",
- "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==",
+ "node_modules/@parcel/optimizer-swc": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/optimizer-swc/-/optimizer-swc-2.16.4.tgz",
+ "integrity": "sha512-+URqwnB6u1gqaLbG1O1DDApH+UVj4WCbK9No1fdxLBxQ9a84jyli25o1kK1hYB9Nb/JMyYNnEBfvYUW6RphOxw==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/utils": "2.16.4",
+ "@swc/core": "^1.11.24",
+ "nullthrows": "^1.1.1"
+ },
"engines": {
- "node": ">=20.19.0"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "node_modules/@parcel/package-manager": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.16.4.tgz",
+ "integrity": "sha512-obWv9gZgdnkT3Kd+fBkKjhdNEY7zfOP5gVaox5i4nQstVCaVnDlMv5FwLEXwehL+WbwEcGyEGGxOHHkAFKk7Cg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/fs": "2.16.4",
+ "@parcel/logger": "2.16.4",
+ "@parcel/node-resolver-core": "3.7.4",
+ "@parcel/types": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "@parcel/workers": "2.16.4",
+ "@swc/core": "^1.11.24",
+ "semver": "^7.7.1"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "peerDependencies": {
+ "@parcel/core": "^2.16.4"
}
},
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "node_modules/@parcel/packager-css": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.16.4.tgz",
+ "integrity": "sha512-rWRtfiX+VVIOZvq64jpeNUKkvWAbnokfHQsk/js1s5jD4ViNQgPcNLiRaiIANjymqL6+dQqWvGUSW2a5FAZYfg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/utils": "2.16.4",
+ "lightningcss": "^1.30.1",
+ "nullthrows": "^1.1.1"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/chai": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
- "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
+ "node_modules/@parcel/packager-html": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.16.4.tgz",
+ "integrity": "sha512-AWo5f6SSqBsg2uWOsX0gPX8hCx2iE6GYLg2Z4/cDy2mPlwDICN8/bxItEztSZFmObi+ti26eetBKRDxAUivyIQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/types": "2.16.4",
+ "@parcel/utils": "2.16.4"
+ },
"engines": {
- "node": ">=18"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "node_modules/@parcel/packager-js": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.16.4.tgz",
+ "integrity": "sha512-L2o39f/fhta+hxto7w8OTUKdstY+te5BmHZREckbQm0KTBg93BG7jB0bfoxLSZF0d8uuAYIVXjzeHNqha+du1g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/types": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "globals": "^13.24.0",
+ "nullthrows": "^1.1.1"
},
"engines": {
- "node": ">=10"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
},
"funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "node_modules/@parcel/packager-raw": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.16.4.tgz",
+ "integrity": "sha512-A9j60G9OmbTkEeE4WRMXCiErEprHLs9NkUlC4HXCxmSrPMOVaMaMva2LdejE3A9kujZqYtYfuc8+a+jN+Nro4w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "color-name": "~1.1.4"
+ "@parcel/plugin": "2.16.4"
},
"engines": {
- "node": ">=7.0.0"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/corser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
- "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
+ "node_modules/@parcel/packager-svg": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.16.4.tgz",
+ "integrity": "sha512-LT9l7eInFrAZJ6w3mYzAUgDq3SIzYbbQyW46Dz26M9lJQbf6uCaATUTac3BEHegW0ikDuw4OOGHK41BVqeeusg==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/types": "2.16.4",
+ "@parcel/utils": "2.16.4"
+ },
"engines": {
- "node": ">= 0.4.0"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "node_modules/@parcel/packager-wasm": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/packager-wasm/-/packager-wasm-2.16.4.tgz",
+ "integrity": "sha512-AY96Aqu/RpmaSZK2RGkIrZWjAperDw8DAlxLAiaP1D/RPVnikZtl5BmcUt/Wz3PrzG7/q9ZVqqKkWsLmhkjXZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ms": "^2.1.1"
- }
- },
- "node_modules/defu": {
- "version": "6.1.7",
- "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz",
- "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "dev": true,
- "license": "Apache-2.0",
+ "@parcel/plugin": "2.16.4"
+ },
"engines": {
- "node": ">=8"
+ "node": ">=16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/dts-resolver": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/dts-resolver/-/dts-resolver-2.1.3.tgz",
- "integrity": "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==",
+ "node_modules/@parcel/plugin": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.16.4.tgz",
+ "integrity": "sha512-aN2VQoRGC1eB41ZCDbPR/Sp0yKOxe31oemzPx1nJzOuebK2Q6FxSrJ9Bjj9j/YCaLzDtPwelsuLOazzVpXJ6qg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/types": "2.16.4"
+ },
"engines": {
- "node": ">=20.19.0"
+ "node": ">= 16.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/sxzz"
- },
- "peerDependencies": {
- "oxc-resolver": ">=11.0.0"
- },
- "peerDependenciesMeta": {
- "oxc-resolver": {
- "optional": true
- }
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "node_modules/@parcel/profiler": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/profiler/-/profiler-2.16.4.tgz",
+ "integrity": "sha512-R3JhfcnoReTv2sVFHPR2xKZvs3d3IRrBl9sWmAftbIJFwT4rU70/W7IdwfaJVkD/6PzHq9mcgOh1WKL4KAxPdA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/events": "2.16.4",
+ "@parcel/types-internal": "2.16.4",
+ "chrome-trace-event": "^1.0.2"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/empathic": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz",
- "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==",
+ "node_modules/@parcel/reporter-cli": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.16.4.tgz",
+ "integrity": "sha512-DQx9TwcTZrDv828+tcwEi//xyW7OHTGzGX1+UEVxPp0mSzuOmDn0zfER8qNIqGr1i4D/FXhb5UJQDhGHV8mOpQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/plugin": "2.16.4",
+ "@parcel/types": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "chalk": "^4.1.2",
+ "term-size": "^2.2.1"
+ },
"engines": {
- "node": ">=14"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/entities": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
- "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "node_modules/@parcel/reporter-dev-server": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.16.4.tgz",
+ "integrity": "sha512-YWvay25htQDifpDRJ0+yFh6xUxKnbfeJxYkPYyuXdxpEUhq4T0UWW0PbPCN/wFX7StgeUTXq5Poeo/+eys9m3w==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
+ "dependencies": {
+ "@parcel/codeframe": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/utils": "2.16.4"
+ },
"engines": {
- "node": ">=0.12"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
},
"funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "node_modules/@parcel/reporter-tracer": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/reporter-tracer/-/reporter-tracer-2.16.4.tgz",
+ "integrity": "sha512-JKnlXpPepak0/ZybmZn9JtyjJiDBWYrt7ZUlXQhQb0xzNcd/k+RqfwVkTKIwyFHsWtym0cwibkvsi2bWFzS7tw==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/plugin": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "chrome-trace-event": "^1.0.3",
+ "nullthrows": "^1.1.1"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "node_modules/@parcel/resolver-default": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.16.4.tgz",
+ "integrity": "sha512-wJe9XQS0hn/t32pntQpJbls3ZL8mGVVhK9L7s7BTmZT9ufnvP2nif1psJz/nbgnP9LF6mLSk43OdMJKpoStsjQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/node-resolver-core": "3.7.4",
+ "@parcel/plugin": "2.16.4"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/es-module-lexer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
- "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "node_modules/@parcel/runtime-browser-hmr": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.16.4.tgz",
+ "integrity": "sha512-asx7p3NjUSfibI3bC7+8+jUIGHWVk2Zuq9SjJGCGDt+auT9A4uSGljnsk1BWWPqqZ0WILubq4czSAqm0+wt4cw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "es-errors": "^1.3.0"
+ "@parcel/plugin": "2.16.4",
+ "@parcel/utils": "2.16.4"
},
"engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/estree-walker": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
- "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/runtime-js": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.16.4.tgz",
+ "integrity": "sha512-gUKmsjg+PULQBu2QbX0QKll9tXSqHPO8NrfxHwWb2lz5xDKDos1oV0I7BoMWbHhUHkoToXZrm654oGViujtVUA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/estree": "^1.0.0"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/eventemitter3": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
- "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
- "dev": true
+ "node_modules/@parcel/runtime-rsc": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/runtime-rsc/-/runtime-rsc-2.16.4.tgz",
+ "integrity": "sha512-CHkotYE/cNiUjJmrc5FD9YhlFp1UF5wMNNJmoWaL40eBzsqcaV0sSn5V3bNapwewn3wrMYgdPgvOTHfaZaG73A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 12.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/expect-type": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
- "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
+ "node_modules/@parcel/runtime-service-worker": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.16.4.tgz",
+ "integrity": "sha512-FT0Q58bf5Re+dq5cL2XHbxqHHFZco6qtRijeVpT3TSPMRPlniMArypSytTeZzVNL7h/hxjWsNu7fRuC0yLB5hA==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
+ "dependencies": {
+ "@parcel/plugin": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "nullthrows": "^1.1.1"
+ },
"engines": {
- "node": ">=12.0.0"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "node_modules/@parcel/rust": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust/-/rust-2.16.4.tgz",
+ "integrity": "sha512-RBMKt9rCdv6jr4vXG6LmHtxzO5TuhQvXo1kSoSIF7fURRZ81D1jzBtLxwLmfxCPsofJNqWwdhy5vIvisX+TLlQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=12.0.0"
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/rust-darwin-arm64": "2.16.4",
+ "@parcel/rust-darwin-x64": "2.16.4",
+ "@parcel/rust-linux-arm-gnueabihf": "2.16.4",
+ "@parcel/rust-linux-arm64-gnu": "2.16.4",
+ "@parcel/rust-linux-arm64-musl": "2.16.4",
+ "@parcel/rust-linux-x64-gnu": "2.16.4",
+ "@parcel/rust-linux-x64-musl": "2.16.4",
+ "@parcel/rust-win32-x64-msvc": "2.16.4"
},
"peerDependencies": {
- "picomatch": "^3 || ^4"
+ "napi-wasm": "^1.1.2"
},
"peerDependenciesMeta": {
- "picomatch": {
+ "napi-wasm": {
"optional": true
}
}
},
- "node_modules/follow-redirects": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
- "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
+ "node_modules/@parcel/rust-darwin-arm64": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust-darwin-arm64/-/rust-darwin-arm64-2.16.4.tgz",
+ "integrity": "sha512-P3Se36H9EO1fOlwXqQNQ+RsVKTGn5ztRSUGbLcT8ba6oOMmU1w7J4R810GgsCbwCuF10TJNUMkuD3Q2Sz15Q3Q==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": ">=4.0"
+ "node": ">= 10"
},
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "node_modules/@parcel/rust-darwin-x64": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust-darwin-x64/-/rust-darwin-x64-2.16.4.tgz",
+ "integrity": "sha512-8aNKNyPIx3EthYpmVJevIdHmFsOApXAEYGi3HU69jTxLgSIfyEHDdGE9lEsMvhSrd/SSo4/euAtiV+pqK04wnA==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "node_modules/@parcel/rust-linux-arm-gnueabihf": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm-gnueabihf/-/rust-linux-arm-gnueabihf-2.16.4.tgz",
+ "integrity": "sha512-QrvqiSHaWRLc0JBHgUHVvDthfWSkA6AFN+ikV1UGENv4j2r/QgvuwJiG0VHrsL6pH5dRqj0vvngHzEgguke9DA==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "node_modules/@parcel/rust-linux-arm64-gnu": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm64-gnu/-/rust-linux-arm64-gnu-2.16.4.tgz",
+ "integrity": "sha512-f3gBWQHLHRUajNZi3SMmDQiEx54RoRbXtZYQNuBQy7+NolfFcgb1ik3QhkT7xovuTF/LBmaqP3UFy0PxvR/iwQ==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">= 0.4"
+ "node": ">= 10"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "node_modules/@parcel/rust-linux-arm64-musl": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm64-musl/-/rust-linux-arm64-musl-2.16.4.tgz",
+ "integrity": "sha512-cwml18RNKsBwHyZnrZg4jpecXkWjaY/mCArocWUxkFXjjB97L56QWQM9W86f2/Y3HcFcnIGJwx1SDDKJrV6OIA==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
},
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/rust-linux-x64-gnu": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust-linux-x64-gnu/-/rust-linux-x64-gnu-2.16.4.tgz",
+ "integrity": "sha512-0xIjQaN8hiG0F9R8coPYidHslDIrbfOS/qFy5GJNbGA3S49h61wZRBMQqa7JFW4+2T8R0J9j0SKHhLXpbLXrIg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">= 0.4"
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/get-tsconfig": {
- "version": "4.13.7",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz",
- "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==",
+ "node_modules/@parcel/rust-linux-x64-musl": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust-linux-x64-musl/-/rust-linux-x64-musl-2.16.4.tgz",
+ "integrity": "sha512-fYn21GIecHK9RoZPKwT9NOwxwl3Gy3RYPR6zvsUi0+hpFo19Ph9EzFXN3lT8Pi5KiwQMCU4rsLb5HoWOBM1FeA==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
- "dependencies": {
- "resolve-pkg-maps": "^1.0.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
},
"funding": {
- "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "node_modules/@parcel/rust-win32-x64-msvc": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/rust-win32-x64-msvc/-/rust-win32-x64-msvc-2.16.4.tgz",
+ "integrity": "sha512-TcpWC3I1mJpfP2++018lgvM7UX0P8IrzNxceBTHUKEIDMwmAYrUKAQFiaU0j1Ldqk6yP8SPZD3cvphumsYpJOQ==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
"engines": {
- "node": ">= 0.4"
+ "node": ">= 10"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/happy-dom": {
- "version": "20.9.0",
- "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.9.0.tgz",
- "integrity": "sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==",
+ "node_modules/@parcel/source-map": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz",
+ "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/node": ">=20.0.0",
- "@types/whatwg-mimetype": "^3.0.2",
- "@types/ws": "^8.18.1",
- "entities": "^7.0.1",
- "whatwg-mimetype": "^3.0.0",
- "ws": "^8.18.3"
+ "detect-libc": "^1.0.3"
},
"engines": {
- "node": ">=20.0.0"
+ "node": "^12.18.3 || >=14"
}
},
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "node_modules/@parcel/source-map/node_modules/detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
"dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
"engines": {
- "node": ">=8"
+ "node": ">=0.10"
}
},
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "node_modules/@parcel/transformer-babel": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.16.4.tgz",
+ "integrity": "sha512-CMDUOQYX7+cmeyHxHSFnoPcwvXNL7rRFE+Q06uVFzsYYiVhbwGF/1J5Bx4cW3Froumqla4YTytTsEteJEybkdA==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/utils": "2.16.4",
+ "browserslist": "^4.24.5",
+ "json5": "^2.2.3",
+ "nullthrows": "^1.1.1",
+ "semver": "^7.7.1"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "node_modules/@parcel/transformer-css": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.16.4.tgz",
+ "integrity": "sha512-VG/+DbDci2HKe20GFRDs65ZQf5GUFfnmZAa1BhVl/MO+ijT3XC3eoVUy5cExRkq4VLcPY4ytL0g/1T2D6x7lBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "function-bind": "^1.1.2"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/utils": "2.16.4",
+ "browserslist": "^4.24.5",
+ "lightningcss": "^1.30.1",
+ "nullthrows": "^1.1.1"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/he": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
- "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
- "dev": true,
- "bin": {
- "he": "bin/he"
- }
- },
- "node_modules/hookable": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.0.tgz",
- "integrity": "sha512-ZoKZSJgu8voGK2geJS+6YtYjvIzu9AOM/KZXsBxr83uhLL++e9pEv/dlgwgy3dvHg06kTz6JOh1hk3C8Ceiymw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/html-encoding-sniffer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
- "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
+ "node_modules/@parcel/transformer-html": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.16.4.tgz",
+ "integrity": "sha512-w6JErYTeNS+KAzUAER18NHFIFFvxiLGd4Fht1UYcb/FDjJdLAMB/FljyEs0Rto/WAhZ2D0MuSL25HQh837R62g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "whatwg-encoding": "^2.0.0"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4"
},
"engines": {
- "node": ">=12"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/http-proxy": {
- "version": "1.18.1",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
- "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "node_modules/@parcel/transformer-image": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.16.4.tgz",
+ "integrity": "sha512-ZzIn3KvvRqMfcect4Dy+57C9XoQXZhpVJKBdQWMp9wM1qJEgsVgGDcaSBYCs/UYSKMRMP6Wm20pKCt408RkQzg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "eventemitter3": "^4.0.0",
- "follow-redirects": "^1.0.0",
- "requires-port": "^1.0.0"
+ "@parcel/plugin": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "@parcel/workers": "2.16.4",
+ "nullthrows": "^1.1.1"
},
"engines": {
- "node": ">=8.0.0"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "peerDependencies": {
+ "@parcel/core": "^2.16.4"
}
},
- "node_modules/http-server": {
- "version": "14.1.1",
- "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
- "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
+ "node_modules/@parcel/transformer-js": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.16.4.tgz",
+ "integrity": "sha512-FD2fdO6URwAGBPidb3x1dDgLBt972mko0LelcSU05aC/pcKaV9mbCtINbPul1MlStzkxDelhuImcCYIyerheVQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "basic-auth": "^2.0.1",
- "chalk": "^4.1.2",
- "corser": "^2.0.1",
- "he": "^1.2.0",
- "html-encoding-sniffer": "^3.0.0",
- "http-proxy": "^1.18.1",
- "mime": "^1.6.0",
- "minimist": "^1.2.6",
- "opener": "^1.5.1",
- "portfinder": "^1.0.28",
- "secure-compare": "3.0.1",
- "union": "~0.5.0",
- "url-join": "^4.0.1"
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "@parcel/utils": "2.16.4",
+ "@parcel/workers": "2.16.4",
+ "@swc/helpers": "^0.5.0",
+ "browserslist": "^4.24.5",
+ "nullthrows": "^1.1.1",
+ "regenerator-runtime": "^0.14.1",
+ "semver": "^7.7.1"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
},
- "bin": {
- "http-server": "bin/http-server"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
},
- "engines": {
- "node": ">=12"
+ "peerDependencies": {
+ "@parcel/core": "^2.16.4"
}
},
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "node_modules/@parcel/transformer-json": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.16.4.tgz",
+ "integrity": "sha512-pB3ZNqgokdkBCJ+4G0BrPYcIkyM9K1HVk0GvjzcLEFDKsoAp8BGEM68FzagFM/nVq9anYTshIaoh349GK0M/bg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
+ "@parcel/plugin": "2.16.4",
+ "json5": "^2.2.3"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/import-without-cache": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/import-without-cache/-/import-without-cache-0.2.5.tgz",
- "integrity": "sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==",
+ "node_modules/@parcel/transformer-node": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-node/-/transformer-node-2.16.4.tgz",
+ "integrity": "sha512-7t43CPGfMJk1LqFokwxHSsRi+kKC2QvDXaMtqiMShmk50LCwn81WgzuFvNhMwf6lSiBihWupGwF3Fqksg+aisg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@parcel/plugin": "2.16.4"
+ },
"engines": {
- "node": ">=20.19.0"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
},
"funding": {
- "url": "https://github.com/sponsors/sxzz"
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "node_modules/@parcel/transformer-postcss": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.16.4.tgz",
+ "integrity": "sha512-jfmh9ho03H+qwz9S1b/a/oaOmgfMovtHKYDweIGMjKULKIee3AFRqo8RZIOuUMjDuqHWK8SqQmjery4syFV3Xw==",
"dev": true,
"license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
+ "dependencies": {
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "clone": "^2.1.2",
+ "nullthrows": "^1.1.1",
+ "postcss-value-parser": "^4.2.0",
+ "semver": "^7.7.1"
},
"engines": {
- "node": ">=6"
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/lefthook": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-2.1.5.tgz",
- "integrity": "sha512-yB9IFWurFllusbPZqvG0EavTmpNXPya2MuO7Li7YT78xAj3uCQ3AgmW9TVUbTTsSMhsegbiAMRpwfEk2TP1P0A==",
+ "node_modules/@parcel/transformer-posthtml": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.16.4.tgz",
+ "integrity": "sha512-+GXsmGx1L25KQGQnwclgEuQe1t4QU+IoDkgN+Ikj+EnQCOWG4/ts2VpMBeqP5F18ZT4cCSRafj6317o/2lSGJg==",
"dev": true,
- "hasInstallScript": true,
"license": "MIT",
- "bin": {
- "lefthook": "bin/index.js"
+ "dependencies": {
+ "@parcel/plugin": "2.16.4",
+ "@parcel/utils": "2.16.4"
},
- "optionalDependencies": {
- "lefthook-darwin-arm64": "2.1.5",
- "lefthook-darwin-x64": "2.1.5",
- "lefthook-freebsd-arm64": "2.1.5",
- "lefthook-freebsd-x64": "2.1.5",
- "lefthook-linux-arm64": "2.1.5",
- "lefthook-linux-x64": "2.1.5",
- "lefthook-openbsd-arm64": "2.1.5",
- "lefthook-openbsd-x64": "2.1.5",
- "lefthook-windows-arm64": "2.1.5",
- "lefthook-windows-x64": "2.1.5"
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/lefthook-darwin-arm64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-2.1.5.tgz",
- "integrity": "sha512-VITTaw8PxxyE26gkZ8UcwIa5ZrWnKNRGLeeSrqri40cQdXvLTEoMq2tjjw7eiL9UcB0waRReDdzydevy9GOPUQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/lefthook-darwin-x64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-2.1.5.tgz",
- "integrity": "sha512-AvtjYiW0BSGHBGrdvL313seUymrW9FxI+6JJwJ+ZSaa2sH81etrTB0wAwlH1L9VfFwK9+gWvatZBvLfF3L4fPw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/lefthook-freebsd-arm64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-2.1.5.tgz",
- "integrity": "sha512-mXjJwe8jKGWGiBYUxfQY1ab3Nn5NhafqT9q3KJz8m5joGGQj4JD0cbWxF1nVBLBWsDGbWZRZunTCMGcIScT2bQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/lefthook-freebsd-x64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-2.1.5.tgz",
- "integrity": "sha512-exD69dCjc1K45BxatDPGoH4NmEvgLKPm4kJLOWn1fTeHRKZwWiFPwnjknEoG2OemlCDHmCU++5X40kMEG0WBlA==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@parcel/transformer-raw": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.16.4.tgz",
+ "integrity": "sha512-7WDUPq+bW11G9jKxaQIVL+NPGolV99oq/GXhpjYip0SaGaLzRCW7gEk60cftuk0O7MsDaX5jcAJm3G/AX+LJKg==",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
+ "dependencies": {
+ "@parcel/plugin": "2.16.4"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/lefthook-linux-arm64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-2.1.5.tgz",
- "integrity": "sha512-57TDKC5ewWpsCLZQKIJMHumFEObYKVundmPpiWhX491hINRZYYOL/26yrnVnNcidThRzTiTC+HLcuplLcaXtbA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@parcel/transformer-react-refresh-wrap": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.16.4.tgz",
+ "integrity": "sha512-MiLNZrsGQJTANKKa4lzZyUbGj/en0Hms474mMdQkCBFg6GmjfmXwaMMgtTfPA3ZwSp2+3LeObCyca/f9B2gBZQ==",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
+ "dependencies": {
+ "@parcel/error-overlay": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "react-refresh": "^0.16.0"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/lefthook-linux-x64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-2.1.5.tgz",
- "integrity": "sha512-bqK3LrAB5l5YaCaoHk6qRWlITrGWzP4FbwRxA31elbxjd0wgNWZ2Sn3zEfSEcxz442g7/PPkEwqqsTx0kSFzpg==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@parcel/transformer-svg": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.16.4.tgz",
+ "integrity": "sha512-0dm4cQr/WpfQP6N0xjFtwdLTxcONDfoLgTOMk4eNUWydHipSgmLtvUk/nOc/FWkwztRScfAObtZXOiPOd3Oy9A==",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
+ "dependencies": {
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/plugin": "2.16.4",
+ "@parcel/rust": "2.16.4"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "parcel": "^2.16.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/lefthook-openbsd-arm64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-openbsd-arm64/-/lefthook-openbsd-arm64-2.1.5.tgz",
- "integrity": "sha512-5aSwK7vV3A6t0w9PnxCMiVjQlcvopBP50BtmnnLnNJyAYHnFbZ0Baq5M0WkE9IsUkWSux0fe6fd0jDkuG711MA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@parcel/types": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.16.4.tgz",
+ "integrity": "sha512-ctx4mBskZHXeDVHg4OjMwx18jfYH9BzI/7yqbDQVGvd5lyA+/oVVzYdpele2J2i2sSaJ87cA8nb57GDQ8kHAqA==",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
+ "dependencies": {
+ "@parcel/types-internal": "2.16.4",
+ "@parcel/workers": "2.16.4"
+ }
},
- "node_modules/lefthook-openbsd-x64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-openbsd-x64/-/lefthook-openbsd-x64-2.1.5.tgz",
- "integrity": "sha512-Y+pPdDuENJ8qWnUgL02xxhpjblc0WnwXvWGfqnl3WZrAgHzQpwx3G6469RID/wlNVdHYAlw3a8UkFSMYsTzXvA==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@parcel/types-internal": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/types-internal/-/types-internal-2.16.4.tgz",
+ "integrity": "sha512-PE6Qmt5cjzBxX+6MPLiF7r+twoC+V9Skt3zyuBQ+H1c0i9o07Bbz2NKX10nvlPukfmW6Fu/1RvTLkzBZR1bU6A==",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
+ "dependencies": {
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/feature-flags": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "utility-types": "^3.11.0"
+ }
},
- "node_modules/lefthook-windows-arm64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-2.1.5.tgz",
- "integrity": "sha512-2PlcFBjTzJaMufw0c28kfhB/0zmaRCU0TRPPsil/HU2YNOExod4upPGLk9qjgsOmb2YVWFz6zq6u7+D1yqmzTQ==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@parcel/utils": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.16.4.tgz",
+ "integrity": "sha512-lkmxQHcHyOWZLbV8t+h2CGZIkPiBurLm/TS5wNT7+tq0qt9KbVwL7FP2K93TbXhLMGTmpI79Bf3qKniPM167Mw==",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
+ "dependencies": {
+ "@parcel/codeframe": "2.16.4",
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/logger": "2.16.4",
+ "@parcel/markdown-ansi": "2.16.4",
+ "@parcel/rust": "2.16.4",
+ "@parcel/source-map": "^2.1.1",
+ "chalk": "^4.1.2",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
},
- "node_modules/lefthook-windows-x64": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-2.1.5.tgz",
- "integrity": "sha512-yiAh8qxml6uqy10jDxOdN9fOQpyLxBFY1fgCEAhn7sVJYmJKRhjqSBwZX6LG5MQjzr29KStrIdw7TR3lf3rT7Q==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@parcel/watcher": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
+ "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
"dev": true,
+ "hasInstallScript": true,
"license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/lightningcss": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
- "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
- "dev": true,
- "license": "MPL-2.0",
"dependencies": {
- "detect-libc": "^2.0.3"
+ "detect-libc": "^2.0.3",
+ "is-glob": "^4.0.3",
+ "node-addon-api": "^7.0.0",
+ "picomatch": "^4.0.3"
},
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
- "lightningcss-android-arm64": "1.32.0",
- "lightningcss-darwin-arm64": "1.32.0",
- "lightningcss-darwin-x64": "1.32.0",
- "lightningcss-freebsd-x64": "1.32.0",
- "lightningcss-linux-arm-gnueabihf": "1.32.0",
- "lightningcss-linux-arm64-gnu": "1.32.0",
- "lightningcss-linux-arm64-musl": "1.32.0",
- "lightningcss-linux-x64-gnu": "1.32.0",
- "lightningcss-linux-x64-musl": "1.32.0",
- "lightningcss-win32-arm64-msvc": "1.32.0",
- "lightningcss-win32-x64-msvc": "1.32.0"
- }
- },
- "node_modules/lightningcss-android-arm64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
- "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+ "@parcel/watcher-android-arm64": "2.5.6",
+ "@parcel/watcher-darwin-arm64": "2.5.6",
+ "@parcel/watcher-darwin-x64": "2.5.6",
+ "@parcel/watcher-freebsd-x64": "2.5.6",
+ "@parcel/watcher-linux-arm-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm-musl": "2.5.6",
+ "@parcel/watcher-linux-arm64-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm64-musl": "2.5.6",
+ "@parcel/watcher-linux-x64-glibc": "2.5.6",
+ "@parcel/watcher-linux-x64-musl": "2.5.6",
+ "@parcel/watcher-win32-arm64": "2.5.6",
+ "@parcel/watcher-win32-ia32": "2.5.6",
+ "@parcel/watcher-win32-x64": "2.5.6"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
+ "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
"cpu": [
"arm64"
],
"dev": true,
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
- "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
+ "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
"cpu": [
"arm64"
],
"dev": true,
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
- "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
+ "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
"cpu": [
"x64"
],
"dev": true,
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
- "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
+ "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
"cpu": [
"x64"
],
"dev": true,
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
- "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
+ "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
"cpu": [
"arm"
],
"dev": true,
- "license": "MPL-2.0",
- "optional": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
- "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
+ "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
+ "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
"cpu": [
"arm64"
],
@@ -2188,23 +2882,23 @@
"libc": [
"glibc"
],
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
- "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
+ "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
"cpu": [
"arm64"
],
@@ -2212,23 +2906,23 @@
"libc": [
"musl"
],
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
- "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
+ "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
"cpu": [
"x64"
],
@@ -2236,23 +2930,23 @@
"libc": [
"glibc"
],
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
- "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
+ "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
"cpu": [
"x64"
],
@@ -2260,503 +2954,5707 @@
"libc": [
"musl"
],
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
- "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
+ "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
"cpu": [
"arm64"
],
"dev": true,
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
- "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
+ "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
+ "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
"cpu": [
"x64"
],
"dev": true,
- "license": "MPL-2.0",
+ "license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
- "node": ">= 12.0.0"
+ "node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lodash": {
- "version": "4.18.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
- "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "node_modules/@parcel/workers": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.16.4.tgz",
+ "integrity": "sha512-dkBEWqnHXDZnRbTZouNt4uEGIslJT+V0c8OH1MPOfjISp1ucD6/u9ET8k9d/PxS9h1hL53og0SpBuuSEPLDl6A==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/logger": "2.16.4",
+ "@parcel/profiler": "2.16.4",
+ "@parcel/types-internal": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "peerDependencies": {
+ "@parcel/core": "^2.16.4"
+ }
},
- "node_modules/magic-string": {
- "version": "0.30.21",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
- "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "node_modules/@peculiar/asn1-cms": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz",
+ "integrity": "sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
+ "@peculiar/asn1-schema": "^2.6.0",
+ "@peculiar/asn1-x509": "^2.6.1",
+ "@peculiar/asn1-x509-attr": "^2.6.1",
+ "asn1js": "^3.0.6",
+ "tslib": "^2.8.1"
}
},
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "node_modules/@peculiar/asn1-csr": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz",
+ "integrity": "sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-schema": "^2.6.0",
+ "@peculiar/asn1-x509": "^2.6.1",
+ "asn1js": "^3.0.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/asn1-ecc": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz",
+ "integrity": "sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-schema": "^2.6.0",
+ "@peculiar/asn1-x509": "^2.6.1",
+ "asn1js": "^3.0.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/asn1-pfx": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz",
+ "integrity": "sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-cms": "^2.6.1",
+ "@peculiar/asn1-pkcs8": "^2.6.1",
+ "@peculiar/asn1-rsa": "^2.6.1",
+ "@peculiar/asn1-schema": "^2.6.0",
+ "asn1js": "^3.0.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/asn1-pkcs8": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz",
+ "integrity": "sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-schema": "^2.6.0",
+ "@peculiar/asn1-x509": "^2.6.1",
+ "asn1js": "^3.0.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/asn1-pkcs9": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz",
+ "integrity": "sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-cms": "^2.6.1",
+ "@peculiar/asn1-pfx": "^2.6.1",
+ "@peculiar/asn1-pkcs8": "^2.6.1",
+ "@peculiar/asn1-schema": "^2.6.0",
+ "@peculiar/asn1-x509": "^2.6.1",
+ "@peculiar/asn1-x509-attr": "^2.6.1",
+ "asn1js": "^3.0.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/asn1-rsa": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz",
+ "integrity": "sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-schema": "^2.6.0",
+ "@peculiar/asn1-x509": "^2.6.1",
+ "asn1js": "^3.0.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/asn1-schema": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz",
+ "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asn1js": "^3.0.6",
+ "pvtsutils": "^1.3.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/asn1-x509": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz",
+ "integrity": "sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-schema": "^2.6.0",
+ "asn1js": "^3.0.6",
+ "pvtsutils": "^1.3.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/asn1-x509-attr": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz",
+ "integrity": "sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-schema": "^2.6.0",
+ "@peculiar/asn1-x509": "^2.6.1",
+ "asn1js": "^3.0.6",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@peculiar/x509": {
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz",
+ "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@peculiar/asn1-cms": "^2.6.0",
+ "@peculiar/asn1-csr": "^2.6.0",
+ "@peculiar/asn1-ecc": "^2.6.0",
+ "@peculiar/asn1-pkcs9": "^2.6.0",
+ "@peculiar/asn1-rsa": "^2.6.0",
+ "@peculiar/asn1-schema": "^2.6.0",
+ "@peculiar/asn1-x509": "^2.6.0",
+ "pvtsutils": "^1.3.6",
+ "reflect-metadata": "^0.2.2",
+ "tslib": "^2.8.1",
+ "tsyringe": "^4.10.0"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": ">=20.0.0"
}
},
- "node_modules/mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
"dev": true,
- "bin": {
- "mime": "cli.js"
+ "license": "MIT"
+ },
+ "node_modules/@publint/pack": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@publint/pack/-/pack-0.1.4.tgz",
+ "integrity": "sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://bjornlu.com/sponsor"
+ }
+ },
+ "node_modules/@quansync/fs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz",
+ "integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quansync": "^1.0.0"
},
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.16.tgz",
+ "integrity": "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
"engines": {
- "node": ">=4"
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.16.tgz",
+ "integrity": "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.16.tgz",
+ "integrity": "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.16.tgz",
+ "integrity": "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.16.tgz",
+ "integrity": "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.16.tgz",
+ "integrity": "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.16.tgz",
+ "integrity": "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.16.tgz",
+ "integrity": "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.16.tgz",
+ "integrity": "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.16.tgz",
+ "integrity": "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.16.tgz",
+ "integrity": "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.16.tgz",
+ "integrity": "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.16.tgz",
+ "integrity": "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.9.2",
+ "@emnapi/runtime": "1.9.2",
+ "@napi-rs/wasm-runtime": "^1.1.4"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.16.tgz",
+ "integrity": "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.16.tgz",
+ "integrity": "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz",
+ "integrity": "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rsbuild/core": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.7.5.tgz",
+ "integrity": "sha512-i37urpoV4y9NSsGiUOuLdoI42KJ5h4gAZ8EG8Ilmsond3bxoAoOCu7YvC+1pJ7p+r16suVPW8cki891ZKHOoXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rspack/core": "~1.7.10",
+ "@rspack/lite-tapable": "~1.1.0",
+ "@swc/helpers": "^0.5.20",
+ "core-js": "~3.47.0",
+ "jiti": "^2.6.1"
+ },
+ "bin": {
+ "rsbuild": "bin/rsbuild.js"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
+ "node_modules/@rspack/binding": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.7.11.tgz",
+ "integrity": "sha512-2MGdy2s2HimsDT444Bp5XnALzNRxuBNc7y0JzyuqKbHBywd4x2NeXyhWXXoxufaCFu5PBc9Qq9jyfjW2Aeh06Q==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "@rspack/binding-darwin-arm64": "1.7.11",
+ "@rspack/binding-darwin-x64": "1.7.11",
+ "@rspack/binding-linux-arm64-gnu": "1.7.11",
+ "@rspack/binding-linux-arm64-musl": "1.7.11",
+ "@rspack/binding-linux-x64-gnu": "1.7.11",
+ "@rspack/binding-linux-x64-musl": "1.7.11",
+ "@rspack/binding-wasm32-wasi": "1.7.11",
+ "@rspack/binding-win32-arm64-msvc": "1.7.11",
+ "@rspack/binding-win32-ia32-msvc": "1.7.11",
+ "@rspack/binding-win32-x64-msvc": "1.7.11"
+ }
+ },
+ "node_modules/@rspack/binding-darwin-arm64": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.7.11.tgz",
+ "integrity": "sha512-oduECiZVqbO5zlVw+q7Vy65sJFth99fWPTyucwvLJJtJkPL5n17Uiql2cYP6Ijn0pkqtf1SXgK8WjiKLG5bIig==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rspack/binding-darwin-x64": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.7.11.tgz",
+ "integrity": "sha512-a1+TtTE9ap6RalgFi7FGIgkJP6O4Vy6ctv+9WGJy53E4kuqHR0RygzaiVxCI/GMc/vBT9vY23hyrpWb3d1vtXA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rspack/binding-linux-arm64-gnu": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.7.11.tgz",
+ "integrity": "sha512-P0QrGRPbTWu6RKWfN0bDtbnEps3rXH0MWIMreZABoUrVmNQKtXR6e73J3ub6a+di5s2+K0M2LJ9Bh2/H4UsDUA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rspack/binding-linux-arm64-musl": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.7.11.tgz",
+ "integrity": "sha512-6ky7R43VMjWwmx3Yx7Jl7faLBBMAgMDt+/bN35RgwjiPgsIByz65EwytUVuW9rikB43BGHvA/eqlnjLrUzNBqw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rspack/binding-linux-x64-gnu": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.7.11.tgz",
+ "integrity": "sha512-cuOJMfCOvb2Wgsry5enXJ3iT1FGUjdPqtGUBVupQlEG4ntSYsQ2PtF4wIDVasR3wdxC5nQbipOrDiN/u6fYsdQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rspack/binding-linux-x64-musl": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.7.11.tgz",
+ "integrity": "sha512-CoK37hva4AmHGh3VCsQXmGr40L36m1/AdnN5LEjUX6kx5rEH7/1nEBN6Ii72pejqDVvk9anEROmPDiPw10tpFg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rspack/binding-wasm32-wasi": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.7.11.tgz",
+ "integrity": "sha512-OtrmnPUVJMxjNa3eDMfHyPdtlLRmmp/aIm0fQHlAOATbZvlGm12q7rhPW5BXTu1yh+1rQ1/uqvz+SzKEZXuJaQ==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "1.0.7"
+ }
+ },
+ "node_modules/@rspack/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz",
+ "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.5.0",
+ "@emnapi/runtime": "^1.5.0",
+ "@tybys/wasm-util": "^0.10.1"
+ }
+ },
+ "node_modules/@rspack/binding-win32-arm64-msvc": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.7.11.tgz",
+ "integrity": "sha512-lObFW6e5lCWNgTBNwT//yiEDbsxm9QG4BYUojqeXxothuzJ/L6ibXz6+gLMvbOvLGV3nKgkXmx8GvT9WDKR0mA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rspack/binding-win32-ia32-msvc": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.7.11.tgz",
+ "integrity": "sha512-0pYGnZd8PPqNR68zQ8skamqNAXEA1sUfXuAdYcknIIRq2wsbiwFzIc0Pov1cIfHYab37G7sSIPBiOUdOWF5Ivw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rspack/binding-win32-x64-msvc": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.7.11.tgz",
+ "integrity": "sha512-EeQXayoQk/uBkI3pdoXfQBXNIUrADq56L3s/DFyM2pJeUDrWmhfIw2UFIGkYPTMSCo8F2JcdcGM32FGJrSnU0Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rspack/core": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.7.11.tgz",
+ "integrity": "sha512-rsD9b+Khmot5DwCMiB3cqTQo53ioPG3M/A7BySu8+0+RS7GCxKm+Z+mtsjtG/vsu4Tn2tcqCdZtA3pgLoJB+ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@module-federation/runtime-tools": "0.22.0",
+ "@rspack/binding": "1.7.11",
+ "@rspack/lite-tapable": "1.1.0"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ },
+ "peerDependencies": {
+ "@swc/helpers": ">=0.5.1"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rspack/lite-tapable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.1.0.tgz",
+ "integrity": "sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sqlite.org/in-worker-demo": {
+ "resolved": "demos/in-worker-demo",
+ "link": true
+ },
+ "node_modules/@sqlite.org/kvvfs-demo": {
+ "resolved": "demos/kvvfs-demo",
+ "link": true
+ },
+ "node_modules/@sqlite.org/main-thread-demo": {
+ "resolved": "demos/main-thread-demo",
+ "link": true
+ },
+ "node_modules/@sqlite.org/opfs-demo": {
+ "resolved": "demos/opfs-demo",
+ "link": true
+ },
+ "node_modules/@sqlite.org/opfs-wl-demo": {
+ "resolved": "demos/opfs-wl-demo",
+ "link": true
+ },
+ "node_modules/@sqlite.org/sahpool-demo": {
+ "resolved": "demos/sahpool-demo",
+ "link": true
+ },
+ "node_modules/@sqlite.org/sahpool-parcel-demo": {
+ "resolved": "demos/sahpool-parcel-demo",
+ "link": true
+ },
+ "node_modules/@sqlite.org/sahpool-rsbuild-demo": {
+ "resolved": "demos/sahpool-rsbuild-demo",
+ "link": true
+ },
+ "node_modules/@sqlite.org/sahpool-webpack-demo": {
+ "resolved": "demos/sahpool-webpack-demo",
+ "link": true
+ },
+ "node_modules/@standard-schema/spec": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@swc/core": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.30.tgz",
+ "integrity": "sha512-R8VQbQY1BZcbIF2p3gjlTCwAQzx1A194ugWfwld5y+WgVVWqVKm7eURGGOVbQVubgKWzidP2agomBbg96rZilQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.26"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.15.30",
+ "@swc/core-darwin-x64": "1.15.30",
+ "@swc/core-linux-arm-gnueabihf": "1.15.30",
+ "@swc/core-linux-arm64-gnu": "1.15.30",
+ "@swc/core-linux-arm64-musl": "1.15.30",
+ "@swc/core-linux-ppc64-gnu": "1.15.30",
+ "@swc/core-linux-s390x-gnu": "1.15.30",
+ "@swc/core-linux-x64-gnu": "1.15.30",
+ "@swc/core-linux-x64-musl": "1.15.30",
+ "@swc/core-win32-arm64-msvc": "1.15.30",
+ "@swc/core-win32-ia32-msvc": "1.15.30",
+ "@swc/core-win32-x64-msvc": "1.15.30"
+ },
+ "peerDependencies": {
+ "@swc/helpers": ">=0.5.17"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/core-darwin-arm64": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.30.tgz",
+ "integrity": "sha512-VvpP+vq08HmGYewMWvrdsxh9s2lthz/808zXm8Yu5kaqeR8Yia2b0eYXleHQ3VAjoStUDk6LzTheBW9KXYQdMA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-darwin-x64": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.30.tgz",
+ "integrity": "sha512-WiJA0hiZI3nwQAO6mu5RqigtWGDtth4Hiq6rbZxAaQyhIcqKIg5IoMRc1Y071lrNJn29eEDMC86Rq58xgUxlDg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.30.tgz",
+ "integrity": "sha512-YANuFUo48kIT6plJgCD0keae9HFXfjxsbvsgevqc0hr/07X/p7sAWTFOGYEc2SXcASaK7UvuQqzlbW8pr7R79g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-gnu": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.30.tgz",
+ "integrity": "sha512-VndG8jaR4ugY6u+iVOT0Q+d2fZd7sLgjPgN8W/Le+3EbZKl+cRfFxV7Eoz4gfLqhmneZPdcIzf9T3LkgkmqNLg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-musl": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.30.tgz",
+ "integrity": "sha512-1SYGs2l0Yyyi0pR/P/NKz/x0kqxkoiw+BXeJjLUdecSk/KasncWlJrc6hOvFSgKHOBrzgM5jwuluKtlT8dnrcA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-ppc64-gnu": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.30.tgz",
+ "integrity": "sha512-TXREtiXeRhbfDFbmhnkIsXpKfzbfT73YkV2ZF6w0sfxgjC5zI2ZAbaCOq25qxvegofj2K93DtOpm9RLaBgqR2g==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-s390x-gnu": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.30.tgz",
+ "integrity": "sha512-DCR2YYeyd6DQE4OuDhImouuNcjXEiEdnn1Y0DyGteugPEDvVuvYk8Xddi+4o2SgWH6jiW8/I+3emZvbep1NC+g==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-gnu": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.30.tgz",
+ "integrity": "sha512-5Pizw3NgfOJ5BJOBK8TIRa59xFW2avESTOBDPTAYwZYa1JNDs+KMF9lUfjJiJLM5HiMs/wPheA9eiT0q9m2AoA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-musl": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.30.tgz",
+ "integrity": "sha512-qyqydP/wyH8alcIP4a2hnGSjHLJjm9H7yDFup+CPy9oTahFgLLwnNcv5UHXqO2Qs3AIND+cls5f/Bb6hqpxdgA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-arm64-msvc": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.30.tgz",
+ "integrity": "sha512-CaQENgDHVGOg1mSF5sQVgvfFHG9kjMor2rkLMLeLOkfZYNj13ppnJ9+lfaBZLZUMMbnlGQnavCJb8PVBUOso7Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-ia32-msvc": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.30.tgz",
+ "integrity": "sha512-30VdLeGk6fugiUs/kUdJ/pAg7z/zpvVbR11RH60jZ0Z42WIeIniYx0rLEWN7h/pKJ3CopqsQ3RsogCAkRKiA2g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-x64-msvc": {
+ "version": "1.15.30",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.30.tgz",
+ "integrity": "sha512-4iObHPR+Q4oDY110EF5SF5eIaaVJNpMdG9C0q3Q92BsJ5y467uHz7sYQhP60WYlLFsLQ1el2YrIPUItUAQGOKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz",
+ "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@swc/types": {
+ "version": "0.1.26",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz",
+ "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3"
+ }
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.6",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
+ "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/bonjour": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz",
+ "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
+ "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*",
+ "assertion-error": "^2.0.1"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect-history-api-fallback": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz",
+ "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express-serve-static-core": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/eslint": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/express": {
+ "version": "4.17.25",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz",
+ "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.33",
+ "@types/qs": "*",
+ "@types/serve-static": "^1"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "4.19.8",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz",
+ "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/http-errors": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
+ "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/http-proxy": {
+ "version": "1.17.17",
+ "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz",
+ "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/jsesc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@types/jsesc/-/jsesc-2.5.1.tgz",
+ "integrity": "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "25.6.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz",
+ "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.19.0"
+ }
+ },
+ "node_modules/@types/qs": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.0.tgz",
+ "integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/retry": {
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz",
+ "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-index": {
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz",
+ "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.10",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz",
+ "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/node": "*",
+ "@types/send": "<1"
+ }
+ },
+ "node_modules/@types/serve-static/node_modules/@types/send": {
+ "version": "0.17.6",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz",
+ "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/sockjs": {
+ "version": "0.3.36",
+ "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz",
+ "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/whatwg-mimetype": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz",
+ "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/ws": {
+ "version": "8.18.1",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
+ "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@typescript/native-preview": {
+ "version": "7.0.0-dev.20260421.2",
+ "resolved": "https://registry.npmjs.org/@typescript/native-preview/-/native-preview-7.0.0-dev.20260421.2.tgz",
+ "integrity": "sha512-CmajHI25HpVWE9R1XFoxr+cphJPxoYD3eFioQtAvXYkMFKnLdICMS9pXre9Pybizb75ejRxjKD5/CVG055rEIg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsgo": "bin/tsgo.js"
+ },
+ "optionalDependencies": {
+ "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260421.2",
+ "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260421.2",
+ "@typescript/native-preview-linux-arm": "7.0.0-dev.20260421.2",
+ "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260421.2",
+ "@typescript/native-preview-linux-x64": "7.0.0-dev.20260421.2",
+ "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260421.2",
+ "@typescript/native-preview-win32-x64": "7.0.0-dev.20260421.2"
+ }
+ },
+ "node_modules/@typescript/native-preview-darwin-arm64": {
+ "version": "7.0.0-dev.20260421.2",
+ "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-arm64/-/native-preview-darwin-arm64-7.0.0-dev.20260421.2.tgz",
+ "integrity": "sha512-fHv1r3ZmVo6zxuAIFmuX3w9QxbcauoG0SsWhmDwm6VmRubLlOJIcmTtlmV3JAb9oOnq8LuzZljzT7Q39fSMQDw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@typescript/native-preview-darwin-x64": {
+ "version": "7.0.0-dev.20260421.2",
+ "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-x64/-/native-preview-darwin-x64-7.0.0-dev.20260421.2.tgz",
+ "integrity": "sha512-KWTR6xbW9t+JS7D5DQIzo75pqVXVWUxF9PMv/+S6xsnOjCVd6g0ixHcFpFMJMKSUQpGPr8Z5f7b8ks6LHW01jg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@typescript/native-preview-linux-arm": {
+ "version": "7.0.0-dev.20260421.2",
+ "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm/-/native-preview-linux-arm-7.0.0-dev.20260421.2.tgz",
+ "integrity": "sha512-BWLQO3nemLDSV5PoE5GPHe1dU9Dth77Kv8/cle9Ujcp4LhPo0KincdPqFH/qKeU/xvW25mgFueflZ1nc4rKuww==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@typescript/native-preview-linux-arm64": {
+ "version": "7.0.0-dev.20260421.2",
+ "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm64/-/native-preview-linux-arm64-7.0.0-dev.20260421.2.tgz",
+ "integrity": "sha512-VLMEuml3BhUb+jaL0TXQ4xvVODxJF+RhkI+tBWvlynsJI4khTXEiwWh+wPOJrsfBRYFRMXEu28Odl/HXkYze8w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@typescript/native-preview-linux-x64": {
+ "version": "7.0.0-dev.20260421.2",
+ "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-x64/-/native-preview-linux-x64-7.0.0-dev.20260421.2.tgz",
+ "integrity": "sha512-qUrJWTB5/wv4wnRG0TRXElAxc2kykNiRNyEIEqBbLmzDlrcvAW7RRy8MXoY1ZyTiKGMu14itZ3x9oW6+blFpRw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@typescript/native-preview-win32-arm64": {
+ "version": "7.0.0-dev.20260421.2",
+ "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-arm64/-/native-preview-win32-arm64-7.0.0-dev.20260421.2.tgz",
+ "integrity": "sha512-Rc6NsWlZmCs5YUKVzKgwoBOoRUGsPzct4BDMRX0csD1devLBBc4AbUXWKsJRbpwIAnqMO1ld4sNHEb+wXgfNHQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@typescript/native-preview-win32-x64": {
+ "version": "7.0.0-dev.20260421.2",
+ "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-x64/-/native-preview-win32-x64-7.0.0-dev.20260421.2.tgz",
+ "integrity": "sha512-GQv1+dya1t6EqF2Cpsb+xoozovdX10JUSf6Kl/8xNkTapzmlHd+uMr+8ku3jIASTxoRGn0Mklgjj3MDKrOTuLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@vitest/browser": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.5.tgz",
+ "integrity": "sha512-iCDGI8c4yg+xmjUg2VsygdAUSIIB4x5Rht/P68OXy1hPELKXHDkzh87lkuTcdYmemRChDkEpB426MmDjzC0ziA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@blazediff/core": "1.9.1",
+ "@vitest/mocker": "4.1.5",
+ "@vitest/utils": "4.1.5",
+ "magic-string": "^0.30.21",
+ "pngjs": "^7.0.0",
+ "sirv": "^3.0.2",
+ "tinyrainbow": "^3.1.0",
+ "ws": "^8.19.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "vitest": "4.1.5"
+ }
+ },
+ "node_modules/@vitest/browser-playwright": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.5.tgz",
+ "integrity": "sha512-CWy0lBQJq97nionyJJdnaU4961IXTl43a7UCu5nHy51IoKxAt6PVIJLo+76rVl7KOOgcWHNkG4kbJu/pW7knvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/browser": "4.1.5",
+ "@vitest/mocker": "4.1.5",
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "playwright": "*",
+ "vitest": "4.1.5"
+ },
+ "peerDependenciesMeta": {
+ "playwright": {
+ "optional": false
+ }
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz",
+ "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.1.0",
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "4.1.5",
+ "@vitest/utils": "4.1.5",
+ "chai": "^6.2.2",
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz",
+ "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "4.1.5",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.21"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz",
+ "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz",
+ "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "4.1.5",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz",
+ "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.1.5",
+ "@vitest/utils": "4.1.5",
+ "magic-string": "^0.30.21",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz",
+ "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz",
+ "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.1.5",
+ "convert-source-map": "^2.0.0",
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+ "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+ "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/accepts/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-phases": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
+ "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "peerDependencies": {
+ "acorn": "^8.14.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/ansi-html-community": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
+ "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==",
+ "dev": true,
+ "engines": [
+ "node >= 0.8.0"
+ ],
+ "license": "Apache-2.0",
+ "bin": {
+ "ansi-html": "bin/ansi-html"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ansis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz",
+ "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/anymatch/node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/asn1js": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz",
+ "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "pvtsutils": "^1.3.6",
+ "pvutils": "^1.1.5",
+ "tslib": "^2.8.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/ast-kit": {
+ "version": "3.0.0-beta.1",
+ "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-3.0.0-beta.1.tgz",
+ "integrity": "sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^8.0.0-beta.4",
+ "estree-walker": "^3.0.3",
+ "pathe": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/base-x": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz",
+ "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.10.20",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.20.tgz",
+ "integrity": "sha512-1AaXxEPfXT+GvTBJFuy4yXVHWJBXa4OdbIebGN/wX5DlsIkU0+wzGnd2lOzokSk51d5LUmqjgBLRLlypLUqInQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/birpc": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-4.0.0.tgz",
+ "integrity": "sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.4",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz",
+ "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "~1.2.0",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.4.24",
+ "on-finished": "~2.4.1",
+ "qs": "~6.14.0",
+ "raw-body": "~2.5.3",
+ "type-is": "~1.6.18",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/bonjour-service": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz",
+ "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "multicast-dns": "^7.2.5"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
+ "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.10.12",
+ "caniuse-lite": "^1.0.30001782",
+ "electron-to-chromium": "^1.5.328",
+ "node-releases": "^2.0.36",
+ "update-browserslist-db": "^1.2.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/bytestreamjs": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz",
+ "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/cac": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz",
+ "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001788",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz",
+ "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chai": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
+ "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+ "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/commander": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": ">= 1.43.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/compression": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
+ "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "compressible": "~2.0.18",
+ "debug": "2.6.9",
+ "negotiator": "~0.6.4",
+ "on-headers": "~1.1.0",
+ "safe-buffer": "5.2.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/connect-history-api-fallback": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz",
+ "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
+ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/core-js": {
+ "version": "3.47.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz",
+ "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/default-browser": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz",
+ "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
+ "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/defu": {
+ "version": "6.1.7",
+ "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz",
+ "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dns-packet": {
+ "version": "5.6.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
+ "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@leichtgewicht/ip-codec": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dotenv-expand": {
+ "version": "11.0.7",
+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz",
+ "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dotenv": "^16.4.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dts-resolver": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/dts-resolver/-/dts-resolver-2.1.3.tgz",
+ "integrity": "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "oxc-resolver": ">=11.0.0"
+ },
+ "peerDependenciesMeta": {
+ "oxc-resolver": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.340",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.340.tgz",
+ "integrity": "sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/empathic": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz",
+ "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.20.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz",
+ "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/envinfo": {
+ "version": "7.21.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz",
+ "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
+ "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/expect-type": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
+ "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
+ "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "~1.20.3",
+ "content-disposition": "~0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "~0.7.1",
+ "cookie-signature": "~1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.3.1",
+ "fresh": "~0.5.2",
+ "http-errors": "~2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "~2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "~0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "~6.14.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "~0.19.0",
+ "serve-static": "~1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "~2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/faye-websocket": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
+ "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "websocket-driver": ">=0.5.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
+ "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "~2.0.2",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
+ "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-port": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz",
+ "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.13.7",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz",
+ "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob-to-regex.js": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz",
+ "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/handle-thing": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/happy-dom": {
+ "version": "20.9.0",
+ "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.9.0.tgz",
+ "integrity": "sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": ">=20.0.0",
+ "@types/whatwg-mimetype": "^3.0.2",
+ "@types/ws": "^8.18.1",
+ "entities": "^7.0.1",
+ "whatwg-mimetype": "^3.0.0",
+ "ws": "^8.18.3"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz",
+ "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.1.tgz",
+ "integrity": "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
+ }
+ },
+ "node_modules/hpack.js/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/hpack.js/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hpack.js/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/http-parser-js": {
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
+ "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/http-proxy-middleware": {
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz",
+ "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-proxy": "^1.17.8",
+ "http-proxy": "^1.18.1",
+ "is-glob": "^4.0.1",
+ "is-plain-obj": "^3.0.0",
+ "micromatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "@types/express": "^4.17.13"
+ },
+ "peerDependenciesMeta": {
+ "@types/express": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/hyperdyperid": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz",
+ "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.18"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-without-cache": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/import-without-cache/-/import-without-cache-0.3.3.tgz",
+ "integrity": "sha512-bDxwDdF04gm550DfZHgffvlX+9kUlcz32UD0AeBTmVPFiWkrexF2XVmiuFFbDhiFuP8fQkrkvI2KdSNPYWAXkQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/ipaddr.js": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz",
+ "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-network-error": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz",
+ "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
+ "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
+ "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/launch-editor": {
+ "version": "2.13.2",
+ "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz",
+ "integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picocolors": "^1.1.1",
+ "shell-quote": "^1.8.3"
+ }
+ },
+ "node_modules/lefthook": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-2.1.6.tgz",
+ "integrity": "sha512-w9sBoR0mdN+kJc3SB85VzpiAAl451/rxdCRcZlwW71QLjkeH3EBQFgc4VMj5apePychYDHAlqEWTB8J8JK/j1Q==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "lefthook": "bin/index.js"
+ },
+ "optionalDependencies": {
+ "lefthook-darwin-arm64": "2.1.6",
+ "lefthook-darwin-x64": "2.1.6",
+ "lefthook-freebsd-arm64": "2.1.6",
+ "lefthook-freebsd-x64": "2.1.6",
+ "lefthook-linux-arm64": "2.1.6",
+ "lefthook-linux-x64": "2.1.6",
+ "lefthook-openbsd-arm64": "2.1.6",
+ "lefthook-openbsd-x64": "2.1.6",
+ "lefthook-windows-arm64": "2.1.6",
+ "lefthook-windows-x64": "2.1.6"
+ }
+ },
+ "node_modules/lefthook-darwin-arm64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-2.1.6.tgz",
+ "integrity": "sha512-hyB7eeiX78BS66f70byTJacDLC/xV1vgMv9n+idFUsrM7J3Udd/ag9Ag5NP3t0eN0EqQqAtrNnt35EH01lxnRQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/lefthook-darwin-x64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-2.1.6.tgz",
+ "integrity": "sha512-5Ka6cFxiH83krt+OMRQtmS6zqoZR5SLXSudLjTbZA1c3ZqF0+dqkeb4XcB6plx6WR0GFizabuc6Bi3iXPIe1eQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/lefthook-freebsd-arm64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-2.1.6.tgz",
+ "integrity": "sha512-VswyOg5CVN3rMaOJ2HtnkltiMKgFHW/wouWxXsV8RxSa4tgWOKxM0EmSXi8qc2jX+LRga6B0uOY6toXS01zWxA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/lefthook-freebsd-x64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-2.1.6.tgz",
+ "integrity": "sha512-vXsCUFYuVwrVWwcypB7Zt2Hf+5pl1V1la7ZfvGYZaTRURu0zF/XUnMF/nOz/PebGv0f4x/iOWXWwP7E42xRWsg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/lefthook-linux-arm64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-2.1.6.tgz",
+ "integrity": "sha512-WDJiQhJdZOvKORZd+kF/ms2l6NSsXzdA9ahflyr65V90AC4jES223W8VtEMbGPUtHuGWMEZ/v/XvwlWv0Ioz9g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/lefthook-linux-x64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-2.1.6.tgz",
+ "integrity": "sha512-C18nCd7nTX1AVL4TcvwMmLAO1VI1OuGluIOTjiPkBQ746Ls1HhL5rl//jMPACmT28YmxIQJ2ZcLPNmhvEVBZvw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/lefthook-openbsd-arm64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-openbsd-arm64/-/lefthook-openbsd-arm64-2.1.6.tgz",
+ "integrity": "sha512-mZOMxM8HiPxVFXDO3PtCUbH4GB8rkveXhsgXF27oAZTYVzQ3gO9vT6r/pxit6msqRXz3fvcwimLVJgb8eRsa8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/lefthook-openbsd-x64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-openbsd-x64/-/lefthook-openbsd-x64-2.1.6.tgz",
+ "integrity": "sha512-sG9ALLZSnnMOfXu+B7SmxFhJhuoAh4bqi5En5aaHJET48TqrLOcWWZuH+7ArFM6gr/U5KfSUvdmHFmY8WqCcIg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/lefthook-windows-arm64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-2.1.6.tgz",
+ "integrity": "sha512-lD8yFWY4Csuljd0Rqs7EQaySC0VvDf7V3rN1FhRMUISTRDHutebIom1Loc8ckQPvKYGC6mftT9k0GvipsS+Brw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/lefthook-windows-x64": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-2.1.6.tgz",
+ "integrity": "sha512-q4z2n3xucLscoWiyMwFViEj3N8MDSkPulMwcJYuCYFHoPhP1h+icqNu7QRLGYj6AnVrCQweiUJY3Tb2X+GbD/A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/lightningcss": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.32.0",
+ "lightningcss-darwin-arm64": "1.32.0",
+ "lightningcss-darwin-x64": "1.32.0",
+ "lightningcss-freebsd-x64": "1.32.0",
+ "lightningcss-linux-arm-gnueabihf": "1.32.0",
+ "lightningcss-linux-arm64-gnu": "1.32.0",
+ "lightningcss-linux-arm64-musl": "1.32.0",
+ "lightningcss-linux-x64-gnu": "1.32.0",
+ "lightningcss-linux-x64-musl": "1.32.0",
+ "lightningcss-win32-arm64-msvc": "1.32.0",
+ "lightningcss-win32-x64-msvc": "1.32.0"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lmdb": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.8.5.tgz",
+ "integrity": "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "msgpackr": "^1.9.5",
+ "node-addon-api": "^6.1.0",
+ "node-gyp-build-optional-packages": "5.1.1",
+ "ordered-binary": "^1.4.1",
+ "weak-lru-cache": "^1.2.2"
+ },
+ "bin": {
+ "download-lmdb-prebuilds": "bin/download-prebuilds.js"
+ },
+ "optionalDependencies": {
+ "@lmdb/lmdb-darwin-arm64": "2.8.5",
+ "@lmdb/lmdb-darwin-x64": "2.8.5",
+ "@lmdb/lmdb-linux-arm": "2.8.5",
+ "@lmdb/lmdb-linux-arm64": "2.8.5",
+ "@lmdb/lmdb-linux-x64": "2.8.5",
+ "@lmdb/lmdb-win32-x64": "2.8.5"
+ }
+ },
+ "node_modules/lmdb/node_modules/node-addon-api": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
+ "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz",
+ "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.11.5"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memfs": {
+ "version": "4.57.2",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.2.tgz",
+ "integrity": "sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jsonjoy.com/fs-core": "4.57.2",
+ "@jsonjoy.com/fs-fsa": "4.57.2",
+ "@jsonjoy.com/fs-node": "4.57.2",
+ "@jsonjoy.com/fs-node-builtins": "4.57.2",
+ "@jsonjoy.com/fs-node-to-fsa": "4.57.2",
+ "@jsonjoy.com/fs-node-utils": "4.57.2",
+ "@jsonjoy.com/fs-print": "4.57.2",
+ "@jsonjoy.com/fs-snapshot": "4.57.2",
+ "@jsonjoy.com/json-pack": "^1.11.0",
+ "@jsonjoy.com/util": "^1.9.0",
+ "glob-to-regex.js": "^1.0.1",
+ "thingies": "^2.5.0",
+ "tree-dump": "^1.0.3",
+ "tslib": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/msgpackr": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.10.tgz",
+ "integrity": "sha512-iCZNq+HszvF+fC3anCm4nBmWEnbeIAfpDs6IStAEKhQ2YSgkjzVG2FF9XJqwwQh5bH3N9OUTUt4QwVN6MLMLtA==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "msgpackr-extract": "^3.0.2"
+ }
+ },
+ "node_modules/msgpackr-extract": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz",
+ "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "node-gyp-build-optional-packages": "5.2.2"
+ },
+ "bin": {
+ "download-msgpackr-prebuilds": "bin/download-prebuilds.js"
+ },
+ "optionalDependencies": {
+ "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3",
+ "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3",
+ "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3",
+ "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3",
+ "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3",
+ "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3"
+ }
+ },
+ "node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
+ "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.1"
+ },
+ "bin": {
+ "node-gyp-build-optional-packages": "bin.js",
+ "node-gyp-build-optional-packages-optional": "optional.js",
+ "node-gyp-build-optional-packages-test": "build-test.js"
+ }
+ },
+ "node_modules/multicast-dns": {
+ "version": "7.2.5",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz",
+ "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dns-packet": "^5.2.2",
+ "thunky": "^1.0.2"
+ },
+ "bin": {
+ "multicast-dns": "cli.js"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-gyp-build-optional-packages": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz",
+ "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-libc": "^2.0.1"
+ },
+ "bin": {
+ "node-gyp-build-optional-packages": "bin.js",
+ "node-gyp-build-optional-packages-optional": "optional.js",
+ "node-gyp-build-optional-packages-test": "build-test.js"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.37",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz",
+ "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nullthrows": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
+ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/obuf": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/obug": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
+ "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/sxzz",
+ "https://opencollective.com/debug"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/on-headers": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
+ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/open": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz",
+ "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "wsl-utils": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ordered-binary": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz",
+ "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/oxfmt": {
+ "version": "0.46.0",
+ "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.46.0.tgz",
+ "integrity": "sha512-CopwJOwPAjZ9p76fCvz+mSOJTw9/NY3cSksZK3VO/bUQ8UoEcketNgUuYS0UB3p+R9XnXe7wGGXUmyFxc7QxJA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinypool": "2.1.0"
+ },
+ "bin": {
+ "oxfmt": "bin/oxfmt"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ },
+ "optionalDependencies": {
+ "@oxfmt/binding-android-arm-eabi": "0.46.0",
+ "@oxfmt/binding-android-arm64": "0.46.0",
+ "@oxfmt/binding-darwin-arm64": "0.46.0",
+ "@oxfmt/binding-darwin-x64": "0.46.0",
+ "@oxfmt/binding-freebsd-x64": "0.46.0",
+ "@oxfmt/binding-linux-arm-gnueabihf": "0.46.0",
+ "@oxfmt/binding-linux-arm-musleabihf": "0.46.0",
+ "@oxfmt/binding-linux-arm64-gnu": "0.46.0",
+ "@oxfmt/binding-linux-arm64-musl": "0.46.0",
+ "@oxfmt/binding-linux-ppc64-gnu": "0.46.0",
+ "@oxfmt/binding-linux-riscv64-gnu": "0.46.0",
+ "@oxfmt/binding-linux-riscv64-musl": "0.46.0",
+ "@oxfmt/binding-linux-s390x-gnu": "0.46.0",
+ "@oxfmt/binding-linux-x64-gnu": "0.46.0",
+ "@oxfmt/binding-linux-x64-musl": "0.46.0",
+ "@oxfmt/binding-openharmony-arm64": "0.46.0",
+ "@oxfmt/binding-win32-arm64-msvc": "0.46.0",
+ "@oxfmt/binding-win32-ia32-msvc": "0.46.0",
+ "@oxfmt/binding-win32-x64-msvc": "0.46.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-retry": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz",
+ "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/retry": "0.12.2",
+ "is-network-error": "^1.0.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/package-manager-detector": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz",
+ "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parcel": {
+ "version": "2.16.4",
+ "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.16.4.tgz",
+ "integrity": "sha512-RQlrqs4ujYNJpTQi+dITqPKNhRWEqpjPd1YBcGp50Wy3FcJHpwu0/iRm7XWz2dKU/Bwp2qCcVYPIeEDYi2uOUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@parcel/config-default": "2.16.4",
+ "@parcel/core": "2.16.4",
+ "@parcel/diagnostic": "2.16.4",
+ "@parcel/events": "2.16.4",
+ "@parcel/feature-flags": "2.16.4",
+ "@parcel/fs": "2.16.4",
+ "@parcel/logger": "2.16.4",
+ "@parcel/package-manager": "2.16.4",
+ "@parcel/reporter-cli": "2.16.4",
+ "@parcel/reporter-dev-server": "2.16.4",
+ "@parcel/reporter-tracer": "2.16.4",
+ "@parcel/utils": "2.16.4",
+ "chalk": "^4.1.2",
+ "commander": "^12.1.0",
+ "get-port": "^4.2.0"
+ },
+ "bin": {
+ "parcel": "lib/bin.js"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
+ "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkijs": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz",
+ "integrity": "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@noble/hashes": "1.4.0",
+ "asn1js": "^3.0.6",
+ "bytestreamjs": "^2.0.1",
+ "pvtsutils": "^1.3.6",
+ "pvutils": "^1.1.3",
+ "tslib": "^2.8.1"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/playwright": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz",
+ "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.59.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz",
+ "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/pngjs": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
+ "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.19.0"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.10",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
+ "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-addr/node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/publint": {
+ "version": "0.3.18",
+ "resolved": "https://registry.npmjs.org/publint/-/publint-0.3.18.tgz",
+ "integrity": "sha512-JRJFeBTrfx4qLwEuGFPk+haJOJN97KnPuK01yj+4k/Wj5BgoOK5uNsivporiqBjk2JDaslg7qJOhGRnpltGeog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@publint/pack": "^0.1.4",
+ "package-manager-detector": "^1.6.0",
+ "picocolors": "^1.1.1",
+ "sade": "^1.8.1"
+ },
+ "bin": {
+ "publint": "src/cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://bjornlu.com/sponsor"
+ }
+ },
+ "node_modules/pvtsutils": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz",
+ "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/pvutils": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz",
+ "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.14.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
+ "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/quansync": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz",
+ "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
}
},
- "node_modules/mkdirp": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
- "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "node_modules/raw-body": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
+ "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "minimist": "^1.2.6"
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.4.24",
+ "unpipe": "~1.0.0"
},
- "bin": {
- "mkdirp": "bin/cmd.js"
+ "engines": {
+ "node": ">= 0.8"
}
},
- "node_modules/mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "node_modules/react-refresh": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.16.0.tgz",
+ "integrity": "sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=4"
+ "node": ">=0.10.0"
}
},
- "node_modules/mrmime": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
- "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
"engines": {
- "node": ">=10"
+ "node": ">= 6"
}
},
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true
- },
- "node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
"license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
+ "dependencies": {
+ "picomatch": "^2.2.1"
},
"engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ "node": ">=8.10.0"
}
},
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "node_modules/readdirp/node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.4"
+ "node": ">=8.6"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/obug": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
- "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
+ "node_modules/rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve": "^1.20.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/reflect-metadata": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
+ "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"dev": true,
- "funding": [
- "https://github.com/sponsors/sxzz",
- "https://opencollective.com/debug"
- ],
"license": "MIT"
},
- "node_modules/opener": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
- "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
- "bin": {
- "opener": "bin/opener-bin.js"
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "node_modules/oxfmt": {
- "version": "0.45.0",
- "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.45.0.tgz",
- "integrity": "sha512-0o/COoN9fY50bjVeM7PQsNgbhndKurBIeTIcspW033OumksjJJmIVDKjAk5HMwU/GHTxSOdGDdhJ6BRzGPmsHg==",
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "1.22.12",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
+ "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "tinypool": "2.1.0"
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
- "oxfmt": "bin/oxfmt"
+ "resolve": "bin/resolve"
},
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/Boshen"
- },
- "optionalDependencies": {
- "@oxfmt/binding-android-arm-eabi": "0.45.0",
- "@oxfmt/binding-android-arm64": "0.45.0",
- "@oxfmt/binding-darwin-arm64": "0.45.0",
- "@oxfmt/binding-darwin-x64": "0.45.0",
- "@oxfmt/binding-freebsd-x64": "0.45.0",
- "@oxfmt/binding-linux-arm-gnueabihf": "0.45.0",
- "@oxfmt/binding-linux-arm-musleabihf": "0.45.0",
- "@oxfmt/binding-linux-arm64-gnu": "0.45.0",
- "@oxfmt/binding-linux-arm64-musl": "0.45.0",
- "@oxfmt/binding-linux-ppc64-gnu": "0.45.0",
- "@oxfmt/binding-linux-riscv64-gnu": "0.45.0",
- "@oxfmt/binding-linux-riscv64-musl": "0.45.0",
- "@oxfmt/binding-linux-s390x-gnu": "0.45.0",
- "@oxfmt/binding-linux-x64-gnu": "0.45.0",
- "@oxfmt/binding-linux-x64-musl": "0.45.0",
- "@oxfmt/binding-openharmony-arm64": "0.45.0",
- "@oxfmt/binding-win32-arm64-msvc": "0.45.0",
- "@oxfmt/binding-win32-ia32-msvc": "0.45.0",
- "@oxfmt/binding-win32-x64-msvc": "0.45.0"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/package-manager-detector": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz",
- "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==",
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
},
- "node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
},
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
- "license": "ISC"
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
},
- "node_modules/picomatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
- "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "node_modules/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
+ "node": ">= 4"
}
},
- "node_modules/playwright": {
- "version": "1.59.1",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz",
- "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==",
+ "node_modules/rolldown": {
+ "version": "1.0.0-rc.16",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.16.tgz",
+ "integrity": "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
"dependencies": {
- "playwright-core": "1.59.1"
+ "@oxc-project/types": "=0.126.0",
+ "@rolldown/pluginutils": "1.0.0-rc.16"
},
"bin": {
- "playwright": "cli.js"
+ "rolldown": "bin/cli.mjs"
},
"engines": {
- "node": ">=18"
+ "node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
- "fsevents": "2.3.2"
- }
- },
- "node_modules/playwright-core": {
- "version": "1.59.1",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz",
- "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "playwright-core": "cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/pngjs": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
- "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
+ "@rolldown/binding-android-arm64": "1.0.0-rc.16",
+ "@rolldown/binding-darwin-arm64": "1.0.0-rc.16",
+ "@rolldown/binding-darwin-x64": "1.0.0-rc.16",
+ "@rolldown/binding-freebsd-x64": "1.0.0-rc.16",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.16",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.16",
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.16",
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.16",
+ "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.16",
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.16",
+ "@rolldown/binding-linux-x64-musl": "1.0.0-rc.16",
+ "@rolldown/binding-openharmony-arm64": "1.0.0-rc.16",
+ "@rolldown/binding-wasm32-wasi": "1.0.0-rc.16",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.16",
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16"
+ }
+ },
+ "node_modules/run-applescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
+ "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=14.19.0"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/portfinder": {
- "version": "1.0.32",
- "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
- "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==",
+ "node_modules/sade": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+ "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
"dev": true,
"dependencies": {
- "async": "^2.6.4",
- "debug": "^3.2.7",
- "mkdirp": "^0.5.6"
+ "mri": "^1.1.0"
},
"engines": {
- "node": ">= 0.12.0"
+ "node": ">=6"
}
},
- "node_modules/postcss": {
- "version": "8.5.9",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
- "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==",
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
"funding": [
{
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
},
{
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
},
{
- "type": "github",
- "url": "https://github.com/sponsors/ai"
+ "type": "consulting",
+ "url": "https://feross.org/support"
}
],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/schema-utils": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
+ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.11",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
},
"engines": {
- "node": "^10 || ^12 || >=14"
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
}
},
- "node_modules/publint": {
- "version": "0.3.18",
- "resolved": "https://registry.npmjs.org/publint/-/publint-0.3.18.tgz",
- "integrity": "sha512-JRJFeBTrfx4qLwEuGFPk+haJOJN97KnPuK01yj+4k/Wj5BgoOK5uNsivporiqBjk2JDaslg7qJOhGRnpltGeog==",
+ "node_modules/select-hose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+ "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/selfsigned": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-5.5.0.tgz",
+ "integrity": "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@publint/pack": "^0.1.4",
- "package-manager-detector": "^1.6.0",
- "picocolors": "^1.1.1",
- "sade": "^1.8.1"
+ "@peculiar/x509": "^1.14.2",
+ "pkijs": "^3.3.3"
},
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "license": "ISC",
"bin": {
- "publint": "src/cli.js"
+ "semver": "bin/semver.js"
},
"engines": {
- "node": ">=18"
+ "node": ">=10"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz",
+ "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "~0.5.2",
+ "http-errors": "~2.0.1",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "~2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "~2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/serve-index": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz",
+ "integrity": "sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.8.0",
+ "mime-types": "~2.1.35",
+ "parseurl": "~1.3.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
},
"funding": {
- "url": "https://bjornlu.com/sponsor"
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/serve-index/node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
}
},
- "node_modules/qs": {
- "version": "6.15.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
- "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==",
+ "node_modules/serve-index/node_modules/http-errors": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
+ "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
"dev": true,
- "license": "BSD-3-Clause",
+ "license": "MIT",
"dependencies": {
- "side-channel": "^1.1.0"
+ "depd": "~1.1.2",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.1"
},
"engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 0.6"
}
},
- "node_modules/quansync": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz",
- "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==",
+ "node_modules/serve-index/node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
"dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/antfu"
- },
- {
- "type": "individual",
- "url": "https://github.com/sponsors/sxzz"
- }
- ],
- "license": "MIT"
- },
- "node_modules/requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
- "dev": true
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
},
- "node_modules/resolve-pkg-maps": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
- "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "node_modules/serve-static": {
+ "version": "1.16.3",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz",
+ "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
"dev": true,
"license": "MIT",
- "funding": {
- "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "~0.19.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
}
},
- "node_modules/rolldown": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz",
- "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==",
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/types": "=0.124.0",
- "@rolldown/pluginutils": "1.0.0-rc.15"
- },
- "bin": {
- "rolldown": "bin/cli.mjs"
+ "kind-of": "^6.0.2"
},
"engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "optionalDependencies": {
- "@rolldown/binding-android-arm64": "1.0.0-rc.15",
- "@rolldown/binding-darwin-arm64": "1.0.0-rc.15",
- "@rolldown/binding-darwin-x64": "1.0.0-rc.15",
- "@rolldown/binding-freebsd-x64": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15",
- "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15",
- "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15",
- "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15",
- "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15",
- "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15"
+ "node": ">=8"
}
},
- "node_modules/sade": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
- "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "mri": "^1.1.0"
+ "shebang-regex": "^3.0.0"
},
"engines": {
- "node": ">=6"
+ "node": ">=8"
}
},
- "node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true
- },
- "node_modules/secure-compare": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
- "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
- "dev": true
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
},
- "node_modules/semver": {
- "version": "7.7.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "node_modules/shell-quote": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
+ "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
"dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
+ "license": "MIT",
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel": {
@@ -2780,14 +8678,14 @@
}
},
"node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
+ "object-inspect": "^1.13.4"
},
"engines": {
"node": ">= 0.4"
@@ -2857,6 +8755,28 @@
"node": ">=18"
}
},
+ "node_modules/sockjs": {
+ "version": "0.3.24",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
+ "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "faye-websocket": "^0.11.3",
+ "uuid": "^8.3.2",
+ "websocket-driver": "^0.7.4"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -2867,6 +8787,99 @@
"node": ">=0.10.0"
}
},
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/spdy": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.0",
+ "handle-thing": "^2.0.0",
+ "http-deceiver": "^1.2.7",
+ "select-hose": "^2.0.0",
+ "spdy-transport": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/spdy-transport": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.0",
+ "detect-node": "^2.0.4",
+ "hpack.js": "^2.1.6",
+ "obuf": "^1.1.2",
+ "readable-stream": "^3.0.6",
+ "wbuf": "^1.7.3"
+ }
+ },
+ "node_modules/spdy-transport/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/spdy-transport/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/spdy/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/spdy/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/stackback": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
@@ -2874,18 +8887,39 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/std-env": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz",
- "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
+ "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"dev": true,
"license": "MIT"
},
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -2893,6 +8927,130 @@
"node": ">=8"
}
},
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz",
+ "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/term-size": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz",
+ "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.46.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz",
+ "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz",
+ "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^4.3.0",
+ "terser": "^5.31.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/thingies": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz",
+ "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "^2"
+ }
+ },
+ "node_modules/thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tinybench": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
@@ -2947,6 +9105,29 @@
"node": ">=14.0.0"
}
},
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
"node_modules/totalist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
@@ -2957,6 +9138,23 @@
"node": ">=6"
}
},
+ "node_modules/tree-dump": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz",
+ "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/streamich"
+ },
+ "peerDependencies": {
+ "tslib": "2"
+ }
+ },
"node_modules/tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
@@ -2968,9 +9166,9 @@
}
},
"node_modules/tsdown": {
- "version": "0.21.8",
- "resolved": "https://registry.npmjs.org/tsdown/-/tsdown-0.21.8.tgz",
- "integrity": "sha512-rHDIER4JU5owYTWptvyDk6pwfA5lCft1P+11HLGeF0uj0CB7vopFvr/E8QOaRmegeyHIEsu4+03j7ysvdgBAVA==",
+ "version": "0.21.9",
+ "resolved": "https://registry.npmjs.org/tsdown/-/tsdown-0.21.9.tgz",
+ "integrity": "sha512-tZPv2zMaMnjj9H9h0SDqpSXa9YWVZWHlG46DnSgNTFX6aq001MSI8kuBzJumr/u099nWj+1v5S7rhbnHk5jCHA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2978,18 +9176,18 @@
"cac": "^7.0.0",
"defu": "^6.1.7",
"empathic": "^2.0.0",
- "hookable": "^6.1.0",
- "import-without-cache": "^0.2.5",
+ "hookable": "^6.1.1",
+ "import-without-cache": "^0.3.3",
"obug": "^2.1.1",
"picomatch": "^4.0.4",
- "rolldown": "1.0.0-rc.15",
+ "rolldown": "1.0.0-rc.16",
"rolldown-plugin-dts": "^0.23.2",
"semver": "^7.7.4",
"tinyexec": "^1.1.1",
"tinyglobby": "^0.2.16",
"tree-kill": "^1.2.2",
"unconfig-core": "^7.5.0",
- "unrun": "^0.2.34"
+ "unrun": "^0.2.36"
},
"bin": {
"tsdown": "dist/run.mjs"
@@ -3002,8 +9200,8 @@
},
"peerDependencies": {
"@arethetypeswrong/core": "^0.18.1",
- "@tsdown/css": "0.21.8",
- "@tsdown/exe": "0.21.8",
+ "@tsdown/css": "0.21.9",
+ "@tsdown/exe": "0.21.9",
"@vitejs/devtools": "*",
"publint": "^0.3.0",
"typescript": "^5.0.0 || ^6.0.0",
@@ -3084,13 +9282,59 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
- "license": "0BSD",
- "optional": true
+ "license": "0BSD"
+ },
+ "node_modules/tsyringe": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz",
+ "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^1.9.3"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/tsyringe/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
},
"node_modules/typescript": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz",
- "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==",
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -3122,26 +9366,24 @@
"dev": true,
"license": "MIT"
},
- "node_modules/union": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
- "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"dev": true,
- "dependencies": {
- "qs": "^6.4.0"
- },
+ "license": "MIT",
"engines": {
- "node": ">= 0.8.0"
+ "node": ">= 0.8"
}
},
"node_modules/unrun": {
- "version": "0.2.35",
- "resolved": "https://registry.npmjs.org/unrun/-/unrun-0.2.35.tgz",
- "integrity": "sha512-nDP7mA4Fu5owDarQtLiiN3lq7tJZHFEAVIchnwP8U3wMeEkLoUNT37Hva85H05Rdw8CArpGmtY+lBjpk9fruVQ==",
+ "version": "0.2.36",
+ "resolved": "https://registry.npmjs.org/unrun/-/unrun-0.2.36.tgz",
+ "integrity": "sha512-ICAGv44LHSKjCdI4B4rk99lJLHXBweutO4MUwu3cavMlYtXID0Tn5e1Kwe/Uj6BSAuHHXfi1JheFVCYhcXHfAg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "rolldown": "1.0.0-rc.15"
+ "rolldown": "1.0.0-rc.16"
},
"bin": {
"unrun": "dist/cli.mjs"
@@ -3161,24 +9403,96 @@
}
}
},
- "node_modules/url-join": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
- "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
- "dev": true
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/utility-types": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz",
+ "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
},
"node_modules/vite": {
- "version": "8.0.8",
- "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz",
- "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
+ "version": "8.0.9",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.9.tgz",
+ "integrity": "sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==",
"dev": true,
"license": "MIT",
"dependencies": {
"lightningcss": "^1.32.0",
"picomatch": "^4.0.4",
- "postcss": "^8.5.8",
- "rolldown": "1.0.0-rc.15",
- "tinyglobby": "^0.2.15"
+ "postcss": "^8.5.10",
+ "rolldown": "1.0.0-rc.16",
+ "tinyglobby": "^0.2.16"
},
"bin": {
"vite": "bin/vite.js"
@@ -3261,19 +9575,19 @@
}
},
"node_modules/vitest": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.4.tgz",
- "integrity": "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz",
+ "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/expect": "4.1.4",
- "@vitest/mocker": "4.1.4",
- "@vitest/pretty-format": "4.1.4",
- "@vitest/runner": "4.1.4",
- "@vitest/snapshot": "4.1.4",
- "@vitest/spy": "4.1.4",
- "@vitest/utils": "4.1.4",
+ "@vitest/expect": "4.1.5",
+ "@vitest/mocker": "4.1.5",
+ "@vitest/pretty-format": "4.1.5",
+ "@vitest/runner": "4.1.5",
+ "@vitest/snapshot": "4.1.5",
+ "@vitest/spy": "4.1.5",
+ "@vitest/utils": "4.1.5",
"es-module-lexer": "^2.0.0",
"expect-type": "^1.3.0",
"magic-string": "^0.30.21",
@@ -3301,12 +9615,12 @@
"@edge-runtime/vm": "*",
"@opentelemetry/api": "^1.9.0",
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
- "@vitest/browser-playwright": "4.1.4",
- "@vitest/browser-preview": "4.1.4",
- "@vitest/browser-webdriverio": "4.1.4",
- "@vitest/coverage-istanbul": "4.1.4",
- "@vitest/coverage-v8": "4.1.4",
- "@vitest/ui": "4.1.4",
+ "@vitest/browser-playwright": "4.1.5",
+ "@vitest/browser-preview": "4.1.5",
+ "@vitest/browser-webdriverio": "4.1.5",
+ "@vitest/coverage-istanbul": "4.1.5",
+ "@vitest/coverage-v8": "4.1.5",
+ "@vitest/ui": "4.1.5",
"happy-dom": "*",
"jsdom": "*",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
@@ -3350,16 +9664,289 @@
}
}
},
- "node_modules/whatwg-encoding": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
- "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
+ "node_modules/watchpack": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz",
+ "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "iconv-lite": "0.6.3"
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
},
"engines": {
- "node": ">=12"
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/wbuf": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/weak-lru-cache": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz",
+ "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/webpack": {
+ "version": "5.106.2",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.106.2.tgz",
+ "integrity": "sha512-wGN3qcrBQIFmQ/c0AiOAQBvrZ5lmY8vbbMv4Mxfgzqd/B6+9pXtLo73WuS1dSGXM5QYY3hZnIbvx+K1xxe6FyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.8",
+ "@types/json-schema": "^7.0.15",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.16.0",
+ "acorn-import-phases": "^1.0.3",
+ "browserslist": "^4.28.1",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.20.0",
+ "es-module-lexer": "^2.0.0",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.11",
+ "loader-runner": "^4.3.1",
+ "mime-db": "^1.54.0",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^4.3.3",
+ "tapable": "^2.3.0",
+ "terser-webpack-plugin": "^5.3.17",
+ "watchpack": "^2.5.1",
+ "webpack-sources": "^3.3.4"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-7.0.2.tgz",
+ "integrity": "sha512-dB0R4T+C/8YuvM+fabdvil6QE44/ChDXikV5lOOkrUeCkW5hTJv2pGLE3keh+D5hjYw8icBaJkZzpFoaHV4T+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@discoveryjs/json-ext": "^1.0.0",
+ "commander": "^14.0.3",
+ "cross-spawn": "^7.0.6",
+ "envinfo": "^7.14.0",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
+ "webpack-merge": "^6.0.1"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.101.0",
+ "webpack-bundle-analyzer": "^4.0.0 || ^5.0.0",
+ "webpack-dev-server": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "webpack-bundle-analyzer": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/webpack-dev-middleware": {
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz",
+ "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "colorette": "^2.0.10",
+ "memfs": "^4.43.1",
+ "mime-types": "^3.0.1",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "schema-utils": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 18.12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "webpack": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-dev-middleware/node_modules/mime-types": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/webpack-dev-server": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz",
+ "integrity": "sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/bonjour": "^3.5.13",
+ "@types/connect-history-api-fallback": "^1.5.4",
+ "@types/express": "^4.17.25",
+ "@types/express-serve-static-core": "^4.17.21",
+ "@types/serve-index": "^1.9.4",
+ "@types/serve-static": "^1.15.5",
+ "@types/sockjs": "^0.3.36",
+ "@types/ws": "^8.5.10",
+ "ansi-html-community": "^0.0.8",
+ "bonjour-service": "^1.2.1",
+ "chokidar": "^3.6.0",
+ "colorette": "^2.0.10",
+ "compression": "^1.8.1",
+ "connect-history-api-fallback": "^2.0.0",
+ "express": "^4.22.1",
+ "graceful-fs": "^4.2.6",
+ "http-proxy-middleware": "^2.0.9",
+ "ipaddr.js": "^2.1.0",
+ "launch-editor": "^2.6.1",
+ "open": "^10.0.3",
+ "p-retry": "^6.2.0",
+ "schema-utils": "^4.2.0",
+ "selfsigned": "^5.5.0",
+ "serve-index": "^1.9.1",
+ "sockjs": "^0.3.24",
+ "spdy": "^4.0.2",
+ "webpack-dev-middleware": "^7.4.2",
+ "ws": "^8.18.0"
+ },
+ "bin": {
+ "webpack-dev-server": "bin/webpack-dev-server.js"
+ },
+ "engines": {
+ "node": ">= 18.12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "webpack": {
+ "optional": true
+ },
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-merge": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz",
+ "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "flat": "^5.0.2",
+ "wildcard": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz",
+ "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8.0"
}
},
"node_modules/whatwg-mimetype": {
@@ -3372,6 +9959,22 @@
"node": ">=12"
}
},
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/why-is-node-running": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
@@ -3389,6 +9992,13 @@
"node": ">=8"
}
},
+ "node_modules/wildcard": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/ws": {
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
@@ -3410,6 +10020,22 @@
"optional": true
}
}
+ },
+ "node_modules/wsl-utils": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz",
+ "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
}
}
}
diff --git a/package.json b/package.json
index 946b798..70f3fe5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@sqlite.org/sqlite-wasm",
- "version": "3.51.2-build9",
+ "version": "3.53.0-build1",
"description": "SQLite Wasm conveniently wrapped as an ES Module.",
"type": "module",
"repository": {
@@ -55,7 +55,13 @@
"publint": "npx publint",
"check-types": "tsgo",
"build": "tsdown",
+ "dev:kvvfs": "npm run dev -w demos/kvvfs-demo",
+ "dev:opfs": "npm run dev -w demos/opfs-demo",
+ "dev:opfs-wl": "npm run dev -w demos/opfs-wl-demo",
"dev:sahpool": "npm run dev -w demos/sahpool-demo",
+ "dev:sahpool-webpack": "npm run dev -w demos/sahpool-webpack-demo",
+ "dev:sahpool-parcel": "npm run dev -w demos/sahpool-parcel-demo",
+ "dev:sahpool-rsbuild": "npm run dev -w demos/sahpool-rsbuild-demo",
"dev:main-thread": "npm run dev -w demos/main-thread-demo",
"dev:in-worker": "npm run dev -w demos/in-worker-demo",
"start": "npx http-server --coop",
@@ -71,17 +77,16 @@
},
"devDependencies": {
"@types/node": "^25.6.0",
- "@typescript/native-preview": "^7.0.0-dev.20260414.1",
- "@vitest/browser": "^4.1.4",
- "@vitest/browser-playwright": "^4.1.4",
+ "@typescript/native-preview": "^7.0.0-dev.20260421.2",
+ "@vitest/browser": "^4.1.5",
+ "@vitest/browser-playwright": "^4.1.5",
"happy-dom": "20.9.0",
- "http-server": "^14.1.1",
- "lefthook": "2.1.5",
- "oxfmt": "^0.45.0",
+ "lefthook": "2.1.6",
+ "oxfmt": "^0.46.0",
"playwright": "^1.59.1",
"publint": "^0.3.18",
- "tsdown": "^0.21.8",
- "typescript": "^6.0.2",
- "vitest": "^4.1.4"
+ "tsdown": "^0.21.9",
+ "typescript": "^6.0.3",
+ "vitest": "^4.1.5"
}
}
diff --git a/src/__tests__/sqlite3-opfs.browser.test.js b/src/__tests__/sqlite3-opfs.browser.test.js
new file mode 100644
index 0000000..9256766
--- /dev/null
+++ b/src/__tests__/sqlite3-opfs.browser.test.js
@@ -0,0 +1,45 @@
+import { describe, expect, test } from 'vitest';
+
+const createWorker = (workerUrl) =>
+ new Worker(workerUrl, {
+ type: 'module',
+ });
+
+const runWorker = async (workerUrl) => {
+ const worker = createWorker(workerUrl);
+
+ try {
+ const result = await new Promise((resolve, reject) => {
+ worker.onmessage = (e) => {
+ if (e.data.type === 'success') {
+ resolve(e.data);
+ } else {
+ reject(new Error(e.data.message || 'Unknown worker error'));
+ }
+ };
+ worker.onerror = (e) => {
+ reject(new Error('Worker error: ' + e.message));
+ };
+ worker.postMessage({ type: 'start' });
+ });
+
+ expect(result.type).toBe('success');
+ expect(result.rows).toEqual([
+ { id: 1, name: 'Alice' },
+ { id: 2, name: 'Bob' },
+ ]);
+ expect(result.persistedCount).toBe(2);
+ } finally {
+ worker.terminate();
+ }
+};
+
+describe('opfs persistence APIs', () => {
+ test('OpfsDb sanity check in Worker (browser)', async () => {
+ await runWorker(new URL('./workers/sqlite3-opfs.worker.js', import.meta.url));
+ });
+
+ test('OpfsWlDb sanity check in Worker (browser)', async () => {
+ await runWorker(new URL('./workers/sqlite3-opfs-wl.worker.js', import.meta.url));
+ });
+});
diff --git a/src/__tests__/workers/sqlite3-opfs-wl.worker.js b/src/__tests__/workers/sqlite3-opfs-wl.worker.js
new file mode 100644
index 0000000..957f3fb
--- /dev/null
+++ b/src/__tests__/workers/sqlite3-opfs-wl.worker.js
@@ -0,0 +1,49 @@
+import sqlite3InitModule from '../../bin/sqlite3-bundler-friendly.mjs';
+
+const cleanupOpfsFile = async (filename) => {
+ const entryName = filename.replace(/^\//, '');
+
+ try {
+ const root = await navigator.storage.getDirectory();
+ await root.removeEntry(entryName);
+ } catch {
+ // Ignore missing-file cleanup errors.
+ }
+};
+
+self.onmessage = async () => {
+ const filename = '/test-opfs-wl-worker.sqlite3';
+
+ try {
+ await cleanupOpfsFile(filename);
+
+ const sqlite3 = await sqlite3InitModule();
+ let db = new sqlite3.oo1.OpfsWlDb(filename, 'ct');
+
+ try {
+ db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
+ db.exec({
+ sql: 'INSERT INTO test (name) VALUES (?), (?)',
+ bind: ['Alice', 'Bob'],
+ });
+
+ const rows = db.selectObjects('SELECT * FROM test ORDER BY id');
+ db.close();
+ db = null;
+
+ db = new sqlite3.oo1.OpfsWlDb(filename, 'w');
+ const persistedCount = db.selectValue('SELECT count(*) FROM test');
+
+ self.postMessage({
+ type: 'success',
+ rows,
+ persistedCount,
+ });
+ } finally {
+ db?.close();
+ await cleanupOpfsFile(filename);
+ }
+ } catch (err) {
+ self.postMessage({ type: 'error', message: err.message, stack: err.stack });
+ }
+};
diff --git a/src/__tests__/workers/sqlite3-opfs.worker.js b/src/__tests__/workers/sqlite3-opfs.worker.js
new file mode 100644
index 0000000..0e4c46b
--- /dev/null
+++ b/src/__tests__/workers/sqlite3-opfs.worker.js
@@ -0,0 +1,49 @@
+import sqlite3InitModule from '../../bin/sqlite3-bundler-friendly.mjs';
+
+const cleanupOpfsFile = async (filename) => {
+ const entryName = filename.replace(/^\//, '');
+
+ try {
+ const root = await navigator.storage.getDirectory();
+ await root.removeEntry(entryName);
+ } catch {
+ // Ignore missing-file cleanup errors.
+ }
+};
+
+self.onmessage = async () => {
+ const filename = '/test-opfs-worker.sqlite3';
+
+ try {
+ await cleanupOpfsFile(filename);
+
+ const sqlite3 = await sqlite3InitModule();
+ let db = new sqlite3.oo1.OpfsDb(filename, 'ct');
+
+ try {
+ db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
+ db.exec({
+ sql: 'INSERT INTO test (name) VALUES (?), (?)',
+ bind: ['Alice', 'Bob'],
+ });
+
+ const rows = db.selectObjects('SELECT * FROM test ORDER BY id');
+ db.close();
+ db = null;
+
+ db = new sqlite3.oo1.OpfsDb(filename, 'w');
+ const persistedCount = db.selectValue('SELECT count(*) FROM test');
+
+ self.postMessage({
+ type: 'success',
+ rows,
+ persistedCount,
+ });
+ } finally {
+ db?.close();
+ await cleanupOpfsFile(filename);
+ }
+ } catch (err) {
+ self.postMessage({ type: 'error', message: err.message, stack: err.stack });
+ }
+};
diff --git a/src/bin/sqlite3-bundler-friendly.mjs b/src/bin/sqlite3-bundler-friendly.mjs
index 0b99fc3..fc385ac 100644
--- a/src/bin/sqlite3-bundler-friendly.mjs
+++ b/src/bin/sqlite3-bundler-friendly.mjs
@@ -27,11 +27,11 @@
/* @preserve
** This code was built from sqlite3 version...
**
-** SQLITE_VERSION "3.52.0"
-** SQLITE_VERSION_NUMBER 3052000
-** SQLITE_SOURCE_ID "2026-01-30 06:37:34 407724c4e80efdf93d885e95b5209a100a3f470fe0298138be57201f65f9817e"
+** SQLITE_VERSION "3.53.0"
+** SQLITE_VERSION_NUMBER 3053000
+** SQLITE_SOURCE_ID "2026-04-09 11:41:38 4525003a53a7fc63ca75c59b22c79608659ca12f0131f52c18637f829977f20b"
**
-** Emscripten SDK: 5.0.0
+** Emscripten SDK: 5.0.5
*/
// This code implements the `-sMODULARIZE` settings by taking the generated
// JS program code (INNER_JS_CODE) and wrapping it in a factory function.
@@ -92,7 +92,7 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR
/**
This file was preprocessed using:
- ./c-pp-lite -o ./bld/pre-js.bundler.js -Dtarget:es6-module -Dtarget:es6-bundler-friendly -DModule.instantiateWasm api/pre-js.c-pp.js
+ ./c-pp -o ./bld/pre-js.bundler.js -Dtarget:es6-module -Dtarget:es6-bundler-friendly -DModule.instantiateWasm api/pre-js.c-pp.js
*/
/* END FILE: api/pre-js.js. */
// end include: ./bld/pre-js.bundler.js
@@ -211,37 +211,17 @@ var isFileURI = (filename) => filename.startsWith('file://');
// include: runtime_stack_check.js
// end include: runtime_stack_check.js
// include: runtime_exceptions.js
+// Base Emscripten EH error class
+class EmscriptenEH {}
+
+class EmscriptenSjLj extends EmscriptenEH {}
+
// end include: runtime_exceptions.js
// include: runtime_debug.js
// end include: runtime_debug.js
var readyPromiseResolve, readyPromiseReject;
// Memory management
-var
-/** @type {!Int8Array} */
- HEAP8,
-/** @type {!Uint8Array} */
- HEAPU8,
-/** @type {!Int16Array} */
- HEAP16,
-/** @type {!Uint16Array} */
- HEAPU16,
-/** @type {!Int32Array} */
- HEAP32,
-/** @type {!Uint32Array} */
- HEAPU32,
-/** @type {!Float32Array} */
- HEAPF32,
-/** @type {!Float64Array} */
- HEAPF64;
-
-// BigInt64Array type is not correctly defined in closure
-var
-/** not-@type {!BigInt64Array} */
- HEAP64,
-/* BigUint64Array type is not correctly defined in closure
-/** not-@type {!BigUint64Array} */
- HEAPU64;
var runtimeInitialized = false;
@@ -269,7 +249,7 @@ function updateMemoryViews() {
function initMemory() {
-
+
if (Module['wasmMemory']) {
wasmMemory = Module['wasmMemory'];
@@ -339,11 +319,14 @@ function postRun() {
// End ATPOSTRUNS hooks
}
-/** @param {string|number=} what */
+/**
+ * @param {string|number=} what
+ * @noreturn
+ */
function abort(what) {
Module['onAbort']?.(what);
- what = 'Aborted(' + what + ')';
+ what = `Aborted(${what})`;
// TODO(sbc): Should we remove printing and leave it up to whoever
// catches the exception?
err(what);
@@ -514,6 +497,36 @@ async function createWasm() {
}
}
+ /** @type {!Int16Array} */
+ var HEAP16;
+
+ /** @type {!Int32Array} */
+ var HEAP32;
+
+ /** not-@type {!BigInt64Array} */
+ var HEAP64;
+
+ /** @type {!Int8Array} */
+ var HEAP8;
+
+ /** @type {!Float32Array} */
+ var HEAPF32;
+
+ /** @type {!Float64Array} */
+ var HEAPF64;
+
+ /** @type {!Uint16Array} */
+ var HEAPU16;
+
+ /** @type {!Uint32Array} */
+ var HEAPU32;
+
+ /** not-@type {!BigUint64Array} */
+ var HEAPU64;
+
+ /** @type {!Uint8Array} */
+ var HEAPU8;
+
var callRuntimeCallbacks = (callbacks) => {
while (callbacks.length > 0) {
// Pass the module as the first argument.
@@ -527,7 +540,7 @@ async function createWasm() {
var addOnPreRun = (cb) => onPreRuns.push(cb);
-
+
/**
* @param {number} ptr
* @param {string} type
@@ -549,7 +562,7 @@ async function createWasm() {
var noExitRuntime = true;
-
+
/**
* @param {number} ptr
* @param {number} value
@@ -639,12 +652,9 @@ join2:(l, r) => PATH.normalize(l + '/' + r),
var initRandomFill = () => {
- return (view) => crypto.getRandomValues(view);
- };
-var randomFill = (view) => {
- // Lazily init on the first invocation.
- (randomFill = initRandomFill())(view);
+ return (view) => (crypto.getRandomValues(view), 0);
};
+var randomFill = (view) => (randomFill = initRandomFill())(view);
@@ -727,14 +737,14 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
* @return {string}
*/
var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => {
-
+
var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul);
-
+
return UTF8Decoder.decode(heapOrArray.buffer ? heapOrArray.subarray(idx, endPtr) : new Uint8Array(heapOrArray.slice(idx, endPtr)));
};
-
+
var FS_stdin_getChar_buffer = [];
-
+
var lengthBytesUTF8 = (str) => {
var len = 0;
for (var i = 0; i < str.length; ++i) {
@@ -755,13 +765,13 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
return len;
};
-
+
var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
// Parameter maxBytesToWrite is not optional. Negative values, 0, null,
// undefined and false each don't write out any bytes.
if (!(maxBytesToWrite > 0))
return 0;
-
+
var startIdx = outIdx;
var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
for (var i = 0; i < str.length; ++i) {
@@ -963,10 +973,10 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
},
},
};
-
-
+
+
var zeroMemory = (ptr, size) => HEAPU8.fill(0, ptr, ptr + size);
-
+
var alignMemory = (size, alignment) => {
return Math.ceil(size / alignment) * alignment;
};
@@ -1040,11 +1050,14 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
} else if (FS.isFile(node.mode)) {
node.node_ops = MEMFS.ops_table.file.node;
node.stream_ops = MEMFS.ops_table.file.stream;
- node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
- // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
- // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
- // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
- node.contents = null;
+ // The actual number of bytes used in the typed array, as opposed to
+ // contents.length which gives the whole capacity.
+ node.usedBytes = 0;
+ // The byte data of the file is stored in a typed array.
+ // Note: typed arrays are not resizable like normal JS arrays are, so
+ // there is a small penalty involved for appending file writes that
+ // continuously grow a file similar to std::vector capacity vs used.
+ node.contents = MEMFS.emptyFileContents ??= new Uint8Array(0);
} else if (FS.isLink(node.mode)) {
node.node_ops = MEMFS.ops_table.link.node;
node.stream_ops = MEMFS.ops_table.link.stream;
@@ -1061,36 +1074,29 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return node;
},
getFileDataAsTypedArray(node) {
- if (!node.contents) return new Uint8Array(0);
- if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
- return new Uint8Array(node.contents);
+ return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
},
expandFileStorage(node, newCapacity) {
- var prevCapacity = node.contents ? node.contents.length : 0;
+ var prevCapacity = node.contents.length;
if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
- // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
- // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
- // avoid overshooting the allocation cap by a very large margin.
+ // Don't expand strictly to the given requested limit if it's only a very
+ // small increase, but instead geometrically grow capacity.
+ // For small filesizes (<1MB), perform size*2 geometric increase, but for
+ // large sizes, do a much more conservative size*1.125 increase to avoid
+ // overshooting the allocation cap by a very large margin.
var CAPACITY_DOUBLING_MAX = 1024 * 1024;
newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
- if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
- var oldContents = node.contents;
+ if (prevCapacity) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
+ var oldContents = MEMFS.getFileDataAsTypedArray(node);
node.contents = new Uint8Array(newCapacity); // Allocate new storage.
- if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
+ node.contents.set(oldContents);
},
resizeFileStorage(node, newSize) {
if (node.usedBytes == newSize) return;
- if (newSize == 0) {
- node.contents = null; // Fully decommit when requesting a resize to zero.
- node.usedBytes = 0;
- } else {
- var oldContents = node.contents;
- node.contents = new Uint8Array(newSize); // Allocate new storage.
- if (oldContents) {
- node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
- }
- node.usedBytes = newSize;
- }
+ var oldContents = node.contents;
+ node.contents = new Uint8Array(newSize); // Allocate new storage.
+ node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
+ node.usedBytes = newSize;
},
node_ops:{
getattr(node) {
@@ -1196,11 +1202,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var contents = stream.node.contents;
if (position >= stream.node.usedBytes) return 0;
var size = Math.min(stream.node.usedBytes - position, length);
- if (size > 8 && contents.subarray) { // non-trivial, and typed array
- buffer.set(contents.subarray(position, position + size), offset);
- } else {
- for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
- }
+ buffer.set(contents.subarray(position, position + size), offset);
return size;
},
write(stream, buffer, offset, length, position, canOwn) {
@@ -1211,37 +1213,23 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (buffer.buffer === HEAP8.buffer) {
canOwn = false;
}
-
+
if (!length) return 0;
var node = stream.node;
node.mtime = node.ctime = Date.now();
-
- if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
- if (canOwn) {
- node.contents = buffer.subarray(offset, offset + length);
- node.usedBytes = length;
- return length;
- } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
- node.contents = buffer.slice(offset, offset + length);
- node.usedBytes = length;
- return length;
- } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
- node.contents.set(buffer.subarray(offset, offset + length), position);
- return length;
- }
- }
-
- // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
- MEMFS.expandFileStorage(node, position+length);
- if (node.contents.subarray && buffer.subarray) {
+
+ if (canOwn) {
+ node.contents = buffer.subarray(offset, offset + length);
+ node.usedBytes = length;
+ } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
+ node.contents = buffer.slice(offset, offset + length);
+ node.usedBytes = length;
+ } else {
+ MEMFS.expandFileStorage(node, position+length);
// Use typed array write which is available.
node.contents.set(buffer.subarray(offset, offset + length), position);
- } else {
- for (var i = 0; i < length; i++) {
- node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
- }
+ node.usedBytes = Math.max(node.usedBytes, position + length);
}
- node.usedBytes = Math.max(node.usedBytes, position + length);
return length;
},
llseek(stream, offset, whence) {
@@ -1266,7 +1254,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var allocated;
var contents = stream.node.contents;
// Only make a new copy when MAP_PRIVATE is specified.
- if (!(flags & 2) && contents && contents.buffer === HEAP8.buffer) {
+ if (!(flags & 2) && contents.buffer === HEAP8.buffer) {
// We can't emulate MAP_SHARED when the file is not backed by the
// buffer we're mapping to (e.g. the HEAP buffer).
allocated = false;
@@ -1298,8 +1286,9 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
},
},
};
-
+
var FS_modeStringToFlags = (str) => {
+ if (typeof str != 'string') return str;
var flagModes = {
'r': 0,
'r+': 2,
@@ -1314,36 +1303,46 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
return flags;
};
-
+
+ var FS_fileDataToTypedArray = (data) => {
+ if (typeof data == 'string') {
+ data = intArrayFromString(data, true);
+ }
+ if (!data.subarray) {
+ data = new Uint8Array(data);
+ }
+ return data;
+ };
+
var FS_getMode = (canRead, canWrite) => {
var mode = 0;
if (canRead) mode |= 292 | 73;
if (canWrite) mode |= 146;
return mode;
};
-
-
+
+
var asyncLoad = async (url) => {
var arrayBuffer = await readAsync(url);
return new Uint8Array(arrayBuffer);
};
-
-
+
+
var FS_createDataFile = (...args) => FS.createDataFile(...args);
-
+
var getUniqueRunDependency = (id) => {
return id;
};
-
+
var runDependencies = 0;
-
-
+
+
var dependenciesFulfilled = null;
var removeRunDependency = (id) => {
runDependencies--;
-
+
Module['monitorRunDependencies']?.(runDependencies);
-
+
if (runDependencies == 0) {
if (dependenciesFulfilled) {
var callback = dependenciesFulfilled;
@@ -1354,17 +1353,17 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
};
var addRunDependency = (id) => {
runDependencies++;
-
+
Module['monitorRunDependencies']?.(runDependencies);
-
+
};
-
-
+
+
var preloadPlugins = [];
var FS_handledByPreloadPlugin = async (byteArray, fullname) => {
// Ensure plugins are ready.
if (typeof Browser != 'undefined') Browser.init();
-
+
for (var plugin of preloadPlugins) {
if (plugin['canHandle'](fullname)) {
return plugin['handle'](byteArray, fullname);
@@ -1380,13 +1379,13 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
var dep = getUniqueRunDependency(`cp ${fullname}`); // might have several active requests for the same fullname
addRunDependency(dep);
-
+
try {
var byteArray = url;
if (typeof url == 'string') {
byteArray = await asyncLoad(url);
}
-
+
byteArray = await FS_handledByPreloadPlugin(byteArray, fullname);
preFinish?.();
if (!dontCreateFile) {
@@ -1412,8 +1411,6 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
ignorePermissions:true,
filesystems:null,
syncFSRequests:0,
- readFiles:{
- },
ErrnoError:class {
name = 'ErrnoError';
// We set the `name` property to be able to identify `FS.ErrnoError`
@@ -1498,31 +1495,31 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
throw new FS.ErrnoError(44);
}
opts.follow_mount ??= true
-
+
if (!PATH.isAbs(path)) {
path = FS.cwd() + '/' + path;
}
-
+
// limit max consecutive symlinks to 40 (SYMLOOP_MAX).
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
// split the absolute path
var parts = path.split('/').filter((p) => !!p);
-
+
// start at the root
var current = FS.root;
var current_path = '/';
-
+
for (var i = 0; i < parts.length; i++) {
var islast = (i === parts.length-1);
if (islast && opts.parent) {
// stop resolving
break;
}
-
+
if (parts[i] === '.') {
continue;
}
-
+
if (parts[i] === '..') {
current_path = PATH.dirname(current_path);
if (FS.isRoot(current)) {
@@ -1536,7 +1533,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
continue;
}
-
+
current_path = PATH.join2(current_path, parts[i]);
try {
current = FS.lookupNode(current, parts[i]);
@@ -1549,12 +1546,12 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
throw e;
}
-
+
// jump to the mount's root node if this is a mountpoint
if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) {
current = current.mounted.root;
}
-
+
// by default, lookupPath will not follow a symlink if it is the final path component.
// setting opts.follow = true will override this behavior.
if (FS.isLink(current.mode) && (!islast || opts.follow)) {
@@ -1587,7 +1584,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
},
hashName(parentid, name) {
var hash = 0;
-
+
for (var i = 0; i < name.length; i++) {
hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
}
@@ -1630,9 +1627,9 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
},
createNode(parent, name, mode, rdev) {
var node = new FS.FSNode(parent, name, mode, rdev);
-
+
FS.hashAddNode(node);
-
+
return node;
},
destroyNode(node) {
@@ -1679,9 +1676,11 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
// return 0 if any user, group or owner bits are set.
if (perms.includes('r') && !(node.mode & 292)) {
return 2;
- } else if (perms.includes('w') && !(node.mode & 146)) {
+ }
+ if (perms.includes('w') && !(node.mode & 146)) {
return 2;
- } else if (perms.includes('x') && !(node.mode & 73)) {
+ }
+ if (perms.includes('x') && !(node.mode & 73)) {
return 2;
}
return 0;
@@ -1722,10 +1721,8 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
return 10;
}
- } else {
- if (FS.isDir(node.mode)) {
- return 31;
- }
+ } else if (FS.isDir(node.mode)) {
+ return 31;
}
return 0;
},
@@ -1735,13 +1732,16 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
if (FS.isLink(node.mode)) {
return 32;
- } else if (FS.isDir(node.mode)) {
- if (FS.flagsToPermissionString(flags) !== 'r' // opening for write
- || (flags & (512 | 64))) { // TODO: check for O_SEARCH? (== search for dir only)
+ }
+ var mode = FS.flagsToPermissionString(flags);
+ if (FS.isDir(node.mode)) {
+ // opening for write
+ // TODO: check for O_SEARCH? (== search for dir only)
+ if (mode !== 'r' || (flags & (512 | 64))) {
return 31;
}
}
- return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+ return FS.nodePermissions(node, mode);
},
checkOpExists(op, err) {
if (!op) {
@@ -1767,7 +1767,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
},
getStream:(fd) => FS.streams[fd],
createStream(stream, fd = -1) {
-
+
// clone it, so we can return an instance of FSStream
stream = Object.assign(new FS.FSStream(), stream);
if (fd == -1) {
@@ -1814,15 +1814,15 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
getMounts(mount) {
var mounts = [];
var check = [mount];
-
+
while (check.length) {
var m = check.pop();
-
+
mounts.push(m);
-
+
check.push(...m.mounts);
}
-
+
return mounts;
},
syncfs(populate, callback) {
@@ -1830,21 +1830,21 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
callback = populate;
populate = false;
}
-
+
FS.syncFSRequests++;
-
+
if (FS.syncFSRequests > 1) {
err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`);
}
-
+
var mounts = FS.getMounts(FS.root.mount);
var completed = 0;
-
+
function doCallback(errCode) {
FS.syncFSRequests--;
return callback(errCode);
}
-
+
function done(errCode) {
if (errCode) {
if (!done.errored) {
@@ -1857,7 +1857,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
doCallback(null);
}
};
-
+
// sync all mounts
for (var mount of mounts) {
if (mount.type.syncfs) {
@@ -1871,77 +1871,77 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var root = mountpoint === '/';
var pseudo = !mountpoint;
var node;
-
+
if (root && FS.root) {
throw new FS.ErrnoError(10);
} else if (!root && !pseudo) {
var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
-
+
mountpoint = lookup.path; // use the absolute path
node = lookup.node;
-
+
if (FS.isMountpoint(node)) {
throw new FS.ErrnoError(10);
}
-
+
if (!FS.isDir(node.mode)) {
throw new FS.ErrnoError(54);
}
}
-
+
var mount = {
type,
opts,
mountpoint,
mounts: []
};
-
+
// create a root node for the fs
var mountRoot = type.mount(mount);
mountRoot.mount = mount;
mount.root = mountRoot;
-
+
if (root) {
FS.root = mountRoot;
} else if (node) {
// set as a mountpoint
node.mounted = mount;
-
+
// add the new mount to the current mount's children
if (node.mount) {
node.mount.mounts.push(mount);
}
}
-
+
return mountRoot;
},
unmount(mountpoint) {
var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
-
+
if (!FS.isMountpoint(lookup.node)) {
throw new FS.ErrnoError(28);
}
-
+
// destroy the nodes for this mount, and all its child mounts
var node = lookup.node;
var mount = node.mounted;
var mounts = FS.getMounts(mount);
-
+
for (var [hash, current] of Object.entries(FS.nameTable)) {
while (current) {
var next = current.name_next;
-
+
if (mounts.includes(current.mount)) {
FS.destroyNode(current);
}
-
+
current = next;
}
}
-
+
// no longer a mountpoint
node.mounted = null;
-
+
// remove this mount from the child mounts
var idx = node.mount.mounts.indexOf(mount);
node.mount.mounts.splice(idx, 1);
@@ -1993,7 +1993,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
flags: 2,
namelen: 255,
};
-
+
if (node.node_ops.statfs) {
Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root));
}
@@ -2057,13 +2057,13 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var new_name = PATH.basename(new_path);
// parents must exist
var lookup, old_dir, new_dir;
-
+
// let the errors from non existent directories percolate up
lookup = FS.lookupPath(old_path, { parent: true });
old_dir = lookup.node;
lookup = FS.lookupPath(new_path, { parent: true });
new_dir = lookup.node;
-
+
if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
// need to be part of the same mount
if (old_dir.mount !== new_dir.mount) {
@@ -2309,7 +2309,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (path === "") {
throw new FS.ErrnoError(44);
}
- flags = typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
+ flags = FS_modeStringToFlags(flags);
if ((flags & 64)) {
mode = (mode & 4095) | 32768;
} else {
@@ -2376,7 +2376,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
// we've already handled these, don't pass down to the underlying vfs
flags &= ~(128 | 512 | 131072);
-
+
// register the stream with the filesystem
var stream = FS.createStream({
node,
@@ -2396,11 +2396,6 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (created) {
FS.chmod(node, mode & 0o777);
}
- if (Module['logReadFiles'] && !(flags & 1)) {
- if (!(path in FS.readFiles)) {
- FS.readFiles[path] = 1;
- }
- }
return stream;
},
close(stream) {
@@ -2547,14 +2542,8 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
writeFile(path, data, opts = {}) {
opts.flags = opts.flags || 577;
var stream = FS.open(path, opts.flags, opts.mode);
- if (typeof data == 'string') {
- data = new Uint8Array(intArrayFromString(data, true));
- }
- if (ArrayBuffer.isView(data)) {
- FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
- } else {
- abort('Unsupported data type');
- }
+ data = FS_fileDataToTypedArray(data);
+ FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
FS.close(stream);
},
cwd:() => FS.currentPath,
@@ -2650,7 +2639,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
// TODO deprecate the old functionality of a single
// input / output callback and that utilizes FS.createDevice
// and instead require a unique set of stream ops
-
+
// by default, we symlink the standard streams to the
// default tty devices. however, if the standard streams
// have been overwritten we create a unique device for
@@ -2670,7 +2659,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
} else {
FS.symlink('/dev/tty1', '/dev/stderr');
}
-
+
// open default streams for the stdin, stdout and stderr devices
var stdin = FS.open('/dev/stdin', 0);
var stdout = FS.open('/dev/stdout', 1);
@@ -2678,25 +2667,25 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
},
staticInit() {
FS.nameTable = new Array(4096);
-
+
FS.mount(MEMFS, {}, '/');
-
+
FS.createDefaultDirectories();
FS.createDefaultDevices();
FS.createSpecialDirectories();
-
+
FS.filesystems = {
'MEMFS': MEMFS,
};
},
init(input, output, error) {
FS.initialized = true;
-
+
// Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
input ??= Module['stdin'];
output ??= Module['stdout'];
error ??= Module['stderr'];
-
+
FS.createStandardStreams(input, output, error);
},
quit() {
@@ -2774,11 +2763,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var mode = FS_getMode(canRead, canWrite);
var node = FS.create(path, mode);
if (data) {
- if (typeof data == 'string') {
- var arr = new Array(data.length);
- for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
- data = arr;
- }
+ data = FS_fileDataToTypedArray(data);
// make sure we can write to the file
FS.chmod(node, mode | 146);
var stream = FS.open(node, 577);
@@ -2880,27 +2865,27 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var header;
var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
-
+
var chunkSize = 1024*1024; // Chunk size in bytes
-
+
if (!hasByteServing) chunkSize = datalength;
-
+
// Function to get a range from the remote URL.
var doXHR = (from, to) => {
if (from > to) abort("invalid range (" + from + ", " + to + ") or no bytes requested!");
if (to > datalength-1) abort("only " + datalength + " bytes available! programmer error!");
-
+
// TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
-
+
// Some hints to the browser that we want binary data.
xhr.responseType = 'arraybuffer';
if (xhr.overrideMimeType) {
xhr.overrideMimeType('text/plain; charset=x-user-defined');
}
-
+
xhr.send(null);
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status);
if (xhr.response !== undefined) {
@@ -2919,7 +2904,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (typeof lazyArray.chunks[chunkNum] == 'undefined') abort('doXHR failed!');
return lazyArray.chunks[chunkNum];
});
-
+
if (usesGzip || !datalength) {
// if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
@@ -2927,7 +2912,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
chunkSize = datalength;
out("LazyFiles on gzip forces download of the whole file when length is accessed");
}
-
+
this._length = datalength;
this._chunkSize = chunkSize;
this.lengthKnown = true;
@@ -2945,7 +2930,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return this._chunkSize;
}
}
-
+
if (globalThis.XMLHttpRequest) {
if (!ENVIRONMENT_IS_WORKER) abort('Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc');
var lazyArray = new LazyUint8Array();
@@ -2953,7 +2938,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
} else {
var properties = { isDevice: false, url: url };
}
-
+
var node = FS.createFile(parent, name, properties, canRead, canWrite);
// This is a total hack, but I want to get this lazy file code out of the
// core of MEMFS. If we want to keep this lazy file concept I feel it should
@@ -3013,9 +2998,9 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return node;
},
};
-
-
-
+
+
+
/**
* Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
* emscripten HEAP, returns a copy of that string as a Javascript String object.
@@ -3112,7 +3097,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
};
function ___syscall_chmod(path, mode) {
try {
-
+
path = SYSCALLS.getStr(path);
FS.chmod(path, mode);
return 0;
@@ -3124,7 +3109,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_faccessat(dirfd, path, amode, flags) {
try {
-
+
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
if (amode & ~7) {
@@ -3152,7 +3137,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_fchmod(fd, mode) {
try {
-
+
FS.fchmod(fd, mode);
return 0;
} catch (e) {
@@ -3163,7 +3148,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_fchown32(fd, owner, group) {
try {
-
+
FS.fchown(fd, owner, group);
return 0;
} catch (e) {
@@ -3179,12 +3164,12 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return ret;
};
var syscallGetVarargP = syscallGetVarargI;
-
-
+
+
function ___syscall_fcntl64(fd, cmd, varargs) {
SYSCALLS.varargs = varargs;
try {
-
+
var stream = SYSCALLS.getStreamFromFD(fd);
switch (cmd) {
case 0: {
@@ -3233,7 +3218,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_fstat64(fd, buf) {
try {
-
+
return SYSCALLS.writeStat(buf, FS.fstat(fd));
} catch (e) {
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
@@ -3242,15 +3227,15 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
var INT53_MAX = 9007199254740992;
-
+
var INT53_MIN = -9007199254740992;
var bigintToI53Checked = (num) => (num < INT53_MIN || num > INT53_MAX) ? NaN : Number(num);
function ___syscall_ftruncate64(fd, length) {
length = bigintToI53Checked(length);
-
-
+
+
try {
-
+
if (isNaN(length)) return -61;
FS.ftruncate(fd, length);
return 0;
@@ -3261,13 +3246,13 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
;
}
-
+
var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
};
function ___syscall_getcwd(buf, size) {
try {
-
+
if (size === 0) return -28;
var cwd = FS.cwd();
var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1;
@@ -3280,11 +3265,11 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
}
-
+
function ___syscall_ioctl(fd, op, varargs) {
SYSCALLS.varargs = varargs;
try {
-
+
var stream = SYSCALLS.getStreamFromFD(fd);
switch (op) {
case 21509: {
@@ -3379,7 +3364,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_lstat64(path, buf) {
try {
-
+
path = SYSCALLS.getStr(path);
return SYSCALLS.writeStat(buf, FS.lstat(path));
} catch (e) {
@@ -3390,7 +3375,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_mkdirat(dirfd, path, mode) {
try {
-
+
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
FS.mkdir(path, mode, 0);
@@ -3403,7 +3388,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_newfstatat(dirfd, path, buf, flags) {
try {
-
+
path = SYSCALLS.getStr(path);
var nofollow = flags & 256;
var allowEmpty = flags & 4096;
@@ -3416,11 +3401,11 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
}
-
+
function ___syscall_openat(dirfd, path, flags, varargs) {
SYSCALLS.varargs = varargs;
try {
-
+
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
var mode = varargs ? syscallGetVarargI() : 0;
@@ -3431,16 +3416,16 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
}
-
-
+
+
function ___syscall_readlinkat(dirfd, path, buf, bufsize) {
try {
-
+
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
if (bufsize <= 0) return -28;
var ret = FS.readlink(path);
-
+
var len = Math.min(bufsize, lengthBytesUTF8(ret));
var endChar = HEAP8[buf+len];
stringToUTF8(ret, buf, bufsize+1);
@@ -3456,7 +3441,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_rmdir(path) {
try {
-
+
path = SYSCALLS.getStr(path);
FS.rmdir(path);
return 0;
@@ -3468,7 +3453,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_stat64(path, buf) {
try {
-
+
path = SYSCALLS.getStr(path);
return SYSCALLS.writeStat(buf, FS.stat(path));
} catch (e) {
@@ -3479,7 +3464,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function ___syscall_unlinkat(dirfd, path, flags) {
try {
-
+
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
if (!flags) {
@@ -3499,10 +3484,10 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var readI53FromI64 = (ptr) => {
return HEAPU32[((ptr)>>2)] + HEAP32[(((ptr)+(4))>>2)] * 4294967296;
};
-
+
function ___syscall_utimensat(dirfd, path, times, flags) {
try {
-
+
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path, true);
var now = Date.now(), atime, mtime;
@@ -3543,22 +3528,22 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
var isLeapYear = (year) => year%4 === 0 && (year%100 !== 0 || year%400 === 0);
-
+
var MONTH_DAYS_LEAP_CUMULATIVE = [0,31,60,91,121,152,182,213,244,274,305,335];
-
+
var MONTH_DAYS_REGULAR_CUMULATIVE = [0,31,59,90,120,151,181,212,243,273,304,334];
var ydayFromDate = (date) => {
var leap = isLeapYear(date.getFullYear());
var monthDaysCumulative = (leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE);
var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1; // -1 since it's days since Jan 1
-
+
return yday;
};
-
+
function __localtime_js(time, tmPtr) {
time = bigintToI53Checked(time);
-
-
+
+
var date = new Date(time*1000);
HEAP32[((tmPtr)>>2)] = date.getSeconds();
HEAP32[(((tmPtr)+(4))>>2)] = date.getMinutes();
@@ -3567,11 +3552,11 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
HEAP32[(((tmPtr)+(16))>>2)] = date.getMonth();
HEAP32[(((tmPtr)+(20))>>2)] = date.getFullYear()-1900;
HEAP32[(((tmPtr)+(24))>>2)] = date.getDay();
-
+
var yday = ydayFromDate(date)|0;
HEAP32[(((tmPtr)+(28))>>2)] = yday;
HEAP32[(((tmPtr)+(36))>>2)] = -(date.getTimezoneOffset() * 60);
-
+
// Attention: DST is in December in South, and some regions don't have DST at all.
var start = new Date(date.getFullYear(), 0, 1);
var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
@@ -3581,17 +3566,17 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
;
}
-
-
-
-
-
+
+
+
+
+
function __mmap_js(len, prot, flags, fd, offset, allocated, addr) {
offset = bigintToI53Checked(offset);
-
-
+
+
try {
-
+
var stream = SYSCALLS.getStreamFromFD(fd);
var res = FS.mmap(stream, len, offset, prot, flags);
var ptr = res.ptr;
@@ -3605,13 +3590,13 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
;
}
-
+
function __munmap_js(addr, len, prot, flags, fd, offset) {
offset = bigintToI53Checked(offset);
-
-
+
+
try {
-
+
var stream = SYSCALLS.getStreamFromFD(fd);
if (prot & 2) {
SYSCALLS.doMsync(addr, stream, len, flags, offset);
@@ -3630,7 +3615,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var summer = new Date(currentYear, 6, 1);
var winterOffset = winter.getTimezoneOffset();
var summerOffset = summer.getTimezoneOffset();
-
+
// Local standard timezone offset. Local standard time is not adjusted for
// daylight savings. This code uses the fact that getTimezoneOffset returns
// a greater value during Standard Time versus Daylight Saving Time (DST).
@@ -3638,28 +3623,28 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
// compares whether the output of the given date the same (Standard) or less
// (DST).
var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
-
+
// timezone is specified as seconds west of UTC ("The external variable
// `timezone` shall be set to the difference, in seconds, between
// Coordinated Universal Time (UTC) and local standard time."), the same
// as returned by stdTimezoneOffset.
// See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
HEAPU32[((timezone)>>2)] = stdTimezoneOffset * 60;
-
+
HEAP32[((daylight)>>2)] = Number(winterOffset != summerOffset);
-
+
var extractZone = (timezoneOffset) => {
// Why inverse sign?
// Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
var sign = timezoneOffset >= 0 ? "-" : "+";
-
+
var absOffset = Math.abs(timezoneOffset)
var hours = String(Math.floor(absOffset / 60)).padStart(2, "0");
var minutes = String(absOffset % 60).padStart(2, "0");
-
+
return `UTC${sign}${hours}${minutes}`;
}
-
+
var winterName = extractZone(winterOffset);
var summerName = extractZone(summerOffset);
if (summerOffset < winterOffset) {
@@ -3673,17 +3658,17 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
};
var _emscripten_get_now = () => performance.now();
-
+
var _emscripten_date_now = () => Date.now();
-
+
var nowIsMonotonic = 1;
-
+
var checkWasiClock = (clock_id) => clock_id >= 0 && clock_id <= 3;
-
+
function _clock_time_get(clk_id, ignored_precision, ptime) {
ignored_precision = bigintToI53Checked(ignored_precision);
-
-
+
+
if (!checkWasiClock(clk_id)) {
return 28;
}
@@ -3713,8 +3698,8 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var _emscripten_get_heap_max = () => getHeapMax();
-
-
+
+
var growMemory = (size) => {
var oldHeapSize = wasmMemory.buffer.byteLength;
var pages = ((size - oldHeapSize + 65535) / 65536) | 0;
@@ -3734,7 +3719,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
requestedSize >>>= 0;
// With multithreaded builds, races can happen (another thread might increase the size
// in between), so return a failure, and let the caller retry.
-
+
// Memory resize rules:
// 1. Always increase heap size to at least the requested size, rounded up
// to next page multiple.
@@ -3751,14 +3736,14 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
// over-eager decision to excessively reserve due to (3) above.
// Hence if an allocation fails, cut down on the amount of excess
// growth, in an attempt to succeed to perform a smaller allocation.
-
+
// A limit is set for how much we can grow. We should not exceed that
// (the wasm binary specifies it, so if we tried, we'd fail anyhow).
var maxHeapSize = getHeapMax();
if (requestedSize > maxHeapSize) {
return false;
}
-
+
// Loop through potential heap size increases. If we attempt a too eager
// reservation that fails, cut down on the attempted size and reserve a
// smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
@@ -3766,12 +3751,12 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth
// but limit overreserving (default to capping at +96MB overgrowth at most)
overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );
-
+
var newSize = Math.min(maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536));
-
+
var replacement = growMemory(newSize);
if (replacement) {
-
+
return true;
}
}
@@ -3780,7 +3765,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var ENV = {
};
-
+
var getExecutableName = () => thisProgram || './this.program';
var getEnvStrings = () => {
if (!getEnvStrings.strings) {
@@ -3812,7 +3797,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
return getEnvStrings.strings;
};
-
+
var _environ_get = (__environ, environ_buf) => {
var bufSize = 0;
var envp = 0;
@@ -3825,7 +3810,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return 0;
};
-
+
var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
var strings = getEnvStrings();
HEAPU32[((penviron_count)>>2)] = strings.length;
@@ -3839,7 +3824,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function _fd_close(fd) {
try {
-
+
var stream = SYSCALLS.getStreamFromFD(fd);
FS.close(stream);
return 0;
@@ -3851,7 +3836,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function _fd_fdstat_get(fd, pbuf) {
try {
-
+
var rightsBase = 0;
var rightsInheriting = 0;
var flags = 0;
@@ -3892,10 +3877,10 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
return ret;
};
-
+
function _fd_read(fd, iov, iovcnt, pnum) {
try {
-
+
var stream = SYSCALLS.getStreamFromFD(fd);
var num = doReadv(stream, iov, iovcnt);
HEAPU32[((pnum)>>2)] = num;
@@ -3906,13 +3891,13 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
}
-
+
function _fd_seek(fd, offset, whence, newOffset) {
offset = bigintToI53Checked(offset);
-
-
+
+
try {
-
+
if (isNaN(offset)) return 61;
var stream = SYSCALLS.getStreamFromFD(fd);
FS.llseek(stream, offset, whence);
@@ -3928,7 +3913,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
function _fd_sync(fd) {
try {
-
+
var stream = SYSCALLS.getStreamFromFD(fd);
var rtn = stream.stream_ops?.fsync?.(stream);
return rtn;
@@ -3958,10 +3943,10 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
return ret;
};
-
+
function _fd_write(fd, iov, iovcnt, pnum) {
try {
-
+
var stream = SYSCALLS.getStreamFromFD(fd);
var num = doWritev(stream, iov, iovcnt);
HEAPU32[((pnum)>>2)] = num;
@@ -4102,6 +4087,7 @@ var _sqlite3_status64,
_sqlite3_bind_null,
_sqlite3_bind_pointer,
_sqlite3_bind_text,
+ _sqlite3_bind_zeroblob,
_sqlite3_bind_parameter_count,
_sqlite3_bind_parameter_name,
_sqlite3_bind_parameter_index,
@@ -4365,6 +4351,7 @@ function assignWasmExports(wasmExports) {
_sqlite3_bind_null = Module['_sqlite3_bind_null'] = wasmExports['sqlite3_bind_null'];
_sqlite3_bind_pointer = Module['_sqlite3_bind_pointer'] = wasmExports['sqlite3_bind_pointer'];
_sqlite3_bind_text = Module['_sqlite3_bind_text'] = wasmExports['sqlite3_bind_text'];
+ _sqlite3_bind_zeroblob = Module['_sqlite3_bind_zeroblob'] = wasmExports['sqlite3_bind_zeroblob'];
_sqlite3_bind_parameter_count = Module['_sqlite3_bind_parameter_count'] = wasmExports['sqlite3_bind_parameter_count'];
_sqlite3_bind_parameter_name = Module['_sqlite3_bind_parameter_name'] = wasmExports['sqlite3_bind_parameter_name'];
_sqlite3_bind_parameter_index = Module['_sqlite3_bind_parameter_index'] = wasmExports['sqlite3_bind_parameter_index'];
@@ -4709,6 +4696,7 @@ Module.runSQLite3PostLoadInit = async function(
- sqlite3-vtab-helper.c-pp.js => Utilities for virtual table impls
- sqlite3-vfs-opfs.c-pp.js => OPFS VFS
- sqlite3-vfs-opfs-sahpool.c-pp.js => OPFS SAHPool VFS
+ - sqlite3-vfs-opfs-wl.c-pp.js => WebLock-using OPFS VFS
- post-js-footer.js => this file's epilogue
And all of that gets sandwiched between extern-pre-js.js and
@@ -4743,11 +4731,11 @@ Module.runSQLite3PostLoadInit = async function(
/* @preserve
** This code was built from sqlite3 version...
**
-** SQLITE_VERSION "3.52.0"
-** SQLITE_VERSION_NUMBER 3052000
-** SQLITE_SOURCE_ID "2026-01-30 06:37:34 407724c4e80efdf93d885e95b5209a100a3f470fe0298138be57201f65f9817e"
+** SQLITE_VERSION "3.53.0"
+** SQLITE_VERSION_NUMBER 3053000
+** SQLITE_SOURCE_ID "2026-04-09 11:41:38 4525003a53a7fc63ca75c59b22c79608659ca12f0131f52c18637f829977f20b"
**
-** Emscripten SDK: 5.0.0
+** Emscripten SDK: 5.0.5
*/
/*
2022-05-22
@@ -4850,6 +4838,13 @@ Module.runSQLite3PostLoadInit = async function(
used in WASMFS-capable builds of the library (which the canonical
builds do not include).
+ - `disable` (as of 3.53.0) may be an object with the following
+ properties:
+ - `vfs`, an object, may contain a map of VFS names to booleans.
+ Any mapping to falsy are disabled. The supported names
+ are: "kvvfs", "opfs", "opfs-sahpool", "opfs-wl".
+ - Other disabling options may be added in the future.
+
[^1] = This property may optionally be a function, in which case
this function calls that function to fetch the value,
enabling delayed evaluation.
@@ -4896,7 +4891,8 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
);
return sqlite3ApiBootstrap.sqlite3;
}
- const config = Object.assign(Object.create(null),{
+ const nu = (...obj)=>Object.assign(Object.create(null),...obj);
+ const config = nu({
exports: undefined,
memory: undefined,
bigIntEnabled: !!globalThis.BigInt64Array,
@@ -4913,7 +4909,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
certain wasm.xWrap.resultAdapter()s.
*/
useStdAlloc: false
- }, apiConfig || {});
+ }, apiConfig);
Object.assign(config, {
allocExportName: config.useStdAlloc ? 'malloc' : 'sqlite3_malloc',
@@ -4946,7 +4942,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
not documented are installed as 1-to-1 proxies for their
C-side counterparts.
*/
- const capi = Object.create(null);
+ const capi = nu();
/**
Holds state which are specific to the WASM-related
infrastructure and glue code.
@@ -4955,7 +4951,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
dynamically after the api object is fully constructed, so
not all are documented in this file.
*/
- const wasm = Object.create(null);
+ const wasm = nu();
/** Internal helper for SQLite3Error ctor. */
const __rcStr = (rc)=>{
@@ -5503,6 +5499,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
toss: function(...args){throw new Error(args.join(' '))},
toss3,
typedArrayPart: wasm.typedArrayPart,
+ nu,
assert: function(arg,msg){
if( !arg ){
util.toss("Assertion failed:",msg);
@@ -5759,7 +5756,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
rv[1] = m ? (f._rxInt.test(m[2]) ? +m[2] : m[2]) : true;
};
}
- const rc = Object.create(null), ov = [0,0];
+ const rc = nu(), ov = [0,0];
let i = 0, k;
while((k = capi.sqlite3_compileoption_get(i++))){
f._opt(k,ov);
@@ -5767,7 +5764,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
}
return f._result = rc;
}else if(Array.isArray(optName)){
- const rc = Object.create(null);
+ const rc = nu();
optName.forEach((v)=>{
rc[v] = capi.sqlite3_compileoption_used(v);
});
@@ -5818,7 +5815,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
The memory lives in the WASM heap and can be used with routines
such as wasm.poke() and wasm.heap8u().slice().
*/
- wasm.pstack = Object.assign(Object.create(null),{
+ wasm.pstack = nu({
/**
Sets the current pstack position to the given pointer. Results
are undefined if the passed-in value did not come from
@@ -6040,7 +6037,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
// sqlite3__wasm_init_wasmfs() is not available
return this.dir = "";
}
- }.bind(Object.create(null));
+ }.bind(nu());
/**
Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
@@ -6394,6 +6391,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
case capi.SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE:
case capi.SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE:
case capi.SQLITE_DBCONFIG_ENABLE_COMMENTS:
+ case capi.SQLITE_DBCONFIG_FP_DIGITS:
if( !this.ip ){
this.ip = wasm.xWrap('sqlite3__wasm_db_config_ip','int',
['sqlite3*', 'int', 'int', '*']);
@@ -6415,7 +6413,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
default:
return capi.SQLITE_MISUSE;
}
- }.bind(Object.create(null));
+ }.bind(nu());
/**
Given a (sqlite3_value*), this function attempts to convert it
@@ -6649,7 +6647,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
const pv = wasm.peekPtr(this.ptr);
return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
- }.bind(Object.create(null));
+ }.bind(nu());
/**
A wrapper around sqlite3_preupdate_new() which fetches the
@@ -6689,6 +6687,62 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
'sqlite3changeset_old');
}/*changeset/preupdate additions*/
+ /**
+ EXPERIMENTAL. For tentative addition in 3.53.0.
+
+ sqlite3_js_retry_busy(maxTimes,callback[,beforeRetry])
+
+ Calls the given _synchronous_ callback function. If that function
+ returns sqlite3.capi.SQLITE_BUSY _or_ throws an SQLite3Error
+ with a resultCode property of that value then it will suppress
+ that error and try again, up to the given maximum number of
+ times. If the callback returns any other value than that,
+ it is returned. If the maximum number of retries has been
+ reached, an SQLite3Error with a resultCode value of
+ sqlite3.capi.SQLITE_BUSY is thrown. If the callback throws any
+ exception other than the aforementioned BUSY exception, it is
+ propagated. If it throws a BUSY exception on its final attempt,
+ that is propagated as well.
+
+ If the beforeRetry argument is given, it must be a _synchronous_
+ function. It is called immediately before each retry of the
+ callback (not for the initial call), passed the attempt number
+ (so it starts with 2, not 1). If it throws, the exception is
+ handled as described above. Its result value is ignored.
+
+ To effectively retry "forever", pass a negative maxTimes value,
+ with the caveat that there is no recovery from that unless the
+ beforeRetry() can figure out when to throw.
+
+ TODO: an async variant of this.
+ */
+ capi.sqlite3_js_retry_busy = function(maxTimes, callback, beforeRetry){
+ for(let n = 1; n <= maxTimes; ++n){
+ try{
+ if( beforeRetry && n>1 ) beforeRetry(n);
+ const rc = callback();
+ if( capi.SQLITE_BUSY===rc ){
+ if( n===maxTimes ){
+ throw new SQLite3Error(rc, [
+ "sqlite3_js_retry_busy() max retry attempts (",
+ maxTimes,
+ ") reached."
+ ].join(''));
+ }
+ continue;
+ }
+ return rc;
+ }catch(e){
+ if( n{};
const debug = sqlite3.__isUnderTest
- ? (...args)=>sqlite3.config.debug("kvvfs:", ...args)
+ ? (...args)=>sqlite3.config.debug?.("kvvfs:", ...args)
: noop;
- const warn = (...args)=>sqlite3.config.warn("kvvfs:", ...args);
- const error = (...args)=>sqlite3.config.error("kvvfs:", ...args);
+ const warn = (...args)=>sqlite3.config.warn?.("kvvfs:", ...args);
+ const error = (...args)=>sqlite3.config.error?.("kvvfs:", ...args);
/**
Implementation of JS's Storage interface for use as backing store
@@ -16179,17 +16240,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
and recreating it whenever a property index might be invalidated.
*/
class KVVfsStorage {
- #map;
- #keys;
- #getKeys(){return this.#keys ??= Object.keys(this.#map);}
+ #map = Object.create(null);
+ #keys = null;
+ #size = 0;
constructor(){
this.clear();
}
+ #getKeys(){
+ return this.#keys ??= Object.keys(this.#map);
+ }
+
key(n){
- const k = this.#getKeys();
- return n= this.#size) return null;
+ return this.#getKeys()[n];
}
getItem(k){
@@ -16197,14 +16262,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
setItem(k,v){
- if( !hop(this.#map, k) ){
+ if( !(k in this.#map) ){
+ ++this.#size;
this.#keys = null;
}
this.#map[k] = ''+v;
}
removeItem(k){
- if( delete this.#map[k] ){
+ if( k in this.#map ){
+ delete this.#map[k];
+ --this.#size;
this.#keys = null;
}
}
@@ -16212,10 +16280,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
clear(){
this.#map = Object.create(null);
this.#keys = null;
+ this.#size = 0;
}
get length() {
- return this.#getKeys().length;
+ return this.#size;
}
}/*KVVfsStorage*/;
@@ -16977,36 +17046,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
},
- // We override xRead/xWrite only for logging/debugging. They
- // should otherwise be disabled (it's faster that way).
- xRead: function(pFile,pTgt,n,iOff64){
- cache.popError();
- try{
- if( kvvfs?.log?.xRead ){
- const h = pFileHandles.get(pFile);
- util.assert(h, "Missing KVVfsFile handle");
- debug("xRead", n, iOff64, h);
- }
- return originalMethods.ioDb.xRead(pFile, pTgt, n, iOff64);
- }catch(e){
- error("xRead",e);
- return cache.setError(e);
- }
- },
- xWrite: function(pFile,pSrc,n,iOff64){
- cache.popError();
- try{
- if( kvvfs?.log?.xWrite ){
- const h = pFileHandles.get(pFile);
- util.assert(h, "Missing KVVfsFile handle");
- debug("xWrite", n, iOff64, h);
- }
- return originalMethods.ioDb.xWrite(pFile, pSrc, n, iOff64);
- }catch(e){
- error("xWrite",e);
- return cache.setError(e);
- }
- },
}/*.ioDb*/,
@@ -17018,9 +17057,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/*.ioJrnl*/
}/*methodOverrides*/;
- debug("pVfs and friends", pVfs, pIoDb, pIoJrnl,
- kvvfsMethods, capi.sqlite3_file.structInfo,
- KVVfsFile.structInfo);
+
try {
util.assert( cache.buffer.n>1024*129, "Heap buffer is not large enough"
/* Native is SQLITE_KVOS_SZ is 133073 as of this writing */ );
@@ -17109,7 +17146,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
limitation which has since been overcome, but removal of
JsStorageDb.prototype.clearStorage() would be a backwards compatibility
break, so this function permits wiping the storage for those two
- cases even if they are opened. Use with case.
+ cases even if they are opened. Use with care.
*/
const sqlite3_js_kvvfs_clear = function callee(which){
if( ''===which ){
@@ -17784,7 +17821,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
return rc;
}catch(e){
- return VT.xErrror('xConnect', e, capi.SQLITE_ERROR);
+ return VT.xError('xConnect', e, capi.SQLITE_ERROR);
}
},
xCreate: wasm.ptr.null, // eponymous only
@@ -17883,7 +17920,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
})/*globalThis.sqlite3ApiBootstrap.initializers*/;
/*
- 2022-09-18
+ 2026-03-04
The author disclaims copyright to this source code. In place of a
legal notice, here is a blessing:
@@ -17894,160 +17931,552 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
***********************************************************************
- This file holds the synchronous half of an sqlite3_vfs
- implementation which proxies, in a synchronous fashion, the
- asynchronous Origin-Private FileSystem (OPFS) APIs using a second
- Worker, implemented in sqlite3-opfs-async-proxy.js. This file is
- intended to be appended to the main sqlite3 JS deliverable somewhere
- after sqlite3-api-oo1.js.
+ This file holds code shared by sqlite3-vfs-opfs{,-wl}.c-pp.js. It
+ creates a private/internal sqlite3.opfs namespace common to the two
+ and used (only) by them and the test framework. It is not part of
+ the public API. The library deletes sqlite3.opfs in its final
+ bootstrapping steps unless it's specifically told to keep them (for
+ testing purposes only) using an undocumented and unsupported
+ mechanism.
*/
-'use strict';
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
-/**
- installOpfsVfs() returns a Promise which, on success, installs an
- sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
- which accept a VFS. It is intended to be called via
- sqlite3ApiBootstrap.initializers or an equivalent mechanism.
+ 'use strict';
+ if( sqlite3.config.disable?.vfs?.opfs &&
+ sqlite3.config.disable.vfs['opfs-vfs'] ){
+ return;
+ }
+ const toss = sqlite3.util.toss,
+ capi = sqlite3.capi,
+ util = sqlite3.util,
+ wasm = sqlite3.wasm;
- The installed VFS uses the Origin-Private FileSystem API for
- all file storage. On error it is rejected with an exception
- explaining the problem. Reasons for rejection include, but are
- not limited to:
+ /**
+ Generic utilities for working with OPFS. This will get filled out
+ by the Promise setup and, on success, installed as sqlite3.opfs.
- - The counterpart Worker (see below) could not be loaded.
+ This is an internal/private namespace intended for use solely by
+ the OPFS VFSes and test code for them. The library bootstrapping
+ process removes this object in non-testing contexts.
+ */
+ const opfsUtil = sqlite3.opfs = Object.create(null);
- - The environment does not support OPFS. That includes when
- this function is called from the main window thread.
+ /**
+ Returns true if _this_ thread has access to the OPFS APIs.
+ */
+ opfsUtil.thisThreadHasOPFS = ()=>{
+ return globalThis.FileSystemHandle &&
+ globalThis.FileSystemDirectoryHandle &&
+ globalThis.FileSystemFileHandle &&
+ globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle &&
+ navigator?.storage?.getDirectory;
+ };
- Significant notes and limitations:
+ /**
+ Must be called by the OPFS VFSes immediately after they determine
+ whether OPFS is available by calling
+ thisThreadHasOPFS(). Resolves to the OPFS storage root directory
+ and sets opfsUtil.rootDirectory to that value.
+ */
+ opfsUtil.getRootDir = async function f(){
+ return f.promise ??= navigator.storage.getDirectory().then(d=>{
+ opfsUtil.rootDirectory = d;
+ return d;
+ }).catch(e=>{
+ delete f.promise;
+ throw e;
+ });
+ };
- - The OPFS features used here are only available in dedicated Worker
- threads. This file tries to detect that case, resulting in a
- rejected Promise if those features do not seem to be available.
+ /**
+ Expects an OPFS file path. It gets resolved, such that ".."
+ components are properly expanded, and returned. If the 2nd arg
+ is true, the result is returned as an array of path elements,
+ else an absolute path string is returned.
+ */
+ opfsUtil.getResolvedPath = function(filename,splitIt){
+ const p = new URL(filename, "file://irrelevant").pathname;
+ return splitIt ? p.split('/').filter((v)=>!!v) : p;
+ };
- - It requires the SharedArrayBuffer and Atomics classes, and the
- former is only available if the HTTP server emits the so-called
- COOP and COEP response headers. These features are required for
- proxying OPFS's synchronous API via the synchronous interface
- required by the sqlite3_vfs API.
+ /**
+ Takes the absolute path to a filesystem element. Returns an
+ array of [handleOfContainingDir, filename]. If the 2nd argument
+ is truthy then each directory element leading to the file is
+ created along the way. Throws if any creation or resolution
+ fails.
+ */
+ opfsUtil.getDirForFilename = async function f(absFilename, createDirs = false){
+ const path = opfsUtil.getResolvedPath(absFilename, true);
+ const filename = path.pop();
+ let dh = await opfsUtil.getRootDir();
+ for(const dirName of path){
+ if(dirName){
+ dh = await dh.getDirectoryHandle(dirName, {create: !!createDirs});
+ }
+ }
+ return [dh, filename];
+ };
- - This function may only be called a single time. When called, this
- function removes itself from the sqlite3 object.
+ /**
+ Creates the given directory name, recursively, in
+ the OPFS filesystem. Returns true if it succeeds or the
+ directory already exists, else false.
+ */
+ opfsUtil.mkdir = async function(absDirName){
+ try {
+ await opfsUtil.getDirForFilename(absDirName+"/filepart", true);
+ return true;
+ }catch(e){
+ //sqlite3.config.warn("mkdir(",absDirName,") failed:",e);
+ return false;
+ }
+ };
- All arguments to this function are for internal/development purposes
- only. They do not constitute a public API and may change at any
- time.
+ /**
+ Checks whether the given OPFS filesystem entry exists,
+ returning true if it does, false if it doesn't or if an
+ exception is intercepted while trying to make the
+ determination.
+ */
+ opfsUtil.entryExists = async function(fsEntryName){
+ try {
+ const [dh, fn] = await opfsUtil.getDirForFilename(fsEntryName);
+ await dh.getFileHandle(fn);
+ return true;
+ }catch(e){
+ return false;
+ }
+ };
- The argument may optionally be a plain object with the following
- configuration options:
+ /**
+ Generates a random ASCII string len characters long, intended for
+ use as a temporary file name.
+ */
+ opfsUtil.randomFilename = function f(len=16){
+ if(!f._chars){
+ f._chars = "abcdefghijklmnopqrstuvwxyz"+
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
+ "012346789";
+ f._n = f._chars.length;
+ }
+ const a = [];
+ let i = 0;
+ for( ; i < len; ++i){
+ const ndx = Math.random() * (f._n * 64) % f._n | 0;
+ a[i] = f._chars[ndx];
+ }
+ return a.join("");
+ /*
+ An alternative impl. with an unpredictable length
+ but much simpler:
- - proxyUri: name of the async proxy JS file.
+ Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36)
+ */
+ };
- - verbose (=2): an integer 0-3. 0 disables all logging, 1 enables
- logging of errors. 2 enables logging of warnings and errors. 3
- additionally enables debugging info. Logging is performed
- via the sqlite3.config.{log|warn|error}() functions.
+ /**
+ Returns a promise which resolves to an object which represents
+ all files and directories in the OPFS tree. The top-most object
+ has two properties: `dirs` is an array of directory entries
+ (described below) and `files` is a list of file names for all
+ files in that directory.
- - sanityChecks (=false): if true, some basic sanity tests are run on
- the OPFS VFS API after it's initialized, before the returned
- Promise resolves. This is only intended for testing and
- development of the VFS, not client-side use.
+ Traversal starts at sqlite3.opfs.rootDirectory.
- On success, the Promise resolves to the top-most sqlite3 namespace
- object and that object gets a new object installed in its
- `opfs` property, containing several OPFS-specific utilities.
-*/
-const installOpfsVfs = function callee(options){
- if(!globalThis.SharedArrayBuffer
- || !globalThis.Atomics){
- return Promise.reject(
- new Error("Cannot install OPFS: Missing SharedArrayBuffer and/or Atomics. "+
- "The server must emit the COOP/COEP response headers to enable those. "+
- "See https://sqlite.org/wasm/doc/trunk/persistence.md#coop-coep")
- );
- }else if('undefined'===typeof WorkerGlobalScope){
- return Promise.reject(
- new Error("The OPFS sqlite3_vfs cannot run in the main thread "+
- "because it requires Atomics.wait().")
- );
- }else if(!globalThis.FileSystemHandle ||
- !globalThis.FileSystemDirectoryHandle ||
- !globalThis.FileSystemFileHandle ||
- !globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle ||
- !navigator?.storage?.getDirectory){
- return Promise.reject(
- new Error("Missing required OPFS APIs.")
- );
- }
- if(!options || 'object'!==typeof options){
- options = Object.create(null);
- }
- const urlParams = new URL(globalThis.location.href).searchParams;
- if(urlParams.has('opfs-disable')){
- //sqlite3.config.warn('Explicitly not installing "opfs" VFS due to opfs-disable flag.');
- return Promise.resolve(sqlite3);
- }
- if(undefined===options.verbose){
- options.verbose = urlParams.has('opfs-verbose')
- ? (+urlParams.get('opfs-verbose') || 2) : 1;
- }
- if(undefined===options.sanityChecks){
- options.sanityChecks = urlParams.has('opfs-sanity-check');
- }
- if(undefined===options.proxyUri){
- options.proxyUri = callee.defaultProxyUri;
- }
+ Each `dirs` entry is an object in this form:
- //sqlite3.config.warn("OPFS options =",options,globalThis.location);
+ ```
+ { name: directoryName,
+ dirs: [...subdirs],
+ files: [...file names]
+ }
+ ```
+
+ The `files` and `subdirs` entries are always set but may be
+ empty arrays.
+
+ The returned object has the same structure but its `name` is
+ an empty string. All returned objects are created with
+ Object.create(null), so have no prototype.
+
+ Design note: the entries do not contain more information,
+ e.g. file sizes, because getting such info is not only
+ expensive but is subject to locking-related errors.
+ */
+ opfsUtil.treeList = async function(){
+ const doDir = async function callee(dirHandle,tgt){
+ tgt.name = dirHandle.name;
+ tgt.dirs = [];
+ tgt.files = [];
+ for await (const handle of dirHandle.values()){
+ if('directory' === handle.kind){
+ const subDir = Object.create(null);
+ tgt.dirs.push(subDir);
+ await callee(handle, subDir);
+ }else{
+ tgt.files.push(handle.name);
+ }
+ }
+ };
+ const root = Object.create(null);
+ const dir = await opfsUtil.getRootDir();
+ await doDir(dir, root);
+ return root;
+ };
+
+ /**
+ Irrevocably deletes _all_ files in the current origin's OPFS.
+ Obviously, this must be used with great caution. It may throw
+ an exception if removal of anything fails (e.g. a file is
+ locked), but the precise conditions under which the underlying
+ APIs will throw are not documented (so we cannot tell you what
+ they are).
+ */
+ opfsUtil.rmfr = async function(){
+ const rd = await opfsUtil.getRootDir();
+ const dir = rd, opt = {recurse: true};
+ for await (const handle of dir.values()){
+ dir.removeEntry(handle.name, opt);
+ }
+ };
+
+ /**
+ Deletes the given OPFS filesystem entry. As this environment
+ has no notion of "current directory", the given name must be an
+ absolute path. If the 2nd argument is truthy, deletion is
+ recursive (use with caution!).
+
+ The returned Promise resolves to true if the deletion was
+ successful, else false (but...). The OPFS API reports the
+ reason for the failure only in human-readable form, not
+ exceptions which can be type-checked to determine the
+ failure. Because of that...
+
+ If the final argument is truthy then this function will
+ propagate any exception on error, rather than returning false.
+ */
+ opfsUtil.unlink = async function(fsEntryName, recursive = false,
+ throwOnError = false){
+ try {
+ const [hDir, filenamePart] =
+ await opfsUtil.getDirForFilename(fsEntryName, false);
+ await hDir.removeEntry(filenamePart, {recursive});
+ return true;
+ }catch(e){
+ if(throwOnError){
+ throw new Error("unlink(",arguments[0],") failed: "+e.message,{
+ cause: e
+ });
+ }
+ return false;
+ }
+ };
+
+ /**
+ Traverses the OPFS filesystem, calling a callback for each
+ entry. The argument may be either a callback function or an
+ options object with any of the following properties:
+
+ - `callback`: function which gets called for each filesystem
+ entry. It gets passed 3 arguments: 1) the
+ FileSystemFileHandle or FileSystemDirectoryHandle of each
+ entry (noting that both are instanceof FileSystemHandle). 2)
+ the FileSystemDirectoryHandle of the parent directory. 3) the
+ current depth level, with 0 being at the top of the tree
+ relative to the starting directory. If the callback returns a
+ literal false, as opposed to any other falsy value, traversal
+ stops without an error. Any exceptions it throws are
+ propagated. Results are undefined if the callback manipulate
+ the filesystem (e.g. removing or adding entries) because the
+ how OPFS iterators behave in the face of such changes is
+ undocumented.
+
+ - `recursive` [bool=true]: specifies whether to recurse into
+ subdirectories or not. Whether recursion is depth-first or
+ breadth-first is unspecified!
+
+ - `directory` [FileSystemDirectoryEntry=sqlite3.opfs.rootDirectory]
+ specifies the starting directory.
+
+ If this function is passed a function, it is assumed to be the
+ callback.
+
+ Returns a promise because it has to (by virtue of being async)
+ but that promise has no specific meaning: the traversal it
+ performs is synchronous. The promise must be used to catch any
+ exceptions propagated by the callback, however.
+ */
+ opfsUtil.traverse = async function(opt){
+ const defaultOpt = {
+ recursive: true,
+ directory: await opfsUtil.getRootDir()
+ };
+ if('function'===typeof opt){
+ opt = {callback:opt};
+ }
+ opt = Object.assign(defaultOpt, opt||{});
+ const doDir = async function callee(dirHandle, depth){
+ for await (const handle of dirHandle.values()){
+ if(false === opt.callback(handle, dirHandle, depth)) return false;
+ else if(opt.recursive && 'directory' === handle.kind){
+ if(false === await callee(handle, depth + 1)) break;
+ }
+ }
+ };
+ doDir(opt.directory, 0);
+ };
+
+ /**
+ Impl of opfsUtil.importDb() when it's given a function as its
+ second argument.
+ */
+ const importDbChunked = async function(filename, callback){
+ const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true);
+ const hFile = await hDir.getFileHandle(fnamePart, {create:true});
+ let sah = await hFile.createSyncAccessHandle();
+ let nWrote = 0, chunk, checkedHeader = false, err = false;
+ try{
+ sah.truncate(0);
+ while( undefined !== (chunk = await callback()) ){
+ if(chunk instanceof ArrayBuffer) chunk = new Uint8Array(chunk);
+ if( !checkedHeader && 0===nWrote && chunk.byteLength>=15 ){
+ util.affirmDbHeader(chunk);
+ checkedHeader = true;
+ }
+ sah.write(chunk, {at: nWrote});
+ nWrote += chunk.byteLength;
+ }
+ if( nWrote < 512 || 0!==nWrote % 512 ){
+ toss("Input size",nWrote,"is not correct for an SQLite database.");
+ }
+ if( !checkedHeader ){
+ const header = new Uint8Array(20);
+ sah.read( header, {at: 0} );
+ util.affirmDbHeader( header );
+ }
+ sah.write(new Uint8Array([1,1]), {at: 18}/*force db out of WAL mode*/);
+ return nWrote;
+ }catch(e){
+ await sah.close();
+ sah = undefined;
+ await hDir.removeEntry( fnamePart ).catch(()=>{});
+ throw e;
+ }finally {
+ if( sah ) await sah.close();
+ }
+ };
+
+ /**
+ Asynchronously imports the given bytes (a byte array or
+ ArrayBuffer) into the given database file.
+
+ Results are undefined if the given db name refers to an opened
+ db.
+
+ If passed a function for its second argument, its behaviour
+ changes: imports its data in chunks fed to it by the given
+ callback function. It calls the callback (which may be async)
+ repeatedly, expecting either a Uint8Array or ArrayBuffer (to
+ denote new input) or undefined (to denote EOF). For so long as
+ the callback continues to return non-undefined, it will append
+ incoming data to the given VFS-hosted database file. When
+ called this way, the resolved value of the returned Promise is
+ the number of bytes written to the target file.
+
+ It very specifically requires the input to be an SQLite3
+ database and throws if that's not the case. It does so in
+ order to prevent this function from taking on a larger scope
+ than it is specifically intended to. i.e. we do not want it to
+ become a convenience for importing arbitrary files into OPFS.
+
+ This routine rewrites the database header bytes in the output
+ file (not the input array) to force disabling of WAL mode.
+
+ On error this throws and the state of the input file is
+ undefined (it depends on where the exception was triggered).
+
+ On success, resolves to the number of bytes written.
+ */
+ opfsUtil.importDb = async function(filename, bytes){
+ if( bytes instanceof Function ){
+ return importDbChunked(filename, bytes);
+ }
+ if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
+ util.affirmIsDb(bytes);
+ const n = bytes.byteLength;
+ const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true);
+ let sah, err, nWrote = 0;
+ try {
+ const hFile = await hDir.getFileHandle(fnamePart, {create:true});
+ sah = await hFile.createSyncAccessHandle();
+ sah.truncate(0);
+ nWrote = sah.write(bytes, {at: 0});
+ if(nWrote != n){
+ toss("Expected to write "+n+" bytes but wrote "+nWrote+".");
+ }
+ sah.write(new Uint8Array([1,1]), {at: 18}) /* force db out of WAL mode */;
+ return nWrote;
+ }catch(e){
+ if( sah ){ await sah.close(); sah = undefined; }
+ await hDir.removeEntry( fnamePart ).catch(()=>{});
+ throw e;
+ }finally{
+ if( sah ) await sah.close();
+ }
+ };
+
+ /**
+ Checks for features required for OPFS VFSes and throws with a
+ descriptive error message if they're not found. This is intended
+ to be run as part of async VFS installation steps.
+ */
+ opfsUtil.vfsInstallationFeatureCheck = function(vfsName){
+ if( !globalThis.SharedArrayBuffer || !globalThis.Atomics ){
+ toss("Cannot install OPFS: Missing SharedArrayBuffer and/or Atomics.",
+ "The server must emit the COOP/COEP response headers to enable those.",
+ "See https://sqlite.org/wasm/doc/trunk/persistence.md#coop-coep");
+ }else if( 'undefined'===typeof WorkerGlobalScope ){
+ toss("The OPFS sqlite3_vfs cannot run in the main thread",
+ "because it requires Atomics.wait().");
+ }else if( !globalThis.FileSystemHandle ||
+ !globalThis.FileSystemDirectoryHandle ||
+ !globalThis.FileSystemFileHandle?.prototype?.createSyncAccessHandle ||
+ !navigator?.storage?.getDirectory ){
+ toss("Missing required OPFS APIs.");
+ }else if( 'opfs-wl'===vfsName && !globalThis.Atomics.waitAsync ){
+ toss('The',vfsName,'VFS requires Atomics.waitAsync(), which is not available.');
+ }
+ };
+
+ /**
+ Must be called by the VFS's main installation routine and passed
+ the options object that function receives and a reference to that
+ function itself (we don't need this anymore).
+
+ It throws if OPFS is not available.
+
+ If it returns falsy, it detected that OPFS should be disabled, in
+ which case the callee should immediately return/resolve to the
+ sqlite3 object.
+
+ Else it returns a new copy of the options object, fleshed out
+ with any missing defaults. The caller must:
+
+ - Set up any local state they need.
+
+ - Call opfsUtil.createVfsState(vfsName,opt), where opt is the
+ object returned by this function.
+
+ - Set up any references they may need to state returned
+ by the previous step.
+
+ - Call opfvs.bindVfs()
+ */
+ opfsUtil.initOptions = function callee(vfsName, options){
+ const urlParams = new URL(globalThis.location.href).searchParams;
+ if( urlParams.has(vfsName+'-disable') ){
+ //sqlite3.config.warn('Explicitly not installing "opfs" VFS due to opfs-disable flag.');
+ return;
+ }
+ try{
+ opfsUtil.vfsInstallationFeatureCheck(vfsName);
+ }catch(e){
+ return;
+ }
+ options = util.nu(options);
+ options.vfsName = vfsName;
+ options.verbose ??= urlParams.has('opfs-verbose')
+ ? +urlParams.get('opfs-verbose') : 1;
+ options.sanityChecks ??= urlParams.has('opfs-sanity-check');
+
+ if( !opfsUtil.proxyUri ){
+ opfsUtil.proxyUri = "sqlite3-opfs-async-proxy.js";
+ if( sqlite3.scriptInfo?.sqlite3Dir ){
+ /* Doing this from one scope up, outside of this function, does
+ not work. */
+ opfsUtil.proxyUri = (
+ sqlite3.scriptInfo.sqlite3Dir + opfsUtil.proxyUri
+ );
+ }
+ }
+ options.proxyUri ??= opfsUtil.proxyUri;
+ if('function' === typeof options.proxyUri){
+ options.proxyUri = options.proxyUri();
+ }
+ //sqlite3.config.warn("opfsUtil options =",JSON.stringify(options), 'urlParams =', urlParams);
+ return opfsUtil.options = options;
+ };
+
+ /**
+ Creates, populates, and returns the main state object used by the
+ "opfs" and "opfs-wl" VFSes, and transfered from those to their
+ async counterparts.
+
+ The returned object's vfs property holds the fully-populated
+ capi.sqlite3_vfs instance, tagged with lots of extra state which
+ the current VFSes need to have exposed to them.
+
+ After setting up any local state needed, the caller must call
+ theVfs.bindVfs(X,Y), where X is an object containing the
+ sqlite3_io_methods to override and Y is a callback which gets
+ triggered if init succeeds, before the final Promise decides
+ whether or not to reject.
+
+ This object must, when it's passed to the async part, contain
+ only cloneable or sharable objects. After the worker's "inited"
+ message arrives, other types of data may be added to it.
+ */
+ opfsUtil.createVfsState = function(){
+ const state = util.nu();
+ const options = opfsUtil.options;
+ state.verbose = options.verbose;
- if('function' === typeof options.proxyUri){
- options.proxyUri = options.proxyUri();
- }
- const thePromise = new Promise(function(promiseResolve_, promiseReject_){
const loggers = [
sqlite3.config.error,
sqlite3.config.warn,
sqlite3.config.log
];
+ const vfsName = options.vfsName
+ || toss("Maintenance required: missing VFS name");
const logImpl = (level,...args)=>{
- if(options.verbose>level) loggers[level]("OPFS syncer:",...args);
+ if(state.verbose>level) loggers[level](vfsName+":",...args);
};
- const log = (...args)=>logImpl(2, ...args);
- const warn = (...args)=>logImpl(1, ...args);
- const error = (...args)=>logImpl(0, ...args);
- const toss = sqlite3.util.toss;
- const capi = sqlite3.capi;
- const util = sqlite3.util;
- const wasm = sqlite3.wasm;
- const sqlite3_vfs = capi.sqlite3_vfs;
- const sqlite3_file = capi.sqlite3_file;
- const sqlite3_io_methods = capi.sqlite3_io_methods;
- /**
- Generic utilities for working with OPFS. This will get filled out
- by the Promise setup and, on success, installed as sqlite3.opfs.
+ const log = (...args)=>logImpl(2, ...args),
+ warn = (...args)=>logImpl(1, ...args),
+ error = (...args)=>logImpl(0, ...args),
+ capi = sqlite3.capi,
+ wasm = sqlite3.wasm;
- ACHTUNG: do not rely on these APIs in client code. They are
- experimental and subject to change or removal as the
- OPFS-specific sqlite3_vfs evolves.
- */
- const opfsUtil = Object.create(null);
+ const opfsVfs = state.vfs = new capi.sqlite3_vfs();
+ const opfsIoMethods = opfsVfs.ioMethods = new capi.sqlite3_io_methods();
- /**
- Returns true if _this_ thread has access to the OPFS APIs.
- */
- const thisThreadHasOPFS = ()=>{
- return globalThis.FileSystemHandle &&
- globalThis.FileSystemDirectoryHandle &&
- globalThis.FileSystemFileHandle &&
- globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle &&
- navigator?.storage?.getDirectory;
- };
+ opfsIoMethods.$iVersion = 1;
+ opfsVfs.$iVersion = 2/*yes, two*/;
+ opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
+ opfsVfs.$mxPathname = 1024/* sure, why not? The OPFS name length limit
+ is undocumented/unspecified. */;
+ opfsVfs.$zName = wasm.allocCString(vfsName);
+ opfsVfs.addOnDispose(
+ '$zName', opfsVfs.$zName, opfsIoMethods
+ /**
+ Pedantic sidebar: the entries in this array are items to
+ clean up when opfsVfs.dispose() is called, but in this
+ environment it will never be called. The VFS instance simply
+ hangs around until the WASM module instance is cleaned up. We
+ "could" _hypothetically_ clean it up by "importing" an
+ sqlite3_os_end() impl into the wasm build, but the shutdown
+ order of the wasm engine and the JS one are undefined so
+ there is no guaranty that the opfsVfs instance would be
+ available in one environment or the other when
+ sqlite3_os_end() is called (_if_ it gets called at all in a
+ wasm build, which is undefined). i.e. addOnDispose() here is
+ a matter of "correctness", not necessity. It just wouldn't do
+ to leave the impression that we're blindly leaking memory.
+ */
+ );
- /**
- Not part of the public API. Solely for internal/development
- use.
- */
- opfsUtil.metrics = {
+ opfsVfs.metrics = util.nu({
+ counters: util.nu(),
dump: function(){
let k, n = 0, t = 0, w = 0;
for(k in state.opIds){
@@ -18062,115 +18491,24 @@ const installOpfsVfs = function callee(options){
"metrics for",globalThis.location.href,":",metrics,
"\nTotal of",n,"op(s) for",t,
"ms (incl. "+w+" ms of waiting on the async side)");
- sqlite3.config.log("Serialization metrics:",metrics.s11n);
- W.postMessage({type:'opfs-async-metrics'});
+ sqlite3.config.log("Serialization metrics:",opfsVfs.metrics.counters.s11n);
+ opfsVfs.worker?.postMessage?.({type:'opfs-async-metrics'});
},
reset: function(){
let k;
const r = (m)=>(m.count = m.time = m.wait = 0);
+ const m = opfsVfs.metrics.counters;
for(k in state.opIds){
- r(metrics[k] = Object.create(null));
+ r(m[k] = Object.create(null));
}
- let s = metrics.s11n = Object.create(null);
+ let s = m.s11n = Object.create(null);
s = s.serialize = Object.create(null);
s.count = s.time = 0;
- s = metrics.s11n.deserialize = Object.create(null);
+ s = m.s11n.deserialize = Object.create(null);
s.count = s.time = 0;
}
- }/*metrics*/;
- const opfsIoMethods = new sqlite3_io_methods();
- const opfsVfs = new sqlite3_vfs()
- .addOnDispose( ()=>opfsIoMethods.dispose());
- let promiseWasRejected = undefined;
- const promiseReject = (err)=>{
- promiseWasRejected = true;
- opfsVfs.dispose();
- return promiseReject_(err);
- };
- const promiseResolve = ()=>{
- promiseWasRejected = false;
- return promiseResolve_(sqlite3);
- };
- const W =
- new Worker(new URL("sqlite3-opfs-async-proxy.js", import.meta.url));
- setTimeout(()=>{
- /* At attempt to work around a browser-specific quirk in which
- the Worker load is failing in such a way that we neither
- resolve nor reject it. This workaround gives that resolve/reject
- a time limit and rejects if that timer expires. Discussion:
- https://sqlite.org/forum/forumpost/a708c98dcb3ef */
- if(undefined===promiseWasRejected){
- promiseReject(
- new Error("Timeout while waiting for OPFS async proxy worker.")
- );
- }
- }, 4000);
- W._originalOnError = W.onerror /* will be restored later */;
- W.onerror = function(err){
- // The error object doesn't contain any useful info when the
- // failure is, e.g., that the remote script is 404.
- error("Error initializing OPFS asyncer:",err);
- promiseReject(new Error("Loading OPFS async Worker failed for unknown reasons."));
- };
- const pDVfs = capi.sqlite3_vfs_find(null)/*pointer to default VFS*/;
- const dVfs = pDVfs
- ? new sqlite3_vfs(pDVfs)
- : null /* dVfs will be null when sqlite3 is built with
- SQLITE_OS_OTHER. */;
- opfsIoMethods.$iVersion = 1;
- opfsVfs.$iVersion = 2/*yes, two*/;
- opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
- opfsVfs.$mxPathname = 1024/* sure, why not? The OPFS name length limit
- is undocumented/unspecified. */;
- opfsVfs.$zName = wasm.allocCString("opfs");
- // All C-side memory of opfsVfs is zeroed out, but just to be explicit:
- opfsVfs.$xDlOpen = opfsVfs.$xDlError = opfsVfs.$xDlSym = opfsVfs.$xDlClose = null;
- opfsVfs.addOnDispose(
- '$zName', opfsVfs.$zName,
- 'cleanup default VFS wrapper', ()=>(dVfs ? dVfs.dispose() : null)
- );
- /**
- Pedantic sidebar about opfsVfs.ondispose: the entries in that array
- are items to clean up when opfsVfs.dispose() is called, but in this
- environment it will never be called. The VFS instance simply
- hangs around until the WASM module instance is cleaned up. We
- "could" _hypothetically_ clean it up by "importing" an
- sqlite3_os_end() impl into the wasm build, but the shutdown order
- of the wasm engine and the JS one are undefined so there is no
- guaranty that the opfsVfs instance would be available in one
- environment or the other when sqlite3_os_end() is called (_if_ it
- gets called at all in a wasm build, which is undefined).
- */
- /**
- State which we send to the async-api Worker or share with it.
- This object must initially contain only cloneable or sharable
- objects. After the worker's "inited" message arrives, other types
- of data may be added to it.
+ })/*opfsVfs.metrics*/;
- For purposes of Atomics.wait() and Atomics.notify(), we use a
- SharedArrayBuffer with one slot reserved for each of the API
- proxy's methods. The sync side of the API uses Atomics.wait()
- on the corresponding slot and the async side uses
- Atomics.notify() on that slot.
-
- The approach of using a single SAB to serialize comms for all
- instances might(?) lead to deadlock situations in multi-db
- cases. We should probably have one SAB here with a single slot
- for locking a per-file initialization step and then allocate a
- separate SAB like the above one for each file. That will
- require a bit of acrobatics but should be feasible. The most
- problematic part is that xOpen() would have to use
- postMessage() to communicate its SharedArrayBuffer, and mixing
- that approach with Atomics.wait/notify() gets a bit messy.
- */
- const state = Object.create(null);
- state.verbose = options.verbose;
- state.littleEndian = (()=>{
- const buffer = new ArrayBuffer(2);
- new DataView(buffer).setInt16(0, 256, true /* ==>littleEndian */);
- // Int16Array uses the platform's endianness.
- return new Int16Array(buffer)[0] === 256;
- })();
/**
asyncIdleWaitTime is how long (ms) to wait, in the async proxy,
for each Atomics.wait() when waiting on inbound VFS API calls.
@@ -18191,7 +18529,8 @@ const installOpfsVfs = function callee(options){
0 = no exception logging.
1 = only log exceptions for "significant" ops like xOpen(),
- xRead(), and xWrite().
+ xRead(), and xWrite(). Exceptions related to, e.g., wait/retry
+ loops in acquiring SyncAccessHandles are not logged.
2 = log all exceptions.
*/
@@ -18217,22 +18556,31 @@ const installOpfsVfs = function callee(options){
state.fileBufferSize/* file i/o block */
+ state.sabS11nSize/* argument/result serialization block */
);
+
+ /**
+ For purposes of Atomics.wait() and Atomics.notify(), we use a
+ SharedArrayBuffer with one slot reserved for each of the API
+ proxy's methods. The sync side of the API uses Atomics.wait()
+ on the corresponding slot and the async side uses
+ Atomics.notify() on that slot. state.opIds holds the SAB slot
+ IDs of each of those.
+ */
state.opIds = Object.create(null);
- const metrics = Object.create(null);
{
/* Indexes for use in our SharedArrayBuffer... */
let i = 0;
/* SAB slot used to communicate which operation is desired
between both workers. This worker writes to it and the other
- listens for changes. */
+ listens for changes and clears it. The values written to it
+ are state.opIds.x[A-Z][a-z]+, defined below.*/
state.opIds.whichOp = i++;
- /* Slot for storing return values. This worker listens to that
- slot and the other worker writes to it. */
+ /* Slot for storing return values. This side listens to that
+ slot and the async proxy writes to it. */
state.opIds.rc = i++;
- /* Each function gets an ID which this worker writes to
- the whichOp slot. The async-api worker uses Atomic.wait()
- on the whichOp slot to figure out which operation to run
- next. */
+ /* Each function gets an ID which this worker writes to the
+ state.opIds.whichOp slot. The async-api worker uses
+ Atomic.wait() on the whichOp slot to figure out which
+ operation to run next. */
state.opIds.xAccess = i++;
state.opIds.xClose = i++;
state.opIds.xDelete = i++;
@@ -18246,24 +18594,28 @@ const installOpfsVfs = function callee(options){
state.opIds.xTruncate = i++;
state.opIds.xUnlock = i++;
state.opIds.xWrite = i++;
- state.opIds.mkdir = i++;
+ state.opIds.mkdir = i++ /*currently unused*/;
+ /** Internal signals which are used only during development and
+ testing via the dev console. */
state.opIds['opfs-async-metrics'] = i++;
state.opIds['opfs-async-shutdown'] = i++;
/* The retry slot is used by the async part for wait-and-retry
- semantics. Though we could hypothetically use the xSleep slot
- for that, doing so might lead to undesired side effects. */
+ semantics. It is never written to, only used as a convenient
+ place to wait-with-timeout for a value which will never be
+ written, i.e. sleep()ing, before retrying a failed attempt to
+ acquire a SharedAccessHandle. */
state.opIds.retry = i++;
state.sabOP = new SharedArrayBuffer(
- i * 4/* ==sizeof int32, noting that Atomics.wait() and friends
- can only function on Int32Array views of an SAB. */);
- opfsUtil.metrics.reset();
+ i * 4/* 4==sizeof int32, noting that Atomics.wait() and
+ friends can only function on Int32Array views of an
+ SAB. */);
}
/**
SQLITE_xxx constants to export to the async worker
counterpart...
*/
state.sq3Codes = Object.create(null);
- [
+ for(const k of [
'SQLITE_ACCESS_EXISTS',
'SQLITE_ACCESS_READWRITE',
'SQLITE_BUSY',
@@ -18291,17 +18643,22 @@ const installOpfsVfs = function callee(options){
'SQLITE_OPEN_CREATE',
'SQLITE_OPEN_DELETEONCLOSE',
'SQLITE_OPEN_MAIN_DB',
- 'SQLITE_OPEN_READONLY'
- ].forEach((k)=>{
- if(undefined === (state.sq3Codes[k] = capi[k])){
- toss("Maintenance required: not found:",k);
- }
- });
+ 'SQLITE_OPEN_READONLY',
+ 'SQLITE_LOCK_NONE',
+ 'SQLITE_LOCK_SHARED',
+ 'SQLITE_LOCK_RESERVED',
+ 'SQLITE_LOCK_PENDING',
+ 'SQLITE_LOCK_EXCLUSIVE'
+ ]){
+ state.sq3Codes[k] =
+ capi[k] ?? toss("Maintenance required: not found:",k);
+ }
+
state.opfsFlags = Object.assign(Object.create(null),{
/**
Flag for use with xOpen(). URI flag "opfs-unlock-asap=1"
enables this. See defaultUnlockAsap, below.
- */
+ */
OPFS_UNLOCK_ASAP: 0x01,
/**
Flag for use with xOpen(). URI flag "delete-before-open=1"
@@ -18314,33 +18671,37 @@ const installOpfsVfs = function callee(options){
downstream errors. An unlink can fail if, e.g., another tab
has the handle open.
- It goes without saying that deleting a file out from under another
- instance results in Undefined Behavior.
+ It goes without saying that deleting a file out from under
+ another instance results in Undefined Behavior.
*/
OPFS_UNLINK_BEFORE_OPEN: 0x02,
/**
- If true, any async routine which implicitly acquires a sync
- access handle (i.e. an OPFS lock) will release that lock at
- the end of the call which acquires it. If false, such
- "autolocks" are not released until the VFS is idle for some
- brief amount of time.
-
- The benefit of enabling this is much higher concurrency. The
- down-side is much-reduced performance (as much as a 4x decrease
- in speedtest1).
+ If true, any async routine which must implicitly acquire a
+ sync access handle (i.e. an OPFS lock), without an active
+ xLock(), will release that lock at the end of the call which
+ acquires it. If false, such implicit locks are not released
+ until the VFS is idle for some brief amount of time, as
+ defined by state.asyncIdleWaitTime.
+
+ The benefit of enabling this is higher concurrency. The
+ down-side is much-reduced performance (as much as a 4x
+ decrease in speedtest1).
*/
defaultUnlockAsap: false
});
+ opfsVfs.metrics.reset()/*must not be called until state.opIds is set up*/;
+ const metrics = opfsVfs.metrics.counters;
+
/**
Runs the given operation (by name) in the async worker
counterpart, waits for its response, and returns the result
- which the async worker writes to SAB[state.opIds.rc]. The
- 2nd and subsequent arguments must be the arguments for the
- async op.
+ which the async worker writes to SAB[state.opIds.rc]. The 2nd
+ and subsequent arguments must be the arguments for the async op
+ (see sqlite3-opfs-async-proxy.c-pp.js).
*/
- const opRun = (op,...args)=>{
- const opNdx = state.opIds[op] || toss("Invalid op ID:",op);
+ const opRun = opfsVfs.opRun = (op,...args)=>{
+ const opNdx = state.opIds[op] || toss(opfsVfs.vfsName+": Invalid op ID:",op);
state.s11n.serialize(...args);
Atomics.store(state.sabOPView, state.opIds.rc, -1);
Atomics.store(state.sabOPView, state.opIds.whichOp, opNdx);
@@ -18355,14 +18716,15 @@ const installOpfsVfs = function callee(options){
https://github.com/sqlite/sqlite-wasm/issues/12
Summary: in at least one browser flavor, under high loads,
- the wait()/notify() pairings can get out of sync. Calling
- wait() here until it returns 'not-equal' gets them back in
- sync.
+ the wait()/notify() pairings can get out of sync and/or
+ spuriously wake up. Calling wait() here until it returns
+ 'not-equal' gets them back in sync.
*/
}
/* When the above wait() call returns 'not-equal', the async
- half will have completed the operation and reported its results
- in the state.opIds.rc slot of the SAB. */
+ half will have completed the operation and reported its
+ results in the state.opIds.rc slot of the SAB. It may have
+ also serialized an exception for us. */
const rc = Atomics.load(state.sabOPView, state.opIds.rc);
metrics[op].wait += performance.now() - t;
if(rc && state.asyncS11nExceptions){
@@ -18372,248 +18734,41 @@ const installOpfsVfs = function callee(options){
return rc;
};
- /**
- Not part of the public API. Only for test/development use.
- */
- opfsUtil.debug = {
- asyncShutdown: ()=>{
- warn("Shutting down OPFS async listener. The OPFS VFS will no longer work.");
- opRun('opfs-async-shutdown');
- },
- asyncRestart: ()=>{
- warn("Attempting to restart OPFS VFS async listener. Might work, might not.");
- W.postMessage({type: 'opfs-async-restart'});
- }
- };
-
- const initS11n = ()=>{
- /**
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ACHTUNG: this code is 100% duplicated in the other half of
- this proxy! The documentation is maintained in the
- "synchronous half".
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- This proxy de/serializes cross-thread function arguments and
- output-pointer values via the state.sabIO SharedArrayBuffer,
- using the region defined by (state.sabS11nOffset,
- state.sabS11nOffset + state.sabS11nSize]. Only one dataset is
- recorded at a time.
-
- This is not a general-purpose format. It only supports the
- range of operations, and data sizes, needed by the
- sqlite3_vfs and sqlite3_io_methods operations. Serialized
- data are transient and this serialization algorithm may
- change at any time.
-
- The data format can be succinctly summarized as:
-
- Nt...Td...D
-
- Where:
-
- - N = number of entries (1 byte)
-
- - t = type ID of first argument (1 byte)
-
- - ...T = type IDs of the 2nd and subsequent arguments (1 byte
- each).
-
- - d = raw bytes of first argument (per-type size).
-
- - ...D = raw bytes of the 2nd and subsequent arguments (per-type
- size).
-
- All types except strings have fixed sizes. Strings are stored
- using their TextEncoder/TextDecoder representations. It would
- arguably make more sense to store them as Int16Arrays of
- their JS character values, but how best/fastest to get that
- in and out of string form is an open point. Initial
- experimentation with that approach did not gain us any speed.
-
- Historical note: this impl was initially about 1% this size by
- using using JSON.stringify/parse(), but using fit-to-purpose
- serialization saves considerable runtime.
- */
- if(state.s11n) return state.s11n;
- const textDecoder = new TextDecoder(),
- textEncoder = new TextEncoder('utf-8'),
- viewU8 = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize),
- viewDV = new DataView(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
- state.s11n = Object.create(null);
- /* Only arguments and return values of these types may be
- serialized. This covers the whole range of types needed by the
- sqlite3_vfs API. */
- const TypeIds = Object.create(null);
- TypeIds.number = { id: 1, size: 8, getter: 'getFloat64', setter: 'setFloat64' };
- TypeIds.bigint = { id: 2, size: 8, getter: 'getBigInt64', setter: 'setBigInt64' };
- TypeIds.boolean = { id: 3, size: 4, getter: 'getInt32', setter: 'setInt32' };
- TypeIds.string = { id: 4 };
-
- const getTypeId = (v)=>(
- TypeIds[typeof v]
- || toss("Maintenance required: this value type cannot be serialized.",v)
- );
- const getTypeIdById = (tid)=>{
- switch(tid){
- case TypeIds.number.id: return TypeIds.number;
- case TypeIds.bigint.id: return TypeIds.bigint;
- case TypeIds.boolean.id: return TypeIds.boolean;
- case TypeIds.string.id: return TypeIds.string;
- default: toss("Invalid type ID:",tid);
- }
- };
-
- /**
- Returns an array of the deserialized state stored by the most
- recent serialize() operation (from this thread or the
- counterpart thread), or null if the serialization buffer is
- empty. If passed a truthy argument, the serialization buffer
- is cleared after deserialization.
- */
- state.s11n.deserialize = function(clear=false){
- ++metrics.s11n.deserialize.count;
- const t = performance.now();
- const argc = viewU8[0];
- const rc = argc ? [] : null;
- if(argc){
- const typeIds = [];
- let offset = 1, i, n, v;
- for(i = 0; i < argc; ++i, ++offset){
- typeIds.push(getTypeIdById(viewU8[offset]));
- }
- for(i = 0; i < argc; ++i){
- const t = typeIds[i];
- if(t.getter){
- v = viewDV[t.getter](offset, state.littleEndian);
- offset += t.size;
- }else{/*String*/
- n = viewDV.getInt32(offset, state.littleEndian);
- offset += 4;
- v = textDecoder.decode(viewU8.slice(offset, offset+n));
- offset += n;
- }
- rc.push(v);
- }
- }
- if(clear) viewU8[0] = 0;
- //log("deserialize:",argc, rc);
- metrics.s11n.deserialize.time += performance.now() - t;
- return rc;
- };
-
- /**
- Serializes all arguments to the shared buffer for consumption
- by the counterpart thread.
-
- This routine is only intended for serializing OPFS VFS
- arguments and (in at least one special case) result values,
- and the buffer is sized to be able to comfortably handle
- those.
-
- If passed no arguments then it zeroes out the serialization
- state.
- */
- state.s11n.serialize = function(...args){
- const t = performance.now();
- ++metrics.s11n.serialize.count;
- if(args.length){
- //log("serialize():",args);
- const typeIds = [];
- let i = 0, offset = 1;
- viewU8[0] = args.length & 0xff /* header = # of args */;
- for(; i < args.length; ++i, ++offset){
- /* Write the TypeIds.id value into the next args.length
- bytes. */
- typeIds.push(getTypeId(args[i]));
- viewU8[offset] = typeIds[i].id;
- }
- for(i = 0; i < args.length; ++i) {
- /* Deserialize the following bytes based on their
- corresponding TypeIds.id from the header. */
- const t = typeIds[i];
- if(t.setter){
- viewDV[t.setter](offset, args[i], state.littleEndian);
- offset += t.size;
- }else{/*String*/
- const s = textEncoder.encode(args[i]);
- viewDV.setInt32(offset, s.byteLength, state.littleEndian);
- offset += 4;
- viewU8.set(s, offset);
- offset += s.byteLength;
- }
- }
- //log("serialize() result:",viewU8.slice(0,offset));
- }else{
- viewU8[0] = 0;
- }
- metrics.s11n.serialize.time += performance.now() - t;
- };
- return state.s11n;
- }/*initS11n()*/;
-
- /**
- Generates a random ASCII string len characters long, intended for
- use as a temporary file name.
- */
- const randomFilename = function f(len=16){
- if(!f._chars){
- f._chars = "abcdefghijklmnopqrstuvwxyz"+
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
- "012346789";
- f._n = f._chars.length;
- }
- const a = [];
- let i = 0;
- for( ; i < len; ++i){
- const ndx = Math.random() * (f._n * 64) % f._n | 0;
- a[i] = f._chars[ndx];
- }
- return a.join("");
- /*
- An alternative impl. with an unpredictable length
- but much simpler:
-
- Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36)
- */
- };
-
- /**
- Map of sqlite3_file pointers to objects constructed by xOpen().
- */
- const __openFiles = Object.create(null);
-
const opTimer = Object.create(null);
opTimer.op = undefined;
opTimer.start = undefined;
- const mTimeStart = (op)=>{
+ const mTimeStart = opfsVfs.mTimeStart = (op)=>{
opTimer.start = performance.now();
opTimer.op = op;
++metrics[op].count;
};
- const mTimeEnd = ()=>(
+ const mTimeEnd = opfsVfs.mTimeEnd = ()=>(
metrics[opTimer.op].time += performance.now() - opTimer.start
);
+ /**
+ Map of sqlite3_file pointers to objects constructed by xOpen().
+ */
+ const __openFiles = opfsVfs.__openFiles = Object.create(null);
+
/**
Impls for the sqlite3_io_methods methods. Maintenance reminder:
members are in alphabetical order to simplify finding them.
*/
- const ioSyncWrappers = {
+ const ioSyncWrappers = opfsVfs.ioSyncWrappers = util.nu({
xCheckReservedLock: function(pFile,pOut){
/**
- As of late 2022, only a single lock can be held on an OPFS
- file. We have no way of checking whether any _other_ db
- connection has a lock except by trying to obtain and (on
- success) release a sync-handle for it, but doing so would
- involve an inherent race condition. For the time being,
- pending a better solution, we simply report whether the
- given pFile is open.
-
- Update 2024-06-12: based on forum discussions, this
- function now always sets pOut to 0 (false):
-
- https://sqlite.org/forum/forumpost/a2f573b00cda1372
+ After consultation with a topic expert: "opfs-wl" will
+ continue to use the same no-op impl which "opfs" does
+ because:
+
+ - xCheckReservedLock() is just a hint. If SQLite needs to
+ lock, it's still going to try to lock.
+
+ - We cannot do this check synchronously in "opfs-wl",
+ so would need to pass it to the async proxy. That would
+ make it inordinately expensive considering that it's
+ just a hint.
*/
wasm.poke(pOut, 0, 'i32');
return 0;
@@ -18635,7 +18790,7 @@ const installOpfsVfs = function callee(options){
},
xFileControl: function(pFile, opId, pArg){
/*mTimeStart('xFileControl');
- mTimeEnd();*/
+ mTimeEnd();*/
return capi.SQLITE_NOTFOUND;
},
xFileSize: function(pFile,pSz64){
@@ -18653,25 +18808,8 @@ const installOpfsVfs = function callee(options){
mTimeEnd();
return rc;
},
- xLock: function(pFile,lockType){
- mTimeStart('xLock');
- const f = __openFiles[pFile];
- let rc = 0;
- /* All OPFS locks are exclusive locks. If xLock() has
- previously succeeded, do nothing except record the lock
- type. If no lock is active, have the async counterpart
- lock the file. */
- if( !f.lockType ) {
- rc = opRun('xLock', pFile, lockType);
- if( 0===rc ) f.lockType = lockType;
- }else{
- f.lockType = lockType;
- }
- mTimeEnd();
- return rc;
- },
xRead: function(pFile,pDest,n,offset64){
- mTimeStart('xRead');
+ mTimeStart('xRead');
const f = __openFiles[pFile];
let rc;
try {
@@ -18693,7 +18831,6 @@ const installOpfsVfs = function callee(options){
},
xSync: function(pFile,flags){
mTimeStart('xSync');
- ++metrics.xSync.count;
const rc = opRun('xSync', pFile, flags);
mTimeEnd();
return rc;
@@ -18704,18 +18841,6 @@ const installOpfsVfs = function callee(options){
mTimeEnd();
return rc;
},
- xUnlock: function(pFile,lockType){
- mTimeStart('xUnlock');
- const f = __openFiles[pFile];
- let rc = 0;
- if( capi.SQLITE_LOCK_NONE === lockType
- && f.lockType ){
- rc = opRun('xUnlock', pFile, lockType);
- }
- if( 0===rc ) f.lockType = lockType;
- mTimeEnd();
- return rc;
- },
xWrite: function(pFile,pSrc,n,offset64){
mTimeStart('xWrite');
const f = __openFiles[pFile];
@@ -18732,23 +18857,21 @@ const installOpfsVfs = function callee(options){
mTimeEnd();
return rc;
}
- }/*ioSyncWrappers*/;
+ })/*ioSyncWrappers*/;
/**
Impls for the sqlite3_vfs methods. Maintenance reminder: members
are in alphabetical order to simplify finding them.
*/
- const vfsSyncWrappers = {
+ const vfsSyncWrappers = opfsVfs.vfsSyncWrappers = {
xAccess: function(pVfs,zName,flags,pOut){
- mTimeStart('xAccess');
+ mTimeStart('xAccess');
const rc = opRun('xAccess', wasm.cstrToJs(zName));
wasm.poke( pOut, (rc ? 0 : 1), 'i32' );
mTimeEnd();
return 0;
},
xCurrentTime: function(pVfs,pOut){
- /* If it turns out that we need to adjust for timezone, see:
- https://stackoverflow.com/a/11760121/1458521 */
wasm.poke(pOut, 2440587.5 + (new Date().getTime()/86400000),
'double');
return 0;
@@ -18772,18 +18895,22 @@ const installOpfsVfs = function callee(options){
/*CANTOPEN is required by the docs but SQLITE_RANGE would be a closer match*/;
},
xGetLastError: function(pVfs,nOut,pOut){
- /* TODO: store exception.message values from the async
- partner in a dedicated SharedArrayBuffer, noting that we'd have
- to encode them... TextEncoder can do that for us. */
- warn("OPFS xGetLastError() has nothing sensible to return.");
+ /* Mutex use in the overlying APIs cause xGetLastError() to
+ not be terribly useful for us. e.g. it can't be used to
+ convey error messages from xOpen() because there would be a
+ race condition between sqlite3_open()'s call to xOpen() and
+ this function. */
+ sqlite3.config.warn("OPFS xGetLastError() has nothing sensible to return.");
return 0;
},
//xSleep is optionally defined below
xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){
mTimeStart('xOpen');
let opfsFlags = 0;
- if(0===zName){
- zName = randomFilename();
+ let jzName, zToFree;
+ if( !zName ){
+ jzName = opfsUtil.randomFilename();
+ zName = zToFree = wasm.allocCString(jzName);
}else if(wasm.isPtr(zName)){
if(capi.sqlite3_uri_boolean(zName, "opfs-unlock-asap", 0)){
/* -----------------------^^^^^ MUST pass the untranslated
@@ -18793,18 +18920,24 @@ const installOpfsVfs = function callee(options){
if(capi.sqlite3_uri_boolean(zName, "delete-before-open", 0)){
opfsFlags |= state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN;
}
- zName = wasm.cstrToJs(zName);
- //warn("xOpen zName =",zName, "opfsFlags =",opfsFlags);
- }
- const fh = Object.create(null);
- fh.fid = pFile;
- fh.filename = zName;
- fh.sab = new SharedArrayBuffer(state.fileBufferSize);
- fh.flags = flags;
- fh.readOnly = !(capi.SQLITE_OPEN_CREATE & flags)
- && !!(flags & capi.SQLITE_OPEN_READONLY);
- const rc = opRun('xOpen', pFile, zName, flags, opfsFlags);
- if(!rc){
+ jzName = wasm.cstrToJs(zName);
+ //sqlite3.config.warn("xOpen zName =",zName, "opfsFlags =",opfsFlags);
+ }else{
+ sqlite3.config.error("Impossible zName value in xOpen?", zName);
+ return capi.SQLITE_CANTOPEN;
+ }
+ const fh = util.nu({
+ fid: pFile,
+ filename: jzName,
+ sab: new SharedArrayBuffer(state.fileBufferSize),
+ flags: flags,
+ readOnly: !(capi.SQLITE_OPEN_CREATE & flags)
+ && !!(flags & capi.SQLITE_OPEN_READONLY)
+ });
+ const rc = opRun('xOpen', pFile, jzName, flags, opfsFlags);
+ if(rc){
+ if( zToFree ) wasm.dealloc(zToFree);
+ }else{
/* Recall that sqlite3_vfs::xClose() will be called, even on
error, unless pFile->pMethods is NULL. */
if(fh.readOnly){
@@ -18812,7 +18945,8 @@ const installOpfsVfs = function callee(options){
}
__openFiles[pFile] = fh;
fh.sabView = state.sabFileBufView;
- fh.sq3File = new sqlite3_file(pFile);
+ fh.sq3File = new capi.sqlite3_file(pFile);
+ if( zToFree ) fh.sq3File.addOnDispose(zToFree);
fh.sq3File.$pMethods = opfsIoMethods.pointer;
fh.lockType = capi.SQLITE_LOCK_NONE;
}
@@ -18821,515 +18955,572 @@ const installOpfsVfs = function callee(options){
}/*xOpen()*/
}/*vfsSyncWrappers*/;
- if(dVfs){
- opfsVfs.$xRandomness = dVfs.$xRandomness;
- opfsVfs.$xSleep = dVfs.$xSleep;
- }
- if(!opfsVfs.$xRandomness){
- /* If the default VFS has no xRandomness(), add a basic JS impl... */
- vfsSyncWrappers.xRandomness = function(pVfs, nOut, pOut){
- const heap = wasm.heap8u();
- let i = 0;
- const npOut = Number(pOut);
- for(; i < nOut; ++i) heap[npOut + i] = (Math.random()*255000) & 0xFF;
- return i;
- };
- }
- if(!opfsVfs.$xSleep){
- /* If we can inherit an xSleep() impl from the default VFS then
- assume it's sane and use it, otherwise install a JS-based
- one. */
- vfsSyncWrappers.xSleep = function(pVfs,ms){
- Atomics.wait(state.sabOPView, state.opIds.xSleep, 0, ms);
- return 0;
- };
- }
+ const pDVfs = capi.sqlite3_vfs_find(null)/*pointer to default VFS*/;
+ if(pDVfs){
+ const dVfs = new capi.sqlite3_vfs(pDVfs);
+ opfsVfs.$xRandomness = dVfs.$xRandomness;
+ opfsVfs.$xSleep = dVfs.$xSleep;
+ dVfs.dispose();
+ }
+ if(!opfsVfs.$xRandomness){
+ /* If the default VFS has no xRandomness(), add a basic JS impl... */
+ opfsVfs.vfsSyncWrappers.xRandomness = function(pVfs, nOut, pOut){
+ const heap = wasm.heap8u();
+ let i = 0;
+ const npOut = Number(pOut);
+ for(; i < nOut; ++i) heap[npOut + i] = (Math.random()*255000) & 0xFF;
+ return i;
+ };
+ }
+ if(!opfsVfs.$xSleep){
+ /* If we can inherit an xSleep() impl from the default VFS then
+ assume it's sane and use it, otherwise install a JS-based
+ one. */
+ opfsVfs.vfsSyncWrappers.xSleep = function(pVfs,ms){
+ mTimeStart('xSleep');
+ Atomics.wait(state.sabOPView, state.opIds.xSleep, 0, ms);
+ mTimeEnd();
+ return 0;
+ };
+ }
+
+const initS11n = function(){
+ /**
+ This proxy de/serializes cross-thread function arguments and
+ output-pointer values via the state.sabIO SharedArrayBuffer,
+ using the region defined by (state.sabS11nOffset,
+ state.sabS11nOffset + state.sabS11nSize]. Only one dataset is
+ recorded at a time.
+
+ This is not a general-purpose format. It only supports the
+ range of operations, and data sizes, needed by the
+ sqlite3_vfs and sqlite3_io_methods operations. Serialized
+ data are transient and this serialization algorithm may
+ change at any time.
+
+ The data format can be succinctly summarized as:
+
+ Nt...Td...D
+
+ Where:
+
+ - N = number of entries (1 byte)
+
+ - t = type ID of first argument (1 byte)
+
+ - ...T = type IDs of the 2nd and subsequent arguments (1 byte
+ each).
+
+ - d = raw bytes of first argument (per-type size).
+
+ - ...D = raw bytes of the 2nd and subsequent arguments (per-type
+ size).
+
+ All types except strings have fixed sizes. Strings are stored
+ using their TextEncoder/TextDecoder representations. It would
+ arguably make more sense to store them as Int16Arrays of
+ their JS character values, but how best/fastest to get that
+ in and out of string form is an open point. Initial
+ experimentation with that approach did not gain us any speed.
+
+ Historical note: this impl was initially about 1% this size by
+ using using JSON.stringify/parse(), but using fit-to-purpose
+ serialization saves considerable runtime.
+ */
+ if(state.s11n) return state.s11n;
+ const textDecoder = new TextDecoder(),
+ textEncoder = new TextEncoder('utf-8'),
+ viewU8 = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize),
+ viewDV = new DataView(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
+ state.s11n = Object.create(null);
+ /* Only arguments and return values of these types may be
+ serialized. This covers the whole range of types needed by the
+ sqlite3_vfs API. */
+ const TypeIds = Object.create(null);
+ TypeIds.number = { id: 1, size: 8, getter: 'getFloat64', setter: 'setFloat64' };
+ TypeIds.bigint = { id: 2, size: 8, getter: 'getBigInt64', setter: 'setBigInt64' };
+ TypeIds.boolean = { id: 3, size: 4, getter: 'getInt32', setter: 'setInt32' };
+ TypeIds.string = { id: 4 };
+
+ const getTypeId = (v)=>(
+ TypeIds[typeof v]
+ || toss("Maintenance required: this value type cannot be serialized.",v)
+ );
+ const getTypeIdById = (tid)=>{
+ switch(tid){
+ case TypeIds.number.id: return TypeIds.number;
+ case TypeIds.bigint.id: return TypeIds.bigint;
+ case TypeIds.boolean.id: return TypeIds.boolean;
+ case TypeIds.string.id: return TypeIds.string;
+ default: toss("Invalid type ID:",tid);
+ }
+ };
+
+ /**
+ Returns an array of the deserialized state stored by the most
+ recent serialize() operation (from this thread or the
+ counterpart thread), or null if the serialization buffer is
+ empty. If passed a truthy argument, the serialization buffer
+ is cleared after deserialization.
+ */
+ state.s11n.deserialize = function(clear=false){
+ const t = performance.now();
+ const argc = viewU8[0];
+ const rc = argc ? [] : null;
+ if(argc){
+ const typeIds = [];
+ let offset = 1, i, n, v;
+ for(i = 0; i < argc; ++i, ++offset){
+ typeIds.push(getTypeIdById(viewU8[offset]));
+ }
+ for(i = 0; i < argc; ++i){
+ const t = typeIds[i];
+ if(t.getter){
+ v = viewDV[t.getter](offset, state.littleEndian);
+ offset += t.size;
+ }else{/*String*/
+ n = viewDV.getInt32(offset, state.littleEndian);
+ offset += 4;
+ v = textDecoder.decode(viewU8.slice(offset, offset+n));
+ offset += n;
+ }
+ rc.push(v);
+ }
+ }
+ if(clear) viewU8[0] = 0;
+ //log("deserialize:",argc, rc);
+ return rc;
+ };
+
+ /**
+ Serializes all arguments to the shared buffer for consumption
+ by the counterpart thread.
+
+ This routine is only intended for serializing OPFS VFS
+ arguments and (in at least one special case) result values,
+ and the buffer is sized to be able to comfortably handle
+ those.
+
+ If passed no arguments then it zeroes out the serialization
+ state.
+ */
+ state.s11n.serialize = function(...args){
+ const t = performance.now();
+ if(args.length){
+ //log("serialize():",args);
+ const typeIds = [];
+ let i = 0, offset = 1;
+ viewU8[0] = args.length & 0xff /* header = # of args */;
+ for(; i < args.length; ++i, ++offset){
+ /* Write the TypeIds.id value into the next args.length
+ bytes. */
+ typeIds.push(getTypeId(args[i]));
+ viewU8[offset] = typeIds[i].id;
+ }
+ for(i = 0; i < args.length; ++i) {
+ /* Deserialize the following bytes based on their
+ corresponding TypeIds.id from the header. */
+ const t = typeIds[i];
+ if(t.setter){
+ viewDV[t.setter](offset, args[i], state.littleEndian);
+ offset += t.size;
+ }else{/*String*/
+ const s = textEncoder.encode(args[i]);
+ viewDV.setInt32(offset, s.byteLength, state.littleEndian);
+ offset += 4;
+ viewU8.set(s, offset);
+ offset += s.byteLength;
+ }
+ }
+ //log("serialize() result:",viewU8.slice(0,offset));
+ }else{
+ viewU8[0] = 0;
+ }
+ };
+
+
+ return state.s11n;
+}/*initS11n()*/;
+ opfsVfs.initS11n = initS11n;
+
+ /**
+ To be called by the VFS's main installation routine after it has
+ wired up enough state to provide its overridden io-method impls
+ (which must be properties of the ioMethods argument). Returns a
+ Promise which the installation routine must return. callback must
+ be a function which performs any post-bootstrap touchups, namely
+ plugging in a sqlite3.oo1 wrapper. It is passed (sqlite3, opfsVfs),
+ where opfsVfs is the sqlite3_vfs object which was set up by
+ opfsUtil.createVfsState().
+ */
+ opfsVfs.bindVfs = function(ioMethods, callback){
+ Object.assign(opfsVfs.ioSyncWrappers, ioMethods);
+ const thePromise = new Promise(function(promiseResolve_, promiseReject_){
+ let promiseWasRejected = undefined;
+ const promiseReject = (err)=>{
+ promiseWasRejected = true;
+ opfsVfs.dispose();
+ return promiseReject_(err);
+ };
+ const promiseResolve = ()=>{
+ try{
+ callback(sqlite3, opfsVfs);
+ }catch(e){
+ return promiseReject(e);
+ }
+ promiseWasRejected = false;
+ return promiseResolve_(sqlite3);
+ };
+ const options = opfsUtil.options;
+ let proxyUri = options.proxyUri +(
+ (options.proxyUri.indexOf('?')<0) ? '?' : '&'
+ )+'vfs='+vfsName;
+ //sqlite3.config.error("proxyUri",options.proxyUri, (new Error()));
+ const opfsAsyncProxyUrl = new URL('sqlite3-opfs-async-proxy.js', import.meta.url);
+ opfsAsyncProxyUrl.searchParams.set('vfs', vfsName);
+
+ const W = opfsVfs.worker = new Worker(opfsAsyncProxyUrl.toString());
+
+ let zombieTimer = setTimeout(()=>{
+ /* At attempt to work around a browser-specific quirk in which
+ the Worker load is failing in such a way that we neither
+ resolve nor reject it. This workaround gives that resolve/reject
+ a time limit and rejects if that timer expires. Discussion:
+ https://sqlite.org/forum/forumpost/a708c98dcb3ef */
+ if(undefined===promiseWasRejected){
+ promiseReject(
+ new Error("Timeout while waiting for OPFS async proxy worker.")
+ );
+ }
+ }, 4000);
+ W._originalOnError = W.onerror /* will be restored later */;
+ W.onerror = function(err){
+ // The error object doesn't contain any useful info when the
+ // failure is, e.g., that the remote script is 404.
+ error("Error initializing OPFS asyncer:",err);
+ promiseReject(new Error("Loading OPFS async Worker failed for unknown reasons."));
+ };
+
+ const opRun = opfsVfs.opRun;
+
+ const sanityCheck = function(){
+ const scope = wasm.scopedAllocPush();
+ const sq3File = new capi.sqlite3_file();
+ try{
+ const fid = sq3File.pointer;
+ const openFlags = capi.SQLITE_OPEN_CREATE
+ | capi.SQLITE_OPEN_READWRITE
+ //| capi.SQLITE_OPEN_DELETEONCLOSE
+ | capi.SQLITE_OPEN_MAIN_DB;
+ const pOut = wasm.scopedAlloc(8);
+ const dbFile = "/sanity/check/file"+randomFilename(8);
+ const zDbFile = wasm.scopedAllocCString(dbFile);
+ let rc;
+ state.s11n.serialize("This is ä string.");
+ rc = state.s11n.deserialize();
+ log("deserialize() says:",rc);
+ if("This is ä string."!==rc[0]) toss("String d13n error.");
+ opfsVfs.vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
+ rc = wasm.peek(pOut,'i32');
+ log("xAccess(",dbFile,") exists ?=",rc);
+ rc = opfsVfs.vfsSyncWrappers.xOpen(opfsVfs.pointer, zDbFile,
+ fid, openFlags, pOut);
+ log("open rc =",rc,"state.sabOPView[xOpen] =",
+ state.sabOPView[state.opIds.xOpen]);
+ if(0!==rc){
+ error("open failed with code",rc);
+ return;
+ }
+ opfsVfs.vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
+ rc = wasm.peek(pOut,'i32');
+ if(!rc) toss("xAccess() failed to detect file.");
+ rc = opfsVfs.ioSyncWrappers.xSync(sq3File.pointer, 0);
+ if(rc) toss('sync failed w/ rc',rc);
+ rc = opfsVfs.ioSyncWrappers.xTruncate(sq3File.pointer, 1024);
+ if(rc) toss('truncate failed w/ rc',rc);
+ wasm.poke(pOut,0,'i64');
+ rc = opfsVfs.ioSyncWrappers.xFileSize(sq3File.pointer, pOut);
+ if(rc) toss('xFileSize failed w/ rc',rc);
+ log("xFileSize says:",wasm.peek(pOut, 'i64'));
+ rc = opfsVfs.ioSyncWrappers.xWrite(sq3File.pointer, zDbFile, 10, 1);
+ if(rc) toss("xWrite() failed!");
+ const readBuf = wasm.scopedAlloc(16);
+ rc = opfsVfs.ioSyncWrappers.xRead(sq3File.pointer, readBuf, 6, 2);
+ wasm.poke(readBuf+6,0);
+ let jRead = wasm.cstrToJs(readBuf);
+ log("xRead() got:",jRead);
+ if("sanity"!==jRead) toss("Unexpected xRead() value.");
+ if(opfsVfs.vfsSyncWrappers.xSleep){
+ log("xSleep()ing before close()ing...");
+ opfsVfs.vfsSyncWrappers.xSleep(opfsVfs.pointer,2000);
+ log("waking up from xSleep()");
+ }
+ rc = opfsVfs.ioSyncWrappers.xClose(fid);
+ log("xClose rc =",rc,"sabOPView =",state.sabOPView);
+ log("Deleting file:",dbFile);
+ opfsVfs.vfsSyncWrappers.xDelete(opfsVfs.pointer, zDbFile, 0x1234);
+ opfsVfs.vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
+ rc = wasm.peek(pOut,'i32');
+ if(rc) toss("Expecting 0 from xAccess(",dbFile,") after xDelete().");
+ warn("End of OPFS sanity checks.");
+ }finally{
+ sq3File.dispose();
+ wasm.scopedAllocPop(scope);
+ }
+ }/*sanityCheck()*/;
+
+ W.onmessage = function({data}){
+ //sqlite3.config.warn(vfsName,"Worker.onmessage:",data);
+ switch(data.type){
+ case 'opfs-unavailable':
+ /* Async proxy has determined that OPFS is unavailable. There's
+ nothing more for us to do here. */
+ promiseReject(new Error(data.payload.join(' ')));
+ break;
+ case 'opfs-async-loaded':
+ /* Arrives as soon as the asyc proxy finishes loading.
+ Pass our config and shared state on to the async
+ worker. */
+ delete state.vfs;
+ W.postMessage({type: 'opfs-async-init', args: util.nu(state)});
+ break;
+ case 'opfs-async-inited': {
+ /* Indicates that the async partner has received the 'init'
+ and has finished initializing, so the real work can
+ begin... */
+ if(true===promiseWasRejected){
+ break /* promise was already rejected via timer */;
+ }
+ clearTimeout(zombieTimer);
+ zombieTimer = null;
+ try {
+ sqlite3.vfs.installVfs({
+ io: {struct: opfsVfs.ioMethods, methods: opfsVfs.ioSyncWrappers},
+ vfs: {struct: opfsVfs, methods: opfsVfs.vfsSyncWrappers}
+ });
+ state.sabOPView = new Int32Array(state.sabOP);
+ state.sabFileBufView = new Uint8Array(state.sabIO, 0, state.fileBufferSize);
+ state.sabS11nView = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
+ opfsVfs.initS11n();
+ delete opfsVfs.initS11n;
+ if(options.sanityChecks){
+ warn("Running sanity checks because of opfs-sanity-check URL arg...");
+ sanityCheck();
+ }
+ if(opfsUtil.thisThreadHasOPFS()){
+ opfsUtil.getRootDir().then((d)=>{
+ W.onerror = W._originalOnError;
+ delete W._originalOnError;
+ log("End of OPFS sqlite3_vfs setup.", opfsVfs);
+ promiseResolve();
+ }).catch(promiseReject);
+ }else{
+ promiseResolve();
+ }
+ }catch(e){
+ error(e);
+ promiseReject(e);
+ }
+ break;
+ }
+ case 'debug':
+ warn("debug message from worker:",data);
+ break;
+ default: {
+ const errMsg = (
+ "Unexpected message from the OPFS async worker: " +
+ JSON.stringify(data)
+ );
+ error(errMsg);
+ promiseReject(new Error(errMsg));
+ break;
+ }
+ }/*switch(data.type)*/
+ }/*W.onmessage()*/;
+ })/*thePromise*/;
+ return thePromise;
+ }/*bindVfs()*/;
+
+ return state;
+ }/*createVfsState()*/;
+
+}/*sqlite3ApiBootstrap.initializers*/);
+/*
+ 2022-09-18
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ This file holds the synchronous half of an sqlite3_vfs
+ implementation which proxies, in a synchronous fashion, the
+ asynchronous Origin-Private FileSystem (OPFS) APIs using a second
+ Worker, implemented in sqlite3-opfs-async-proxy.js. This file is
+ intended to be appended to the main sqlite3 JS deliverable somewhere
+ after sqlite3-api-oo1.js.
+*/
+'use strict';
+globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
+ if( !sqlite3.opfs || sqlite3.config.disable?.vfs?.opfs ){
+ return;
+ }
+ const util = sqlite3.util,
+ opfsUtil = sqlite3.opfs || sqlite3.util.toss("Missing sqlite3.opfs");
+ /**
+ installOpfsVfs() returns a Promise which, on success, installs an
+ sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
+ which accept a VFS. It is intended to be called via
+ sqlite3ApiBootstrap.initializers or an equivalent mechanism.
+
+ The installed VFS uses the Origin-Private FileSystem API for
+ all file storage. On error it is rejected with an exception
+ explaining the problem. Reasons for rejection include, but are
+ not limited to:
- /**
- Expects an OPFS file path. It gets resolved, such that ".."
- components are properly expanded, and returned. If the 2nd arg
- is true, the result is returned as an array of path elements,
- else an absolute path string is returned.
- */
- opfsUtil.getResolvedPath = function(filename,splitIt){
- const p = new URL(filename, "file://irrelevant").pathname;
- return splitIt ? p.split('/').filter((v)=>!!v) : p;
- };
+ - The counterpart Worker (see below) could not be loaded.
- /**
- Takes the absolute path to a filesystem element. Returns an
- array of [handleOfContainingDir, filename]. If the 2nd argument
- is truthy then each directory element leading to the file is
- created along the way. Throws if any creation or resolution
- fails.
- */
- opfsUtil.getDirForFilename = async function f(absFilename, createDirs = false){
- const path = opfsUtil.getResolvedPath(absFilename, true);
- const filename = path.pop();
- let dh = opfsUtil.rootDirectory;
- for(const dirName of path){
- if(dirName){
- dh = await dh.getDirectoryHandle(dirName, {create: !!createDirs});
- }
- }
- return [dh, filename];
- };
+ - The environment does not support OPFS. That includes when
+ this function is called from the main window thread.
- /**
- Creates the given directory name, recursively, in
- the OPFS filesystem. Returns true if it succeeds or the
- directory already exists, else false.
- */
- opfsUtil.mkdir = async function(absDirName){
- try {
- await opfsUtil.getDirForFilename(absDirName+"/filepart", true);
- return true;
- }catch(e){
- //sqlite3.config.warn("mkdir(",absDirName,") failed:",e);
- return false;
- }
- };
- /**
- Checks whether the given OPFS filesystem entry exists,
- returning true if it does, false if it doesn't or if an
- exception is intercepted while trying to make the
- determination.
- */
- opfsUtil.entryExists = async function(fsEntryName){
- try {
- const [dh, fn] = await opfsUtil.getDirForFilename(fsEntryName);
- await dh.getFileHandle(fn);
- return true;
- }catch(e){
- return false;
- }
- };
+ Significant notes and limitations:
- /**
- Generates a random ASCII string, intended for use as a
- temporary file name. Its argument is the length of the string,
- defaulting to 16.
- */
- opfsUtil.randomFilename = randomFilename;
+ - The OPFS features used here are only available in dedicated Worker
+ threads. This file tries to detect that case, resulting in a
+ rejected Promise if those features do not seem to be available.
- /**
- Returns a promise which resolves to an object which represents
- all files and directories in the OPFS tree. The top-most object
- has two properties: `dirs` is an array of directory entries
- (described below) and `files` is a list of file names for all
- files in that directory.
+ - It requires the SharedArrayBuffer and Atomics classes, and the
+ former is only available if the HTTP server emits the so-called
+ COOP and COEP response headers. These features are required for
+ proxying OPFS's synchronous API via the synchronous interface
+ required by the sqlite3_vfs API.
- Traversal starts at sqlite3.opfs.rootDirectory.
+ - This function may only be called a single time. When called, this
+ function removes itself from the sqlite3 object.
- Each `dirs` entry is an object in this form:
+ All arguments to this function are for internal/development purposes
+ only. They do not constitute a public API and may change at any
+ time.
- ```
- { name: directoryName,
- dirs: [...subdirs],
- files: [...file names]
- }
- ```
+ The argument may optionally be a plain object with the following
+ configuration options:
- The `files` and `subdirs` entries are always set but may be
- empty arrays.
+ - proxyUri: name of the async proxy JS file or a synchronous function
+ which, when called, returns such a name.
- The returned object has the same structure but its `name` is
- an empty string. All returned objects are created with
- Object.create(null), so have no prototype.
+ - verbose (=2): an integer 0-3. 0 disables all logging, 1 enables
+ logging of errors. 2 enables logging of warnings and errors. 3
+ additionally enables debugging info. Logging is performed
+ via the sqlite3.config.{log|warn|error}() functions.
- Design note: the entries do not contain more information,
- e.g. file sizes, because getting such info is not only
- expensive but is subject to locking-related errors.
- */
- opfsUtil.treeList = async function(){
- const doDir = async function callee(dirHandle,tgt){
- tgt.name = dirHandle.name;
- tgt.dirs = [];
- tgt.files = [];
- for await (const handle of dirHandle.values()){
- if('directory' === handle.kind){
- const subDir = Object.create(null);
- tgt.dirs.push(subDir);
- await callee(handle, subDir);
- }else{
- tgt.files.push(handle.name);
- }
- }
- };
- const root = Object.create(null);
- await doDir(opfsUtil.rootDirectory, root);
- return root;
- };
+ - sanityChecks (=false): if true, some basic sanity tests are run on
+ the OPFS VFS API after it's initialized, before the returned
+ Promise resolves. This is only intended for testing and
+ development of the VFS, not client-side use.
- /**
- Irrevocably deletes _all_ files in the current origin's OPFS.
- Obviously, this must be used with great caution. It may throw
- an exception if removal of anything fails (e.g. a file is
- locked), but the precise conditions under which the underlying
- APIs will throw are not documented (so we cannot tell you what
- they are).
- */
- opfsUtil.rmfr = async function(){
- const dir = opfsUtil.rootDirectory, opt = {recurse: true};
- for await (const handle of dir.values()){
- dir.removeEntry(handle.name, opt);
- }
- };
+ Additionaly, the (officially undocumented) 'opfs-disable' URL
+ argument will disable OPFS, making this function a no-op.
- /**
- Deletes the given OPFS filesystem entry. As this environment
- has no notion of "current directory", the given name must be an
- absolute path. If the 2nd argument is truthy, deletion is
- recursive (use with caution!).
-
- The returned Promise resolves to true if the deletion was
- successful, else false (but...). The OPFS API reports the
- reason for the failure only in human-readable form, not
- exceptions which can be type-checked to determine the
- failure. Because of that...
-
- If the final argument is truthy then this function will
- propagate any exception on error, rather than returning false.
- */
- opfsUtil.unlink = async function(fsEntryName, recursive = false,
- throwOnError = false){
- try {
- const [hDir, filenamePart] =
- await opfsUtil.getDirForFilename(fsEntryName, false);
- await hDir.removeEntry(filenamePart, {recursive});
- return true;
- }catch(e){
- if(throwOnError){
- throw new Error("unlink(",arguments[0],") failed: "+e.message,{
- cause: e
- });
- }
- return false;
- }
- };
+ On success, the Promise resolves to the top-most sqlite3 namespace
+ object. Success does not necessarily mean that it installs the VFS,
+ as there are legitimate non-error reasons for OPFS not to be
+ available.
+*/
+const installOpfsVfs = async function(options){
+ options = opfsUtil.initOptions('opfs',options);
+ if( !options ) return sqlite3;
+ const capi = sqlite3.capi,
+ state = opfsUtil.createVfsState(),
+ opfsVfs = state.vfs,
+ metrics = opfsVfs.metrics.counters,
+ mTimeStart = opfsVfs.mTimeStart,
+ mTimeEnd = opfsVfs.mTimeEnd,
+ opRun = opfsVfs.opRun,
+ debug = (...args)=>sqlite3.config.debug("opfs:",...args),
+ warn = (...args)=>sqlite3.config.warn("opfs:",...args),
+ __openFiles = opfsVfs.__openFiles;
+
+ //debug("options:",JSON.stringify(options));
+ /*
+ At this point, createVfsState() has populated:
- /**
- Traverses the OPFS filesystem, calling a callback for each
- entry. The argument may be either a callback function or an
- options object with any of the following properties:
-
- - `callback`: function which gets called for each filesystem
- entry. It gets passed 3 arguments: 1) the
- FileSystemFileHandle or FileSystemDirectoryHandle of each
- entry (noting that both are instanceof FileSystemHandle). 2)
- the FileSystemDirectoryHandle of the parent directory. 3) the
- current depth level, with 0 being at the top of the tree
- relative to the starting directory. If the callback returns a
- literal false, as opposed to any other falsy value, traversal
- stops without an error. Any exceptions it throws are
- propagated. Results are undefined if the callback manipulate
- the filesystem (e.g. removing or adding entries) because the
- how OPFS iterators behave in the face of such changes is
- undocumented.
-
- - `recursive` [bool=true]: specifies whether to recurse into
- subdirectories or not. Whether recursion is depth-first or
- breadth-first is unspecified!
-
- - `directory` [FileSystemDirectoryEntry=sqlite3.opfs.rootDirectory]
- specifies the starting directory.
-
- If this function is passed a function, it is assumed to be the
- callback.
-
- Returns a promise because it has to (by virtue of being async)
- but that promise has no specific meaning: the traversal it
- performs is synchronous. The promise must be used to catch any
- exceptions propagated by the callback, however.
- */
- opfsUtil.traverse = async function(opt){
- const defaultOpt = {
- recursive: true,
- directory: opfsUtil.rootDirectory
- };
- if('function'===typeof opt){
- opt = {callback:opt};
- }
- opt = Object.assign(defaultOpt, opt||{});
- const doDir = async function callee(dirHandle, depth){
- for await (const handle of dirHandle.values()){
- if(false === opt.callback(handle, dirHandle, depth)) return false;
- else if(opt.recursive && 'directory' === handle.kind){
- if(false === await callee(handle, depth + 1)) break;
- }
- }
- };
- doDir(opt.directory, 0);
- };
+ - state: the configuration object we share with the async proxy.
- /**
- impl of importDb() when it's given a function as its second
- argument.
- */
- const importDbChunked = async function(filename, callback){
- const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true);
- const hFile = await hDir.getFileHandle(fnamePart, {create:true});
- let sah = await hFile.createSyncAccessHandle();
- let nWrote = 0, chunk, checkedHeader = false, err = false;
- try{
- sah.truncate(0);
- while( undefined !== (chunk = await callback()) ){
- if(chunk instanceof ArrayBuffer) chunk = new Uint8Array(chunk);
- if( !checkedHeader && 0===nWrote && chunk.byteLength>=15 ){
- util.affirmDbHeader(chunk);
- checkedHeader = true;
- }
- sah.write(chunk, {at: nWrote});
- nWrote += chunk.byteLength;
- }
- if( nWrote < 512 || 0!==nWrote % 512 ){
- toss("Input size",nWrote,"is not correct for an SQLite database.");
- }
- if( !checkedHeader ){
- const header = new Uint8Array(20);
- sah.read( header, {at: 0} );
- util.affirmDbHeader( header );
- }
- sah.write(new Uint8Array([1,1]), {at: 18}/*force db out of WAL mode*/);
- return nWrote;
- }catch(e){
- await sah.close();
- sah = undefined;
- await hDir.removeEntry( fnamePart ).catch(()=>{});
- throw e;
- }finally {
- if( sah ) await sah.close();
- }
- };
+ - opfsVfs: an sqlite3_vfs instance with lots of JS state attached
+ to it.
- /**
- Asynchronously imports the given bytes (a byte array or
- ArrayBuffer) into the given database file.
-
- Results are undefined if the given db name refers to an opened
- db.
-
- If passed a function for its second argument, its behaviour
- changes: imports its data in chunks fed to it by the given
- callback function. It calls the callback (which may be async)
- repeatedly, expecting either a Uint8Array or ArrayBuffer (to
- denote new input) or undefined (to denote EOF). For so long as
- the callback continues to return non-undefined, it will append
- incoming data to the given VFS-hosted database file. When
- called this way, the resolved value of the returned Promise is
- the number of bytes written to the target file.
-
- It very specifically requires the input to be an SQLite3
- database and throws if that's not the case. It does so in
- order to prevent this function from taking on a larger scope
- than it is specifically intended to. i.e. we do not want it to
- become a convenience for importing arbitrary files into OPFS.
-
- This routine rewrites the database header bytes in the output
- file (not the input array) to force disabling of WAL mode.
-
- On error this throws and the state of the input file is
- undefined (it depends on where the exception was triggered).
-
- On success, resolves to the number of bytes written.
- */
- opfsUtil.importDb = async function(filename, bytes){
- if( bytes instanceof Function ){
- return importDbChunked(filename, bytes);
+ with any code common to both the "opfs" and "opfs-wl" VFSes. Now
+ comes the VFS-dependent work...
+ */
+ return opfsVfs.bindVfs(util.nu({
+ xLock: function(pFile,lockType){
+ mTimeStart('xLock');
+ ++metrics.xLock.count;
+ const f = __openFiles[pFile];
+ let rc = 0;
+ /* All OPFS locks are exclusive locks. If xLock() has
+ previously succeeded, do nothing except record the lock
+ type. If no lock is active, have the async counterpart
+ lock the file. */
+ if( f.lockType ) {
+ f.lockType = lockType;
+ }else{
+ rc = opRun('xLock', pFile, lockType);
+ if( 0===rc ) f.lockType = lockType;
}
- if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
- util.affirmIsDb(bytes);
- const n = bytes.byteLength;
- const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true);
- let sah, err, nWrote = 0;
- try {
- const hFile = await hDir.getFileHandle(fnamePart, {create:true});
- sah = await hFile.createSyncAccessHandle();
- sah.truncate(0);
- nWrote = sah.write(bytes, {at: 0});
- if(nWrote != n){
- toss("Expected to write "+n+" bytes but wrote "+nWrote+".");
- }
- sah.write(new Uint8Array([1,1]), {at: 18}) /* force db out of WAL mode */;
- return nWrote;
- }catch(e){
- if( sah ){ await sah.close(); sah = undefined; }
- await hDir.removeEntry( fnamePart ).catch(()=>{});
- throw e;
- }finally{
- if( sah ) await sah.close();
+ mTimeEnd();
+ return rc;
+ },
+ xUnlock: function(pFile,lockType){
+ mTimeStart('xUnlock');
+ ++metrics.xUnlock.count;
+ const f = __openFiles[pFile];
+ let rc = 0;
+ if( capi.SQLITE_LOCK_NONE === lockType
+ && f.lockType ){
+ rc = opRun('xUnlock', pFile, lockType);
}
- };
-
+ if( 0===rc ) f.lockType = lockType;
+ mTimeEnd();
+ return rc;
+ }
+ }), function(sqlite3, vfs){
+ /* Post-VFS-registration initialization... */
if(sqlite3.oo1){
const OpfsDb = function(...args){
const opt = sqlite3.oo1.DB.dbCtorHelper.normalizeArgs(...args);
- opt.vfs = opfsVfs.$zName;
+ opt.vfs = vfs.$zName;
sqlite3.oo1.DB.dbCtorHelper.call(this, opt);
};
OpfsDb.prototype = Object.create(sqlite3.oo1.DB.prototype);
sqlite3.oo1.OpfsDb = OpfsDb;
OpfsDb.importDb = opfsUtil.importDb;
- sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenCallback(
- opfsVfs.pointer,
- function(oo1Db, sqlite3){
- /* Set a relatively high default busy-timeout handler to
- help OPFS dbs deal with multi-tab/multi-worker
- contention. */
- sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000);
- }
- );
- }/*extend sqlite3.oo1*/
-
- const sanityCheck = function(){
- const scope = wasm.scopedAllocPush();
- const sq3File = new sqlite3_file();
- try{
- const fid = sq3File.pointer;
- const openFlags = capi.SQLITE_OPEN_CREATE
- | capi.SQLITE_OPEN_READWRITE
- //| capi.SQLITE_OPEN_DELETEONCLOSE
- | capi.SQLITE_OPEN_MAIN_DB;
- const pOut = wasm.scopedAlloc(8);
- const dbFile = "/sanity/check/file"+randomFilename(8);
- const zDbFile = wasm.scopedAllocCString(dbFile);
- let rc;
- state.s11n.serialize("This is ä string.");
- rc = state.s11n.deserialize();
- log("deserialize() says:",rc);
- if("This is ä string."!==rc[0]) toss("String d13n error.");
- vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
- rc = wasm.peek(pOut,'i32');
- log("xAccess(",dbFile,") exists ?=",rc);
- rc = vfsSyncWrappers.xOpen(opfsVfs.pointer, zDbFile,
- fid, openFlags, pOut);
- log("open rc =",rc,"state.sabOPView[xOpen] =",
- state.sabOPView[state.opIds.xOpen]);
- if(0!==rc){
- error("open failed with code",rc);
- return;
- }
- vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
- rc = wasm.peek(pOut,'i32');
- if(!rc) toss("xAccess() failed to detect file.");
- rc = ioSyncWrappers.xSync(sq3File.pointer, 0);
- if(rc) toss('sync failed w/ rc',rc);
- rc = ioSyncWrappers.xTruncate(sq3File.pointer, 1024);
- if(rc) toss('truncate failed w/ rc',rc);
- wasm.poke(pOut,0,'i64');
- rc = ioSyncWrappers.xFileSize(sq3File.pointer, pOut);
- if(rc) toss('xFileSize failed w/ rc',rc);
- log("xFileSize says:",wasm.peek(pOut, 'i64'));
- rc = ioSyncWrappers.xWrite(sq3File.pointer, zDbFile, 10, 1);
- if(rc) toss("xWrite() failed!");
- const readBuf = wasm.scopedAlloc(16);
- rc = ioSyncWrappers.xRead(sq3File.pointer, readBuf, 6, 2);
- wasm.poke(readBuf+6,0);
- let jRead = wasm.cstrToJs(readBuf);
- log("xRead() got:",jRead);
- if("sanity"!==jRead) toss("Unexpected xRead() value.");
- if(vfsSyncWrappers.xSleep){
- log("xSleep()ing before close()ing...");
- vfsSyncWrappers.xSleep(opfsVfs.pointer,2000);
- log("waking up from xSleep()");
- }
- rc = ioSyncWrappers.xClose(fid);
- log("xClose rc =",rc,"sabOPView =",state.sabOPView);
- log("Deleting file:",dbFile);
- vfsSyncWrappers.xDelete(opfsVfs.pointer, zDbFile, 0x1234);
- vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
- rc = wasm.peek(pOut,'i32');
- if(rc) toss("Expecting 0 from xAccess(",dbFile,") after xDelete().");
- warn("End of OPFS sanity checks.");
- }finally{
- sq3File.dispose();
- wasm.scopedAllocPop(scope);
- }
- }/*sanityCheck()*/;
-
- W.onmessage = function({data}){
- //log("Worker.onmessage:",data);
- switch(data.type){
- case 'opfs-unavailable':
- /* Async proxy has determined that OPFS is unavailable. There's
- nothing more for us to do here. */
- promiseReject(new Error(data.payload.join(' ')));
- break;
- case 'opfs-async-loaded':
- /* Arrives as soon as the asyc proxy finishes loading.
- Pass our config and shared state on to the async
- worker. */
- W.postMessage({type: 'opfs-async-init',args: state});
- break;
- case 'opfs-async-inited': {
- /* Indicates that the async partner has received the 'init'
- and has finished initializing, so the real work can
- begin... */
- if(true===promiseWasRejected){
- break /* promise was already rejected via timer */;
- }
- try {
- sqlite3.vfs.installVfs({
- io: {struct: opfsIoMethods, methods: ioSyncWrappers},
- vfs: {struct: opfsVfs, methods: vfsSyncWrappers}
- });
- state.sabOPView = new Int32Array(state.sabOP);
- state.sabFileBufView = new Uint8Array(state.sabIO, 0, state.fileBufferSize);
- state.sabS11nView = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
- initS11n();
- if(options.sanityChecks){
- warn("Running sanity checks because of opfs-sanity-check URL arg...");
- sanityCheck();
- }
- if(thisThreadHasOPFS()){
- navigator.storage.getDirectory().then((d)=>{
- W.onerror = W._originalOnError;
- delete W._originalOnError;
- sqlite3.opfs = opfsUtil;
- opfsUtil.rootDirectory = d;
- log("End of OPFS sqlite3_vfs setup.", opfsVfs);
- promiseResolve();
- }).catch(promiseReject);
- }else{
- promiseResolve();
- }
- }catch(e){
- error(e);
- promiseReject(e);
- }
- break;
+ if( true ){
+ /* 2026-03-06: this was a design mis-decision and is
+ inconsistent with sqlite3_open() and friends, but is
+ retained against the risk of introducing regressions if
+ it's removed. */
+ sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenCallback(
+ opfsVfs.pointer,
+ function(oo1Db, sqlite3){
+ /* Set a relatively high default busy-timeout handler to
+ help OPFS dbs deal with multi-tab/multi-worker
+ contention. */
+ sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000);
}
- default: {
- const errMsg = (
- "Unexpected message from the OPFS async worker: " +
- JSON.stringify(data)
- );
- error(errMsg);
- promiseReject(new Error(errMsg));
- break;
- }
- }/*switch(data.type)*/
- }/*W.onmessage()*/;
- })/*thePromise*/;
- return thePromise;
+ );
+ }
+ }/*extend sqlite3.oo1*/
+ })/*bindVfs()*/;
}/*installOpfsVfs()*/;
-installOpfsVfs.defaultProxyUri =
- "sqlite3-opfs-async-proxy.js";
globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
- try{
- let proxyJs = installOpfsVfs.defaultProxyUri;
- if( sqlite3?.scriptInfo?.sqlite3Dir ){
- installOpfsVfs.defaultProxyUri =
- sqlite3.scriptInfo.sqlite3Dir + proxyJs;
- //sqlite3.config.warn("installOpfsVfs.defaultProxyUri =",installOpfsVfs.defaultProxyUri);
- }
- return installOpfsVfs().catch((e)=>{
- sqlite3.config.warn("Ignoring inability to install OPFS sqlite3_vfs:",e.message);
- });
- }catch(e){
- sqlite3.config.error("installOpfsVfs() exception:",e);
- return Promise.reject(e);
- }
+ return installOpfsVfs().catch((e)=>{
+ sqlite3.config.warn("Ignoring inability to install 'opfs' sqlite3_vfs:",e);
+ })
});
}/*sqlite3ApiBootstrap.initializers.push()*/);
/*
@@ -19388,6 +19579,10 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
*/
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
'use strict';
+ if( sqlite3.config.disable?.vfs?.['opfs-sahpool'] ){
+ return;
+ }
+
const toss = sqlite3.util.toss;
const toss3 = sqlite3.util.toss3;
const initPromises = Object.create(null) /* cache of (name:result) of VFS init results */;
@@ -20795,6 +20990,132 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
});
}/*installOpfsSAHPoolVfs()*/;
}/*sqlite3ApiBootstrap.initializers*/);
+/*
+ 2026-02-20
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ This file is a reimplementation of the "opfs" VFS (as distinct from
+ "opfs-sahpool") which uses WebLocks for locking instead of a bespoke
+ Atomics.wait()/notify() protocol. This file holds the "synchronous
+ half" of the VFS, whereas it shares the "asynchronous half" with the
+ "opfs" VFS.
+
+ Testing has failed to show any genuine functional difference between
+ these VFSes other than "opfs-wl" being able to dole out xLock()
+ requests in a strictly FIFO manner by virtue of WebLocks being
+ globally managed by the browser. This tends to lead to, but does not
+ guaranty, fairer distribution of locks. Differences are unlikely to
+ be noticed except, perhaps, under very high contention.
+
+ This file is intended to be appended to the main sqlite3 JS
+ deliverable somewhere after opfs-common-shared.c-pp.js.
+*/
+'use strict';
+globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
+ if( !sqlite3.opfs || sqlite3.config.disable?.vfs?.['opfs-wl'] ){
+ return;
+ }
+ const util = sqlite3.util,
+ toss = sqlite3.util.toss;
+ const opfsUtil = sqlite3.opfs;
+ const vfsName = 'opfs-wl';
+/**
+ installOpfsWlVfs() returns a Promise which, on success, installs an
+ sqlite3_vfs named "opfs-wl", suitable for use with all sqlite3 APIs
+ which accept a VFS. It is intended to be called via
+ sqlite3ApiBootstrap.initializers or an equivalent mechanism.
+
+ This VFS is essentially identical to the "opfs" VFS but uses
+ WebLocks for its xLock() and xUnlock() implementations.
+
+ Quirks specific to this VFS:
+
+ - The (officially undocumented) 'opfs-wl-disable' URL
+ argument will disable OPFS, making this function a no-op.
+
+ Aside from locking differences in the VFSes, this function
+ otherwise behaves the same as
+ sqlite3-vfs-opfs.c-pp.js:installOpfsVfs().
+*/
+const installOpfsWlVfs = async function(options){
+ options = opfsUtil.initOptions(vfsName,options);
+ if( !options ) return sqlite3;
+ const capi = sqlite3.capi,
+ state = opfsUtil.createVfsState(),
+ opfsVfs = state.vfs,
+ metrics = opfsVfs.metrics.counters,
+ mTimeStart = opfsVfs.mTimeStart,
+ mTimeEnd = opfsVfs.mTimeEnd,
+ opRun = opfsVfs.opRun,
+ debug = (...args)=>sqlite3.config.debug(vfsName+":",...args),
+ warn = (...args)=>sqlite3.config.warn(vfsName+":",...args),
+ __openFiles = opfsVfs.__openFiles;
+
+ //debug("state",JSON.stringify(options));
+ /*
+ At this point, createVfsState() has populated:
+
+ - state: the configuration object we share with the async proxy.
+
+ - opfsVfs: an sqlite3_vfs instance with lots of JS state attached
+ to it.
+
+ with any code common to both the "opfs" and "opfs-wl" VFSes. Now
+ comes the VFS-dependent work...
+ */
+ return opfsVfs.bindVfs(util.nu({
+ xLock: function(pFile,lockType){
+ mTimeStart('xLock');
+ //debug("xLock()...");
+ const f = __openFiles[pFile];
+ const rc = opRun('xLock', pFile, lockType);
+ if( !rc ) f.lockType = lockType;
+ mTimeEnd();
+ return rc;
+ },
+ xUnlock: function(pFile,lockType){
+ mTimeStart('xUnlock');
+ const f = __openFiles[pFile];
+ const rc = opRun('xUnlock', pFile, lockType);
+ if( !rc ) f.lockType = lockType;
+ mTimeEnd();
+ return rc;
+ }
+ }), function(sqlite3, vfs){
+ /* Post-VFS-registration initialization... */
+ if(sqlite3.oo1){
+ const OpfsWlDb = function(...args){
+ const opt = sqlite3.oo1.DB.dbCtorHelper.normalizeArgs(...args);
+ opt.vfs = vfs.$zName;
+ sqlite3.oo1.DB.dbCtorHelper.call(this, opt);
+ };
+ OpfsWlDb.prototype = Object.create(sqlite3.oo1.DB.prototype);
+ sqlite3.oo1.OpfsWlDb = OpfsWlDb;
+ OpfsWlDb.importDb = opfsUtil.importDb;
+ /* The "opfs" VFS variant adds a
+ oo1.DB.dbCtorHelper.setVfsPostOpenCallback() callback to set
+ a high busy_timeout. That was a design mis-decision and is
+ inconsistent with sqlite3_open() and friends, but is retained
+ against the risk of introducing regressions if it's removed.
+ This variant does not repeat that mistake.
+ */
+ }
+ })/*bindVfs()*/;
+}/*installOpfsWlVfs()*/;
+globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
+ return installOpfsWlVfs().catch((e)=>{
+ sqlite3.config.warn("Ignoring inability to install the",vfsName,"sqlite3_vfs:",e);
+ });
+});
+}/*sqlite3ApiBootstrap.initializers.push()*/);
/*
2022-07-22
diff --git a/src/bin/sqlite3-node.mjs b/src/bin/sqlite3-node.mjs
index ddcfbc1..09e55f4 100644
--- a/src/bin/sqlite3-node.mjs
+++ b/src/bin/sqlite3-node.mjs
@@ -27,11 +27,11 @@
/* @preserve
** This code was built from sqlite3 version...
**
-** SQLITE_VERSION "3.52.0"
-** SQLITE_VERSION_NUMBER 3052000
-** SQLITE_SOURCE_ID "2026-01-30 06:37:34 407724c4e80efdf93d885e95b5209a100a3f470fe0298138be57201f65f9817e"
+** SQLITE_VERSION "3.53.0"
+** SQLITE_VERSION_NUMBER 3053000
+** SQLITE_SOURCE_ID "2026-04-09 11:41:38 4525003a53a7fc63ca75c59b22c79608659ca12f0131f52c18637f829977f20b"
**
-** Emscripten SDK: 5.0.0
+** Emscripten SDK: 5.0.5
*/
// This code implements the `-sMODULARIZE` settings by taking the generated
// JS program code (INNER_JS_CODE) and wrapping it in a factory function.
@@ -98,7 +98,7 @@ if (ENVIRONMENT_IS_NODE) {
/**
This file was preprocessed using:
- ./c-pp-lite -o ./bld/pre-js.node.js -Dtarget:node -Dtarget:es6-module -Dtarget:es6-bundler-friendly -Dunsupported-build -DModule.instantiateWasm api/pre-js.c-pp.js
+ ./c-pp -o ./bld/pre-js.node.js -Dtarget:node -Dtarget:es6-module -Dtarget:es6-bundler-friendly -Dunsupported-build -DModule.instantiateWasm api/pre-js.c-pp.js
*/
/**
UNSUPPORTED BUILD:
@@ -108,7 +108,8 @@ if (ENVIRONMENT_IS_NODE) {
load. It may not work properly. Only builds _directly_ targeting
browser environments ("vanilla" JS and ESM modules) are supported
and tested. Builds which _indirectly_ target browsers (namely
- bundler-friendly builds) are not supported deliverables.
+ bundler-friendly builds and any node builds) are not supported
+ deliverables.
*/
/* END FILE: api/pre-js.js. */
// end include: ./bld/pre-js.node.js
@@ -235,37 +236,17 @@ var isFileURI = (filename) => filename.startsWith('file://');
// include: runtime_stack_check.js
// end include: runtime_stack_check.js
// include: runtime_exceptions.js
+// Base Emscripten EH error class
+class EmscriptenEH {}
+
+class EmscriptenSjLj extends EmscriptenEH {}
+
// end include: runtime_exceptions.js
// include: runtime_debug.js
// end include: runtime_debug.js
var readyPromiseResolve, readyPromiseReject;
// Memory management
-var
-/** @type {!Int8Array} */
- HEAP8,
-/** @type {!Uint8Array} */
- HEAPU8,
-/** @type {!Int16Array} */
- HEAP16,
-/** @type {!Uint16Array} */
- HEAPU16,
-/** @type {!Int32Array} */
- HEAP32,
-/** @type {!Uint32Array} */
- HEAPU32,
-/** @type {!Float32Array} */
- HEAPF32,
-/** @type {!Float64Array} */
- HEAPF64;
-
-// BigInt64Array type is not correctly defined in closure
-var
-/** not-@type {!BigInt64Array} */
- HEAP64,
-/* BigUint64Array type is not correctly defined in closure
-/** not-@type {!BigUint64Array} */
- HEAPU64;
var runtimeInitialized = false;
@@ -363,11 +344,14 @@ function postRun() {
// End ATPOSTRUNS hooks
}
-/** @param {string|number=} what */
+/**
+ * @param {string|number=} what
+ * @noreturn
+ */
function abort(what) {
Module['onAbort']?.(what);
- what = 'Aborted(' + what + ')';
+ what = `Aborted(${what})`;
// TODO(sbc): Should we remove printing and leave it up to whoever
// catches the exception?
err(what);
@@ -545,6 +529,36 @@ async function createWasm() {
}
}
+ /** @type {!Int16Array} */
+ var HEAP16;
+
+ /** @type {!Int32Array} */
+ var HEAP32;
+
+ /** not-@type {!BigInt64Array} */
+ var HEAP64;
+
+ /** @type {!Int8Array} */
+ var HEAP8;
+
+ /** @type {!Float32Array} */
+ var HEAPF32;
+
+ /** @type {!Float64Array} */
+ var HEAPF64;
+
+ /** @type {!Uint16Array} */
+ var HEAPU16;
+
+ /** @type {!Uint32Array} */
+ var HEAPU32;
+
+ /** not-@type {!BigUint64Array} */
+ var HEAPU64;
+
+ /** @type {!Uint8Array} */
+ var HEAPU8;
+
var callRuntimeCallbacks = (callbacks) => {
while (callbacks.length > 0) {
// Pass the module as the first argument.
@@ -675,12 +689,9 @@ var initRandomFill = () => {
return (view) => nodeCrypto.randomFillSync(view);
}
- return (view) => crypto.getRandomValues(view);
- };
-var randomFill = (view) => {
- // Lazily init on the first invocation.
- (randomFill = initRandomFill())(view);
+ return (view) => (crypto.getRandomValues(view), 0);
};
+var randomFill = (view) => (randomFill = initRandomFill())(view);
@@ -1098,11 +1109,14 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
} else if (FS.isFile(node.mode)) {
node.node_ops = MEMFS.ops_table.file.node;
node.stream_ops = MEMFS.ops_table.file.stream;
- node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
- // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
- // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
- // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
- node.contents = null;
+ // The actual number of bytes used in the typed array, as opposed to
+ // contents.length which gives the whole capacity.
+ node.usedBytes = 0;
+ // The byte data of the file is stored in a typed array.
+ // Note: typed arrays are not resizable like normal JS arrays are, so
+ // there is a small penalty involved for appending file writes that
+ // continuously grow a file similar to std::vector capacity vs used.
+ node.contents = MEMFS.emptyFileContents ??= new Uint8Array(0);
} else if (FS.isLink(node.mode)) {
node.node_ops = MEMFS.ops_table.link.node;
node.stream_ops = MEMFS.ops_table.link.stream;
@@ -1119,36 +1133,29 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return node;
},
getFileDataAsTypedArray(node) {
- if (!node.contents) return new Uint8Array(0);
- if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
- return new Uint8Array(node.contents);
+ return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
},
expandFileStorage(node, newCapacity) {
- var prevCapacity = node.contents ? node.contents.length : 0;
+ var prevCapacity = node.contents.length;
if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
- // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
- // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
- // avoid overshooting the allocation cap by a very large margin.
+ // Don't expand strictly to the given requested limit if it's only a very
+ // small increase, but instead geometrically grow capacity.
+ // For small filesizes (<1MB), perform size*2 geometric increase, but for
+ // large sizes, do a much more conservative size*1.125 increase to avoid
+ // overshooting the allocation cap by a very large margin.
var CAPACITY_DOUBLING_MAX = 1024 * 1024;
newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
- if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
- var oldContents = node.contents;
+ if (prevCapacity) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
+ var oldContents = MEMFS.getFileDataAsTypedArray(node);
node.contents = new Uint8Array(newCapacity); // Allocate new storage.
- if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
+ node.contents.set(oldContents);
},
resizeFileStorage(node, newSize) {
if (node.usedBytes == newSize) return;
- if (newSize == 0) {
- node.contents = null; // Fully decommit when requesting a resize to zero.
- node.usedBytes = 0;
- } else {
- var oldContents = node.contents;
- node.contents = new Uint8Array(newSize); // Allocate new storage.
- if (oldContents) {
- node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
- }
- node.usedBytes = newSize;
- }
+ var oldContents = node.contents;
+ node.contents = new Uint8Array(newSize); // Allocate new storage.
+ node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
+ node.usedBytes = newSize;
},
node_ops:{
getattr(node) {
@@ -1254,11 +1261,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var contents = stream.node.contents;
if (position >= stream.node.usedBytes) return 0;
var size = Math.min(stream.node.usedBytes - position, length);
- if (size > 8 && contents.subarray) { // non-trivial, and typed array
- buffer.set(contents.subarray(position, position + size), offset);
- } else {
- for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
- }
+ buffer.set(contents.subarray(position, position + size), offset);
return size;
},
write(stream, buffer, offset, length, position, canOwn) {
@@ -1274,32 +1277,18 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var node = stream.node;
node.mtime = node.ctime = Date.now();
- if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
- if (canOwn) {
- node.contents = buffer.subarray(offset, offset + length);
- node.usedBytes = length;
- return length;
- } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
- node.contents = buffer.slice(offset, offset + length);
- node.usedBytes = length;
- return length;
- } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
- node.contents.set(buffer.subarray(offset, offset + length), position);
- return length;
- }
- }
-
- // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
- MEMFS.expandFileStorage(node, position+length);
- if (node.contents.subarray && buffer.subarray) {
+ if (canOwn) {
+ node.contents = buffer.subarray(offset, offset + length);
+ node.usedBytes = length;
+ } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
+ node.contents = buffer.slice(offset, offset + length);
+ node.usedBytes = length;
+ } else {
+ MEMFS.expandFileStorage(node, position+length);
// Use typed array write which is available.
node.contents.set(buffer.subarray(offset, offset + length), position);
- } else {
- for (var i = 0; i < length; i++) {
- node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
- }
+ node.usedBytes = Math.max(node.usedBytes, position + length);
}
- node.usedBytes = Math.max(node.usedBytes, position + length);
return length;
},
llseek(stream, offset, whence) {
@@ -1324,7 +1313,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var allocated;
var contents = stream.node.contents;
// Only make a new copy when MAP_PRIVATE is specified.
- if (!(flags & 2) && contents && contents.buffer === HEAP8.buffer) {
+ if (!(flags & 2) && contents.buffer === HEAP8.buffer) {
// We can't emulate MAP_SHARED when the file is not backed by the
// buffer we're mapping to (e.g. the HEAP buffer).
allocated = false;
@@ -1358,6 +1347,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
};
var FS_modeStringToFlags = (str) => {
+ if (typeof str != 'string') return str;
var flagModes = {
'r': 0,
'r+': 2,
@@ -1373,6 +1363,16 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return flags;
};
+ var FS_fileDataToTypedArray = (data) => {
+ if (typeof data == 'string') {
+ data = intArrayFromString(data, true);
+ }
+ if (!data.subarray) {
+ data = new Uint8Array(data);
+ }
+ return data;
+ };
+
var FS_getMode = (canRead, canWrite) => {
var mode = 0;
if (canRead) mode |= 292 | 73;
@@ -1470,8 +1470,6 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
ignorePermissions:true,
filesystems:null,
syncFSRequests:0,
- readFiles:{
- },
ErrnoError:class {
name = 'ErrnoError';
// We set the `name` property to be able to identify `FS.ErrnoError`
@@ -1737,9 +1735,11 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
// return 0 if any user, group or owner bits are set.
if (perms.includes('r') && !(node.mode & 292)) {
return 2;
- } else if (perms.includes('w') && !(node.mode & 146)) {
+ }
+ if (perms.includes('w') && !(node.mode & 146)) {
return 2;
- } else if (perms.includes('x') && !(node.mode & 73)) {
+ }
+ if (perms.includes('x') && !(node.mode & 73)) {
return 2;
}
return 0;
@@ -1780,10 +1780,8 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
return 10;
}
- } else {
- if (FS.isDir(node.mode)) {
- return 31;
- }
+ } else if (FS.isDir(node.mode)) {
+ return 31;
}
return 0;
},
@@ -1793,13 +1791,16 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
if (FS.isLink(node.mode)) {
return 32;
- } else if (FS.isDir(node.mode)) {
- if (FS.flagsToPermissionString(flags) !== 'r' // opening for write
- || (flags & (512 | 64))) { // TODO: check for O_SEARCH? (== search for dir only)
+ }
+ var mode = FS.flagsToPermissionString(flags);
+ if (FS.isDir(node.mode)) {
+ // opening for write
+ // TODO: check for O_SEARCH? (== search for dir only)
+ if (mode !== 'r' || (flags & (512 | 64))) {
return 31;
}
}
- return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+ return FS.nodePermissions(node, mode);
},
checkOpExists(op, err) {
if (!op) {
@@ -2367,7 +2368,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (path === "") {
throw new FS.ErrnoError(44);
}
- flags = typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
+ flags = FS_modeStringToFlags(flags);
if ((flags & 64)) {
mode = (mode & 4095) | 32768;
} else {
@@ -2454,11 +2455,6 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (created) {
FS.chmod(node, mode & 0o777);
}
- if (Module['logReadFiles'] && !(flags & 1)) {
- if (!(path in FS.readFiles)) {
- FS.readFiles[path] = 1;
- }
- }
return stream;
},
close(stream) {
@@ -2605,14 +2601,8 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
writeFile(path, data, opts = {}) {
opts.flags = opts.flags || 577;
var stream = FS.open(path, opts.flags, opts.mode);
- if (typeof data == 'string') {
- data = new Uint8Array(intArrayFromString(data, true));
- }
- if (ArrayBuffer.isView(data)) {
- FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
- } else {
- abort('Unsupported data type');
- }
+ data = FS_fileDataToTypedArray(data);
+ FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
FS.close(stream);
},
cwd:() => FS.currentPath,
@@ -2832,11 +2822,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var mode = FS_getMode(canRead, canWrite);
var node = FS.create(path, mode);
if (data) {
- if (typeof data == 'string') {
- var arr = new Array(data.length);
- for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
- data = arr;
- }
+ data = FS_fileDataToTypedArray(data);
// make sure we can write to the file
FS.chmod(node, mode | 146);
var stream = FS.open(node, 577);
@@ -4160,6 +4146,7 @@ var _sqlite3_status64,
_sqlite3_bind_null,
_sqlite3_bind_pointer,
_sqlite3_bind_text,
+ _sqlite3_bind_zeroblob,
_sqlite3_bind_parameter_count,
_sqlite3_bind_parameter_name,
_sqlite3_bind_parameter_index,
@@ -4423,6 +4410,7 @@ function assignWasmExports(wasmExports) {
_sqlite3_bind_null = Module['_sqlite3_bind_null'] = wasmExports['sqlite3_bind_null'];
_sqlite3_bind_pointer = Module['_sqlite3_bind_pointer'] = wasmExports['sqlite3_bind_pointer'];
_sqlite3_bind_text = Module['_sqlite3_bind_text'] = wasmExports['sqlite3_bind_text'];
+ _sqlite3_bind_zeroblob = Module['_sqlite3_bind_zeroblob'] = wasmExports['sqlite3_bind_zeroblob'];
_sqlite3_bind_parameter_count = Module['_sqlite3_bind_parameter_count'] = wasmExports['sqlite3_bind_parameter_count'];
_sqlite3_bind_parameter_name = Module['_sqlite3_bind_parameter_name'] = wasmExports['sqlite3_bind_parameter_name'];
_sqlite3_bind_parameter_index = Module['_sqlite3_bind_parameter_index'] = wasmExports['sqlite3_bind_parameter_index'];
@@ -4767,6 +4755,7 @@ Module.runSQLite3PostLoadInit = async function(
- sqlite3-vtab-helper.c-pp.js => Utilities for virtual table impls
- sqlite3-vfs-opfs.c-pp.js => OPFS VFS
- sqlite3-vfs-opfs-sahpool.c-pp.js => OPFS SAHPool VFS
+ - sqlite3-vfs-opfs-wl.c-pp.js => WebLock-using OPFS VFS
- post-js-footer.js => this file's epilogue
And all of that gets sandwiched between extern-pre-js.js and
@@ -4801,11 +4790,11 @@ Module.runSQLite3PostLoadInit = async function(
/* @preserve
** This code was built from sqlite3 version...
**
-** SQLITE_VERSION "3.52.0"
-** SQLITE_VERSION_NUMBER 3052000
-** SQLITE_SOURCE_ID "2026-01-30 06:37:34 407724c4e80efdf93d885e95b5209a100a3f470fe0298138be57201f65f9817e"
+** SQLITE_VERSION "3.53.0"
+** SQLITE_VERSION_NUMBER 3053000
+** SQLITE_SOURCE_ID "2026-04-09 11:41:38 4525003a53a7fc63ca75c59b22c79608659ca12f0131f52c18637f829977f20b"
**
-** Emscripten SDK: 5.0.0
+** Emscripten SDK: 5.0.5
*/
/*
2022-05-22
@@ -4908,6 +4897,13 @@ Module.runSQLite3PostLoadInit = async function(
used in WASMFS-capable builds of the library (which the canonical
builds do not include).
+ - `disable` (as of 3.53.0) may be an object with the following
+ properties:
+ - `vfs`, an object, may contain a map of VFS names to booleans.
+ Any mapping to falsy are disabled. The supported names
+ are: "kvvfs", "opfs", "opfs-sahpool", "opfs-wl".
+ - Other disabling options may be added in the future.
+
[^1] = This property may optionally be a function, in which case
this function calls that function to fetch the value,
enabling delayed evaluation.
@@ -4954,7 +4950,8 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
);
return sqlite3ApiBootstrap.sqlite3;
}
- const config = Object.assign(Object.create(null),{
+ const nu = (...obj)=>Object.assign(Object.create(null),...obj);
+ const config = nu({
exports: undefined,
memory: undefined,
bigIntEnabled: !!globalThis.BigInt64Array,
@@ -4971,7 +4968,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
certain wasm.xWrap.resultAdapter()s.
*/
useStdAlloc: false
- }, apiConfig || {});
+ }, apiConfig);
Object.assign(config, {
allocExportName: config.useStdAlloc ? 'malloc' : 'sqlite3_malloc',
@@ -5004,7 +5001,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
not documented are installed as 1-to-1 proxies for their
C-side counterparts.
*/
- const capi = Object.create(null);
+ const capi = nu();
/**
Holds state which are specific to the WASM-related
infrastructure and glue code.
@@ -5013,7 +5010,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
dynamically after the api object is fully constructed, so
not all are documented in this file.
*/
- const wasm = Object.create(null);
+ const wasm = nu();
/** Internal helper for SQLite3Error ctor. */
const __rcStr = (rc)=>{
@@ -5561,6 +5558,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
toss: function(...args){throw new Error(args.join(' '))},
toss3,
typedArrayPart: wasm.typedArrayPart,
+ nu,
assert: function(arg,msg){
if( !arg ){
util.toss("Assertion failed:",msg);
@@ -5817,7 +5815,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
rv[1] = m ? (f._rxInt.test(m[2]) ? +m[2] : m[2]) : true;
};
}
- const rc = Object.create(null), ov = [0,0];
+ const rc = nu(), ov = [0,0];
let i = 0, k;
while((k = capi.sqlite3_compileoption_get(i++))){
f._opt(k,ov);
@@ -5825,7 +5823,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
}
return f._result = rc;
}else if(Array.isArray(optName)){
- const rc = Object.create(null);
+ const rc = nu();
optName.forEach((v)=>{
rc[v] = capi.sqlite3_compileoption_used(v);
});
@@ -5876,7 +5874,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
The memory lives in the WASM heap and can be used with routines
such as wasm.poke() and wasm.heap8u().slice().
*/
- wasm.pstack = Object.assign(Object.create(null),{
+ wasm.pstack = nu({
/**
Sets the current pstack position to the given pointer. Results
are undefined if the passed-in value did not come from
@@ -6098,7 +6096,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
// sqlite3__wasm_init_wasmfs() is not available
return this.dir = "";
}
- }.bind(Object.create(null));
+ }.bind(nu());
/**
Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
@@ -6452,6 +6450,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
case capi.SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE:
case capi.SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE:
case capi.SQLITE_DBCONFIG_ENABLE_COMMENTS:
+ case capi.SQLITE_DBCONFIG_FP_DIGITS:
if( !this.ip ){
this.ip = wasm.xWrap('sqlite3__wasm_db_config_ip','int',
['sqlite3*', 'int', 'int', '*']);
@@ -6473,7 +6472,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
default:
return capi.SQLITE_MISUSE;
}
- }.bind(Object.create(null));
+ }.bind(nu());
/**
Given a (sqlite3_value*), this function attempts to convert it
@@ -6707,7 +6706,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
const pv = wasm.peekPtr(this.ptr);
return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
- }.bind(Object.create(null));
+ }.bind(nu());
/**
A wrapper around sqlite3_preupdate_new() which fetches the
@@ -6747,6 +6746,62 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
'sqlite3changeset_old');
}/*changeset/preupdate additions*/
+ /**
+ EXPERIMENTAL. For tentative addition in 3.53.0.
+
+ sqlite3_js_retry_busy(maxTimes,callback[,beforeRetry])
+
+ Calls the given _synchronous_ callback function. If that function
+ returns sqlite3.capi.SQLITE_BUSY _or_ throws an SQLite3Error
+ with a resultCode property of that value then it will suppress
+ that error and try again, up to the given maximum number of
+ times. If the callback returns any other value than that,
+ it is returned. If the maximum number of retries has been
+ reached, an SQLite3Error with a resultCode value of
+ sqlite3.capi.SQLITE_BUSY is thrown. If the callback throws any
+ exception other than the aforementioned BUSY exception, it is
+ propagated. If it throws a BUSY exception on its final attempt,
+ that is propagated as well.
+
+ If the beforeRetry argument is given, it must be a _synchronous_
+ function. It is called immediately before each retry of the
+ callback (not for the initial call), passed the attempt number
+ (so it starts with 2, not 1). If it throws, the exception is
+ handled as described above. Its result value is ignored.
+
+ To effectively retry "forever", pass a negative maxTimes value,
+ with the caveat that there is no recovery from that unless the
+ beforeRetry() can figure out when to throw.
+
+ TODO: an async variant of this.
+ */
+ capi.sqlite3_js_retry_busy = function(maxTimes, callback, beforeRetry){
+ for(let n = 1; n <= maxTimes; ++n){
+ try{
+ if( beforeRetry && n>1 ) beforeRetry(n);
+ const rc = callback();
+ if( capi.SQLITE_BUSY===rc ){
+ if( n===maxTimes ){
+ throw new SQLite3Error(rc, [
+ "sqlite3_js_retry_busy() max retry attempts (",
+ maxTimes,
+ ") reached."
+ ].join(''));
+ }
+ continue;
+ }
+ return rc;
+ }catch(e){
+ if( n{};
const debug = sqlite3.__isUnderTest
- ? (...args)=>sqlite3.config.debug("kvvfs:", ...args)
+ ? (...args)=>sqlite3.config.debug?.("kvvfs:", ...args)
: noop;
- const warn = (...args)=>sqlite3.config.warn("kvvfs:", ...args);
- const error = (...args)=>sqlite3.config.error("kvvfs:", ...args);
+ const warn = (...args)=>sqlite3.config.warn?.("kvvfs:", ...args);
+ const error = (...args)=>sqlite3.config.error?.("kvvfs:", ...args);
/**
Implementation of JS's Storage interface for use as backing store
@@ -16237,17 +16299,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
and recreating it whenever a property index might be invalidated.
*/
class KVVfsStorage {
- #map;
- #keys;
- #getKeys(){return this.#keys ??= Object.keys(this.#map);}
+ #map = Object.create(null);
+ #keys = null;
+ #size = 0;
constructor(){
this.clear();
}
+ #getKeys(){
+ return this.#keys ??= Object.keys(this.#map);
+ }
+
key(n){
- const k = this.#getKeys();
- return n= this.#size) return null;
+ return this.#getKeys()[n];
}
getItem(k){
@@ -16255,14 +16321,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
setItem(k,v){
- if( !hop(this.#map, k) ){
+ if( !(k in this.#map) ){
+ ++this.#size;
this.#keys = null;
}
this.#map[k] = ''+v;
}
removeItem(k){
- if( delete this.#map[k] ){
+ if( k in this.#map ){
+ delete this.#map[k];
+ --this.#size;
this.#keys = null;
}
}
@@ -16270,10 +16339,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
clear(){
this.#map = Object.create(null);
this.#keys = null;
+ this.#size = 0;
}
get length() {
- return this.#getKeys().length;
+ return this.#size;
}
}/*KVVfsStorage*/;
@@ -17035,36 +17105,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
},
- // We override xRead/xWrite only for logging/debugging. They
- // should otherwise be disabled (it's faster that way).
- xRead: function(pFile,pTgt,n,iOff64){
- cache.popError();
- try{
- if( kvvfs?.log?.xRead ){
- const h = pFileHandles.get(pFile);
- util.assert(h, "Missing KVVfsFile handle");
- debug("xRead", n, iOff64, h);
- }
- return originalMethods.ioDb.xRead(pFile, pTgt, n, iOff64);
- }catch(e){
- error("xRead",e);
- return cache.setError(e);
- }
- },
- xWrite: function(pFile,pSrc,n,iOff64){
- cache.popError();
- try{
- if( kvvfs?.log?.xWrite ){
- const h = pFileHandles.get(pFile);
- util.assert(h, "Missing KVVfsFile handle");
- debug("xWrite", n, iOff64, h);
- }
- return originalMethods.ioDb.xWrite(pFile, pSrc, n, iOff64);
- }catch(e){
- error("xWrite",e);
- return cache.setError(e);
- }
- },
}/*.ioDb*/,
@@ -17076,9 +17116,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/*.ioJrnl*/
}/*methodOverrides*/;
- debug("pVfs and friends", pVfs, pIoDb, pIoJrnl,
- kvvfsMethods, capi.sqlite3_file.structInfo,
- KVVfsFile.structInfo);
+
try {
util.assert( cache.buffer.n>1024*129, "Heap buffer is not large enough"
/* Native is SQLITE_KVOS_SZ is 133073 as of this writing */ );
@@ -17167,7 +17205,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
limitation which has since been overcome, but removal of
JsStorageDb.prototype.clearStorage() would be a backwards compatibility
break, so this function permits wiping the storage for those two
- cases even if they are opened. Use with case.
+ cases even if they are opened. Use with care.
*/
const sqlite3_js_kvvfs_clear = function callee(which){
if( ''===which ){
@@ -17842,7 +17880,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
return rc;
}catch(e){
- return VT.xErrror('xConnect', e, capi.SQLITE_ERROR);
+ return VT.xError('xConnect', e, capi.SQLITE_ERROR);
}
},
xCreate: wasm.ptr.null, // eponymous only
@@ -17940,7 +17978,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
})/*globalThis.sqlite3ApiBootstrap.initializers*/;
-/* The OPFS VFS parts are elided from builds targeting node.js. */
/*
The OPFS SAH Pool VFS parts are elided from builds targeting
node.js.
diff --git a/src/bin/sqlite3-opfs-async-proxy.js b/src/bin/sqlite3-opfs-async-proxy.js
index 79fc473..e09bbbd 100644
--- a/src/bin/sqlite3-opfs-async-proxy.js
+++ b/src/bin/sqlite3-opfs-async-proxy.js
@@ -46,10 +46,23 @@
theFunc().then(...) is not compatible with the change to
synchronous, but we do do not use those APIs that way. i.e. we don't
_need_ to change anything for this, but at some point (after Chrome
- versions (approximately) 104-107 are extinct) should change our
+ versions (approximately) 104-107 are extinct) we should change our
usage of those methods to remove the "await".
*/
+
"use strict";
+const urlParams = new URL(globalThis.location.href).searchParams;
+const vfsName = urlParams.get('vfs');
+if( !vfsName ){
+ throw new Error("Expecting vfs=opfs|opfs-wl URL argument for this worker");
+}
+/**
+ We use this to allow us to differentiate debug output from
+ multiple instances, e.g. multiple Workers to the "opfs"
+ VFS or both the "opfs" and "opfs-wl" VFSes.
+*/
+const workerId = (Math.random() * 10000000) | 0;
+const isWebLocker = 'opfs-wl'===urlParams.get('vfs');
const wPost = (type,...args)=>postMessage({type, payload:args});
const installAsyncProxy = function(){
const toss = function(...args){throw new Error(args.join(' '))};
@@ -66,6 +79,174 @@ const installAsyncProxy = function(){
*/
const state = Object.create(null);
+ /* initS11n() is preprocessor-injected so that we have identical
+ copies in the synchronous and async halves. This side does not
+ load the SQLite library, so does not have access to that copy. */
+const initS11n = function(){
+ /**
+ This proxy de/serializes cross-thread function arguments and
+ output-pointer values via the state.sabIO SharedArrayBuffer,
+ using the region defined by (state.sabS11nOffset,
+ state.sabS11nOffset + state.sabS11nSize]. Only one dataset is
+ recorded at a time.
+
+ This is not a general-purpose format. It only supports the
+ range of operations, and data sizes, needed by the
+ sqlite3_vfs and sqlite3_io_methods operations. Serialized
+ data are transient and this serialization algorithm may
+ change at any time.
+
+ The data format can be succinctly summarized as:
+
+ Nt...Td...D
+
+ Where:
+
+ - N = number of entries (1 byte)
+
+ - t = type ID of first argument (1 byte)
+
+ - ...T = type IDs of the 2nd and subsequent arguments (1 byte
+ each).
+
+ - d = raw bytes of first argument (per-type size).
+
+ - ...D = raw bytes of the 2nd and subsequent arguments (per-type
+ size).
+
+ All types except strings have fixed sizes. Strings are stored
+ using their TextEncoder/TextDecoder representations. It would
+ arguably make more sense to store them as Int16Arrays of
+ their JS character values, but how best/fastest to get that
+ in and out of string form is an open point. Initial
+ experimentation with that approach did not gain us any speed.
+
+ Historical note: this impl was initially about 1% this size by
+ using using JSON.stringify/parse(), but using fit-to-purpose
+ serialization saves considerable runtime.
+ */
+ if(state.s11n) return state.s11n;
+ const textDecoder = new TextDecoder(),
+ textEncoder = new TextEncoder('utf-8'),
+ viewU8 = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize),
+ viewDV = new DataView(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
+ state.s11n = Object.create(null);
+ /* Only arguments and return values of these types may be
+ serialized. This covers the whole range of types needed by the
+ sqlite3_vfs API. */
+ const TypeIds = Object.create(null);
+ TypeIds.number = { id: 1, size: 8, getter: 'getFloat64', setter: 'setFloat64' };
+ TypeIds.bigint = { id: 2, size: 8, getter: 'getBigInt64', setter: 'setBigInt64' };
+ TypeIds.boolean = { id: 3, size: 4, getter: 'getInt32', setter: 'setInt32' };
+ TypeIds.string = { id: 4 };
+
+ const getTypeId = (v)=>(
+ TypeIds[typeof v]
+ || toss("Maintenance required: this value type cannot be serialized.",v)
+ );
+ const getTypeIdById = (tid)=>{
+ switch(tid){
+ case TypeIds.number.id: return TypeIds.number;
+ case TypeIds.bigint.id: return TypeIds.bigint;
+ case TypeIds.boolean.id: return TypeIds.boolean;
+ case TypeIds.string.id: return TypeIds.string;
+ default: toss("Invalid type ID:",tid);
+ }
+ };
+
+ /**
+ Returns an array of the deserialized state stored by the most
+ recent serialize() operation (from this thread or the
+ counterpart thread), or null if the serialization buffer is
+ empty. If passed a truthy argument, the serialization buffer
+ is cleared after deserialization.
+ */
+ state.s11n.deserialize = function(clear=false){
+ const t = performance.now();
+ const argc = viewU8[0];
+ const rc = argc ? [] : null;
+ if(argc){
+ const typeIds = [];
+ let offset = 1, i, n, v;
+ for(i = 0; i < argc; ++i, ++offset){
+ typeIds.push(getTypeIdById(viewU8[offset]));
+ }
+ for(i = 0; i < argc; ++i){
+ const t = typeIds[i];
+ if(t.getter){
+ v = viewDV[t.getter](offset, state.littleEndian);
+ offset += t.size;
+ }else{/*String*/
+ n = viewDV.getInt32(offset, state.littleEndian);
+ offset += 4;
+ v = textDecoder.decode(viewU8.slice(offset, offset+n));
+ offset += n;
+ }
+ rc.push(v);
+ }
+ }
+ if(clear) viewU8[0] = 0;
+ //log("deserialize:",argc, rc);
+ return rc;
+ };
+
+ /**
+ Serializes all arguments to the shared buffer for consumption
+ by the counterpart thread.
+
+ This routine is only intended for serializing OPFS VFS
+ arguments and (in at least one special case) result values,
+ and the buffer is sized to be able to comfortably handle
+ those.
+
+ If passed no arguments then it zeroes out the serialization
+ state.
+ */
+ state.s11n.serialize = function(...args){
+ const t = performance.now();
+ if(args.length){
+ //log("serialize():",args);
+ const typeIds = [];
+ let i = 0, offset = 1;
+ viewU8[0] = args.length & 0xff /* header = # of args */;
+ for(; i < args.length; ++i, ++offset){
+ /* Write the TypeIds.id value into the next args.length
+ bytes. */
+ typeIds.push(getTypeId(args[i]));
+ viewU8[offset] = typeIds[i].id;
+ }
+ for(i = 0; i < args.length; ++i) {
+ /* Deserialize the following bytes based on their
+ corresponding TypeIds.id from the header. */
+ const t = typeIds[i];
+ if(t.setter){
+ viewDV[t.setter](offset, args[i], state.littleEndian);
+ offset += t.size;
+ }else{/*String*/
+ const s = textEncoder.encode(args[i]);
+ viewDV.setInt32(offset, s.byteLength, state.littleEndian);
+ offset += 4;
+ viewU8.set(s, offset);
+ offset += s.byteLength;
+ }
+ }
+ //log("serialize() result:",viewU8.slice(0,offset));
+ }else{
+ viewU8[0] = 0;
+ }
+ };
+
+ state.s11n.storeException = state.asyncS11nExceptions
+ ? ((priority,e)=>{
+ if(priority<=state.asyncS11nExceptions){
+ state.s11n.serialize([e.name,': ',e.message].join(""));
+ }
+ })
+ : ()=>{};
+
+ return state.s11n;
+}/*initS11n()*/;
+
/**
verbose:
@@ -82,7 +263,7 @@ const installAsyncProxy = function(){
2:console.log.bind(console)
};
const logImpl = (level,...args)=>{
- if(state.verbose>level) loggers[level]("OPFS asyncer:",...args);
+ if(state.verbose>level) loggers[level](vfsName+' async-proxy',workerId+":",...args);
};
const log = (...args)=>logImpl(2, ...args);
const warn = (...args)=>logImpl(1, ...args);
@@ -97,12 +278,13 @@ const installAsyncProxy = function(){
*/
const __openFiles = Object.create(null);
/**
- __implicitLocks is a Set of sqlite3_file pointers (integers) which were
- "auto-locked". i.e. those for which we obtained a sync access
- handle without an explicit xLock() call. Such locks will be
- released during db connection idle time, whereas a sync access
- handle obtained via xLock(), or subsequently xLock()'d after
- auto-acquisition, will not be released until xUnlock() is called.
+ __implicitLocks is a Set of sqlite3_file pointers (integers)
+ which were "auto-locked". i.e. those for which we necessarily
+ obtain a sync access handle without an explicit xLock() call
+ guarding access. Such locks will be released during
+ `waitLoop()`'s idle time, whereas a sync access handle obtained
+ via xLock(), or subsequently xLock()'d after auto-acquisition,
+ will not be released until xUnlock() is called.
Maintenance reminder: if we relinquish auto-locks at the end of the
operation which acquires them, we pay a massive performance
@@ -271,10 +453,11 @@ const installAsyncProxy = function(){
In order to help alleviate cross-tab contention for a dabase, if
an exception is thrown while acquiring the handle, this routine
- will wait briefly and try again, up to some fixed number of
- times. If acquisition still fails at that point it will give up
- and propagate the exception. Client-level code will see that as
- an I/O error.
+ will wait briefly and try again, up to `maxTries` of times. If
+ acquisition still fails at that point it will give up and
+ propagate the exception. Client-level code will see that either
+ as an I/O error or SQLITE_BUSY, depending on the exception and
+ the context.
2024-06-12: there is a rare race condition here which has been
reported a single time:
@@ -289,13 +472,31 @@ const installAsyncProxy = function(){
there's another race condition there). That's easy to say but
creating a viable test for that condition has proven challenging
so far.
+
+ Interface quirk: if fh.xLock is falsy and the handle is acquired
+ then fh.fid is added to __implicitLocks(). If fh.xLock is truthy,
+ it is not added as an implicit lock. i.e. xLock() impls must set
+ fh.xLock immediately _before_ calling this and must arrange to
+ restore it to its previous value if this function throws.
+
+ 2026-03-06:
+
+ - baseWaitTime is the number of milliseconds to wait for the
+ first retry, increasing by one factor for each retry. It defaults
+ to (state.asyncIdleWaitTime*2).
+
+ - maxTries is the number of attempt to make, each one spaced out
+ by one additional factor of the baseWaitTime (e.g. 300, then 600,
+ then 900, the 1200...). This MUST be an integer >0.
+
+ Only the Web Locks impl should use the 3rd and 4th parameters.
*/
- const getSyncHandle = async (fh,opName)=>{
+ const getSyncHandle = async (fh, opName, baseWaitTime, maxTries = 6)=>{
if(!fh.syncHandle){
const t = performance.now();
log("Acquiring sync handle for",fh.filenameAbs);
- const maxTries = 6,
- msBase = state.asyncIdleWaitTime * 2;
+ const msBase = baseWaitTime ?? (state.asyncIdleWaitTime * 2);
+ maxTries ??= 6;
let i = 1, ms = msBase;
for(; true; ms = msBase * ++i){
try {
@@ -329,6 +530,9 @@ const installAsyncProxy = function(){
/**
Stores the given value at state.sabOPView[state.opIds.rc] and then
Atomics.notify()'s it.
+
+ The opName is only used for logging and debugging - all result
+ codes are expected on the same state.sabOPView slot.
*/
const storeAndNotify = (opName, value)=>{
log(opName+"() => notify(",value,")");
@@ -458,24 +662,12 @@ const installAsyncProxy = function(){
await releaseImplicitLock(fh);
storeAndNotify('xFileSize', rc);
},
- xLock: async function(fid/*sqlite3_file pointer*/,
- lockType/*SQLITE_LOCK_...*/){
- const fh = __openFiles[fid];
- let rc = 0;
- const oldLockType = fh.xLock;
- fh.xLock = lockType;
- if( !fh.syncHandle ){
- try {
- await getSyncHandle(fh,'xLock');
- __implicitLocks.delete(fid);
- }catch(e){
- state.s11n.storeException(1,e);
- rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_LOCK);
- fh.xLock = oldLockType;
- }
- }
- storeAndNotify('xLock',rc);
- },
+ /**
+ The first argument is semantically invalid here - it's an
+ address in the synchronous side's heap. We can do nothing with
+ it here except use it as a unique-per-file identifier.
+ i.e. a lookup key.
+ */
xOpen: async function(fid/*sqlite3_file pointer*/, filename,
flags/*SQLITE_OPEN_...*/,
opfsFlags/*OPFS_...*/){
@@ -533,7 +725,7 @@ const installAsyncProxy = function(){
rc = state.sq3Codes.SQLITE_IOERR_SHORT_READ;
}
}catch(e){
- error("xRead() failed",e,fh);
+ //error("xRead() failed",e,fh);
state.s11n.storeException(1,e);
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_READ);
}
@@ -560,29 +752,13 @@ const installAsyncProxy = function(){
affirmNotRO('xTruncate', fh);
await (await getSyncHandle(fh,'xTruncate')).truncate(size);
}catch(e){
- error("xTruncate():",e,fh);
+ //error("xTruncate():",e,fh);
state.s11n.storeException(2,e);
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_TRUNCATE);
}
await releaseImplicitLock(fh);
storeAndNotify('xTruncate',rc);
},
- xUnlock: async function(fid/*sqlite3_file pointer*/,
- lockType/*SQLITE_LOCK_...*/){
- let rc = 0;
- const fh = __openFiles[fid];
- if( fh.syncHandle
- && state.sq3Codes.SQLITE_LOCK_NONE===lockType
- /* Note that we do not differentiate between lock types in
- this VFS. We're either locked or unlocked. */ ){
- try { await closeSyncHandle(fh) }
- catch(e){
- state.s11n.storeException(1,e);
- rc = state.sq3Codes.SQLITE_IOERR_UNLOCK;
- }
- }
- storeAndNotify('xUnlock',rc);
- },
xWrite: async function(fid/*sqlite3_file pointer*/,n,offset64){
let rc;
const fh = __openFiles[fid];
@@ -594,7 +770,7 @@ const installAsyncProxy = function(){
{at: Number(offset64)})
) ? 0 : state.sq3Codes.SQLITE_IOERR_WRITE;
}catch(e){
- error("xWrite():",e,fh);
+ //error("xWrite():",e,fh);
state.s11n.storeException(1,e);
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_WRITE);
}
@@ -603,152 +779,269 @@ const installAsyncProxy = function(){
}
}/*vfsAsyncImpls*/;
- const initS11n = ()=>{
- /**
- ACHTUNG: this code is 100% duplicated in the other half of this
- proxy! The documentation is maintained in the "synchronous half".
+ if( isWebLocker ){
+ /* We require separate xLock() and xUnlock() implementations for the
+ original and Web Lock implementations. The ones in this block
+ are for the WebLock impl.
+
+ The Golden Rule for this impl is: if we have a web lock, we
+ must also hold the SAH. When "upgrading" an implicit lock to a
+ requested (explicit) lock, we must remove the SAH from the
+ __implicitLocks set. When we unlock, we release both the web
+ lock and the SAH. That invariant must be kept intact or race
+ conditions on SAHs will ensue.
*/
- if(state.s11n) return state.s11n;
- const textDecoder = new TextDecoder(),
- textEncoder = new TextEncoder('utf-8'),
- viewU8 = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize),
- viewDV = new DataView(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
- state.s11n = Object.create(null);
- const TypeIds = Object.create(null);
- TypeIds.number = { id: 1, size: 8, getter: 'getFloat64', setter: 'setFloat64' };
- TypeIds.bigint = { id: 2, size: 8, getter: 'getBigInt64', setter: 'setBigInt64' };
- TypeIds.boolean = { id: 3, size: 4, getter: 'getInt32', setter: 'setInt32' };
- TypeIds.string = { id: 4 };
- const getTypeId = (v)=>(
- TypeIds[typeof v]
- || toss("Maintenance required: this value type cannot be serialized.",v)
- );
- const getTypeIdById = (tid)=>{
- switch(tid){
- case TypeIds.number.id: return TypeIds.number;
- case TypeIds.bigint.id: return TypeIds.bigint;
- case TypeIds.boolean.id: return TypeIds.boolean;
- case TypeIds.string.id: return TypeIds.string;
- default: toss("Invalid type ID:",tid);
- }
- };
- state.s11n.deserialize = function(clear=false){
- const argc = viewU8[0];
- const rc = argc ? [] : null;
- if(argc){
- const typeIds = [];
- let offset = 1, i, n, v;
- for(i = 0; i < argc; ++i, ++offset){
- typeIds.push(getTypeIdById(viewU8[offset]));
+ /** Registry of active Web Locks: fid -> { mode, resolveRelease } */
+ const __activeWebLocks = Object.create(null);
+
+ vfsAsyncImpls.xLock = async function(fid/*sqlite3_file pointer*/,
+ lockType/*SQLITE_LOCK_...*/,
+ isFromUnlock/*only if called from this.xUnlock()*/){
+ const whichOp = isFromUnlock ? 'xUnlock' : 'xLock';
+ const fh = __openFiles[fid];
+ //error("xLock()",fid, lockType, isFromUnlock, fh);
+ const requestedMode = (lockType >= state.sq3Codes.SQLITE_LOCK_RESERVED)
+ ? 'exclusive' : 'shared';
+ const existing = __activeWebLocks[fid];
+ if( existing ){
+ if( existing.mode === requestedMode
+ || (existing.mode === 'exclusive'
+ && requestedMode === 'shared') ) {
+ fh.xLock = lockType;
+ storeAndNotify(whichOp, 0);
+ /* Don't do this: existing.mode = requestedMode;
+
+ Paraphrased from advice given by a consulting developer:
+
+ If you hold an exclusive lock and SQLite requests shared,
+ you should keep exiting.mode as exclusive in because the
+ underlying Web Lock is still exclusive. Changing it to
+ shared would trick xLock into thinking it needs to
+ perform a release/re-acquire dance if an exclusive is
+ later requested.
+ */
+ return 0 /* Already held at required or higher level */;
}
- for(i = 0; i < argc; ++i){
- const t = typeIds[i];
- if(t.getter){
- v = viewDV[t.getter](offset, state.littleEndian);
- offset += t.size;
- }else{/*String*/
- n = viewDV.getInt32(offset, state.littleEndian);
- offset += 4;
- v = textDecoder.decode(viewU8.slice(offset, offset+n));
- offset += n;
+ /*
+ Upgrade path: we must release shared and acquire exclusive.
+ This transition is NOT atomic in Web Locks API.
+
+ It _effectively_ is atomic if we don't call
+ closeSyncHandle(fh), as no other worker can lock that until
+ we let it go. But we can't do that without eventually
+ leading to deadly embrace situations, so we don't do that.
+ (That's not a hypothetical, it has happened.)
+ */
+ await closeSyncHandle(fh);
+ existing.resolveRelease();
+ delete __activeWebLocks[fid];
+ }
+
+ const lockName = "sqlite3-vfs-opfs:" + fh.filenameAbs;
+ const oldLockType = fh.xLock;
+ return new Promise((resolveWaitLoop) => {
+ //log("xLock() initial promise entered...");
+ navigator.locks.request(lockName, { mode: requestedMode }, async (lock) => {
+ //log("xLock() Web Lock entered.", fh);
+ __implicitLocks.delete(fid);
+ let rc = 0;
+ try{
+ fh.xLock = lockType/*must be set before getSyncHandle() is called!*/;
+ await getSyncHandle(fh, 'xLock', state.asyncIdleWaitTime, 5);
+ }catch(e){
+ fh.xLock = oldLockType;
+ state.s11n.storeException(1, e);
+ rc = GetSyncHandleError.convertRc(e, state.sq3Codes.SQLITE_BUSY);
}
- rc.push(v);
- }
+ const releasePromise = rc
+ ? undefined
+ : new Promise((resolveRelease) => {
+ __activeWebLocks[fid] = { mode: requestedMode, resolveRelease };
+ });
+ storeAndNotify(whichOp, rc) /* unblock the C side */;
+ resolveWaitLoop(0) /* unblock waitLoop() */;
+ await releasePromise /* hold the lock until xUnlock */;
+ });
+ });
+ };
+
+ /** Internal helper for the opfs-wl xUnlock() */
+ const wlCloseHandle = async(fh)=>{
+ let rc = 0;
+ try{
+ /* For the record, we've never once seen closeSyncHandle()
+ throw, nor should it because destructors do not throw. */
+ await closeSyncHandle(fh);
+ }catch(e){
+ state.s11n.storeException(1,e);
+ rc = state.sq3Codes.SQLITE_IOERR_UNLOCK;
}
- if(clear) viewU8[0] = 0;
- //log("deserialize:",argc, rc);
return rc;
};
- state.s11n.serialize = function(...args){
- if(args.length){
- //log("serialize():",args);
- const typeIds = [];
- let i = 0, offset = 1;
- viewU8[0] = args.length & 0xff /* header = # of args */;
- for(; i < args.length; ++i, ++offset){
- /* Write the TypeIds.id value into the next args.length
- bytes. */
- typeIds.push(getTypeId(args[i]));
- viewU8[offset] = typeIds[i].id;
- }
- for(i = 0; i < args.length; ++i) {
- /* Deserialize the following bytes based on their
- corresponding TypeIds.id from the header. */
- const t = typeIds[i];
- if(t.setter){
- viewDV[t.setter](offset, args[i], state.littleEndian);
- offset += t.size;
- }else{/*String*/
- const s = textEncoder.encode(args[i]);
- viewDV.setInt32(offset, s.byteLength, state.littleEndian);
- offset += 4;
- viewU8.set(s, offset);
- offset += s.byteLength;
- }
+
+ vfsAsyncImpls.xUnlock = async function(fid/*sqlite3_file pointer*/,
+ lockType/*SQLITE_LOCK_...*/){
+ const fh = __openFiles[fid];
+ const existing = __activeWebLocks[fid];
+ if( !existing ){
+ const rc = await wlCloseHandle(fh);
+ storeAndNotify('xUnlock', rc);
+ return rc;
+ }
+ //log("xUnlock()",fid, lockType, fh);
+ let rc = 0;
+ if( lockType === state.sq3Codes.SQLITE_LOCK_NONE ){
+ /* SQLite usually unlocks all the way to NONE */
+ rc = await wlCloseHandle(fh);
+ existing.resolveRelease();
+ delete __activeWebLocks[fid];
+ fh.xLock = lockType;
+ }else if( lockType === state.sq3Codes.SQLITE_LOCK_SHARED
+ && existing.mode === 'exclusive' ){
+ /* downgrade EXCLUSIVE -> SHARED */
+ rc = await wlCloseHandle(fh);
+ if( 0===rc ){
+ fh.xLock = lockType;
+ existing.resolveRelease();
+ delete __activeWebLocks[fid];
+ return vfsAsyncImpls.xLock(fid, lockType, true);
}
- //log("serialize() result:",viewU8.slice(0,offset));
}else{
- viewU8[0] = 0;
+ /* ??? */
+ error("xUnlock() unhandled condition", fh);
+ }
+ storeAndNotify('xUnlock', rc);
+ return 0;
+ }
+
+ }else{
+ /* Original/"legacy" xLock() and xUnlock() */
+
+ vfsAsyncImpls.xLock = async function(fid/*sqlite3_file pointer*/,
+ lockType/*SQLITE_LOCK_...*/){
+ const fh = __openFiles[fid];
+ let rc = 0;
+ const oldLockType = fh.xLock;
+ fh.xLock = lockType;
+ if( !fh.syncHandle ){
+ try {
+ await getSyncHandle(fh,'xLock');
+ __implicitLocks.delete(fid);
+ }catch(e){
+ state.s11n.storeException(1,e);
+ rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_LOCK);
+ fh.xLock = oldLockType;
+ }
}
+ storeAndNotify('xLock',rc);
};
- state.s11n.storeException = state.asyncS11nExceptions
- ? ((priority,e)=>{
- if(priority<=state.asyncS11nExceptions){
- state.s11n.serialize([e.name,': ',e.message].join(""));
+ vfsAsyncImpls.xUnlock = async function(fid/*sqlite3_file pointer*/,
+ lockType/*SQLITE_LOCK_...*/){
+ let rc = 0;
+ const fh = __openFiles[fid];
+ if( fh.syncHandle
+ && state.sq3Codes.SQLITE_LOCK_NONE===lockType
+ /* Note that we do not differentiate between lock types in
+ this VFS. We're either locked or unlocked. */ ){
+ try { await closeSyncHandle(fh) }
+ catch(e){
+ state.s11n.storeException(1,e);
+ rc = state.sq3Codes.SQLITE_IOERR_UNLOCK;
}
- })
- : ()=>{};
+ }
+ storeAndNotify('xUnlock',rc);
+ }
- return state.s11n;
- }/*initS11n()*/;
+ }/*xLock() and xUnlock() impls*/
const waitLoop = async function f(){
- const opHandlers = Object.create(null);
- for(let k of Object.keys(state.opIds)){
- const vi = vfsAsyncImpls[k];
- if(!vi) continue;
- const o = Object.create(null);
- opHandlers[state.opIds[k]] = o;
- o.key = k;
- o.f = vi;
+ if( !f.inited ){
+ f.inited = true;
+ f.opHandlers = Object.create(null);
+ for(let k of Object.keys(state.opIds)){
+ const vi = vfsAsyncImpls[k];
+ if(!vi) continue;
+ const o = Object.create(null);
+ f.opHandlers[state.opIds[k]] = o;
+ o.key = k;
+ o.f = vi;
+ }
}
+ const opIds = state.opIds;
+ const opView = state.sabOPView;
+ const slotWhichOp = opIds.whichOp;
+ const idleWaitTime = state.asyncIdleWaitTime;
+ const hasWaitAsync = !!Atomics.waitAsync;
while(!flagAsyncShutdown){
try {
- if('not-equal'!==Atomics.wait(
- state.sabOPView, state.opIds.whichOp, 0, state.asyncIdleWaitTime
- )){
- /* Maintenance note: we compare against 'not-equal' because
-
- https://github.com/tomayac/sqlite-wasm/issues/12
-
- is reporting that this occasionally, under high loads,
- returns 'ok', which leads to the whichOp being 0 (which
- isn't a valid operation ID and leads to an exception,
- along with a corresponding ugly console log
- message). Unfortunately, the conditions for that cannot
- be reliably reproduced. The only place in our code which
- writes a 0 to the state.opIds.whichOp SharedArrayBuffer
- index is a few lines down from here, and that instance
- is required in order for clear communication between
- the sync half of this proxy and this half.
+ let opId;
+ if( hasWaitAsync ){
+ opId = Atomics.load(opView, slotWhichOp);
+ if( 0===opId ){
+ const rv = Atomics.waitAsync(opView, slotWhichOp, 0,
+ idleWaitTime);
+ if( rv.async ) await rv.value;
+ await releaseImplicitLocks();
+ continue;
+ }
+ }else{
+ /**
+ For browsers without Atomics.waitAsync(), we require
+ the legacy implementation. Browser versions where
+ waitAsync() arrived:
+
+ Chrome: 90 (2021-04-13)
+ Firefox: 145 (2025-11-11)
+ Safari: 16.4 (2023-03-27)
+
+ The "opfs" VFS was not born until Chrome was somewhere in
+ the v104-108 range (Summer/Autumn 2022) and did not work
+ with Safari < v17 (2023-09-18) due to a WebKit bug which
+ restricted OPFS access from sub-Workers.
+
+ The waitAsync() counterpart of this block can be used by
+ both "opfs" and "opfs-wl", whereas this block can only be
+ used by "opfs". Performance comparisons between the two
+ in high-contention tests have been indecisive.
*/
- await releaseImplicitLocks();
- continue;
+ if('not-equal'!==Atomics.wait(
+ state.sabOPView, slotWhichOp, 0, state.asyncIdleWaitTime
+ )){
+ /* Maintenance note: we compare against 'not-equal' because
+
+ https://github.com/tomayac/sqlite-wasm/issues/12
+
+ is reporting that this occasionally, under high loads,
+ returns 'ok', which leads to the whichOp being 0 (which
+ isn't a valid operation ID and leads to an exception,
+ along with a corresponding ugly console log
+ message). Unfortunately, the conditions for that cannot
+ be reliably reproduced. The only place in our code which
+ writes a 0 to the state.opIds.whichOp SharedArrayBuffer
+ index is a few lines down from here, and that instance
+ is required in order for clear communication between
+ the sync half of this proxy and this half.
+
+ Much later (2026-03-07): that phenomenon is apparently
+ called a spurious wakeup.
+ */
+ await releaseImplicitLocks();
+ continue;
+ }
+ opId = Atomics.load(state.sabOPView, slotWhichOp);
}
- const opId = Atomics.load(state.sabOPView, state.opIds.whichOp);
- Atomics.store(state.sabOPView, state.opIds.whichOp, 0);
- const hnd = opHandlers[opId] ?? toss("No waitLoop handler for whichOp #",opId);
+ Atomics.store(opView, slotWhichOp, 0);
+ const hnd = f.opHandlers[opId]?.f ?? toss("No waitLoop handler for whichOp #",opId);
const args = state.s11n.deserialize(
true /* clear s11n to keep the caller from confusing this with
an exception string written by the upcoming
operation */
) || [];
- //warn("waitLoop() whichOp =",opId, hnd, args);
- if(hnd.f) await hnd.f(...args);
- else error("Missing callback for opId",opId);
+ //error("waitLoop() whichOp =",opId, f.opHandlers[opId].key, args);
+ await hnd(...args);
}catch(e){
- error('in waitLoop():',e);
+ error('in waitLoop():', e);
}
}
};
@@ -756,6 +1049,7 @@ const installAsyncProxy = function(){
navigator.storage.getDirectory().then(function(d){
state.rootDir = d;
globalThis.onmessage = function({data}){
+ //log(globalThis.location.href,"onmessage()",data);
switch(data.type){
case 'opfs-async-init':{
/* Receive shared state from synchronous partner */
@@ -771,6 +1065,7 @@ const installAsyncProxy = function(){
}
});
initS11n();
+ //warn("verbosity =",opt.verbose, state.verbose);
log("init state",state);
wPost('opfs-async-inited');
waitLoop();
@@ -782,22 +1077,27 @@ const installAsyncProxy = function(){
flagAsyncShutdown = false;
waitLoop();
}
- break;
+ break;
}
};
wPost('opfs-async-loaded');
}).catch((e)=>error("error initializing OPFS asyncer:",e));
}/*installAsyncProxy()*/;
-if(!globalThis.SharedArrayBuffer){
+if(globalThis.window === globalThis){
+ wPost('opfs-unavailable',
+ "This code cannot run from the main thread.",
+ "Load it as a Worker from a separate Worker.");
+}else if(!globalThis.SharedArrayBuffer){
wPost('opfs-unavailable', "Missing SharedArrayBuffer API.",
"The server must emit the COOP/COEP response headers to enable that.");
}else if(!globalThis.Atomics){
wPost('opfs-unavailable', "Missing Atomics API.",
"The server must emit the COOP/COEP response headers to enable that.");
+}else if(isWebLocker && !globalThis.Atomics.waitAsync){
+ wPost('opfs-unavailable',"Missing required Atomics.waitSync() for "+vfsName);
}else if(!globalThis.FileSystemHandle ||
!globalThis.FileSystemDirectoryHandle ||
- !globalThis.FileSystemFileHandle ||
- !globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle ||
+ !globalThis.FileSystemFileHandle?.prototype?.createSyncAccessHandle ||
!navigator?.storage?.getDirectory){
wPost('opfs-unavailable',"Missing required OPFS APIs.");
}else{
diff --git a/src/bin/sqlite3.mjs b/src/bin/sqlite3.mjs
index 900dc64..1b7c6ab 100644
--- a/src/bin/sqlite3.mjs
+++ b/src/bin/sqlite3.mjs
@@ -27,11 +27,11 @@
/* @preserve
** This code was built from sqlite3 version...
**
-** SQLITE_VERSION "3.52.0"
-** SQLITE_VERSION_NUMBER 3052000
-** SQLITE_SOURCE_ID "2026-01-30 06:37:34 407724c4e80efdf93d885e95b5209a100a3f470fe0298138be57201f65f9817e"
+** SQLITE_VERSION "3.53.0"
+** SQLITE_VERSION_NUMBER 3053000
+** SQLITE_SOURCE_ID "2026-04-09 11:41:38 4525003a53a7fc63ca75c59b22c79608659ca12f0131f52c18637f829977f20b"
**
-** Emscripten SDK: 5.0.0
+** Emscripten SDK: 5.0.5
*/
// This code implements the `-sMODULARIZE` settings by taking the generated
// JS program code (INNER_JS_CODE) and wrapping it in a factory function.
@@ -92,7 +92,7 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR
/**
This file was preprocessed using:
- ./c-pp-lite -o ./bld/pre-js.esm.js -Dtarget:es6-module -DModule.instantiateWasm api/pre-js.c-pp.js
+ ./c-pp -o ./bld/pre-js.esm.js -Dtarget:es6-module -DModule.instantiateWasm api/pre-js.c-pp.js
*/
(function(Module){
const sIMS =
@@ -302,37 +302,17 @@ var isFileURI = (filename) => filename.startsWith('file://');
// include: runtime_stack_check.js
// end include: runtime_stack_check.js
// include: runtime_exceptions.js
+// Base Emscripten EH error class
+class EmscriptenEH {}
+
+class EmscriptenSjLj extends EmscriptenEH {}
+
// end include: runtime_exceptions.js
// include: runtime_debug.js
// end include: runtime_debug.js
var readyPromiseResolve, readyPromiseReject;
// Memory management
-var
-/** @type {!Int8Array} */
- HEAP8,
-/** @type {!Uint8Array} */
- HEAPU8,
-/** @type {!Int16Array} */
- HEAP16,
-/** @type {!Uint16Array} */
- HEAPU16,
-/** @type {!Int32Array} */
- HEAP32,
-/** @type {!Uint32Array} */
- HEAPU32,
-/** @type {!Float32Array} */
- HEAPF32,
-/** @type {!Float64Array} */
- HEAPF64;
-
-// BigInt64Array type is not correctly defined in closure
-var
-/** not-@type {!BigInt64Array} */
- HEAP64,
-/* BigUint64Array type is not correctly defined in closure
-/** not-@type {!BigUint64Array} */
- HEAPU64;
var runtimeInitialized = false;
@@ -430,11 +410,14 @@ function postRun() {
// End ATPOSTRUNS hooks
}
-/** @param {string|number=} what */
+/**
+ * @param {string|number=} what
+ * @noreturn
+ */
function abort(what) {
Module['onAbort']?.(what);
- what = 'Aborted(' + what + ')';
+ what = `Aborted(${what})`;
// TODO(sbc): Should we remove printing and leave it up to whoever
// catches the exception?
err(what);
@@ -605,6 +588,36 @@ async function createWasm() {
}
}
+ /** @type {!Int16Array} */
+ var HEAP16;
+
+ /** @type {!Int32Array} */
+ var HEAP32;
+
+ /** not-@type {!BigInt64Array} */
+ var HEAP64;
+
+ /** @type {!Int8Array} */
+ var HEAP8;
+
+ /** @type {!Float32Array} */
+ var HEAPF32;
+
+ /** @type {!Float64Array} */
+ var HEAPF64;
+
+ /** @type {!Uint16Array} */
+ var HEAPU16;
+
+ /** @type {!Uint32Array} */
+ var HEAPU32;
+
+ /** not-@type {!BigUint64Array} */
+ var HEAPU64;
+
+ /** @type {!Uint8Array} */
+ var HEAPU8;
+
var callRuntimeCallbacks = (callbacks) => {
while (callbacks.length > 0) {
// Pass the module as the first argument.
@@ -730,12 +743,9 @@ join2:(l, r) => PATH.normalize(l + '/' + r),
var initRandomFill = () => {
- return (view) => crypto.getRandomValues(view);
- };
-var randomFill = (view) => {
- // Lazily init on the first invocation.
- (randomFill = initRandomFill())(view);
+ return (view) => (crypto.getRandomValues(view), 0);
};
+var randomFill = (view) => (randomFill = initRandomFill())(view);
@@ -1131,11 +1141,14 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
} else if (FS.isFile(node.mode)) {
node.node_ops = MEMFS.ops_table.file.node;
node.stream_ops = MEMFS.ops_table.file.stream;
- node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
- // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
- // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
- // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
- node.contents = null;
+ // The actual number of bytes used in the typed array, as opposed to
+ // contents.length which gives the whole capacity.
+ node.usedBytes = 0;
+ // The byte data of the file is stored in a typed array.
+ // Note: typed arrays are not resizable like normal JS arrays are, so
+ // there is a small penalty involved for appending file writes that
+ // continuously grow a file similar to std::vector capacity vs used.
+ node.contents = MEMFS.emptyFileContents ??= new Uint8Array(0);
} else if (FS.isLink(node.mode)) {
node.node_ops = MEMFS.ops_table.link.node;
node.stream_ops = MEMFS.ops_table.link.stream;
@@ -1152,36 +1165,29 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return node;
},
getFileDataAsTypedArray(node) {
- if (!node.contents) return new Uint8Array(0);
- if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
- return new Uint8Array(node.contents);
+ return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
},
expandFileStorage(node, newCapacity) {
- var prevCapacity = node.contents ? node.contents.length : 0;
+ var prevCapacity = node.contents.length;
if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
- // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
- // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
- // avoid overshooting the allocation cap by a very large margin.
+ // Don't expand strictly to the given requested limit if it's only a very
+ // small increase, but instead geometrically grow capacity.
+ // For small filesizes (<1MB), perform size*2 geometric increase, but for
+ // large sizes, do a much more conservative size*1.125 increase to avoid
+ // overshooting the allocation cap by a very large margin.
var CAPACITY_DOUBLING_MAX = 1024 * 1024;
newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
- if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
- var oldContents = node.contents;
+ if (prevCapacity) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
+ var oldContents = MEMFS.getFileDataAsTypedArray(node);
node.contents = new Uint8Array(newCapacity); // Allocate new storage.
- if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
+ node.contents.set(oldContents);
},
resizeFileStorage(node, newSize) {
if (node.usedBytes == newSize) return;
- if (newSize == 0) {
- node.contents = null; // Fully decommit when requesting a resize to zero.
- node.usedBytes = 0;
- } else {
- var oldContents = node.contents;
- node.contents = new Uint8Array(newSize); // Allocate new storage.
- if (oldContents) {
- node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
- }
- node.usedBytes = newSize;
- }
+ var oldContents = node.contents;
+ node.contents = new Uint8Array(newSize); // Allocate new storage.
+ node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
+ node.usedBytes = newSize;
},
node_ops:{
getattr(node) {
@@ -1287,11 +1293,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var contents = stream.node.contents;
if (position >= stream.node.usedBytes) return 0;
var size = Math.min(stream.node.usedBytes - position, length);
- if (size > 8 && contents.subarray) { // non-trivial, and typed array
- buffer.set(contents.subarray(position, position + size), offset);
- } else {
- for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
- }
+ buffer.set(contents.subarray(position, position + size), offset);
return size;
},
write(stream, buffer, offset, length, position, canOwn) {
@@ -1307,32 +1309,18 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var node = stream.node;
node.mtime = node.ctime = Date.now();
- if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
- if (canOwn) {
- node.contents = buffer.subarray(offset, offset + length);
- node.usedBytes = length;
- return length;
- } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
- node.contents = buffer.slice(offset, offset + length);
- node.usedBytes = length;
- return length;
- } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
- node.contents.set(buffer.subarray(offset, offset + length), position);
- return length;
- }
- }
-
- // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
- MEMFS.expandFileStorage(node, position+length);
- if (node.contents.subarray && buffer.subarray) {
+ if (canOwn) {
+ node.contents = buffer.subarray(offset, offset + length);
+ node.usedBytes = length;
+ } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
+ node.contents = buffer.slice(offset, offset + length);
+ node.usedBytes = length;
+ } else {
+ MEMFS.expandFileStorage(node, position+length);
// Use typed array write which is available.
node.contents.set(buffer.subarray(offset, offset + length), position);
- } else {
- for (var i = 0; i < length; i++) {
- node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
- }
+ node.usedBytes = Math.max(node.usedBytes, position + length);
}
- node.usedBytes = Math.max(node.usedBytes, position + length);
return length;
},
llseek(stream, offset, whence) {
@@ -1357,7 +1345,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var allocated;
var contents = stream.node.contents;
// Only make a new copy when MAP_PRIVATE is specified.
- if (!(flags & 2) && contents && contents.buffer === HEAP8.buffer) {
+ if (!(flags & 2) && contents.buffer === HEAP8.buffer) {
// We can't emulate MAP_SHARED when the file is not backed by the
// buffer we're mapping to (e.g. the HEAP buffer).
allocated = false;
@@ -1391,6 +1379,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
};
var FS_modeStringToFlags = (str) => {
+ if (typeof str != 'string') return str;
var flagModes = {
'r': 0,
'r+': 2,
@@ -1406,6 +1395,16 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
return flags;
};
+ var FS_fileDataToTypedArray = (data) => {
+ if (typeof data == 'string') {
+ data = intArrayFromString(data, true);
+ }
+ if (!data.subarray) {
+ data = new Uint8Array(data);
+ }
+ return data;
+ };
+
var FS_getMode = (canRead, canWrite) => {
var mode = 0;
if (canRead) mode |= 292 | 73;
@@ -1503,8 +1502,6 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
ignorePermissions:true,
filesystems:null,
syncFSRequests:0,
- readFiles:{
- },
ErrnoError:class {
name = 'ErrnoError';
// We set the `name` property to be able to identify `FS.ErrnoError`
@@ -1770,9 +1767,11 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
// return 0 if any user, group or owner bits are set.
if (perms.includes('r') && !(node.mode & 292)) {
return 2;
- } else if (perms.includes('w') && !(node.mode & 146)) {
+ }
+ if (perms.includes('w') && !(node.mode & 146)) {
return 2;
- } else if (perms.includes('x') && !(node.mode & 73)) {
+ }
+ if (perms.includes('x') && !(node.mode & 73)) {
return 2;
}
return 0;
@@ -1813,10 +1812,8 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
return 10;
}
- } else {
- if (FS.isDir(node.mode)) {
- return 31;
- }
+ } else if (FS.isDir(node.mode)) {
+ return 31;
}
return 0;
},
@@ -1826,13 +1823,16 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
}
if (FS.isLink(node.mode)) {
return 32;
- } else if (FS.isDir(node.mode)) {
- if (FS.flagsToPermissionString(flags) !== 'r' // opening for write
- || (flags & (512 | 64))) { // TODO: check for O_SEARCH? (== search for dir only)
+ }
+ var mode = FS.flagsToPermissionString(flags);
+ if (FS.isDir(node.mode)) {
+ // opening for write
+ // TODO: check for O_SEARCH? (== search for dir only)
+ if (mode !== 'r' || (flags & (512 | 64))) {
return 31;
}
}
- return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+ return FS.nodePermissions(node, mode);
},
checkOpExists(op, err) {
if (!op) {
@@ -2400,7 +2400,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (path === "") {
throw new FS.ErrnoError(44);
}
- flags = typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
+ flags = FS_modeStringToFlags(flags);
if ((flags & 64)) {
mode = (mode & 4095) | 32768;
} else {
@@ -2487,11 +2487,6 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
if (created) {
FS.chmod(node, mode & 0o777);
}
- if (Module['logReadFiles'] && !(flags & 1)) {
- if (!(path in FS.readFiles)) {
- FS.readFiles[path] = 1;
- }
- }
return stream;
},
close(stream) {
@@ -2638,14 +2633,8 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
writeFile(path, data, opts = {}) {
opts.flags = opts.flags || 577;
var stream = FS.open(path, opts.flags, opts.mode);
- if (typeof data == 'string') {
- data = new Uint8Array(intArrayFromString(data, true));
- }
- if (ArrayBuffer.isView(data)) {
- FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
- } else {
- abort('Unsupported data type');
- }
+ data = FS_fileDataToTypedArray(data);
+ FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
FS.close(stream);
},
cwd:() => FS.currentPath,
@@ -2865,11 +2854,7 @@ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
var mode = FS_getMode(canRead, canWrite);
var node = FS.create(path, mode);
if (data) {
- if (typeof data == 'string') {
- var arr = new Array(data.length);
- for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
- data = arr;
- }
+ data = FS_fileDataToTypedArray(data);
// make sure we can write to the file
FS.chmod(node, mode | 146);
var stream = FS.open(node, 577);
@@ -4193,6 +4178,7 @@ var _sqlite3_status64,
_sqlite3_bind_null,
_sqlite3_bind_pointer,
_sqlite3_bind_text,
+ _sqlite3_bind_zeroblob,
_sqlite3_bind_parameter_count,
_sqlite3_bind_parameter_name,
_sqlite3_bind_parameter_index,
@@ -4456,6 +4442,7 @@ function assignWasmExports(wasmExports) {
_sqlite3_bind_null = Module['_sqlite3_bind_null'] = wasmExports['sqlite3_bind_null'];
_sqlite3_bind_pointer = Module['_sqlite3_bind_pointer'] = wasmExports['sqlite3_bind_pointer'];
_sqlite3_bind_text = Module['_sqlite3_bind_text'] = wasmExports['sqlite3_bind_text'];
+ _sqlite3_bind_zeroblob = Module['_sqlite3_bind_zeroblob'] = wasmExports['sqlite3_bind_zeroblob'];
_sqlite3_bind_parameter_count = Module['_sqlite3_bind_parameter_count'] = wasmExports['sqlite3_bind_parameter_count'];
_sqlite3_bind_parameter_name = Module['_sqlite3_bind_parameter_name'] = wasmExports['sqlite3_bind_parameter_name'];
_sqlite3_bind_parameter_index = Module['_sqlite3_bind_parameter_index'] = wasmExports['sqlite3_bind_parameter_index'];
@@ -4800,6 +4787,7 @@ Module.runSQLite3PostLoadInit = async function(
- sqlite3-vtab-helper.c-pp.js => Utilities for virtual table impls
- sqlite3-vfs-opfs.c-pp.js => OPFS VFS
- sqlite3-vfs-opfs-sahpool.c-pp.js => OPFS SAHPool VFS
+ - sqlite3-vfs-opfs-wl.c-pp.js => WebLock-using OPFS VFS
- post-js-footer.js => this file's epilogue
And all of that gets sandwiched between extern-pre-js.js and
@@ -4834,11 +4822,11 @@ Module.runSQLite3PostLoadInit = async function(
/* @preserve
** This code was built from sqlite3 version...
**
-** SQLITE_VERSION "3.52.0"
-** SQLITE_VERSION_NUMBER 3052000
-** SQLITE_SOURCE_ID "2026-01-30 06:37:34 407724c4e80efdf93d885e95b5209a100a3f470fe0298138be57201f65f9817e"
+** SQLITE_VERSION "3.53.0"
+** SQLITE_VERSION_NUMBER 3053000
+** SQLITE_SOURCE_ID "2026-04-09 11:41:38 4525003a53a7fc63ca75c59b22c79608659ca12f0131f52c18637f829977f20b"
**
-** Emscripten SDK: 5.0.0
+** Emscripten SDK: 5.0.5
*/
/*
2022-05-22
@@ -4941,6 +4929,13 @@ Module.runSQLite3PostLoadInit = async function(
used in WASMFS-capable builds of the library (which the canonical
builds do not include).
+ - `disable` (as of 3.53.0) may be an object with the following
+ properties:
+ - `vfs`, an object, may contain a map of VFS names to booleans.
+ Any mapping to falsy are disabled. The supported names
+ are: "kvvfs", "opfs", "opfs-sahpool", "opfs-wl".
+ - Other disabling options may be added in the future.
+
[^1] = This property may optionally be a function, in which case
this function calls that function to fetch the value,
enabling delayed evaluation.
@@ -4987,7 +4982,8 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
);
return sqlite3ApiBootstrap.sqlite3;
}
- const config = Object.assign(Object.create(null),{
+ const nu = (...obj)=>Object.assign(Object.create(null),...obj);
+ const config = nu({
exports: undefined,
memory: undefined,
bigIntEnabled: !!globalThis.BigInt64Array,
@@ -5004,7 +5000,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
certain wasm.xWrap.resultAdapter()s.
*/
useStdAlloc: false
- }, apiConfig || {});
+ }, apiConfig);
Object.assign(config, {
allocExportName: config.useStdAlloc ? 'malloc' : 'sqlite3_malloc',
@@ -5037,7 +5033,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
not documented are installed as 1-to-1 proxies for their
C-side counterparts.
*/
- const capi = Object.create(null);
+ const capi = nu();
/**
Holds state which are specific to the WASM-related
infrastructure and glue code.
@@ -5046,7 +5042,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
dynamically after the api object is fully constructed, so
not all are documented in this file.
*/
- const wasm = Object.create(null);
+ const wasm = nu();
/** Internal helper for SQLite3Error ctor. */
const __rcStr = (rc)=>{
@@ -5594,6 +5590,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
toss: function(...args){throw new Error(args.join(' '))},
toss3,
typedArrayPart: wasm.typedArrayPart,
+ nu,
assert: function(arg,msg){
if( !arg ){
util.toss("Assertion failed:",msg);
@@ -5850,7 +5847,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
rv[1] = m ? (f._rxInt.test(m[2]) ? +m[2] : m[2]) : true;
};
}
- const rc = Object.create(null), ov = [0,0];
+ const rc = nu(), ov = [0,0];
let i = 0, k;
while((k = capi.sqlite3_compileoption_get(i++))){
f._opt(k,ov);
@@ -5858,7 +5855,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
}
return f._result = rc;
}else if(Array.isArray(optName)){
- const rc = Object.create(null);
+ const rc = nu();
optName.forEach((v)=>{
rc[v] = capi.sqlite3_compileoption_used(v);
});
@@ -5909,7 +5906,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
The memory lives in the WASM heap and can be used with routines
such as wasm.poke() and wasm.heap8u().slice().
*/
- wasm.pstack = Object.assign(Object.create(null),{
+ wasm.pstack = nu({
/**
Sets the current pstack position to the given pointer. Results
are undefined if the passed-in value did not come from
@@ -6131,7 +6128,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
// sqlite3__wasm_init_wasmfs() is not available
return this.dir = "";
}
- }.bind(Object.create(null));
+ }.bind(nu());
/**
Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
@@ -6485,6 +6482,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
case capi.SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE:
case capi.SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE:
case capi.SQLITE_DBCONFIG_ENABLE_COMMENTS:
+ case capi.SQLITE_DBCONFIG_FP_DIGITS:
if( !this.ip ){
this.ip = wasm.xWrap('sqlite3__wasm_db_config_ip','int',
['sqlite3*', 'int', 'int', '*']);
@@ -6506,7 +6504,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
default:
return capi.SQLITE_MISUSE;
}
- }.bind(Object.create(null));
+ }.bind(nu());
/**
Given a (sqlite3_value*), this function attempts to convert it
@@ -6740,7 +6738,7 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
const pv = wasm.peekPtr(this.ptr);
return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
- }.bind(Object.create(null));
+ }.bind(nu());
/**
A wrapper around sqlite3_preupdate_new() which fetches the
@@ -6780,6 +6778,62 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
'sqlite3changeset_old');
}/*changeset/preupdate additions*/
+ /**
+ EXPERIMENTAL. For tentative addition in 3.53.0.
+
+ sqlite3_js_retry_busy(maxTimes,callback[,beforeRetry])
+
+ Calls the given _synchronous_ callback function. If that function
+ returns sqlite3.capi.SQLITE_BUSY _or_ throws an SQLite3Error
+ with a resultCode property of that value then it will suppress
+ that error and try again, up to the given maximum number of
+ times. If the callback returns any other value than that,
+ it is returned. If the maximum number of retries has been
+ reached, an SQLite3Error with a resultCode value of
+ sqlite3.capi.SQLITE_BUSY is thrown. If the callback throws any
+ exception other than the aforementioned BUSY exception, it is
+ propagated. If it throws a BUSY exception on its final attempt,
+ that is propagated as well.
+
+ If the beforeRetry argument is given, it must be a _synchronous_
+ function. It is called immediately before each retry of the
+ callback (not for the initial call), passed the attempt number
+ (so it starts with 2, not 1). If it throws, the exception is
+ handled as described above. Its result value is ignored.
+
+ To effectively retry "forever", pass a negative maxTimes value,
+ with the caveat that there is no recovery from that unless the
+ beforeRetry() can figure out when to throw.
+
+ TODO: an async variant of this.
+ */
+ capi.sqlite3_js_retry_busy = function(maxTimes, callback, beforeRetry){
+ for(let n = 1; n <= maxTimes; ++n){
+ try{
+ if( beforeRetry && n>1 ) beforeRetry(n);
+ const rc = callback();
+ if( capi.SQLITE_BUSY===rc ){
+ if( n===maxTimes ){
+ throw new SQLite3Error(rc, [
+ "sqlite3_js_retry_busy() max retry attempts (",
+ maxTimes,
+ ") reached."
+ ].join(''));
+ }
+ continue;
+ }
+ return rc;
+ }catch(e){
+ if( n{};
const debug = sqlite3.__isUnderTest
- ? (...args)=>sqlite3.config.debug("kvvfs:", ...args)
+ ? (...args)=>sqlite3.config.debug?.("kvvfs:", ...args)
: noop;
- const warn = (...args)=>sqlite3.config.warn("kvvfs:", ...args);
- const error = (...args)=>sqlite3.config.error("kvvfs:", ...args);
+ const warn = (...args)=>sqlite3.config.warn?.("kvvfs:", ...args);
+ const error = (...args)=>sqlite3.config.error?.("kvvfs:", ...args);
/**
Implementation of JS's Storage interface for use as backing store
@@ -16270,17 +16331,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
and recreating it whenever a property index might be invalidated.
*/
class KVVfsStorage {
- #map;
- #keys;
- #getKeys(){return this.#keys ??= Object.keys(this.#map);}
+ #map = Object.create(null);
+ #keys = null;
+ #size = 0;
constructor(){
this.clear();
}
+ #getKeys(){
+ return this.#keys ??= Object.keys(this.#map);
+ }
+
key(n){
- const k = this.#getKeys();
- return n= this.#size) return null;
+ return this.#getKeys()[n];
}
getItem(k){
@@ -16288,14 +16353,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
setItem(k,v){
- if( !hop(this.#map, k) ){
+ if( !(k in this.#map) ){
+ ++this.#size;
this.#keys = null;
}
this.#map[k] = ''+v;
}
removeItem(k){
- if( delete this.#map[k] ){
+ if( k in this.#map ){
+ delete this.#map[k];
+ --this.#size;
this.#keys = null;
}
}
@@ -16303,10 +16371,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
clear(){
this.#map = Object.create(null);
this.#keys = null;
+ this.#size = 0;
}
get length() {
- return this.#getKeys().length;
+ return this.#size;
}
}/*KVVfsStorage*/;
@@ -17068,36 +17137,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
},
- // We override xRead/xWrite only for logging/debugging. They
- // should otherwise be disabled (it's faster that way).
- xRead: function(pFile,pTgt,n,iOff64){
- cache.popError();
- try{
- if( kvvfs?.log?.xRead ){
- const h = pFileHandles.get(pFile);
- util.assert(h, "Missing KVVfsFile handle");
- debug("xRead", n, iOff64, h);
- }
- return originalMethods.ioDb.xRead(pFile, pTgt, n, iOff64);
- }catch(e){
- error("xRead",e);
- return cache.setError(e);
- }
- },
- xWrite: function(pFile,pSrc,n,iOff64){
- cache.popError();
- try{
- if( kvvfs?.log?.xWrite ){
- const h = pFileHandles.get(pFile);
- util.assert(h, "Missing KVVfsFile handle");
- debug("xWrite", n, iOff64, h);
- }
- return originalMethods.ioDb.xWrite(pFile, pSrc, n, iOff64);
- }catch(e){
- error("xWrite",e);
- return cache.setError(e);
- }
- },
}/*.ioDb*/,
@@ -17109,9 +17148,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/*.ioJrnl*/
}/*methodOverrides*/;
- debug("pVfs and friends", pVfs, pIoDb, pIoJrnl,
- kvvfsMethods, capi.sqlite3_file.structInfo,
- KVVfsFile.structInfo);
+
try {
util.assert( cache.buffer.n>1024*129, "Heap buffer is not large enough"
/* Native is SQLITE_KVOS_SZ is 133073 as of this writing */ );
@@ -17200,7 +17237,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
limitation which has since been overcome, but removal of
JsStorageDb.prototype.clearStorage() would be a backwards compatibility
break, so this function permits wiping the storage for those two
- cases even if they are opened. Use with case.
+ cases even if they are opened. Use with care.
*/
const sqlite3_js_kvvfs_clear = function callee(which){
if( ''===which ){
@@ -17875,7 +17912,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
return rc;
}catch(e){
- return VT.xErrror('xConnect', e, capi.SQLITE_ERROR);
+ return VT.xError('xConnect', e, capi.SQLITE_ERROR);
}
},
xCreate: wasm.ptr.null, // eponymous only
@@ -17974,7 +18011,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
})/*globalThis.sqlite3ApiBootstrap.initializers*/;
/*
- 2022-09-18
+ 2026-03-04
The author disclaims copyright to this source code. In place of a
legal notice, here is a blessing:
@@ -17985,283 +18022,584 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
***********************************************************************
- This file holds the synchronous half of an sqlite3_vfs
- implementation which proxies, in a synchronous fashion, the
- asynchronous Origin-Private FileSystem (OPFS) APIs using a second
- Worker, implemented in sqlite3-opfs-async-proxy.js. This file is
- intended to be appended to the main sqlite3 JS deliverable somewhere
- after sqlite3-api-oo1.js.
+ This file holds code shared by sqlite3-vfs-opfs{,-wl}.c-pp.js. It
+ creates a private/internal sqlite3.opfs namespace common to the two
+ and used (only) by them and the test framework. It is not part of
+ the public API. The library deletes sqlite3.opfs in its final
+ bootstrapping steps unless it's specifically told to keep them (for
+ testing purposes only) using an undocumented and unsupported
+ mechanism.
*/
-'use strict';
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
-/**
- installOpfsVfs() returns a Promise which, on success, installs an
- sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
- which accept a VFS. It is intended to be called via
- sqlite3ApiBootstrap.initializers or an equivalent mechanism.
-
- The installed VFS uses the Origin-Private FileSystem API for
- all file storage. On error it is rejected with an exception
- explaining the problem. Reasons for rejection include, but are
- not limited to:
+ 'use strict';
+ if( sqlite3.config.disable?.vfs?.opfs &&
+ sqlite3.config.disable.vfs['opfs-vfs'] ){
+ return;
+ }
+ const toss = sqlite3.util.toss,
+ capi = sqlite3.capi,
+ util = sqlite3.util,
+ wasm = sqlite3.wasm;
- - The counterpart Worker (see below) could not be loaded.
+ /**
+ Generic utilities for working with OPFS. This will get filled out
+ by the Promise setup and, on success, installed as sqlite3.opfs.
- - The environment does not support OPFS. That includes when
- this function is called from the main window thread.
+ This is an internal/private namespace intended for use solely by
+ the OPFS VFSes and test code for them. The library bootstrapping
+ process removes this object in non-testing contexts.
+ */
+ const opfsUtil = sqlite3.opfs = Object.create(null);
- Significant notes and limitations:
+ /**
+ Returns true if _this_ thread has access to the OPFS APIs.
+ */
+ opfsUtil.thisThreadHasOPFS = ()=>{
+ return globalThis.FileSystemHandle &&
+ globalThis.FileSystemDirectoryHandle &&
+ globalThis.FileSystemFileHandle &&
+ globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle &&
+ navigator?.storage?.getDirectory;
+ };
- - The OPFS features used here are only available in dedicated Worker
- threads. This file tries to detect that case, resulting in a
- rejected Promise if those features do not seem to be available.
+ /**
+ Must be called by the OPFS VFSes immediately after they determine
+ whether OPFS is available by calling
+ thisThreadHasOPFS(). Resolves to the OPFS storage root directory
+ and sets opfsUtil.rootDirectory to that value.
+ */
+ opfsUtil.getRootDir = async function f(){
+ return f.promise ??= navigator.storage.getDirectory().then(d=>{
+ opfsUtil.rootDirectory = d;
+ return d;
+ }).catch(e=>{
+ delete f.promise;
+ throw e;
+ });
+ };
- - It requires the SharedArrayBuffer and Atomics classes, and the
- former is only available if the HTTP server emits the so-called
- COOP and COEP response headers. These features are required for
- proxying OPFS's synchronous API via the synchronous interface
- required by the sqlite3_vfs API.
+ /**
+ Expects an OPFS file path. It gets resolved, such that ".."
+ components are properly expanded, and returned. If the 2nd arg
+ is true, the result is returned as an array of path elements,
+ else an absolute path string is returned.
+ */
+ opfsUtil.getResolvedPath = function(filename,splitIt){
+ const p = new URL(filename, "file://irrelevant").pathname;
+ return splitIt ? p.split('/').filter((v)=>!!v) : p;
+ };
- - This function may only be called a single time. When called, this
- function removes itself from the sqlite3 object.
+ /**
+ Takes the absolute path to a filesystem element. Returns an
+ array of [handleOfContainingDir, filename]. If the 2nd argument
+ is truthy then each directory element leading to the file is
+ created along the way. Throws if any creation or resolution
+ fails.
+ */
+ opfsUtil.getDirForFilename = async function f(absFilename, createDirs = false){
+ const path = opfsUtil.getResolvedPath(absFilename, true);
+ const filename = path.pop();
+ let dh = await opfsUtil.getRootDir();
+ for(const dirName of path){
+ if(dirName){
+ dh = await dh.getDirectoryHandle(dirName, {create: !!createDirs});
+ }
+ }
+ return [dh, filename];
+ };
- All arguments to this function are for internal/development purposes
- only. They do not constitute a public API and may change at any
- time.
+ /**
+ Creates the given directory name, recursively, in
+ the OPFS filesystem. Returns true if it succeeds or the
+ directory already exists, else false.
+ */
+ opfsUtil.mkdir = async function(absDirName){
+ try {
+ await opfsUtil.getDirForFilename(absDirName+"/filepart", true);
+ return true;
+ }catch(e){
+ //sqlite3.config.warn("mkdir(",absDirName,") failed:",e);
+ return false;
+ }
+ };
- The argument may optionally be a plain object with the following
- configuration options:
+ /**
+ Checks whether the given OPFS filesystem entry exists,
+ returning true if it does, false if it doesn't or if an
+ exception is intercepted while trying to make the
+ determination.
+ */
+ opfsUtil.entryExists = async function(fsEntryName){
+ try {
+ const [dh, fn] = await opfsUtil.getDirForFilename(fsEntryName);
+ await dh.getFileHandle(fn);
+ return true;
+ }catch(e){
+ return false;
+ }
+ };
- - proxyUri: name of the async proxy JS file.
+ /**
+ Generates a random ASCII string len characters long, intended for
+ use as a temporary file name.
+ */
+ opfsUtil.randomFilename = function f(len=16){
+ if(!f._chars){
+ f._chars = "abcdefghijklmnopqrstuvwxyz"+
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
+ "012346789";
+ f._n = f._chars.length;
+ }
+ const a = [];
+ let i = 0;
+ for( ; i < len; ++i){
+ const ndx = Math.random() * (f._n * 64) % f._n | 0;
+ a[i] = f._chars[ndx];
+ }
+ return a.join("");
+ /*
+ An alternative impl. with an unpredictable length
+ but much simpler:
- - verbose (=2): an integer 0-3. 0 disables all logging, 1 enables
- logging of errors. 2 enables logging of warnings and errors. 3
- additionally enables debugging info. Logging is performed
- via the sqlite3.config.{log|warn|error}() functions.
+ Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36)
+ */
+ };
- - sanityChecks (=false): if true, some basic sanity tests are run on
- the OPFS VFS API after it's initialized, before the returned
- Promise resolves. This is only intended for testing and
- development of the VFS, not client-side use.
+ /**
+ Returns a promise which resolves to an object which represents
+ all files and directories in the OPFS tree. The top-most object
+ has two properties: `dirs` is an array of directory entries
+ (described below) and `files` is a list of file names for all
+ files in that directory.
- On success, the Promise resolves to the top-most sqlite3 namespace
- object and that object gets a new object installed in its
- `opfs` property, containing several OPFS-specific utilities.
-*/
-const installOpfsVfs = function callee(options){
- if(!globalThis.SharedArrayBuffer
- || !globalThis.Atomics){
- return Promise.reject(
- new Error("Cannot install OPFS: Missing SharedArrayBuffer and/or Atomics. "+
- "The server must emit the COOP/COEP response headers to enable those. "+
- "See https://sqlite.org/wasm/doc/trunk/persistence.md#coop-coep")
- );
- }else if('undefined'===typeof WorkerGlobalScope){
- return Promise.reject(
- new Error("The OPFS sqlite3_vfs cannot run in the main thread "+
- "because it requires Atomics.wait().")
- );
- }else if(!globalThis.FileSystemHandle ||
- !globalThis.FileSystemDirectoryHandle ||
- !globalThis.FileSystemFileHandle ||
- !globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle ||
- !navigator?.storage?.getDirectory){
- return Promise.reject(
- new Error("Missing required OPFS APIs.")
- );
- }
- if(!options || 'object'!==typeof options){
- options = Object.create(null);
- }
- const urlParams = new URL(globalThis.location.href).searchParams;
- if(urlParams.has('opfs-disable')){
- //sqlite3.config.warn('Explicitly not installing "opfs" VFS due to opfs-disable flag.');
- return Promise.resolve(sqlite3);
- }
- if(undefined===options.verbose){
- options.verbose = urlParams.has('opfs-verbose')
- ? (+urlParams.get('opfs-verbose') || 2) : 1;
- }
- if(undefined===options.sanityChecks){
- options.sanityChecks = urlParams.has('opfs-sanity-check');
- }
- if(undefined===options.proxyUri){
- options.proxyUri = callee.defaultProxyUri;
- }
+ Traversal starts at sqlite3.opfs.rootDirectory.
- //sqlite3.config.warn("OPFS options =",options,globalThis.location);
+ Each `dirs` entry is an object in this form:
- if('function' === typeof options.proxyUri){
- options.proxyUri = options.proxyUri();
- }
- const thePromise = new Promise(function(promiseResolve_, promiseReject_){
- const loggers = [
- sqlite3.config.error,
- sqlite3.config.warn,
- sqlite3.config.log
- ];
- const logImpl = (level,...args)=>{
- if(options.verbose>level) loggers[level]("OPFS syncer:",...args);
- };
- const log = (...args)=>logImpl(2, ...args);
- const warn = (...args)=>logImpl(1, ...args);
- const error = (...args)=>logImpl(0, ...args);
- const toss = sqlite3.util.toss;
- const capi = sqlite3.capi;
- const util = sqlite3.util;
- const wasm = sqlite3.wasm;
- const sqlite3_vfs = capi.sqlite3_vfs;
- const sqlite3_file = capi.sqlite3_file;
- const sqlite3_io_methods = capi.sqlite3_io_methods;
- /**
- Generic utilities for working with OPFS. This will get filled out
- by the Promise setup and, on success, installed as sqlite3.opfs.
+ ```
+ { name: directoryName,
+ dirs: [...subdirs],
+ files: [...file names]
+ }
+ ```
- ACHTUNG: do not rely on these APIs in client code. They are
- experimental and subject to change or removal as the
- OPFS-specific sqlite3_vfs evolves.
- */
- const opfsUtil = Object.create(null);
+ The `files` and `subdirs` entries are always set but may be
+ empty arrays.
- /**
- Returns true if _this_ thread has access to the OPFS APIs.
- */
- const thisThreadHasOPFS = ()=>{
- return globalThis.FileSystemHandle &&
- globalThis.FileSystemDirectoryHandle &&
- globalThis.FileSystemFileHandle &&
- globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle &&
- navigator?.storage?.getDirectory;
- };
+ The returned object has the same structure but its `name` is
+ an empty string. All returned objects are created with
+ Object.create(null), so have no prototype.
- /**
- Not part of the public API. Solely for internal/development
- use.
- */
- opfsUtil.metrics = {
- dump: function(){
- let k, n = 0, t = 0, w = 0;
- for(k in state.opIds){
- const m = metrics[k];
- n += m.count;
- t += m.time;
- w += m.wait;
- m.avgTime = (m.count && m.time) ? (m.time / m.count) : 0;
- m.avgWait = (m.count && m.wait) ? (m.wait / m.count) : 0;
- }
- sqlite3.config.log(globalThis.location.href,
- "metrics for",globalThis.location.href,":",metrics,
- "\nTotal of",n,"op(s) for",t,
- "ms (incl. "+w+" ms of waiting on the async side)");
- sqlite3.config.log("Serialization metrics:",metrics.s11n);
- W.postMessage({type:'opfs-async-metrics'});
- },
- reset: function(){
- let k;
- const r = (m)=>(m.count = m.time = m.wait = 0);
- for(k in state.opIds){
- r(metrics[k] = Object.create(null));
+ Design note: the entries do not contain more information,
+ e.g. file sizes, because getting such info is not only
+ expensive but is subject to locking-related errors.
+ */
+ opfsUtil.treeList = async function(){
+ const doDir = async function callee(dirHandle,tgt){
+ tgt.name = dirHandle.name;
+ tgt.dirs = [];
+ tgt.files = [];
+ for await (const handle of dirHandle.values()){
+ if('directory' === handle.kind){
+ const subDir = Object.create(null);
+ tgt.dirs.push(subDir);
+ await callee(handle, subDir);
+ }else{
+ tgt.files.push(handle.name);
}
- let s = metrics.s11n = Object.create(null);
- s = s.serialize = Object.create(null);
- s.count = s.time = 0;
- s = metrics.s11n.deserialize = Object.create(null);
- s.count = s.time = 0;
}
- }/*metrics*/;
- const opfsIoMethods = new sqlite3_io_methods();
- const opfsVfs = new sqlite3_vfs()
- .addOnDispose( ()=>opfsIoMethods.dispose());
- let promiseWasRejected = undefined;
- const promiseReject = (err)=>{
- promiseWasRejected = true;
- opfsVfs.dispose();
- return promiseReject_(err);
};
- const promiseResolve = ()=>{
- promiseWasRejected = false;
- return promiseResolve_(sqlite3);
+ const root = Object.create(null);
+ const dir = await opfsUtil.getRootDir();
+ await doDir(dir, root);
+ return root;
+ };
+
+ /**
+ Irrevocably deletes _all_ files in the current origin's OPFS.
+ Obviously, this must be used with great caution. It may throw
+ an exception if removal of anything fails (e.g. a file is
+ locked), but the precise conditions under which the underlying
+ APIs will throw are not documented (so we cannot tell you what
+ they are).
+ */
+ opfsUtil.rmfr = async function(){
+ const rd = await opfsUtil.getRootDir();
+ const dir = rd, opt = {recurse: true};
+ for await (const handle of dir.values()){
+ dir.removeEntry(handle.name, opt);
+ }
+ };
+
+ /**
+ Deletes the given OPFS filesystem entry. As this environment
+ has no notion of "current directory", the given name must be an
+ absolute path. If the 2nd argument is truthy, deletion is
+ recursive (use with caution!).
+
+ The returned Promise resolves to true if the deletion was
+ successful, else false (but...). The OPFS API reports the
+ reason for the failure only in human-readable form, not
+ exceptions which can be type-checked to determine the
+ failure. Because of that...
+
+ If the final argument is truthy then this function will
+ propagate any exception on error, rather than returning false.
+ */
+ opfsUtil.unlink = async function(fsEntryName, recursive = false,
+ throwOnError = false){
+ try {
+ const [hDir, filenamePart] =
+ await opfsUtil.getDirForFilename(fsEntryName, false);
+ await hDir.removeEntry(filenamePart, {recursive});
+ return true;
+ }catch(e){
+ if(throwOnError){
+ throw new Error("unlink(",arguments[0],") failed: "+e.message,{
+ cause: e
+ });
+ }
+ return false;
+ }
+ };
+
+ /**
+ Traverses the OPFS filesystem, calling a callback for each
+ entry. The argument may be either a callback function or an
+ options object with any of the following properties:
+
+ - `callback`: function which gets called for each filesystem
+ entry. It gets passed 3 arguments: 1) the
+ FileSystemFileHandle or FileSystemDirectoryHandle of each
+ entry (noting that both are instanceof FileSystemHandle). 2)
+ the FileSystemDirectoryHandle of the parent directory. 3) the
+ current depth level, with 0 being at the top of the tree
+ relative to the starting directory. If the callback returns a
+ literal false, as opposed to any other falsy value, traversal
+ stops without an error. Any exceptions it throws are
+ propagated. Results are undefined if the callback manipulate
+ the filesystem (e.g. removing or adding entries) because the
+ how OPFS iterators behave in the face of such changes is
+ undocumented.
+
+ - `recursive` [bool=true]: specifies whether to recurse into
+ subdirectories or not. Whether recursion is depth-first or
+ breadth-first is unspecified!
+
+ - `directory` [FileSystemDirectoryEntry=sqlite3.opfs.rootDirectory]
+ specifies the starting directory.
+
+ If this function is passed a function, it is assumed to be the
+ callback.
+
+ Returns a promise because it has to (by virtue of being async)
+ but that promise has no specific meaning: the traversal it
+ performs is synchronous. The promise must be used to catch any
+ exceptions propagated by the callback, however.
+ */
+ opfsUtil.traverse = async function(opt){
+ const defaultOpt = {
+ recursive: true,
+ directory: await opfsUtil.getRootDir()
};
- const W =
- new Worker(new URL(options.proxyUri, import.meta.url));
- setTimeout(()=>{
- /* At attempt to work around a browser-specific quirk in which
- the Worker load is failing in such a way that we neither
- resolve nor reject it. This workaround gives that resolve/reject
- a time limit and rejects if that timer expires. Discussion:
- https://sqlite.org/forum/forumpost/a708c98dcb3ef */
- if(undefined===promiseWasRejected){
- promiseReject(
- new Error("Timeout while waiting for OPFS async proxy worker.")
- );
+ if('function'===typeof opt){
+ opt = {callback:opt};
+ }
+ opt = Object.assign(defaultOpt, opt||{});
+ const doDir = async function callee(dirHandle, depth){
+ for await (const handle of dirHandle.values()){
+ if(false === opt.callback(handle, dirHandle, depth)) return false;
+ else if(opt.recursive && 'directory' === handle.kind){
+ if(false === await callee(handle, depth + 1)) break;
+ }
}
- }, 4000);
- W._originalOnError = W.onerror /* will be restored later */;
- W.onerror = function(err){
- // The error object doesn't contain any useful info when the
- // failure is, e.g., that the remote script is 404.
- error("Error initializing OPFS asyncer:",err);
- promiseReject(new Error("Loading OPFS async Worker failed for unknown reasons."));
};
- const pDVfs = capi.sqlite3_vfs_find(null)/*pointer to default VFS*/;
- const dVfs = pDVfs
- ? new sqlite3_vfs(pDVfs)
- : null /* dVfs will be null when sqlite3 is built with
- SQLITE_OS_OTHER. */;
+ doDir(opt.directory, 0);
+ };
+
+ /**
+ Impl of opfsUtil.importDb() when it's given a function as its
+ second argument.
+ */
+ const importDbChunked = async function(filename, callback){
+ const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true);
+ const hFile = await hDir.getFileHandle(fnamePart, {create:true});
+ let sah = await hFile.createSyncAccessHandle();
+ let nWrote = 0, chunk, checkedHeader = false, err = false;
+ try{
+ sah.truncate(0);
+ while( undefined !== (chunk = await callback()) ){
+ if(chunk instanceof ArrayBuffer) chunk = new Uint8Array(chunk);
+ if( !checkedHeader && 0===nWrote && chunk.byteLength>=15 ){
+ util.affirmDbHeader(chunk);
+ checkedHeader = true;
+ }
+ sah.write(chunk, {at: nWrote});
+ nWrote += chunk.byteLength;
+ }
+ if( nWrote < 512 || 0!==nWrote % 512 ){
+ toss("Input size",nWrote,"is not correct for an SQLite database.");
+ }
+ if( !checkedHeader ){
+ const header = new Uint8Array(20);
+ sah.read( header, {at: 0} );
+ util.affirmDbHeader( header );
+ }
+ sah.write(new Uint8Array([1,1]), {at: 18}/*force db out of WAL mode*/);
+ return nWrote;
+ }catch(e){
+ await sah.close();
+ sah = undefined;
+ await hDir.removeEntry( fnamePart ).catch(()=>{});
+ throw e;
+ }finally {
+ if( sah ) await sah.close();
+ }
+ };
+
+ /**
+ Asynchronously imports the given bytes (a byte array or
+ ArrayBuffer) into the given database file.
+
+ Results are undefined if the given db name refers to an opened
+ db.
+
+ If passed a function for its second argument, its behaviour
+ changes: imports its data in chunks fed to it by the given
+ callback function. It calls the callback (which may be async)
+ repeatedly, expecting either a Uint8Array or ArrayBuffer (to
+ denote new input) or undefined (to denote EOF). For so long as
+ the callback continues to return non-undefined, it will append
+ incoming data to the given VFS-hosted database file. When
+ called this way, the resolved value of the returned Promise is
+ the number of bytes written to the target file.
+
+ It very specifically requires the input to be an SQLite3
+ database and throws if that's not the case. It does so in
+ order to prevent this function from taking on a larger scope
+ than it is specifically intended to. i.e. we do not want it to
+ become a convenience for importing arbitrary files into OPFS.
+
+ This routine rewrites the database header bytes in the output
+ file (not the input array) to force disabling of WAL mode.
+
+ On error this throws and the state of the input file is
+ undefined (it depends on where the exception was triggered).
+
+ On success, resolves to the number of bytes written.
+ */
+ opfsUtil.importDb = async function(filename, bytes){
+ if( bytes instanceof Function ){
+ return importDbChunked(filename, bytes);
+ }
+ if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
+ util.affirmIsDb(bytes);
+ const n = bytes.byteLength;
+ const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true);
+ let sah, err, nWrote = 0;
+ try {
+ const hFile = await hDir.getFileHandle(fnamePart, {create:true});
+ sah = await hFile.createSyncAccessHandle();
+ sah.truncate(0);
+ nWrote = sah.write(bytes, {at: 0});
+ if(nWrote != n){
+ toss("Expected to write "+n+" bytes but wrote "+nWrote+".");
+ }
+ sah.write(new Uint8Array([1,1]), {at: 18}) /* force db out of WAL mode */;
+ return nWrote;
+ }catch(e){
+ if( sah ){ await sah.close(); sah = undefined; }
+ await hDir.removeEntry( fnamePart ).catch(()=>{});
+ throw e;
+ }finally{
+ if( sah ) await sah.close();
+ }
+ };
+
+ /**
+ Checks for features required for OPFS VFSes and throws with a
+ descriptive error message if they're not found. This is intended
+ to be run as part of async VFS installation steps.
+ */
+ opfsUtil.vfsInstallationFeatureCheck = function(vfsName){
+ if( !globalThis.SharedArrayBuffer || !globalThis.Atomics ){
+ toss("Cannot install OPFS: Missing SharedArrayBuffer and/or Atomics.",
+ "The server must emit the COOP/COEP response headers to enable those.",
+ "See https://sqlite.org/wasm/doc/trunk/persistence.md#coop-coep");
+ }else if( 'undefined'===typeof WorkerGlobalScope ){
+ toss("The OPFS sqlite3_vfs cannot run in the main thread",
+ "because it requires Atomics.wait().");
+ }else if( !globalThis.FileSystemHandle ||
+ !globalThis.FileSystemDirectoryHandle ||
+ !globalThis.FileSystemFileHandle?.prototype?.createSyncAccessHandle ||
+ !navigator?.storage?.getDirectory ){
+ toss("Missing required OPFS APIs.");
+ }else if( 'opfs-wl'===vfsName && !globalThis.Atomics.waitAsync ){
+ toss('The',vfsName,'VFS requires Atomics.waitAsync(), which is not available.');
+ }
+ };
+
+ /**
+ Must be called by the VFS's main installation routine and passed
+ the options object that function receives and a reference to that
+ function itself (we don't need this anymore).
+
+ It throws if OPFS is not available.
+
+ If it returns falsy, it detected that OPFS should be disabled, in
+ which case the callee should immediately return/resolve to the
+ sqlite3 object.
+
+ Else it returns a new copy of the options object, fleshed out
+ with any missing defaults. The caller must:
+
+ - Set up any local state they need.
+
+ - Call opfsUtil.createVfsState(vfsName,opt), where opt is the
+ object returned by this function.
+
+ - Set up any references they may need to state returned
+ by the previous step.
+
+ - Call opfvs.bindVfs()
+ */
+ opfsUtil.initOptions = function callee(vfsName, options){
+ const urlParams = new URL(globalThis.location.href).searchParams;
+ if( urlParams.has(vfsName+'-disable') ){
+ //sqlite3.config.warn('Explicitly not installing "opfs" VFS due to opfs-disable flag.');
+ return;
+ }
+ try{
+ opfsUtil.vfsInstallationFeatureCheck(vfsName);
+ }catch(e){
+ return;
+ }
+ options = util.nu(options);
+ options.vfsName = vfsName;
+ options.verbose ??= urlParams.has('opfs-verbose')
+ ? +urlParams.get('opfs-verbose') : 1;
+ options.sanityChecks ??= urlParams.has('opfs-sanity-check');
+
+ if( !opfsUtil.proxyUri ){
+ opfsUtil.proxyUri = "sqlite3-opfs-async-proxy.js";
+ if( sqlite3.scriptInfo?.sqlite3Dir ){
+ /* Doing this from one scope up, outside of this function, does
+ not work. */
+ opfsUtil.proxyUri = (
+ sqlite3.scriptInfo.sqlite3Dir + opfsUtil.proxyUri
+ );
+ }
+ }
+ options.proxyUri ??= opfsUtil.proxyUri;
+ if('function' === typeof options.proxyUri){
+ options.proxyUri = options.proxyUri();
+ }
+ //sqlite3.config.warn("opfsUtil options =",JSON.stringify(options), 'urlParams =', urlParams);
+ return opfsUtil.options = options;
+ };
+
+ /**
+ Creates, populates, and returns the main state object used by the
+ "opfs" and "opfs-wl" VFSes, and transfered from those to their
+ async counterparts.
+
+ The returned object's vfs property holds the fully-populated
+ capi.sqlite3_vfs instance, tagged with lots of extra state which
+ the current VFSes need to have exposed to them.
+
+ After setting up any local state needed, the caller must call
+ theVfs.bindVfs(X,Y), where X is an object containing the
+ sqlite3_io_methods to override and Y is a callback which gets
+ triggered if init succeeds, before the final Promise decides
+ whether or not to reject.
+
+ This object must, when it's passed to the async part, contain
+ only cloneable or sharable objects. After the worker's "inited"
+ message arrives, other types of data may be added to it.
+ */
+ opfsUtil.createVfsState = function(){
+ const state = util.nu();
+ const options = opfsUtil.options;
+ state.verbose = options.verbose;
+
+ const loggers = [
+ sqlite3.config.error,
+ sqlite3.config.warn,
+ sqlite3.config.log
+ ];
+ const vfsName = options.vfsName
+ || toss("Maintenance required: missing VFS name");
+ const logImpl = (level,...args)=>{
+ if(state.verbose>level) loggers[level](vfsName+":",...args);
+ };
+ const log = (...args)=>logImpl(2, ...args),
+ warn = (...args)=>logImpl(1, ...args),
+ error = (...args)=>logImpl(0, ...args),
+ capi = sqlite3.capi,
+ wasm = sqlite3.wasm;
+
+ const opfsVfs = state.vfs = new capi.sqlite3_vfs();
+ const opfsIoMethods = opfsVfs.ioMethods = new capi.sqlite3_io_methods();
+
opfsIoMethods.$iVersion = 1;
opfsVfs.$iVersion = 2/*yes, two*/;
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
opfsVfs.$mxPathname = 1024/* sure, why not? The OPFS name length limit
is undocumented/unspecified. */;
- opfsVfs.$zName = wasm.allocCString("opfs");
- // All C-side memory of opfsVfs is zeroed out, but just to be explicit:
- opfsVfs.$xDlOpen = opfsVfs.$xDlError = opfsVfs.$xDlSym = opfsVfs.$xDlClose = null;
+ opfsVfs.$zName = wasm.allocCString(vfsName);
opfsVfs.addOnDispose(
- '$zName', opfsVfs.$zName,
- 'cleanup default VFS wrapper', ()=>(dVfs ? dVfs.dispose() : null)
+ '$zName', opfsVfs.$zName, opfsIoMethods
+ /**
+ Pedantic sidebar: the entries in this array are items to
+ clean up when opfsVfs.dispose() is called, but in this
+ environment it will never be called. The VFS instance simply
+ hangs around until the WASM module instance is cleaned up. We
+ "could" _hypothetically_ clean it up by "importing" an
+ sqlite3_os_end() impl into the wasm build, but the shutdown
+ order of the wasm engine and the JS one are undefined so
+ there is no guaranty that the opfsVfs instance would be
+ available in one environment or the other when
+ sqlite3_os_end() is called (_if_ it gets called at all in a
+ wasm build, which is undefined). i.e. addOnDispose() here is
+ a matter of "correctness", not necessity. It just wouldn't do
+ to leave the impression that we're blindly leaking memory.
+ */
);
- /**
- Pedantic sidebar about opfsVfs.ondispose: the entries in that array
- are items to clean up when opfsVfs.dispose() is called, but in this
- environment it will never be called. The VFS instance simply
- hangs around until the WASM module instance is cleaned up. We
- "could" _hypothetically_ clean it up by "importing" an
- sqlite3_os_end() impl into the wasm build, but the shutdown order
- of the wasm engine and the JS one are undefined so there is no
- guaranty that the opfsVfs instance would be available in one
- environment or the other when sqlite3_os_end() is called (_if_ it
- gets called at all in a wasm build, which is undefined).
- */
- /**
- State which we send to the async-api Worker or share with it.
- This object must initially contain only cloneable or sharable
- objects. After the worker's "inited" message arrives, other types
- of data may be added to it.
- For purposes of Atomics.wait() and Atomics.notify(), we use a
- SharedArrayBuffer with one slot reserved for each of the API
- proxy's methods. The sync side of the API uses Atomics.wait()
- on the corresponding slot and the async side uses
- Atomics.notify() on that slot.
-
- The approach of using a single SAB to serialize comms for all
- instances might(?) lead to deadlock situations in multi-db
- cases. We should probably have one SAB here with a single slot
- for locking a per-file initialization step and then allocate a
- separate SAB like the above one for each file. That will
- require a bit of acrobatics but should be feasible. The most
- problematic part is that xOpen() would have to use
- postMessage() to communicate its SharedArrayBuffer, and mixing
- that approach with Atomics.wait/notify() gets a bit messy.
- */
- const state = Object.create(null);
- state.verbose = options.verbose;
- state.littleEndian = (()=>{
- const buffer = new ArrayBuffer(2);
- new DataView(buffer).setInt16(0, 256, true /* ==>littleEndian */);
- // Int16Array uses the platform's endianness.
- return new Int16Array(buffer)[0] === 256;
- })();
+ opfsVfs.metrics = util.nu({
+ counters: util.nu(),
+ dump: function(){
+ let k, n = 0, t = 0, w = 0;
+ for(k in state.opIds){
+ const m = metrics[k];
+ n += m.count;
+ t += m.time;
+ w += m.wait;
+ m.avgTime = (m.count && m.time) ? (m.time / m.count) : 0;
+ m.avgWait = (m.count && m.wait) ? (m.wait / m.count) : 0;
+ }
+ sqlite3.config.log(globalThis.location.href,
+ "metrics for",globalThis.location.href,":",metrics,
+ "\nTotal of",n,"op(s) for",t,
+ "ms (incl. "+w+" ms of waiting on the async side)");
+ sqlite3.config.log("Serialization metrics:",opfsVfs.metrics.counters.s11n);
+ opfsVfs.worker?.postMessage?.({type:'opfs-async-metrics'});
+ },
+ reset: function(){
+ let k;
+ const r = (m)=>(m.count = m.time = m.wait = 0);
+ const m = opfsVfs.metrics.counters;
+ for(k in state.opIds){
+ r(m[k] = Object.create(null));
+ }
+ let s = m.s11n = Object.create(null);
+ s = s.serialize = Object.create(null);
+ s.count = s.time = 0;
+ s = m.s11n.deserialize = Object.create(null);
+ s.count = s.time = 0;
+ }
+ })/*opfsVfs.metrics*/;
+
/**
asyncIdleWaitTime is how long (ms) to wait, in the async proxy,
for each Atomics.wait() when waiting on inbound VFS API calls.
@@ -18282,7 +18620,8 @@ const installOpfsVfs = function callee(options){
0 = no exception logging.
1 = only log exceptions for "significant" ops like xOpen(),
- xRead(), and xWrite().
+ xRead(), and xWrite(). Exceptions related to, e.g., wait/retry
+ loops in acquiring SyncAccessHandles are not logged.
2 = log all exceptions.
*/
@@ -18308,22 +18647,31 @@ const installOpfsVfs = function callee(options){
state.fileBufferSize/* file i/o block */
+ state.sabS11nSize/* argument/result serialization block */
);
+
+ /**
+ For purposes of Atomics.wait() and Atomics.notify(), we use a
+ SharedArrayBuffer with one slot reserved for each of the API
+ proxy's methods. The sync side of the API uses Atomics.wait()
+ on the corresponding slot and the async side uses
+ Atomics.notify() on that slot. state.opIds holds the SAB slot
+ IDs of each of those.
+ */
state.opIds = Object.create(null);
- const metrics = Object.create(null);
{
/* Indexes for use in our SharedArrayBuffer... */
let i = 0;
/* SAB slot used to communicate which operation is desired
between both workers. This worker writes to it and the other
- listens for changes. */
+ listens for changes and clears it. The values written to it
+ are state.opIds.x[A-Z][a-z]+, defined below.*/
state.opIds.whichOp = i++;
- /* Slot for storing return values. This worker listens to that
- slot and the other worker writes to it. */
+ /* Slot for storing return values. This side listens to that
+ slot and the async proxy writes to it. */
state.opIds.rc = i++;
- /* Each function gets an ID which this worker writes to
- the whichOp slot. The async-api worker uses Atomic.wait()
- on the whichOp slot to figure out which operation to run
- next. */
+ /* Each function gets an ID which this worker writes to the
+ state.opIds.whichOp slot. The async-api worker uses
+ Atomic.wait() on the whichOp slot to figure out which
+ operation to run next. */
state.opIds.xAccess = i++;
state.opIds.xClose = i++;
state.opIds.xDelete = i++;
@@ -18337,24 +18685,28 @@ const installOpfsVfs = function callee(options){
state.opIds.xTruncate = i++;
state.opIds.xUnlock = i++;
state.opIds.xWrite = i++;
- state.opIds.mkdir = i++;
+ state.opIds.mkdir = i++ /*currently unused*/;
+ /** Internal signals which are used only during development and
+ testing via the dev console. */
state.opIds['opfs-async-metrics'] = i++;
state.opIds['opfs-async-shutdown'] = i++;
/* The retry slot is used by the async part for wait-and-retry
- semantics. Though we could hypothetically use the xSleep slot
- for that, doing so might lead to undesired side effects. */
+ semantics. It is never written to, only used as a convenient
+ place to wait-with-timeout for a value which will never be
+ written, i.e. sleep()ing, before retrying a failed attempt to
+ acquire a SharedAccessHandle. */
state.opIds.retry = i++;
state.sabOP = new SharedArrayBuffer(
- i * 4/* ==sizeof int32, noting that Atomics.wait() and friends
- can only function on Int32Array views of an SAB. */);
- opfsUtil.metrics.reset();
+ i * 4/* 4==sizeof int32, noting that Atomics.wait() and
+ friends can only function on Int32Array views of an
+ SAB. */);
}
/**
SQLITE_xxx constants to export to the async worker
counterpart...
*/
state.sq3Codes = Object.create(null);
- [
+ for(const k of [
'SQLITE_ACCESS_EXISTS',
'SQLITE_ACCESS_READWRITE',
'SQLITE_BUSY',
@@ -18382,17 +18734,22 @@ const installOpfsVfs = function callee(options){
'SQLITE_OPEN_CREATE',
'SQLITE_OPEN_DELETEONCLOSE',
'SQLITE_OPEN_MAIN_DB',
- 'SQLITE_OPEN_READONLY'
- ].forEach((k)=>{
- if(undefined === (state.sq3Codes[k] = capi[k])){
- toss("Maintenance required: not found:",k);
- }
- });
+ 'SQLITE_OPEN_READONLY',
+ 'SQLITE_LOCK_NONE',
+ 'SQLITE_LOCK_SHARED',
+ 'SQLITE_LOCK_RESERVED',
+ 'SQLITE_LOCK_PENDING',
+ 'SQLITE_LOCK_EXCLUSIVE'
+ ]){
+ state.sq3Codes[k] =
+ capi[k] ?? toss("Maintenance required: not found:",k);
+ }
+
state.opfsFlags = Object.assign(Object.create(null),{
/**
Flag for use with xOpen(). URI flag "opfs-unlock-asap=1"
enables this. See defaultUnlockAsap, below.
- */
+ */
OPFS_UNLOCK_ASAP: 0x01,
/**
Flag for use with xOpen(). URI flag "delete-before-open=1"
@@ -18405,33 +18762,37 @@ const installOpfsVfs = function callee(options){
downstream errors. An unlink can fail if, e.g., another tab
has the handle open.
- It goes without saying that deleting a file out from under another
- instance results in Undefined Behavior.
+ It goes without saying that deleting a file out from under
+ another instance results in Undefined Behavior.
*/
OPFS_UNLINK_BEFORE_OPEN: 0x02,
/**
- If true, any async routine which implicitly acquires a sync
- access handle (i.e. an OPFS lock) will release that lock at
- the end of the call which acquires it. If false, such
- "autolocks" are not released until the VFS is idle for some
- brief amount of time.
-
- The benefit of enabling this is much higher concurrency. The
- down-side is much-reduced performance (as much as a 4x decrease
- in speedtest1).
+ If true, any async routine which must implicitly acquire a
+ sync access handle (i.e. an OPFS lock), without an active
+ xLock(), will release that lock at the end of the call which
+ acquires it. If false, such implicit locks are not released
+ until the VFS is idle for some brief amount of time, as
+ defined by state.asyncIdleWaitTime.
+
+ The benefit of enabling this is higher concurrency. The
+ down-side is much-reduced performance (as much as a 4x
+ decrease in speedtest1).
*/
defaultUnlockAsap: false
});
+ opfsVfs.metrics.reset()/*must not be called until state.opIds is set up*/;
+ const metrics = opfsVfs.metrics.counters;
+
/**
Runs the given operation (by name) in the async worker
counterpart, waits for its response, and returns the result
- which the async worker writes to SAB[state.opIds.rc]. The
- 2nd and subsequent arguments must be the arguments for the
- async op.
+ which the async worker writes to SAB[state.opIds.rc]. The 2nd
+ and subsequent arguments must be the arguments for the async op
+ (see sqlite3-opfs-async-proxy.c-pp.js).
*/
- const opRun = (op,...args)=>{
- const opNdx = state.opIds[op] || toss("Invalid op ID:",op);
+ const opRun = opfsVfs.opRun = (op,...args)=>{
+ const opNdx = state.opIds[op] || toss(opfsVfs.vfsName+": Invalid op ID:",op);
state.s11n.serialize(...args);
Atomics.store(state.sabOPView, state.opIds.rc, -1);
Atomics.store(state.sabOPView, state.opIds.whichOp, opNdx);
@@ -18446,14 +18807,15 @@ const installOpfsVfs = function callee(options){
https://github.com/sqlite/sqlite-wasm/issues/12
Summary: in at least one browser flavor, under high loads,
- the wait()/notify() pairings can get out of sync. Calling
- wait() here until it returns 'not-equal' gets them back in
- sync.
+ the wait()/notify() pairings can get out of sync and/or
+ spuriously wake up. Calling wait() here until it returns
+ 'not-equal' gets them back in sync.
*/
}
/* When the above wait() call returns 'not-equal', the async
- half will have completed the operation and reported its results
- in the state.opIds.rc slot of the SAB. */
+ half will have completed the operation and reported its
+ results in the state.opIds.rc slot of the SAB. It may have
+ also serialized an exception for us. */
const rc = Atomics.load(state.sabOPView, state.opIds.rc);
metrics[op].wait += performance.now() - t;
if(rc && state.asyncS11nExceptions){
@@ -18463,248 +18825,41 @@ const installOpfsVfs = function callee(options){
return rc;
};
- /**
- Not part of the public API. Only for test/development use.
- */
- opfsUtil.debug = {
- asyncShutdown: ()=>{
- warn("Shutting down OPFS async listener. The OPFS VFS will no longer work.");
- opRun('opfs-async-shutdown');
- },
- asyncRestart: ()=>{
- warn("Attempting to restart OPFS VFS async listener. Might work, might not.");
- W.postMessage({type: 'opfs-async-restart'});
- }
- };
-
- const initS11n = ()=>{
- /**
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ACHTUNG: this code is 100% duplicated in the other half of
- this proxy! The documentation is maintained in the
- "synchronous half".
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- This proxy de/serializes cross-thread function arguments and
- output-pointer values via the state.sabIO SharedArrayBuffer,
- using the region defined by (state.sabS11nOffset,
- state.sabS11nOffset + state.sabS11nSize]. Only one dataset is
- recorded at a time.
-
- This is not a general-purpose format. It only supports the
- range of operations, and data sizes, needed by the
- sqlite3_vfs and sqlite3_io_methods operations. Serialized
- data are transient and this serialization algorithm may
- change at any time.
-
- The data format can be succinctly summarized as:
-
- Nt...Td...D
-
- Where:
-
- - N = number of entries (1 byte)
-
- - t = type ID of first argument (1 byte)
-
- - ...T = type IDs of the 2nd and subsequent arguments (1 byte
- each).
-
- - d = raw bytes of first argument (per-type size).
-
- - ...D = raw bytes of the 2nd and subsequent arguments (per-type
- size).
-
- All types except strings have fixed sizes. Strings are stored
- using their TextEncoder/TextDecoder representations. It would
- arguably make more sense to store them as Int16Arrays of
- their JS character values, but how best/fastest to get that
- in and out of string form is an open point. Initial
- experimentation with that approach did not gain us any speed.
-
- Historical note: this impl was initially about 1% this size by
- using using JSON.stringify/parse(), but using fit-to-purpose
- serialization saves considerable runtime.
- */
- if(state.s11n) return state.s11n;
- const textDecoder = new TextDecoder(),
- textEncoder = new TextEncoder('utf-8'),
- viewU8 = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize),
- viewDV = new DataView(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
- state.s11n = Object.create(null);
- /* Only arguments and return values of these types may be
- serialized. This covers the whole range of types needed by the
- sqlite3_vfs API. */
- const TypeIds = Object.create(null);
- TypeIds.number = { id: 1, size: 8, getter: 'getFloat64', setter: 'setFloat64' };
- TypeIds.bigint = { id: 2, size: 8, getter: 'getBigInt64', setter: 'setBigInt64' };
- TypeIds.boolean = { id: 3, size: 4, getter: 'getInt32', setter: 'setInt32' };
- TypeIds.string = { id: 4 };
-
- const getTypeId = (v)=>(
- TypeIds[typeof v]
- || toss("Maintenance required: this value type cannot be serialized.",v)
- );
- const getTypeIdById = (tid)=>{
- switch(tid){
- case TypeIds.number.id: return TypeIds.number;
- case TypeIds.bigint.id: return TypeIds.bigint;
- case TypeIds.boolean.id: return TypeIds.boolean;
- case TypeIds.string.id: return TypeIds.string;
- default: toss("Invalid type ID:",tid);
- }
- };
-
- /**
- Returns an array of the deserialized state stored by the most
- recent serialize() operation (from this thread or the
- counterpart thread), or null if the serialization buffer is
- empty. If passed a truthy argument, the serialization buffer
- is cleared after deserialization.
- */
- state.s11n.deserialize = function(clear=false){
- ++metrics.s11n.deserialize.count;
- const t = performance.now();
- const argc = viewU8[0];
- const rc = argc ? [] : null;
- if(argc){
- const typeIds = [];
- let offset = 1, i, n, v;
- for(i = 0; i < argc; ++i, ++offset){
- typeIds.push(getTypeIdById(viewU8[offset]));
- }
- for(i = 0; i < argc; ++i){
- const t = typeIds[i];
- if(t.getter){
- v = viewDV[t.getter](offset, state.littleEndian);
- offset += t.size;
- }else{/*String*/
- n = viewDV.getInt32(offset, state.littleEndian);
- offset += 4;
- v = textDecoder.decode(viewU8.slice(offset, offset+n));
- offset += n;
- }
- rc.push(v);
- }
- }
- if(clear) viewU8[0] = 0;
- //log("deserialize:",argc, rc);
- metrics.s11n.deserialize.time += performance.now() - t;
- return rc;
- };
-
- /**
- Serializes all arguments to the shared buffer for consumption
- by the counterpart thread.
-
- This routine is only intended for serializing OPFS VFS
- arguments and (in at least one special case) result values,
- and the buffer is sized to be able to comfortably handle
- those.
-
- If passed no arguments then it zeroes out the serialization
- state.
- */
- state.s11n.serialize = function(...args){
- const t = performance.now();
- ++metrics.s11n.serialize.count;
- if(args.length){
- //log("serialize():",args);
- const typeIds = [];
- let i = 0, offset = 1;
- viewU8[0] = args.length & 0xff /* header = # of args */;
- for(; i < args.length; ++i, ++offset){
- /* Write the TypeIds.id value into the next args.length
- bytes. */
- typeIds.push(getTypeId(args[i]));
- viewU8[offset] = typeIds[i].id;
- }
- for(i = 0; i < args.length; ++i) {
- /* Deserialize the following bytes based on their
- corresponding TypeIds.id from the header. */
- const t = typeIds[i];
- if(t.setter){
- viewDV[t.setter](offset, args[i], state.littleEndian);
- offset += t.size;
- }else{/*String*/
- const s = textEncoder.encode(args[i]);
- viewDV.setInt32(offset, s.byteLength, state.littleEndian);
- offset += 4;
- viewU8.set(s, offset);
- offset += s.byteLength;
- }
- }
- //log("serialize() result:",viewU8.slice(0,offset));
- }else{
- viewU8[0] = 0;
- }
- metrics.s11n.serialize.time += performance.now() - t;
- };
- return state.s11n;
- }/*initS11n()*/;
-
- /**
- Generates a random ASCII string len characters long, intended for
- use as a temporary file name.
- */
- const randomFilename = function f(len=16){
- if(!f._chars){
- f._chars = "abcdefghijklmnopqrstuvwxyz"+
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
- "012346789";
- f._n = f._chars.length;
- }
- const a = [];
- let i = 0;
- for( ; i < len; ++i){
- const ndx = Math.random() * (f._n * 64) % f._n | 0;
- a[i] = f._chars[ndx];
- }
- return a.join("");
- /*
- An alternative impl. with an unpredictable length
- but much simpler:
-
- Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36)
- */
- };
-
- /**
- Map of sqlite3_file pointers to objects constructed by xOpen().
- */
- const __openFiles = Object.create(null);
-
const opTimer = Object.create(null);
opTimer.op = undefined;
opTimer.start = undefined;
- const mTimeStart = (op)=>{
+ const mTimeStart = opfsVfs.mTimeStart = (op)=>{
opTimer.start = performance.now();
opTimer.op = op;
++metrics[op].count;
};
- const mTimeEnd = ()=>(
+ const mTimeEnd = opfsVfs.mTimeEnd = ()=>(
metrics[opTimer.op].time += performance.now() - opTimer.start
);
+ /**
+ Map of sqlite3_file pointers to objects constructed by xOpen().
+ */
+ const __openFiles = opfsVfs.__openFiles = Object.create(null);
+
/**
Impls for the sqlite3_io_methods methods. Maintenance reminder:
members are in alphabetical order to simplify finding them.
*/
- const ioSyncWrappers = {
+ const ioSyncWrappers = opfsVfs.ioSyncWrappers = util.nu({
xCheckReservedLock: function(pFile,pOut){
/**
- As of late 2022, only a single lock can be held on an OPFS
- file. We have no way of checking whether any _other_ db
- connection has a lock except by trying to obtain and (on
- success) release a sync-handle for it, but doing so would
- involve an inherent race condition. For the time being,
- pending a better solution, we simply report whether the
- given pFile is open.
-
- Update 2024-06-12: based on forum discussions, this
- function now always sets pOut to 0 (false):
-
- https://sqlite.org/forum/forumpost/a2f573b00cda1372
+ After consultation with a topic expert: "opfs-wl" will
+ continue to use the same no-op impl which "opfs" does
+ because:
+
+ - xCheckReservedLock() is just a hint. If SQLite needs to
+ lock, it's still going to try to lock.
+
+ - We cannot do this check synchronously in "opfs-wl",
+ so would need to pass it to the async proxy. That would
+ make it inordinately expensive considering that it's
+ just a hint.
*/
wasm.poke(pOut, 0, 'i32');
return 0;
@@ -18726,7 +18881,7 @@ const installOpfsVfs = function callee(options){
},
xFileControl: function(pFile, opId, pArg){
/*mTimeStart('xFileControl');
- mTimeEnd();*/
+ mTimeEnd();*/
return capi.SQLITE_NOTFOUND;
},
xFileSize: function(pFile,pSz64){
@@ -18744,25 +18899,8 @@ const installOpfsVfs = function callee(options){
mTimeEnd();
return rc;
},
- xLock: function(pFile,lockType){
- mTimeStart('xLock');
- const f = __openFiles[pFile];
- let rc = 0;
- /* All OPFS locks are exclusive locks. If xLock() has
- previously succeeded, do nothing except record the lock
- type. If no lock is active, have the async counterpart
- lock the file. */
- if( !f.lockType ) {
- rc = opRun('xLock', pFile, lockType);
- if( 0===rc ) f.lockType = lockType;
- }else{
- f.lockType = lockType;
- }
- mTimeEnd();
- return rc;
- },
xRead: function(pFile,pDest,n,offset64){
- mTimeStart('xRead');
+ mTimeStart('xRead');
const f = __openFiles[pFile];
let rc;
try {
@@ -18784,7 +18922,6 @@ const installOpfsVfs = function callee(options){
},
xSync: function(pFile,flags){
mTimeStart('xSync');
- ++metrics.xSync.count;
const rc = opRun('xSync', pFile, flags);
mTimeEnd();
return rc;
@@ -18795,18 +18932,6 @@ const installOpfsVfs = function callee(options){
mTimeEnd();
return rc;
},
- xUnlock: function(pFile,lockType){
- mTimeStart('xUnlock');
- const f = __openFiles[pFile];
- let rc = 0;
- if( capi.SQLITE_LOCK_NONE === lockType
- && f.lockType ){
- rc = opRun('xUnlock', pFile, lockType);
- }
- if( 0===rc ) f.lockType = lockType;
- mTimeEnd();
- return rc;
- },
xWrite: function(pFile,pSrc,n,offset64){
mTimeStart('xWrite');
const f = __openFiles[pFile];
@@ -18823,23 +18948,21 @@ const installOpfsVfs = function callee(options){
mTimeEnd();
return rc;
}
- }/*ioSyncWrappers*/;
+ })/*ioSyncWrappers*/;
/**
Impls for the sqlite3_vfs methods. Maintenance reminder: members
are in alphabetical order to simplify finding them.
*/
- const vfsSyncWrappers = {
+ const vfsSyncWrappers = opfsVfs.vfsSyncWrappers = {
xAccess: function(pVfs,zName,flags,pOut){
- mTimeStart('xAccess');
+ mTimeStart('xAccess');
const rc = opRun('xAccess', wasm.cstrToJs(zName));
wasm.poke( pOut, (rc ? 0 : 1), 'i32' );
mTimeEnd();
return 0;
},
xCurrentTime: function(pVfs,pOut){
- /* If it turns out that we need to adjust for timezone, see:
- https://stackoverflow.com/a/11760121/1458521 */
wasm.poke(pOut, 2440587.5 + (new Date().getTime()/86400000),
'double');
return 0;
@@ -18863,18 +18986,22 @@ const installOpfsVfs = function callee(options){
/*CANTOPEN is required by the docs but SQLITE_RANGE would be a closer match*/;
},
xGetLastError: function(pVfs,nOut,pOut){
- /* TODO: store exception.message values from the async
- partner in a dedicated SharedArrayBuffer, noting that we'd have
- to encode them... TextEncoder can do that for us. */
- warn("OPFS xGetLastError() has nothing sensible to return.");
+ /* Mutex use in the overlying APIs cause xGetLastError() to
+ not be terribly useful for us. e.g. it can't be used to
+ convey error messages from xOpen() because there would be a
+ race condition between sqlite3_open()'s call to xOpen() and
+ this function. */
+ sqlite3.config.warn("OPFS xGetLastError() has nothing sensible to return.");
return 0;
},
//xSleep is optionally defined below
xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){
mTimeStart('xOpen');
let opfsFlags = 0;
- if(0===zName){
- zName = randomFilename();
+ let jzName, zToFree;
+ if( !zName ){
+ jzName = opfsUtil.randomFilename();
+ zName = zToFree = wasm.allocCString(jzName);
}else if(wasm.isPtr(zName)){
if(capi.sqlite3_uri_boolean(zName, "opfs-unlock-asap", 0)){
/* -----------------------^^^^^ MUST pass the untranslated
@@ -18884,18 +19011,24 @@ const installOpfsVfs = function callee(options){
if(capi.sqlite3_uri_boolean(zName, "delete-before-open", 0)){
opfsFlags |= state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN;
}
- zName = wasm.cstrToJs(zName);
- //warn("xOpen zName =",zName, "opfsFlags =",opfsFlags);
- }
- const fh = Object.create(null);
- fh.fid = pFile;
- fh.filename = zName;
- fh.sab = new SharedArrayBuffer(state.fileBufferSize);
- fh.flags = flags;
- fh.readOnly = !(capi.SQLITE_OPEN_CREATE & flags)
- && !!(flags & capi.SQLITE_OPEN_READONLY);
- const rc = opRun('xOpen', pFile, zName, flags, opfsFlags);
- if(!rc){
+ jzName = wasm.cstrToJs(zName);
+ //sqlite3.config.warn("xOpen zName =",zName, "opfsFlags =",opfsFlags);
+ }else{
+ sqlite3.config.error("Impossible zName value in xOpen?", zName);
+ return capi.SQLITE_CANTOPEN;
+ }
+ const fh = util.nu({
+ fid: pFile,
+ filename: jzName,
+ sab: new SharedArrayBuffer(state.fileBufferSize),
+ flags: flags,
+ readOnly: !(capi.SQLITE_OPEN_CREATE & flags)
+ && !!(flags & capi.SQLITE_OPEN_READONLY)
+ });
+ const rc = opRun('xOpen', pFile, jzName, flags, opfsFlags);
+ if(rc){
+ if( zToFree ) wasm.dealloc(zToFree);
+ }else{
/* Recall that sqlite3_vfs::xClose() will be called, even on
error, unless pFile->pMethods is NULL. */
if(fh.readOnly){
@@ -18903,7 +19036,8 @@ const installOpfsVfs = function callee(options){
}
__openFiles[pFile] = fh;
fh.sabView = state.sabFileBufView;
- fh.sq3File = new sqlite3_file(pFile);
+ fh.sq3File = new capi.sqlite3_file(pFile);
+ if( zToFree ) fh.sq3File.addOnDispose(zToFree);
fh.sq3File.$pMethods = opfsIoMethods.pointer;
fh.lockType = capi.SQLITE_LOCK_NONE;
}
@@ -18912,515 +19046,569 @@ const installOpfsVfs = function callee(options){
}/*xOpen()*/
}/*vfsSyncWrappers*/;
- if(dVfs){
- opfsVfs.$xRandomness = dVfs.$xRandomness;
- opfsVfs.$xSleep = dVfs.$xSleep;
- }
- if(!opfsVfs.$xRandomness){
- /* If the default VFS has no xRandomness(), add a basic JS impl... */
- vfsSyncWrappers.xRandomness = function(pVfs, nOut, pOut){
- const heap = wasm.heap8u();
- let i = 0;
- const npOut = Number(pOut);
- for(; i < nOut; ++i) heap[npOut + i] = (Math.random()*255000) & 0xFF;
- return i;
- };
- }
- if(!opfsVfs.$xSleep){
- /* If we can inherit an xSleep() impl from the default VFS then
- assume it's sane and use it, otherwise install a JS-based
- one. */
- vfsSyncWrappers.xSleep = function(pVfs,ms){
- Atomics.wait(state.sabOPView, state.opIds.xSleep, 0, ms);
- return 0;
- };
- }
+ const pDVfs = capi.sqlite3_vfs_find(null)/*pointer to default VFS*/;
+ if(pDVfs){
+ const dVfs = new capi.sqlite3_vfs(pDVfs);
+ opfsVfs.$xRandomness = dVfs.$xRandomness;
+ opfsVfs.$xSleep = dVfs.$xSleep;
+ dVfs.dispose();
+ }
+ if(!opfsVfs.$xRandomness){
+ /* If the default VFS has no xRandomness(), add a basic JS impl... */
+ opfsVfs.vfsSyncWrappers.xRandomness = function(pVfs, nOut, pOut){
+ const heap = wasm.heap8u();
+ let i = 0;
+ const npOut = Number(pOut);
+ for(; i < nOut; ++i) heap[npOut + i] = (Math.random()*255000) & 0xFF;
+ return i;
+ };
+ }
+ if(!opfsVfs.$xSleep){
+ /* If we can inherit an xSleep() impl from the default VFS then
+ assume it's sane and use it, otherwise install a JS-based
+ one. */
+ opfsVfs.vfsSyncWrappers.xSleep = function(pVfs,ms){
+ mTimeStart('xSleep');
+ Atomics.wait(state.sabOPView, state.opIds.xSleep, 0, ms);
+ mTimeEnd();
+ return 0;
+ };
+ }
+
+const initS11n = function(){
+ /**
+ This proxy de/serializes cross-thread function arguments and
+ output-pointer values via the state.sabIO SharedArrayBuffer,
+ using the region defined by (state.sabS11nOffset,
+ state.sabS11nOffset + state.sabS11nSize]. Only one dataset is
+ recorded at a time.
+
+ This is not a general-purpose format. It only supports the
+ range of operations, and data sizes, needed by the
+ sqlite3_vfs and sqlite3_io_methods operations. Serialized
+ data are transient and this serialization algorithm may
+ change at any time.
+
+ The data format can be succinctly summarized as:
+
+ Nt...Td...D
+
+ Where:
+
+ - N = number of entries (1 byte)
+
+ - t = type ID of first argument (1 byte)
+
+ - ...T = type IDs of the 2nd and subsequent arguments (1 byte
+ each).
+
+ - d = raw bytes of first argument (per-type size).
+
+ - ...D = raw bytes of the 2nd and subsequent arguments (per-type
+ size).
+
+ All types except strings have fixed sizes. Strings are stored
+ using their TextEncoder/TextDecoder representations. It would
+ arguably make more sense to store them as Int16Arrays of
+ their JS character values, but how best/fastest to get that
+ in and out of string form is an open point. Initial
+ experimentation with that approach did not gain us any speed.
+
+ Historical note: this impl was initially about 1% this size by
+ using using JSON.stringify/parse(), but using fit-to-purpose
+ serialization saves considerable runtime.
+ */
+ if(state.s11n) return state.s11n;
+ const textDecoder = new TextDecoder(),
+ textEncoder = new TextEncoder('utf-8'),
+ viewU8 = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize),
+ viewDV = new DataView(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
+ state.s11n = Object.create(null);
+ /* Only arguments and return values of these types may be
+ serialized. This covers the whole range of types needed by the
+ sqlite3_vfs API. */
+ const TypeIds = Object.create(null);
+ TypeIds.number = { id: 1, size: 8, getter: 'getFloat64', setter: 'setFloat64' };
+ TypeIds.bigint = { id: 2, size: 8, getter: 'getBigInt64', setter: 'setBigInt64' };
+ TypeIds.boolean = { id: 3, size: 4, getter: 'getInt32', setter: 'setInt32' };
+ TypeIds.string = { id: 4 };
+
+ const getTypeId = (v)=>(
+ TypeIds[typeof v]
+ || toss("Maintenance required: this value type cannot be serialized.",v)
+ );
+ const getTypeIdById = (tid)=>{
+ switch(tid){
+ case TypeIds.number.id: return TypeIds.number;
+ case TypeIds.bigint.id: return TypeIds.bigint;
+ case TypeIds.boolean.id: return TypeIds.boolean;
+ case TypeIds.string.id: return TypeIds.string;
+ default: toss("Invalid type ID:",tid);
+ }
+ };
+
+ /**
+ Returns an array of the deserialized state stored by the most
+ recent serialize() operation (from this thread or the
+ counterpart thread), or null if the serialization buffer is
+ empty. If passed a truthy argument, the serialization buffer
+ is cleared after deserialization.
+ */
+ state.s11n.deserialize = function(clear=false){
+ const t = performance.now();
+ const argc = viewU8[0];
+ const rc = argc ? [] : null;
+ if(argc){
+ const typeIds = [];
+ let offset = 1, i, n, v;
+ for(i = 0; i < argc; ++i, ++offset){
+ typeIds.push(getTypeIdById(viewU8[offset]));
+ }
+ for(i = 0; i < argc; ++i){
+ const t = typeIds[i];
+ if(t.getter){
+ v = viewDV[t.getter](offset, state.littleEndian);
+ offset += t.size;
+ }else{/*String*/
+ n = viewDV.getInt32(offset, state.littleEndian);
+ offset += 4;
+ v = textDecoder.decode(viewU8.slice(offset, offset+n));
+ offset += n;
+ }
+ rc.push(v);
+ }
+ }
+ if(clear) viewU8[0] = 0;
+ //log("deserialize:",argc, rc);
+ return rc;
+ };
+
+ /**
+ Serializes all arguments to the shared buffer for consumption
+ by the counterpart thread.
+
+ This routine is only intended for serializing OPFS VFS
+ arguments and (in at least one special case) result values,
+ and the buffer is sized to be able to comfortably handle
+ those.
+
+ If passed no arguments then it zeroes out the serialization
+ state.
+ */
+ state.s11n.serialize = function(...args){
+ const t = performance.now();
+ if(args.length){
+ //log("serialize():",args);
+ const typeIds = [];
+ let i = 0, offset = 1;
+ viewU8[0] = args.length & 0xff /* header = # of args */;
+ for(; i < args.length; ++i, ++offset){
+ /* Write the TypeIds.id value into the next args.length
+ bytes. */
+ typeIds.push(getTypeId(args[i]));
+ viewU8[offset] = typeIds[i].id;
+ }
+ for(i = 0; i < args.length; ++i) {
+ /* Deserialize the following bytes based on their
+ corresponding TypeIds.id from the header. */
+ const t = typeIds[i];
+ if(t.setter){
+ viewDV[t.setter](offset, args[i], state.littleEndian);
+ offset += t.size;
+ }else{/*String*/
+ const s = textEncoder.encode(args[i]);
+ viewDV.setInt32(offset, s.byteLength, state.littleEndian);
+ offset += 4;
+ viewU8.set(s, offset);
+ offset += s.byteLength;
+ }
+ }
+ //log("serialize() result:",viewU8.slice(0,offset));
+ }else{
+ viewU8[0] = 0;
+ }
+ };
+
+
+ return state.s11n;
+}/*initS11n()*/;
+ opfsVfs.initS11n = initS11n;
+
+ /**
+ To be called by the VFS's main installation routine after it has
+ wired up enough state to provide its overridden io-method impls
+ (which must be properties of the ioMethods argument). Returns a
+ Promise which the installation routine must return. callback must
+ be a function which performs any post-bootstrap touchups, namely
+ plugging in a sqlite3.oo1 wrapper. It is passed (sqlite3, opfsVfs),
+ where opfsVfs is the sqlite3_vfs object which was set up by
+ opfsUtil.createVfsState().
+ */
+ opfsVfs.bindVfs = function(ioMethods, callback){
+ Object.assign(opfsVfs.ioSyncWrappers, ioMethods);
+ const thePromise = new Promise(function(promiseResolve_, promiseReject_){
+ let promiseWasRejected = undefined;
+ const promiseReject = (err)=>{
+ promiseWasRejected = true;
+ opfsVfs.dispose();
+ return promiseReject_(err);
+ };
+ const promiseResolve = ()=>{
+ try{
+ callback(sqlite3, opfsVfs);
+ }catch(e){
+ return promiseReject(e);
+ }
+ promiseWasRejected = false;
+ return promiseResolve_(sqlite3);
+ };
+ const options = opfsUtil.options;
+ let proxyUri = options.proxyUri +(
+ (options.proxyUri.indexOf('?')<0) ? '?' : '&'
+ )+'vfs='+vfsName;
+ //sqlite3.config.error("proxyUri",options.proxyUri, (new Error()));
+ const W = opfsVfs.worker =
+ new Worker(new URL(proxyUri, import.meta.url));
+ let zombieTimer = setTimeout(()=>{
+ /* At attempt to work around a browser-specific quirk in which
+ the Worker load is failing in such a way that we neither
+ resolve nor reject it. This workaround gives that resolve/reject
+ a time limit and rejects if that timer expires. Discussion:
+ https://sqlite.org/forum/forumpost/a708c98dcb3ef */
+ if(undefined===promiseWasRejected){
+ promiseReject(
+ new Error("Timeout while waiting for OPFS async proxy worker.")
+ );
+ }
+ }, 4000);
+ W._originalOnError = W.onerror /* will be restored later */;
+ W.onerror = function(err){
+ // The error object doesn't contain any useful info when the
+ // failure is, e.g., that the remote script is 404.
+ error("Error initializing OPFS asyncer:",err);
+ promiseReject(new Error("Loading OPFS async Worker failed for unknown reasons."));
+ };
+
+ const opRun = opfsVfs.opRun;
+
+ const sanityCheck = function(){
+ const scope = wasm.scopedAllocPush();
+ const sq3File = new capi.sqlite3_file();
+ try{
+ const fid = sq3File.pointer;
+ const openFlags = capi.SQLITE_OPEN_CREATE
+ | capi.SQLITE_OPEN_READWRITE
+ //| capi.SQLITE_OPEN_DELETEONCLOSE
+ | capi.SQLITE_OPEN_MAIN_DB;
+ const pOut = wasm.scopedAlloc(8);
+ const dbFile = "/sanity/check/file"+randomFilename(8);
+ const zDbFile = wasm.scopedAllocCString(dbFile);
+ let rc;
+ state.s11n.serialize("This is ä string.");
+ rc = state.s11n.deserialize();
+ log("deserialize() says:",rc);
+ if("This is ä string."!==rc[0]) toss("String d13n error.");
+ opfsVfs.vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
+ rc = wasm.peek(pOut,'i32');
+ log("xAccess(",dbFile,") exists ?=",rc);
+ rc = opfsVfs.vfsSyncWrappers.xOpen(opfsVfs.pointer, zDbFile,
+ fid, openFlags, pOut);
+ log("open rc =",rc,"state.sabOPView[xOpen] =",
+ state.sabOPView[state.opIds.xOpen]);
+ if(0!==rc){
+ error("open failed with code",rc);
+ return;
+ }
+ opfsVfs.vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
+ rc = wasm.peek(pOut,'i32');
+ if(!rc) toss("xAccess() failed to detect file.");
+ rc = opfsVfs.ioSyncWrappers.xSync(sq3File.pointer, 0);
+ if(rc) toss('sync failed w/ rc',rc);
+ rc = opfsVfs.ioSyncWrappers.xTruncate(sq3File.pointer, 1024);
+ if(rc) toss('truncate failed w/ rc',rc);
+ wasm.poke(pOut,0,'i64');
+ rc = opfsVfs.ioSyncWrappers.xFileSize(sq3File.pointer, pOut);
+ if(rc) toss('xFileSize failed w/ rc',rc);
+ log("xFileSize says:",wasm.peek(pOut, 'i64'));
+ rc = opfsVfs.ioSyncWrappers.xWrite(sq3File.pointer, zDbFile, 10, 1);
+ if(rc) toss("xWrite() failed!");
+ const readBuf = wasm.scopedAlloc(16);
+ rc = opfsVfs.ioSyncWrappers.xRead(sq3File.pointer, readBuf, 6, 2);
+ wasm.poke(readBuf+6,0);
+ let jRead = wasm.cstrToJs(readBuf);
+ log("xRead() got:",jRead);
+ if("sanity"!==jRead) toss("Unexpected xRead() value.");
+ if(opfsVfs.vfsSyncWrappers.xSleep){
+ log("xSleep()ing before close()ing...");
+ opfsVfs.vfsSyncWrappers.xSleep(opfsVfs.pointer,2000);
+ log("waking up from xSleep()");
+ }
+ rc = opfsVfs.ioSyncWrappers.xClose(fid);
+ log("xClose rc =",rc,"sabOPView =",state.sabOPView);
+ log("Deleting file:",dbFile);
+ opfsVfs.vfsSyncWrappers.xDelete(opfsVfs.pointer, zDbFile, 0x1234);
+ opfsVfs.vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
+ rc = wasm.peek(pOut,'i32');
+ if(rc) toss("Expecting 0 from xAccess(",dbFile,") after xDelete().");
+ warn("End of OPFS sanity checks.");
+ }finally{
+ sq3File.dispose();
+ wasm.scopedAllocPop(scope);
+ }
+ }/*sanityCheck()*/;
+
+ W.onmessage = function({data}){
+ //sqlite3.config.warn(vfsName,"Worker.onmessage:",data);
+ switch(data.type){
+ case 'opfs-unavailable':
+ /* Async proxy has determined that OPFS is unavailable. There's
+ nothing more for us to do here. */
+ promiseReject(new Error(data.payload.join(' ')));
+ break;
+ case 'opfs-async-loaded':
+ /* Arrives as soon as the asyc proxy finishes loading.
+ Pass our config and shared state on to the async
+ worker. */
+ delete state.vfs;
+ W.postMessage({type: 'opfs-async-init', args: util.nu(state)});
+ break;
+ case 'opfs-async-inited': {
+ /* Indicates that the async partner has received the 'init'
+ and has finished initializing, so the real work can
+ begin... */
+ if(true===promiseWasRejected){
+ break /* promise was already rejected via timer */;
+ }
+ clearTimeout(zombieTimer);
+ zombieTimer = null;
+ try {
+ sqlite3.vfs.installVfs({
+ io: {struct: opfsVfs.ioMethods, methods: opfsVfs.ioSyncWrappers},
+ vfs: {struct: opfsVfs, methods: opfsVfs.vfsSyncWrappers}
+ });
+ state.sabOPView = new Int32Array(state.sabOP);
+ state.sabFileBufView = new Uint8Array(state.sabIO, 0, state.fileBufferSize);
+ state.sabS11nView = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
+ opfsVfs.initS11n();
+ delete opfsVfs.initS11n;
+ if(options.sanityChecks){
+ warn("Running sanity checks because of opfs-sanity-check URL arg...");
+ sanityCheck();
+ }
+ if(opfsUtil.thisThreadHasOPFS()){
+ opfsUtil.getRootDir().then((d)=>{
+ W.onerror = W._originalOnError;
+ delete W._originalOnError;
+ log("End of OPFS sqlite3_vfs setup.", opfsVfs);
+ promiseResolve();
+ }).catch(promiseReject);
+ }else{
+ promiseResolve();
+ }
+ }catch(e){
+ error(e);
+ promiseReject(e);
+ }
+ break;
+ }
+ case 'debug':
+ warn("debug message from worker:",data);
+ break;
+ default: {
+ const errMsg = (
+ "Unexpected message from the OPFS async worker: " +
+ JSON.stringify(data)
+ );
+ error(errMsg);
+ promiseReject(new Error(errMsg));
+ break;
+ }
+ }/*switch(data.type)*/
+ }/*W.onmessage()*/;
+ })/*thePromise*/;
+ return thePromise;
+ }/*bindVfs()*/;
+
+ return state;
+ }/*createVfsState()*/;
+
+}/*sqlite3ApiBootstrap.initializers*/);
+/*
+ 2022-09-18
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ This file holds the synchronous half of an sqlite3_vfs
+ implementation which proxies, in a synchronous fashion, the
+ asynchronous Origin-Private FileSystem (OPFS) APIs using a second
+ Worker, implemented in sqlite3-opfs-async-proxy.js. This file is
+ intended to be appended to the main sqlite3 JS deliverable somewhere
+ after sqlite3-api-oo1.js.
+*/
+'use strict';
+globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
+ if( !sqlite3.opfs || sqlite3.config.disable?.vfs?.opfs ){
+ return;
+ }
+ const util = sqlite3.util,
+ opfsUtil = sqlite3.opfs || sqlite3.util.toss("Missing sqlite3.opfs");
+ /**
+ installOpfsVfs() returns a Promise which, on success, installs an
+ sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
+ which accept a VFS. It is intended to be called via
+ sqlite3ApiBootstrap.initializers or an equivalent mechanism.
+
+ The installed VFS uses the Origin-Private FileSystem API for
+ all file storage. On error it is rejected with an exception
+ explaining the problem. Reasons for rejection include, but are
+ not limited to:
- /**
- Expects an OPFS file path. It gets resolved, such that ".."
- components are properly expanded, and returned. If the 2nd arg
- is true, the result is returned as an array of path elements,
- else an absolute path string is returned.
- */
- opfsUtil.getResolvedPath = function(filename,splitIt){
- const p = new URL(filename, "file://irrelevant").pathname;
- return splitIt ? p.split('/').filter((v)=>!!v) : p;
- };
+ - The counterpart Worker (see below) could not be loaded.
- /**
- Takes the absolute path to a filesystem element. Returns an
- array of [handleOfContainingDir, filename]. If the 2nd argument
- is truthy then each directory element leading to the file is
- created along the way. Throws if any creation or resolution
- fails.
- */
- opfsUtil.getDirForFilename = async function f(absFilename, createDirs = false){
- const path = opfsUtil.getResolvedPath(absFilename, true);
- const filename = path.pop();
- let dh = opfsUtil.rootDirectory;
- for(const dirName of path){
- if(dirName){
- dh = await dh.getDirectoryHandle(dirName, {create: !!createDirs});
- }
- }
- return [dh, filename];
- };
+ - The environment does not support OPFS. That includes when
+ this function is called from the main window thread.
- /**
- Creates the given directory name, recursively, in
- the OPFS filesystem. Returns true if it succeeds or the
- directory already exists, else false.
- */
- opfsUtil.mkdir = async function(absDirName){
- try {
- await opfsUtil.getDirForFilename(absDirName+"/filepart", true);
- return true;
- }catch(e){
- //sqlite3.config.warn("mkdir(",absDirName,") failed:",e);
- return false;
- }
- };
- /**
- Checks whether the given OPFS filesystem entry exists,
- returning true if it does, false if it doesn't or if an
- exception is intercepted while trying to make the
- determination.
- */
- opfsUtil.entryExists = async function(fsEntryName){
- try {
- const [dh, fn] = await opfsUtil.getDirForFilename(fsEntryName);
- await dh.getFileHandle(fn);
- return true;
- }catch(e){
- return false;
- }
- };
+ Significant notes and limitations:
- /**
- Generates a random ASCII string, intended for use as a
- temporary file name. Its argument is the length of the string,
- defaulting to 16.
- */
- opfsUtil.randomFilename = randomFilename;
+ - The OPFS features used here are only available in dedicated Worker
+ threads. This file tries to detect that case, resulting in a
+ rejected Promise if those features do not seem to be available.
- /**
- Returns a promise which resolves to an object which represents
- all files and directories in the OPFS tree. The top-most object
- has two properties: `dirs` is an array of directory entries
- (described below) and `files` is a list of file names for all
- files in that directory.
+ - It requires the SharedArrayBuffer and Atomics classes, and the
+ former is only available if the HTTP server emits the so-called
+ COOP and COEP response headers. These features are required for
+ proxying OPFS's synchronous API via the synchronous interface
+ required by the sqlite3_vfs API.
- Traversal starts at sqlite3.opfs.rootDirectory.
+ - This function may only be called a single time. When called, this
+ function removes itself from the sqlite3 object.
- Each `dirs` entry is an object in this form:
+ All arguments to this function are for internal/development purposes
+ only. They do not constitute a public API and may change at any
+ time.
- ```
- { name: directoryName,
- dirs: [...subdirs],
- files: [...file names]
- }
- ```
+ The argument may optionally be a plain object with the following
+ configuration options:
- The `files` and `subdirs` entries are always set but may be
- empty arrays.
+ - proxyUri: name of the async proxy JS file or a synchronous function
+ which, when called, returns such a name.
- The returned object has the same structure but its `name` is
- an empty string. All returned objects are created with
- Object.create(null), so have no prototype.
+ - verbose (=2): an integer 0-3. 0 disables all logging, 1 enables
+ logging of errors. 2 enables logging of warnings and errors. 3
+ additionally enables debugging info. Logging is performed
+ via the sqlite3.config.{log|warn|error}() functions.
- Design note: the entries do not contain more information,
- e.g. file sizes, because getting such info is not only
- expensive but is subject to locking-related errors.
- */
- opfsUtil.treeList = async function(){
- const doDir = async function callee(dirHandle,tgt){
- tgt.name = dirHandle.name;
- tgt.dirs = [];
- tgt.files = [];
- for await (const handle of dirHandle.values()){
- if('directory' === handle.kind){
- const subDir = Object.create(null);
- tgt.dirs.push(subDir);
- await callee(handle, subDir);
- }else{
- tgt.files.push(handle.name);
- }
- }
- };
- const root = Object.create(null);
- await doDir(opfsUtil.rootDirectory, root);
- return root;
- };
+ - sanityChecks (=false): if true, some basic sanity tests are run on
+ the OPFS VFS API after it's initialized, before the returned
+ Promise resolves. This is only intended for testing and
+ development of the VFS, not client-side use.
- /**
- Irrevocably deletes _all_ files in the current origin's OPFS.
- Obviously, this must be used with great caution. It may throw
- an exception if removal of anything fails (e.g. a file is
- locked), but the precise conditions under which the underlying
- APIs will throw are not documented (so we cannot tell you what
- they are).
- */
- opfsUtil.rmfr = async function(){
- const dir = opfsUtil.rootDirectory, opt = {recurse: true};
- for await (const handle of dir.values()){
- dir.removeEntry(handle.name, opt);
- }
- };
+ Additionaly, the (officially undocumented) 'opfs-disable' URL
+ argument will disable OPFS, making this function a no-op.
- /**
- Deletes the given OPFS filesystem entry. As this environment
- has no notion of "current directory", the given name must be an
- absolute path. If the 2nd argument is truthy, deletion is
- recursive (use with caution!).
-
- The returned Promise resolves to true if the deletion was
- successful, else false (but...). The OPFS API reports the
- reason for the failure only in human-readable form, not
- exceptions which can be type-checked to determine the
- failure. Because of that...
-
- If the final argument is truthy then this function will
- propagate any exception on error, rather than returning false.
- */
- opfsUtil.unlink = async function(fsEntryName, recursive = false,
- throwOnError = false){
- try {
- const [hDir, filenamePart] =
- await opfsUtil.getDirForFilename(fsEntryName, false);
- await hDir.removeEntry(filenamePart, {recursive});
- return true;
- }catch(e){
- if(throwOnError){
- throw new Error("unlink(",arguments[0],") failed: "+e.message,{
- cause: e
- });
- }
- return false;
- }
- };
+ On success, the Promise resolves to the top-most sqlite3 namespace
+ object. Success does not necessarily mean that it installs the VFS,
+ as there are legitimate non-error reasons for OPFS not to be
+ available.
+*/
+const installOpfsVfs = async function(options){
+ options = opfsUtil.initOptions('opfs',options);
+ if( !options ) return sqlite3;
+ const capi = sqlite3.capi,
+ state = opfsUtil.createVfsState(),
+ opfsVfs = state.vfs,
+ metrics = opfsVfs.metrics.counters,
+ mTimeStart = opfsVfs.mTimeStart,
+ mTimeEnd = opfsVfs.mTimeEnd,
+ opRun = opfsVfs.opRun,
+ debug = (...args)=>sqlite3.config.debug("opfs:",...args),
+ warn = (...args)=>sqlite3.config.warn("opfs:",...args),
+ __openFiles = opfsVfs.__openFiles;
+
+ //debug("options:",JSON.stringify(options));
+ /*
+ At this point, createVfsState() has populated:
- /**
- Traverses the OPFS filesystem, calling a callback for each
- entry. The argument may be either a callback function or an
- options object with any of the following properties:
-
- - `callback`: function which gets called for each filesystem
- entry. It gets passed 3 arguments: 1) the
- FileSystemFileHandle or FileSystemDirectoryHandle of each
- entry (noting that both are instanceof FileSystemHandle). 2)
- the FileSystemDirectoryHandle of the parent directory. 3) the
- current depth level, with 0 being at the top of the tree
- relative to the starting directory. If the callback returns a
- literal false, as opposed to any other falsy value, traversal
- stops without an error. Any exceptions it throws are
- propagated. Results are undefined if the callback manipulate
- the filesystem (e.g. removing or adding entries) because the
- how OPFS iterators behave in the face of such changes is
- undocumented.
-
- - `recursive` [bool=true]: specifies whether to recurse into
- subdirectories or not. Whether recursion is depth-first or
- breadth-first is unspecified!
-
- - `directory` [FileSystemDirectoryEntry=sqlite3.opfs.rootDirectory]
- specifies the starting directory.
-
- If this function is passed a function, it is assumed to be the
- callback.
-
- Returns a promise because it has to (by virtue of being async)
- but that promise has no specific meaning: the traversal it
- performs is synchronous. The promise must be used to catch any
- exceptions propagated by the callback, however.
- */
- opfsUtil.traverse = async function(opt){
- const defaultOpt = {
- recursive: true,
- directory: opfsUtil.rootDirectory
- };
- if('function'===typeof opt){
- opt = {callback:opt};
- }
- opt = Object.assign(defaultOpt, opt||{});
- const doDir = async function callee(dirHandle, depth){
- for await (const handle of dirHandle.values()){
- if(false === opt.callback(handle, dirHandle, depth)) return false;
- else if(opt.recursive && 'directory' === handle.kind){
- if(false === await callee(handle, depth + 1)) break;
- }
- }
- };
- doDir(opt.directory, 0);
- };
+ - state: the configuration object we share with the async proxy.
- /**
- impl of importDb() when it's given a function as its second
- argument.
- */
- const importDbChunked = async function(filename, callback){
- const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true);
- const hFile = await hDir.getFileHandle(fnamePart, {create:true});
- let sah = await hFile.createSyncAccessHandle();
- let nWrote = 0, chunk, checkedHeader = false, err = false;
- try{
- sah.truncate(0);
- while( undefined !== (chunk = await callback()) ){
- if(chunk instanceof ArrayBuffer) chunk = new Uint8Array(chunk);
- if( !checkedHeader && 0===nWrote && chunk.byteLength>=15 ){
- util.affirmDbHeader(chunk);
- checkedHeader = true;
- }
- sah.write(chunk, {at: nWrote});
- nWrote += chunk.byteLength;
- }
- if( nWrote < 512 || 0!==nWrote % 512 ){
- toss("Input size",nWrote,"is not correct for an SQLite database.");
- }
- if( !checkedHeader ){
- const header = new Uint8Array(20);
- sah.read( header, {at: 0} );
- util.affirmDbHeader( header );
- }
- sah.write(new Uint8Array([1,1]), {at: 18}/*force db out of WAL mode*/);
- return nWrote;
- }catch(e){
- await sah.close();
- sah = undefined;
- await hDir.removeEntry( fnamePart ).catch(()=>{});
- throw e;
- }finally {
- if( sah ) await sah.close();
- }
- };
+ - opfsVfs: an sqlite3_vfs instance with lots of JS state attached
+ to it.
- /**
- Asynchronously imports the given bytes (a byte array or
- ArrayBuffer) into the given database file.
-
- Results are undefined if the given db name refers to an opened
- db.
-
- If passed a function for its second argument, its behaviour
- changes: imports its data in chunks fed to it by the given
- callback function. It calls the callback (which may be async)
- repeatedly, expecting either a Uint8Array or ArrayBuffer (to
- denote new input) or undefined (to denote EOF). For so long as
- the callback continues to return non-undefined, it will append
- incoming data to the given VFS-hosted database file. When
- called this way, the resolved value of the returned Promise is
- the number of bytes written to the target file.
-
- It very specifically requires the input to be an SQLite3
- database and throws if that's not the case. It does so in
- order to prevent this function from taking on a larger scope
- than it is specifically intended to. i.e. we do not want it to
- become a convenience for importing arbitrary files into OPFS.
-
- This routine rewrites the database header bytes in the output
- file (not the input array) to force disabling of WAL mode.
-
- On error this throws and the state of the input file is
- undefined (it depends on where the exception was triggered).
-
- On success, resolves to the number of bytes written.
- */
- opfsUtil.importDb = async function(filename, bytes){
- if( bytes instanceof Function ){
- return importDbChunked(filename, bytes);
+ with any code common to both the "opfs" and "opfs-wl" VFSes. Now
+ comes the VFS-dependent work...
+ */
+ return opfsVfs.bindVfs(util.nu({
+ xLock: function(pFile,lockType){
+ mTimeStart('xLock');
+ ++metrics.xLock.count;
+ const f = __openFiles[pFile];
+ let rc = 0;
+ /* All OPFS locks are exclusive locks. If xLock() has
+ previously succeeded, do nothing except record the lock
+ type. If no lock is active, have the async counterpart
+ lock the file. */
+ if( f.lockType ) {
+ f.lockType = lockType;
+ }else{
+ rc = opRun('xLock', pFile, lockType);
+ if( 0===rc ) f.lockType = lockType;
}
- if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
- util.affirmIsDb(bytes);
- const n = bytes.byteLength;
- const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true);
- let sah, err, nWrote = 0;
- try {
- const hFile = await hDir.getFileHandle(fnamePart, {create:true});
- sah = await hFile.createSyncAccessHandle();
- sah.truncate(0);
- nWrote = sah.write(bytes, {at: 0});
- if(nWrote != n){
- toss("Expected to write "+n+" bytes but wrote "+nWrote+".");
- }
- sah.write(new Uint8Array([1,1]), {at: 18}) /* force db out of WAL mode */;
- return nWrote;
- }catch(e){
- if( sah ){ await sah.close(); sah = undefined; }
- await hDir.removeEntry( fnamePart ).catch(()=>{});
- throw e;
- }finally{
- if( sah ) await sah.close();
+ mTimeEnd();
+ return rc;
+ },
+ xUnlock: function(pFile,lockType){
+ mTimeStart('xUnlock');
+ ++metrics.xUnlock.count;
+ const f = __openFiles[pFile];
+ let rc = 0;
+ if( capi.SQLITE_LOCK_NONE === lockType
+ && f.lockType ){
+ rc = opRun('xUnlock', pFile, lockType);
}
- };
-
+ if( 0===rc ) f.lockType = lockType;
+ mTimeEnd();
+ return rc;
+ }
+ }), function(sqlite3, vfs){
+ /* Post-VFS-registration initialization... */
if(sqlite3.oo1){
const OpfsDb = function(...args){
const opt = sqlite3.oo1.DB.dbCtorHelper.normalizeArgs(...args);
- opt.vfs = opfsVfs.$zName;
+ opt.vfs = vfs.$zName;
sqlite3.oo1.DB.dbCtorHelper.call(this, opt);
};
OpfsDb.prototype = Object.create(sqlite3.oo1.DB.prototype);
sqlite3.oo1.OpfsDb = OpfsDb;
OpfsDb.importDb = opfsUtil.importDb;
- sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenCallback(
- opfsVfs.pointer,
- function(oo1Db, sqlite3){
- /* Set a relatively high default busy-timeout handler to
- help OPFS dbs deal with multi-tab/multi-worker
- contention. */
- sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000);
- }
- );
- }/*extend sqlite3.oo1*/
-
- const sanityCheck = function(){
- const scope = wasm.scopedAllocPush();
- const sq3File = new sqlite3_file();
- try{
- const fid = sq3File.pointer;
- const openFlags = capi.SQLITE_OPEN_CREATE
- | capi.SQLITE_OPEN_READWRITE
- //| capi.SQLITE_OPEN_DELETEONCLOSE
- | capi.SQLITE_OPEN_MAIN_DB;
- const pOut = wasm.scopedAlloc(8);
- const dbFile = "/sanity/check/file"+randomFilename(8);
- const zDbFile = wasm.scopedAllocCString(dbFile);
- let rc;
- state.s11n.serialize("This is ä string.");
- rc = state.s11n.deserialize();
- log("deserialize() says:",rc);
- if("This is ä string."!==rc[0]) toss("String d13n error.");
- vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
- rc = wasm.peek(pOut,'i32');
- log("xAccess(",dbFile,") exists ?=",rc);
- rc = vfsSyncWrappers.xOpen(opfsVfs.pointer, zDbFile,
- fid, openFlags, pOut);
- log("open rc =",rc,"state.sabOPView[xOpen] =",
- state.sabOPView[state.opIds.xOpen]);
- if(0!==rc){
- error("open failed with code",rc);
- return;
- }
- vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
- rc = wasm.peek(pOut,'i32');
- if(!rc) toss("xAccess() failed to detect file.");
- rc = ioSyncWrappers.xSync(sq3File.pointer, 0);
- if(rc) toss('sync failed w/ rc',rc);
- rc = ioSyncWrappers.xTruncate(sq3File.pointer, 1024);
- if(rc) toss('truncate failed w/ rc',rc);
- wasm.poke(pOut,0,'i64');
- rc = ioSyncWrappers.xFileSize(sq3File.pointer, pOut);
- if(rc) toss('xFileSize failed w/ rc',rc);
- log("xFileSize says:",wasm.peek(pOut, 'i64'));
- rc = ioSyncWrappers.xWrite(sq3File.pointer, zDbFile, 10, 1);
- if(rc) toss("xWrite() failed!");
- const readBuf = wasm.scopedAlloc(16);
- rc = ioSyncWrappers.xRead(sq3File.pointer, readBuf, 6, 2);
- wasm.poke(readBuf+6,0);
- let jRead = wasm.cstrToJs(readBuf);
- log("xRead() got:",jRead);
- if("sanity"!==jRead) toss("Unexpected xRead() value.");
- if(vfsSyncWrappers.xSleep){
- log("xSleep()ing before close()ing...");
- vfsSyncWrappers.xSleep(opfsVfs.pointer,2000);
- log("waking up from xSleep()");
- }
- rc = ioSyncWrappers.xClose(fid);
- log("xClose rc =",rc,"sabOPView =",state.sabOPView);
- log("Deleting file:",dbFile);
- vfsSyncWrappers.xDelete(opfsVfs.pointer, zDbFile, 0x1234);
- vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
- rc = wasm.peek(pOut,'i32');
- if(rc) toss("Expecting 0 from xAccess(",dbFile,") after xDelete().");
- warn("End of OPFS sanity checks.");
- }finally{
- sq3File.dispose();
- wasm.scopedAllocPop(scope);
- }
- }/*sanityCheck()*/;
-
- W.onmessage = function({data}){
- //log("Worker.onmessage:",data);
- switch(data.type){
- case 'opfs-unavailable':
- /* Async proxy has determined that OPFS is unavailable. There's
- nothing more for us to do here. */
- promiseReject(new Error(data.payload.join(' ')));
- break;
- case 'opfs-async-loaded':
- /* Arrives as soon as the asyc proxy finishes loading.
- Pass our config and shared state on to the async
- worker. */
- W.postMessage({type: 'opfs-async-init',args: state});
- break;
- case 'opfs-async-inited': {
- /* Indicates that the async partner has received the 'init'
- and has finished initializing, so the real work can
- begin... */
- if(true===promiseWasRejected){
- break /* promise was already rejected via timer */;
- }
- try {
- sqlite3.vfs.installVfs({
- io: {struct: opfsIoMethods, methods: ioSyncWrappers},
- vfs: {struct: opfsVfs, methods: vfsSyncWrappers}
- });
- state.sabOPView = new Int32Array(state.sabOP);
- state.sabFileBufView = new Uint8Array(state.sabIO, 0, state.fileBufferSize);
- state.sabS11nView = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
- initS11n();
- if(options.sanityChecks){
- warn("Running sanity checks because of opfs-sanity-check URL arg...");
- sanityCheck();
- }
- if(thisThreadHasOPFS()){
- navigator.storage.getDirectory().then((d)=>{
- W.onerror = W._originalOnError;
- delete W._originalOnError;
- sqlite3.opfs = opfsUtil;
- opfsUtil.rootDirectory = d;
- log("End of OPFS sqlite3_vfs setup.", opfsVfs);
- promiseResolve();
- }).catch(promiseReject);
- }else{
- promiseResolve();
- }
- }catch(e){
- error(e);
- promiseReject(e);
- }
- break;
+ if( true ){
+ /* 2026-03-06: this was a design mis-decision and is
+ inconsistent with sqlite3_open() and friends, but is
+ retained against the risk of introducing regressions if
+ it's removed. */
+ sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenCallback(
+ opfsVfs.pointer,
+ function(oo1Db, sqlite3){
+ /* Set a relatively high default busy-timeout handler to
+ help OPFS dbs deal with multi-tab/multi-worker
+ contention. */
+ sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000);
}
- default: {
- const errMsg = (
- "Unexpected message from the OPFS async worker: " +
- JSON.stringify(data)
- );
- error(errMsg);
- promiseReject(new Error(errMsg));
- break;
- }
- }/*switch(data.type)*/
- }/*W.onmessage()*/;
- })/*thePromise*/;
- return thePromise;
+ );
+ }
+ }/*extend sqlite3.oo1*/
+ })/*bindVfs()*/;
}/*installOpfsVfs()*/;
-installOpfsVfs.defaultProxyUri =
- "sqlite3-opfs-async-proxy.js";
globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
- try{
- let proxyJs = installOpfsVfs.defaultProxyUri;
- if( sqlite3?.scriptInfo?.sqlite3Dir ){
- installOpfsVfs.defaultProxyUri =
- sqlite3.scriptInfo.sqlite3Dir + proxyJs;
- //sqlite3.config.warn("installOpfsVfs.defaultProxyUri =",installOpfsVfs.defaultProxyUri);
- }
- return installOpfsVfs().catch((e)=>{
- sqlite3.config.warn("Ignoring inability to install OPFS sqlite3_vfs:",e.message);
- });
- }catch(e){
- sqlite3.config.error("installOpfsVfs() exception:",e);
- return Promise.reject(e);
- }
+ return installOpfsVfs().catch((e)=>{
+ sqlite3.config.warn("Ignoring inability to install 'opfs' sqlite3_vfs:",e);
+ })
});
}/*sqlite3ApiBootstrap.initializers.push()*/);
/*
@@ -19479,6 +19667,10 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
*/
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
'use strict';
+ if( sqlite3.config.disable?.vfs?.['opfs-sahpool'] ){
+ return;
+ }
+
const toss = sqlite3.util.toss;
const toss3 = sqlite3.util.toss3;
const initPromises = Object.create(null) /* cache of (name:result) of VFS init results */;
@@ -20886,6 +21078,132 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
});
}/*installOpfsSAHPoolVfs()*/;
}/*sqlite3ApiBootstrap.initializers*/);
+/*
+ 2026-02-20
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ This file is a reimplementation of the "opfs" VFS (as distinct from
+ "opfs-sahpool") which uses WebLocks for locking instead of a bespoke
+ Atomics.wait()/notify() protocol. This file holds the "synchronous
+ half" of the VFS, whereas it shares the "asynchronous half" with the
+ "opfs" VFS.
+
+ Testing has failed to show any genuine functional difference between
+ these VFSes other than "opfs-wl" being able to dole out xLock()
+ requests in a strictly FIFO manner by virtue of WebLocks being
+ globally managed by the browser. This tends to lead to, but does not
+ guaranty, fairer distribution of locks. Differences are unlikely to
+ be noticed except, perhaps, under very high contention.
+
+ This file is intended to be appended to the main sqlite3 JS
+ deliverable somewhere after opfs-common-shared.c-pp.js.
+*/
+'use strict';
+globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
+ if( !sqlite3.opfs || sqlite3.config.disable?.vfs?.['opfs-wl'] ){
+ return;
+ }
+ const util = sqlite3.util,
+ toss = sqlite3.util.toss;
+ const opfsUtil = sqlite3.opfs;
+ const vfsName = 'opfs-wl';
+/**
+ installOpfsWlVfs() returns a Promise which, on success, installs an
+ sqlite3_vfs named "opfs-wl", suitable for use with all sqlite3 APIs
+ which accept a VFS. It is intended to be called via
+ sqlite3ApiBootstrap.initializers or an equivalent mechanism.
+
+ This VFS is essentially identical to the "opfs" VFS but uses
+ WebLocks for its xLock() and xUnlock() implementations.
+
+ Quirks specific to this VFS:
+
+ - The (officially undocumented) 'opfs-wl-disable' URL
+ argument will disable OPFS, making this function a no-op.
+
+ Aside from locking differences in the VFSes, this function
+ otherwise behaves the same as
+ sqlite3-vfs-opfs.c-pp.js:installOpfsVfs().
+*/
+const installOpfsWlVfs = async function(options){
+ options = opfsUtil.initOptions(vfsName,options);
+ if( !options ) return sqlite3;
+ const capi = sqlite3.capi,
+ state = opfsUtil.createVfsState(),
+ opfsVfs = state.vfs,
+ metrics = opfsVfs.metrics.counters,
+ mTimeStart = opfsVfs.mTimeStart,
+ mTimeEnd = opfsVfs.mTimeEnd,
+ opRun = opfsVfs.opRun,
+ debug = (...args)=>sqlite3.config.debug(vfsName+":",...args),
+ warn = (...args)=>sqlite3.config.warn(vfsName+":",...args),
+ __openFiles = opfsVfs.__openFiles;
+
+ //debug("state",JSON.stringify(options));
+ /*
+ At this point, createVfsState() has populated:
+
+ - state: the configuration object we share with the async proxy.
+
+ - opfsVfs: an sqlite3_vfs instance with lots of JS state attached
+ to it.
+
+ with any code common to both the "opfs" and "opfs-wl" VFSes. Now
+ comes the VFS-dependent work...
+ */
+ return opfsVfs.bindVfs(util.nu({
+ xLock: function(pFile,lockType){
+ mTimeStart('xLock');
+ //debug("xLock()...");
+ const f = __openFiles[pFile];
+ const rc = opRun('xLock', pFile, lockType);
+ if( !rc ) f.lockType = lockType;
+ mTimeEnd();
+ return rc;
+ },
+ xUnlock: function(pFile,lockType){
+ mTimeStart('xUnlock');
+ const f = __openFiles[pFile];
+ const rc = opRun('xUnlock', pFile, lockType);
+ if( !rc ) f.lockType = lockType;
+ mTimeEnd();
+ return rc;
+ }
+ }), function(sqlite3, vfs){
+ /* Post-VFS-registration initialization... */
+ if(sqlite3.oo1){
+ const OpfsWlDb = function(...args){
+ const opt = sqlite3.oo1.DB.dbCtorHelper.normalizeArgs(...args);
+ opt.vfs = vfs.$zName;
+ sqlite3.oo1.DB.dbCtorHelper.call(this, opt);
+ };
+ OpfsWlDb.prototype = Object.create(sqlite3.oo1.DB.prototype);
+ sqlite3.oo1.OpfsWlDb = OpfsWlDb;
+ OpfsWlDb.importDb = opfsUtil.importDb;
+ /* The "opfs" VFS variant adds a
+ oo1.DB.dbCtorHelper.setVfsPostOpenCallback() callback to set
+ a high busy_timeout. That was a design mis-decision and is
+ inconsistent with sqlite3_open() and friends, but is retained
+ against the risk of introducing regressions if it's removed.
+ This variant does not repeat that mistake.
+ */
+ }
+ })/*bindVfs()*/;
+}/*installOpfsWlVfs()*/;
+globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
+ return installOpfsWlVfs().catch((e)=>{
+ sqlite3.config.warn("Ignoring inability to install the",vfsName,"sqlite3_vfs:",e);
+ });
+});
+}/*sqlite3ApiBootstrap.initializers.push()*/);
/*
2022-07-22
diff --git a/src/bin/sqlite3.wasm b/src/bin/sqlite3.wasm
index 28b0920..c7336e9 100644
Binary files a/src/bin/sqlite3.wasm and b/src/bin/sqlite3.wasm differ
diff --git a/src/index.d.ts b/src/index.d.ts
index d860abe..cfd245d 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -1262,6 +1262,20 @@ export class JsStorageDb extends Database {
clearStorage(): Sqlite3Result;
}
+export type KvvfsNamespace = {
+ /** Clears all kvvfs-owned state for the given database. */
+ clear: (which?: string) => void;
+
+ /** Returns whether the kvvfs has storage for the given database. */
+ exists: (which: string) => boolean;
+
+ /** Returns an estimate of how many bytes of storage are used by kvvfs. */
+ estimateSize: (which?: string) => Sqlite3Result;
+
+ /** Removes the given kvvfs-backed database. */
+ unlink: (which: string) => void;
+};
+
/**
* SQLite3 database backed by the Origin Private File System API.
*
@@ -2169,6 +2183,9 @@ export type Sqlite3Static = {
/** The namespace for the C-style APIs. */
capi: CAPI;
+ /** Convenience helpers for interacting with the kvvfs. */
+ kvvfs: KvvfsNamespace;
+
/**
* WASM-specific utilities, abstracted to be independent of, and configurable
* for use with, arbitrary WASM runtime environments.
@@ -2178,6 +2195,7 @@ export type Sqlite3Static = {
/** The OO API #1. */
oo1: {
OpfsDb: typeof OpfsDatabase;
+ OpfsWlDb: typeof OpfsDatabase;
JsStorageDb: typeof JsStorageDb;
DB: typeof Database;
};
diff --git a/tsconfig.json b/tsconfig.json
index 61ba9f8..f792bce 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -23,5 +23,5 @@
"skipLibCheck": true,
"module": "NodeNext"
},
- "include": ["tsdown.config.ts", "src"]
+ "include": ["tsdown.config.ts", "oxfmt.config.ts", "src"]
}
diff --git a/vitest.config.ts b/vitest.config.ts
index b6d6f87..ae563b9 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -1,20 +1,21 @@
import { defineConfig, type ViteUserConfig } from 'vitest/config';
import { playwright } from '@vitest/browser-playwright';
+const browserIsolationHeaders = {
+ 'Cross-Origin-Embedder-Policy': 'require-corp',
+ 'Cross-Origin-Opener-Policy': 'same-origin',
+};
+
const vitestConfig: ViteUserConfig = defineConfig({
- server: {
- headers: {
- 'Cross-Origin-Embedder-Policy': 'require-corp',
- 'Cross-Origin-Opener-Policy': 'same-origin',
- },
- },
plugins: [
{
name: 'configure-response-headers',
configureServer: (server) => {
server.middlewares.use((_req, res, next) => {
- res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
- res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
+ for (const [headerName, headerValue] of Object.entries(browserIsolationHeaders)) {
+ res.setHeader(headerName, headerValue);
+ }
+
next();
});
},
@@ -40,14 +41,15 @@ const vitestConfig: ViteUserConfig = defineConfig({
enabled: true,
headless: true,
screenshotFailures: false,
- provider: playwright({
- launchOptions: {
- args: ['--enable-features=SharedArrayBuffer'],
- },
- }),
+ provider: playwright(),
instances: [
{
browser: 'chromium',
+ provider: playwright({
+ launchOptions: {
+ args: ['--enable-features=SharedArrayBuffer'],
+ },
+ }),
},
],
},