sqlite-worker
Advanced tools
Comparing version 0.3.3 to 0.4.0
'use strict'; | ||
const {assign} = Object; | ||
const {assign, dist} = require('./utils.js'); | ||
@@ -13,3 +13,3 @@ const cache = new Map; | ||
function SQLiteWorker(options) { | ||
const library = __filename; | ||
const base = options.dist || dist; | ||
const query = how => (template, ...values) => post(how, {template, values}); | ||
@@ -23,4 +23,3 @@ const post = (action, options) => new Promise((resolve, reject) => { | ||
options.worker || | ||
(library.slice(0, library.lastIndexOf('/')) + '/worker.js'), | ||
{type: 'module'} | ||
(base + '/worker.js') | ||
), { | ||
@@ -36,3 +35,3 @@ onmessage({data: {id, result, error}}) { | ||
}); | ||
return post('init', assign({library}, options)).then(() => ({ | ||
return post('init', assign({library: base + '/init.js'}, options)).then(() => ({ | ||
all: query('all'), | ||
@@ -39,0 +38,0 @@ get: query('get'), |
'use strict'; | ||
const SQLiteTag = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('sqlite-tag')); | ||
const {assign, dist, load} = require('./utils.js'); | ||
@@ -7,4 +8,2 @@ const STORE = 'sqlite'; | ||
const {assign} = Object; | ||
const opener = (name, version = 1) => new Promise((resolve, onerror) => { | ||
@@ -30,14 +29,8 @@ assign(indexedDB.open(name, version), { | ||
const init = (options = {}) => new Promise((resolve, onerror) => { | ||
const {url} = {url: __filename}; | ||
const dir = options.dir || (url.slice(0, url.lastIndexOf('/')) + '/../dist'); | ||
// NEEDED DUE UGLY sql.js EXPORT DANCE | ||
self.exports = {}; | ||
self.module = {exports}; | ||
import(dir + '/sql-wasm.js').then(() => { | ||
const initSqlJs = self.module.exports; | ||
delete self.exports; | ||
const base = options.dist || dist; | ||
load(base + '/sql-wasm.js').then(({default: initSqlJs}) => { | ||
Promise.all([ | ||
opener(options.name || 'sqlite-worker'), | ||
initSqlJs({ | ||
locateFile: file => dir + '/' + file | ||
locateFile: file => base + '/' + file | ||
}) | ||
@@ -44,0 +37,0 @@ ]).then( |
'use strict'; | ||
const {load} = require('./utils.js'); | ||
let db = null; | ||
@@ -21,3 +23,3 @@ | ||
if (!db) | ||
db = import(options.library).then(({init}) => init(options)); | ||
db = load(options.library).then(({init}) => init(options)); | ||
return db.then( | ||
@@ -24,0 +26,0 @@ () => postMessage({id, result: 'OK'}), |
@@ -1,1 +0,1 @@ | ||
const e=new WeakMap,t=(t,...n)=>{const{t:o,v:s}=((e,t)=>{const n=[e[0]],o=[];for(let s=0,l=0,a=0,{length:c}=t;l<c;l++)t[l]instanceof r?n[s]+=t[l].v+e[l+1]:(o[a++]=l,n[++s]=e[l+1]);return{t:n,v:o}})(t,n),l=e.get(t)||e.set(t,{}).get(t);return(l[o]||(l[o]=[o])).concat(s.map((e=>n[e])))};function r(e){this.v=e}const n=(e,r)=>(n,...s)=>new Promise(((a,c)=>{n.some(l)&&c(o(new Error("SQLITE_ERROR: SQL injection hazard")));const[i,...u]=t(n,...s);e[r](i.join("?"),u,((e,t)=>{e?c(e):a(t)}))})),o=e=>(e.code="SQLITE_ERROR",e),s=(e,...t)=>new r(function(e){for(var t=e[0],r=1,n=arguments.length;r<n;r++)t+=arguments[r]+e[r];return t}(e,...t)),l=e=>e.includes("?");function a(e){return{all:n(e,"all"),get:n(e,"get"),query:n(e,"run"),raw:s}}const{assign:c}=Object,i=(e,t=1)=>new Promise(((r,n)=>{c(indexedDB.open(e,t),{onupgradeneeded({target:{result:e,transaction:t}}){e.objectStoreNames.contains("sqlite")||e.createObjectStore("sqlite").createIndex("buffer","buffer",{unique:!0}),c(t,{oncomplete(){r(e)}})},onsuccess({target:{result:e}}){r(e)},onerror:n})})),u=(e={})=>new Promise(((t,r)=>{const{url:n}=import.meta,o=e.dir||n.slice(0,n.lastIndexOf("/"))+"/../dist";self.exports={},self.module={exports:exports},import(o+"/sql-wasm.js").then((()=>{const n=self.module.exports;delete self.exports,Promise.all([i(e.name||"sqlite-worker"),n({locateFile:e=>o+"/"+e})]).then((([n,{Database:o}])=>{const s=e=>n.transaction(["sqlite"],e).objectStore("sqlite");c(s("readonly").get("buffer"),{onsuccess(){let r=Promise.resolve();const{result:n}=this,l=new o(n||e.database||new Uint8Array(0)),i=()=>{r=r.then((()=>new Promise(((t,r)=>{const n=l.export();c(s("readwrite").put(n,"buffer").transaction,{oncomplete(){t(),e.update&&e.update(n)},onabort:r,onerror:r})}))))};n||i();const{all:u,get:f,query:p,raw:d}=a({all(e,t,r){try{const n=l.exec(e,t),o=[];n.forEach(m,o),r(null,o)}catch(e){r(e)}},get(e,t,r){try{const n=l.exec(e+" LIMIT 1",t),o=[];n.forEach(m,o),r(null,o.shift()||null)}catch(e){r(e)}},run(e,t,r){try{r(null,l.run(e,t))}catch(e){r(e)}}});let g=0;t({all:u,get:f,raw:d,query(t){return/\b(?:INSERT|DELETE|UPDATE)\b/i.test(t[0])&&(clearTimeout(g),g=setTimeout(i,e.timeout||250)),p.apply(this,arguments)}})},onerror:r})}),r)}))}));function m({columns:e,values:t}){for(let{length:r}=t,n=0;n<r;n++){const r=t[n],o={};for(let{length:t}=e,n=0;n<t;n++)o[e[n]]=r[n];this.push(o)}}const{assign:f}=Object,p=new Map;let d=0;function g(e){const t=import.meta.url,r=e=>(t,...r)=>n(e,{template:t,values:r}),n=(e,t)=>new Promise(((r,n)=>{const s=d++;p.set(s,{resolve:r,reject:n}),o.postMessage({id:s,action:e,options:t})})),o=f(new Worker(e.worker||t.slice(0,t.lastIndexOf("/"))+"/worker.js",{type:"module"}),{onmessage({data:{id:e,result:t,error:r}}){const{resolve:n,reject:o}=p.get(e);p.delete(e),r?o(r):n(t)}});return n("init",f({library:t},e)).then((()=>({all:r("all"),get:r("get"),query:r("query")})))}export{g as SQLiteWorker,u as init}; | ||
const{assign:e}=Object,t="function"==typeof importScripts,r=t?".":import.meta.url.replace(/\/[^/]*$/,""),o=r=>new Promise((o=>{const n=()=>{const e=self.module.exports;delete self.exports,self.module=void 0,o(e)};if(self.exports={},self.module={exports:exports},t)importScripts(r),n();else{const{head:t}=document;e(t.appendChild(document.createElement("script")),{onload(){t.removeChild(this),n()},src:r})}}));const n=new WeakMap,s=(e,...t)=>{const{t:r,v:o}=((e,t)=>{const r=[e[0]],o=[];for(let n=0,s=0,c=0,{length:a}=t;s<a;s++)t[s]instanceof l?r[n]+=t[s].v+e[s+1]:(o[c++]=s,r[++n]=e[s+1]);return{t:r,v:o}})(e,t),s=n.get(e)||n.set(e,{}).get(e);return(s[r]||(s[r]=[r])).concat(o.map((e=>t[e])))};function l(e){this.v=e}const c=(e,t)=>(r,...o)=>new Promise(((n,l)=>{r.some(u)&&l(a(new Error("SQLITE_ERROR: SQL injection hazard")));const[c,...i]=s(r,...o);e[t](c.join("?"),i,((e,t)=>{e?l(e):n(t)}))})),a=e=>(e.code="SQLITE_ERROR",e),i=(e,...t)=>new l(function(e){for(var t=e[0],r=1,o=arguments.length;r<o;r++)t+=arguments[r]+e[r];return t}(e,...t)),u=e=>e.includes("?");function d(e){return{all:c(e,"all"),get:c(e,"get"),query:c(e,"run"),raw:i}}const p=(t,r=1)=>new Promise(((o,n)=>{e(indexedDB.open(t,r),{onupgradeneeded({target:{result:t,transaction:r}}){t.objectStoreNames.contains("sqlite")||t.createObjectStore("sqlite").createIndex("buffer","buffer",{unique:!0}),e(r,{oncomplete(){o(t)}})},onsuccess({target:{result:e}}){o(e)},onerror:n})})),m=(t={})=>new Promise(((n,s)=>{const l=t.dist||r;o(l+"/sql-wasm.js").then((({default:r})=>{Promise.all([p(t.name||"sqlite-worker"),r({locateFile:e=>l+"/"+e})]).then((([r,{Database:o}])=>{const l=e=>r.transaction(["sqlite"],e).objectStore("sqlite");e(l("readonly").get("buffer"),{onsuccess(){let r=Promise.resolve();const{result:s}=this,c=new o(s||t.database||new Uint8Array(0)),a=()=>{r=r.then((()=>new Promise(((r,o)=>{const n=c.export();e(l("readwrite").put(n,"buffer").transaction,{oncomplete(){r(),t.update&&t.update(n)},onabort:o,onerror:o})}))))};s||a();const{all:i,get:u,query:p,raw:m}=d({all(e,t,r){try{const o=c.exec(e,t),n=[];o.forEach(f,n),r(null,n)}catch(e){r(e)}},get(e,t,r){try{const o=c.exec(e+" LIMIT 1",t),n=[];o.forEach(f,n),r(null,n.shift()||null)}catch(e){r(e)}},run(e,t,r){try{r(null,c.run(e,t))}catch(e){r(e)}}});let h=0;n({all:i,get:u,raw:m,query(e){return/\b(?:INSERT|DELETE|UPDATE)\b/i.test(e[0])&&(clearTimeout(h),h=setTimeout(a,t.timeout||250)),p.apply(this,arguments)}})},onerror:s})}),s)}))}));function f({columns:e,values:t}){for(let{length:r}=t,o=0;o<r;o++){const r=t[o],n={};for(let{length:t}=e,o=0;o<t;o++)n[e[o]]=r[o];this.push(n)}}const h=new Map;let g=0;function w(t){const o=t.dist||r,n=e=>(t,...r)=>s(e,{template:t,values:r}),s=(e,t)=>new Promise(((r,o)=>{const n=g++;h.set(n,{resolve:r,reject:o}),l.postMessage({id:n,action:e,options:t})})),l=e(new Worker(t.worker||o+"/worker.js"),{onmessage({data:{id:e,result:t,error:r}}){const{resolve:o,reject:n}=h.get(e);h.delete(e),r?n(r):o(t)}});return s("init",e({library:o+"/init.js"},t)).then((()=>({all:n("all"),get:n("get"),query:n("query")})))}export{w as SQLiteWorker,m as init}; |
@@ -1,1 +0,1 @@ | ||
let e=null;const t=(e,t,s,{template:a,values:r})=>{e.then((e=>{e[t].apply(null,[a].concat(r)).then((e=>{postMessage({id:s,result:e})}),(({message:e})=>{postMessage({id:s,error:e})}))}))};addEventListener("message",(({data:{id:s,action:a,options:r}})=>{switch(a){case"init":return e||(e=import(r.library).then((({init:e})=>e(r)))),e.then((()=>postMessage({id:s,result:"OK"})),(({message:e})=>postMessage({id:s,error:e})));case"all":return t(e,"all",s,r);case"get":return t(e,"get",s,r);case"query":return t(e,"query",s,r)}})); | ||
!function(){"use strict";const{assign:e}=Object,t="function"==typeof importScripts,s=s=>new Promise((r=>{const o=()=>{const e=self.module.exports;delete self.exports,self.module=void 0,r(e)};if(self.exports={},self.module={exports:exports},t)importScripts(s),o();else{const{head:t}=document;e(t.appendChild(document.createElement("script")),{onload(){t.removeChild(this),o()},src:s})}}));let r=null;const o=(e,t,s,{template:r,values:o})=>{e.then((e=>{e[t].apply(null,[r].concat(o)).then((e=>{postMessage({id:s,result:e})}),(({message:e})=>{postMessage({id:s,error:e})}))}))};addEventListener("message",(({data:{id:e,action:t,options:n}})=>{switch(t){case"init":return r||(r=s(n.library).then((({init:e})=>e(n)))),r.then((()=>postMessage({id:e,result:"OK"})),(({message:t})=>postMessage({id:e,error:t})));case"all":return o(r,"all",e,n);case"get":return o(r,"get",e,n);case"query":return o(r,"query",e,n)}}))}(); |
@@ -1,2 +0,2 @@ | ||
const {assign} = Object; | ||
import {assign, dist} from './utils.js'; | ||
@@ -10,3 +10,3 @@ const cache = new Map; | ||
export function SQLiteWorker(options) { | ||
const library = import.meta.url; | ||
const base = options.dist || dist; | ||
const query = how => (template, ...values) => post(how, {template, values}); | ||
@@ -20,4 +20,3 @@ const post = (action, options) => new Promise((resolve, reject) => { | ||
options.worker || | ||
(library.slice(0, library.lastIndexOf('/')) + '/worker.js'), | ||
{type: 'module'} | ||
(base + '/worker.js') | ||
), { | ||
@@ -33,3 +32,3 @@ onmessage({data: {id, result, error}}) { | ||
}); | ||
return post('init', assign({library}, options)).then(() => ({ | ||
return post('init', assign({library: base + '/init.js'}, options)).then(() => ({ | ||
all: query('all'), | ||
@@ -36,0 +35,0 @@ get: query('get'), |
import SQLiteTag from 'sqlite-tag'; | ||
import {assign, dist, load} from './utils.js'; | ||
@@ -6,4 +7,2 @@ const STORE = 'sqlite'; | ||
const {assign} = Object; | ||
const opener = (name, version = 1) => new Promise((resolve, onerror) => { | ||
@@ -29,14 +28,8 @@ assign(indexedDB.open(name, version), { | ||
export const init = (options = {}) => new Promise((resolve, onerror) => { | ||
const {url} = import.meta; | ||
const dir = options.dir || (url.slice(0, url.lastIndexOf('/')) + '/../dist'); | ||
// NEEDED DUE UGLY sql.js EXPORT DANCE | ||
self.exports = {}; | ||
self.module = {exports}; | ||
import(dir + '/sql-wasm.js').then(() => { | ||
const initSqlJs = self.module.exports; | ||
delete self.exports; | ||
const base = options.dist || dist; | ||
load(base + '/sql-wasm.js').then(({default: initSqlJs}) => { | ||
Promise.all([ | ||
opener(options.name || 'sqlite-worker'), | ||
initSqlJs({ | ||
locateFile: file => dir + '/' + file | ||
locateFile: file => base + '/' + file | ||
}) | ||
@@ -43,0 +36,0 @@ ]).then( |
@@ -0,1 +1,3 @@ | ||
import {load} from './utils.js'; | ||
let db = null; | ||
@@ -20,3 +22,3 @@ | ||
if (!db) | ||
db = import(options.library).then(({init}) => init(options)); | ||
db = load(options.library).then(({init}) => init(options)); | ||
return db.then( | ||
@@ -23,0 +25,0 @@ () => postMessage({id, result: 'OK'}), |
{ | ||
"name": "sqlite-worker", | ||
"version": "0.3.3", | ||
"version": "0.4.0", | ||
"description": "A simple, and persistent, SQLite database for Web and Workers", | ||
"main": "./cjs/index.js", | ||
"scripts": { | ||
"build": "npm run import && npm run cjs && npm run rollup:es && npm run worker", | ||
"build": "npm run import && npm run cjs && npm run rollup:es && npm run rollup:init && npm run rollup:sw && npm run rollup:worker", | ||
"import": "cp node_modules/sql.js/dist/sql-wasm.{js,wasm} dist/", | ||
"cjs": "ascjs --no-default esm cjs && npm run cjs:fix", | ||
"cjs:fix": "sed -i 's/const library = .*/const library = __filename;/' cjs/index.js && sed -i 's/const {url} = .*/const {url} = {url: __filename};/' cjs/init.js", | ||
"cjs:fix": "sed -i 's/{url:[^}]*}/{url: __filename}/' cjs/utils.js", | ||
"rollup:es": "rollup --config rollup/es.config.js", | ||
"worker": "terser esm/worker.js --module -c -m -o dist/worker.js" | ||
"rollup:init": "rollup --config rollup/init.config.js && sed -i 's/const dist = .*/const dist = \".\";/' dist/tmp.js && terser dist/tmp.js --module -c -m -o dist/init.js && rm dist/tmp.js", | ||
"rollup:sw": "rollup --config rollup/sw.config.js && sed -i 's/exports.init =/return/; s/var sqliteWorker =/self.sqliteWorker =/' dist/tmp.js && terser dist/tmp.js -c -m -o dist/sw.js && rm dist/tmp.js", | ||
"rollup:worker": "rollup --config rollup/worker.config.js && sed -i 's/const dist = .*//' dist/tmp.js && terser dist/tmp.js -c -m -o dist/worker.js && rm dist/tmp.js" | ||
}, | ||
@@ -29,2 +31,3 @@ "keywords": [ | ||
"rollup": "^2.36.1", | ||
"rollup-plugin-includepaths": "^0.2.4", | ||
"rollup-plugin-terser": "^7.0.2", | ||
@@ -45,2 +48,6 @@ "sql.js": "^1.4.0", | ||
}, | ||
"./sw": { | ||
"import": "./dist/sw.js", | ||
"default": "./dist/sw.js" | ||
}, | ||
"./worker": { | ||
@@ -47,0 +54,0 @@ "import": "./esm/worker.js", |
168
README.md
@@ -9,39 +9,104 @@ # sqlite-worker | ||
### ⚠ Warning about Workers | ||
## How to use this module | ||
Obviously I was too naive to believe I could `import(...)` modules in 2021 inside workers too, but [the reality is different](https://stackoverflow.com/a/45578811/2800218): | ||
The most important thing for this module to work, is being able to reach its pre-built, and pre-optimized files, via its own [dist](./dist/) folder. | ||
* **Chrome** works without any issue whatsoever as *Worker* from the main thread, but *Service Worker* apparently cannot `import(...)` anything | ||
* **Firefox** never had a dynamic `import`, or even static, I believe, so *Worker* here won't work | ||
* **WebKit** has issues since 2016 too | ||
The resolution is done automatically, whenever this modules is imported via native *ESM*, but due to [a long standing bug](https://stackoverflow.com/a/45578811/2800218) that involves both *Web* and *Service* *Workers* across browsers, such `dist` folder *must* be specified manually, whenever this module is used directly within either a *Service Worker*, or a generic *Web Worker*. | ||
This means that while this module recommendation is to use its *SQLiteWorker* export, or to use the directly its *init* export via *Service Worker*, none of these recommendation actually work as expected, so that for a cross browser experience, using the *init* export from the main thread is the only option. | ||
Please note the *WASM* module *should* also offload from the main thread, but the thing is that I'd love for browsers to fix their inconsistencies regarding ES Modules and remove this whole warning session once they do. | ||
### Importing on Web pages via ESM | ||
In any generic page, it is possible to import this module via native *ESM* with, or without, the help of a *CDN*: | ||
## How to import this module | ||
```html | ||
<script type="module"> | ||
// no ?module needed, it's the main export in unpkg | ||
import {SQLiteWorker} from '//unpkg.com/sqlite-worker'; | ||
This module is pre-bundled in a way it should work, and survive, 3rd party tools, but it needs to be able to reach its own `dist` folder. | ||
SQLiteWorker({name: 'my-db'}).then(async ({all, get, query}) => { | ||
await query`CREATE TABLE IF NOT EXISTS todos (id INTEGER PRIMARY KEY, value TEXT)`; | ||
const {total} = await get`SELECT COUNT(id) as total FROM todos`; | ||
if (total < 1) { | ||
console.log('Inserting some value'); | ||
await query`INSERT INTO todos (value) VALUES (${'a'})`; | ||
await query`INSERT INTO todos (value) VALUES (${'b'})`; | ||
await query`INSERT INTO todos (value) VALUES (${'c'})`; | ||
} | ||
console.log(await all`SELECT * FROM todos`); | ||
}); | ||
</script> | ||
``` | ||
Accordingly, the easiest way to use this module is the following: | ||
If the current [dist](./dist/) folder is pre-installed though, `import {SQLiteWorker} from './js/sqlite-worker/dist/index.js';` would work too. | ||
While above example would run *sqlite-worker* through a *Web Worker*, which is recommended, it is also possible to bootstrap this module right away in the main thread. | ||
```html | ||
<script type="module"> | ||
// no ?module needed, it's the main export in unpkg | ||
import {init} from '//unpkg.com/sqlite-worker'; | ||
init({name: 'my-db'}).then(async ({all, get, query}) => { | ||
// ... same code as before ... | ||
}); | ||
</script> | ||
``` | ||
Beside being slightly faster, avoiding the worker `postMessage` dance, the main difference between `SQLiteWorker` and `init` is that `init` accepts an extra **update** option, that could be used to synchronize remotely the local database, whenever it's needed. | ||
```js | ||
// note: no ?module needed, this is already exported as ESM | ||
import {init, SQLiteWorker} from '//unpkg.com/sqlite-worker'; | ||
import {init} from 'sqlite-worker'; | ||
// either direct init([options]) | ||
// or use SQLiteWorker with defaults (Chrome only) | ||
SQLiteWorker({name: 'my-db'}).then(() => { | ||
console.log('ready'); | ||
init({name: 'my-db', update(uInt8Array) { | ||
// store the latest uInt8Array somewhere | ||
}}); | ||
``` | ||
The very same stored buffer could be used in the future to start from last stored update in case the client erased its data (changed phone, IndexedDB cleared data, etc.). | ||
This functionality could also be used in a *Service Worker*, but the initialization in there would be slightly different. | ||
### Importing on both Web and Service Worker | ||
Instead of `import`, we must use `importScripts` to have cross browser compatibility, but this is not an issue, as this module provides, through its [dist](./dist/) folder, everything needed to do so, as long as such folder is reachable: | ||
```js | ||
// will add a `sqliteWorker` global initiator | ||
importScripts('../../dist/sw.js'); | ||
sqliteWorker({ | ||
// **IMPORTANT** | ||
dist: '/js/sqlite-worker/dist', | ||
name: 'my-db' | ||
}).then(async ({all, get, query}) => { | ||
await query`CREATE TABLE IF NOT EXISTS todos (id INTEGER PRIMARY KEY, value TEXT)`; | ||
const {total} = await get`SELECT COUNT(id) as total FROM todos`; | ||
if (total < 1) { | ||
console.log('Inserting some value'); | ||
await query`INSERT INTO todos (value) VALUES (${'a'})`; | ||
await query`INSERT INTO todos (value) VALUES (${'b'})`; | ||
await query`INSERT INTO todos (value) VALUES (${'c'})`; | ||
} | ||
console.table(await all`SELECT * FROM todos`); | ||
}); | ||
``` | ||
Options defaults, such as `dir` and `library`, or even the `Worker` path, are all resolved automatically, as long as all `dist` files are reachable. | ||
The **dist** option could also be used from generic pages, but usually with `import.meta.url` such information can be easily, automatically, retrieved by the module itself. | ||
It is, however, possible to change these configurations. | ||
#### ℹ About Bundlers | ||
Because of its own folder dependencies, including the *WASM* file, and the module, needed to bootstripe SQLite 3, importing this module via bundlers *might* break its actual execution if: | ||
* all files are not also included in the bundle folder | ||
* the bundler transform `import.meta.url` is a "*too smart*" way, breaking its native functionality | ||
* something else some bundler might do | ||
However, as previously mentioned, if the `dist` option is provided, everything *should* be fine, even if bundled. | ||
### Initialization Options | ||
@@ -52,2 +117,3 @@ | ||
* **name**: the persistent database name. By default it's the *string* `'sqlite-worker'` | ||
* **dist**: the folder, as *string*, containing [all distribution files of this module](./dist/). This is resolved automatically on pages that are not workers, but it must be provided within workers. | ||
* **database**: an initial SQLite database, as `Uint8Array` instance. This is used only the very first time, and it fallbacks to `new Uint8Array(0)`. | ||
@@ -64,3 +130,2 @@ * **timeout**: minimum interval, in milliseconds, between saves, to make storing, and exporting, the database, less greedy. By default it's the *number* `250`. | ||
#### SQLiteWorker Extra Options | ||
@@ -74,14 +139,4 @@ | ||
#### Extra Options | ||
### After Initialization Helpers | ||
These options are resolved by default internally to find the right files. Change these options only if you know what you are doing. | ||
* **dir**: where to find `sql.js` files. By default it's the current module folder plus `/../sqlite`. | ||
* **library**: where to find the `sqlite-worker` library itself. By default is wherever the module has been exported. | ||
### Module exports | ||
Both `init(...)` and `SQLiteWorker(...)` resolves with the [sqlite-tag API](https://github.com/WebReflection/sqlite-tag#api), except for the `raw` utility, which is not implemented via the *Worker* interface, but it's exported within the `init(...)`, as it requires a special instance that won't survive `postMessage` dance. | ||
@@ -99,55 +154,6 @@ | ||
### Direct usage | ||
This is currently the cross browser way to use this module, and it won't work within a *Service Worker* until Chrome fixes its bug. | ||
```js | ||
import {init} from 'sqlite-worker'; | ||
// init([options]) | ||
init({name: 'my-db'}).then(async ({all, get, query}) => { | ||
await query`CREATE TABLE IF NOT EXISTS todos (id INTEGER PRIMARY KEY, value TEXT)`; | ||
const {total} = await get`SELECT COUNT(id) as total FROM todos`; | ||
if (total < 1) { | ||
console.log('Inserting some value'); | ||
await query`INSERT INTO todos (value) VALUES (${'a'})`; | ||
await query`INSERT INTO todos (value) VALUES (${'b'})`; | ||
await query`INSERT INTO todos (value) VALUES (${'c'})`; | ||
} | ||
console.log(await all`SELECT * FROM todos`); | ||
}); | ||
``` | ||
### Worker usage (Chrome only) | ||
This module can also be used as *Worker*, which is a recommendation where the browser is compatible. | ||
If specified, you can pass your own worker via the `worker` option, but by default, this module can be initialized as such: | ||
```js | ||
import {SQLiteWorker} from 'sqlite-worker'; | ||
// SQLiteWorker([options]) | ||
SQLiteWorker({name: 'my-db'}) | ||
.then(async ({all, get, query}) => { | ||
await query`CREATE TABLE IF NOT EXISTS todos (id INTEGER PRIMARY KEY, value TEXT)`; | ||
const {total} = await get`SELECT COUNT(id) as total FROM todos`; | ||
if (total < 1) { | ||
console.log('Inserting some value'); | ||
await query`INSERT INTO todos (value) VALUES (${'a'})`; | ||
await query`INSERT INTO todos (value) VALUES (${'b'})`; | ||
await query`INSERT INTO todos (value) VALUES (${'c'})`; | ||
} | ||
console.log(await all`SELECT * FROM todos`); | ||
}); | ||
``` | ||
## Compatibility | ||
This module requires a browser compatible with *WASM* and dynamic `import(...)`. This module won't work in old Edge or IE, as these don't even know what's a *Service Worker*. | ||
This module requires a browser compatible with *WASM* and native *ESM* `import`. | ||
Please note if you bundle this module there are chances it might not work as expected, as it needs to import *WASM* and other files at runtime, and bundlers might not give it a chance to find these files. Keep the `dist` folder as it is, and import this module from it. | ||
This module won't work in old Edge or IE. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1224259
18
740
155
10