@lo-fi/client-storage
Advanced tools
Comparing version 0.9.0 to 0.10.0
{ | ||
"name": "@lo-fi/client-storage", | ||
"description": "simple key-value storage API backed by various client storage mechanisms", | ||
"version": "0.9.0", | ||
"description": "Simple key-value storage API backed by various client storage mechanisms", | ||
"version": "0.10.0", | ||
"exports": { | ||
@@ -9,4 +9,5 @@ "./idb": "./dist/adapter.idb.mjs", | ||
"./session-storage": "./dist/adapter.session-storage.mjs", | ||
"./cookie": "./dist/adapter.cookie.mjs", | ||
"./opfs": "./dist/adapter.opfs.mjs", | ||
"./cookie": "./dist/adapter.cookie.mjs" | ||
"./opfs-worker": "./dist/adapter.opfs-worker.mjs" | ||
}, | ||
@@ -17,4 +18,5 @@ "browser": { | ||
"@lo-fi/client-storage/session-storage": "./dist/adapter.session-storage.mjs", | ||
"@lo-fi/client-storage/cookie": "./dist/adapter.cookie.mjs", | ||
"@lo-fi/client-storage/opfs": "./dist/adapter.opfs.mjs", | ||
"@lo-fi/client-storage/cookie": "./dist/adapter.cookie.mjs" | ||
"@lo-fi/client-storage/opfs-worker": "./dist/adapter.opfs-worker.mjs" | ||
}, | ||
@@ -21,0 +23,0 @@ "scripts": { |
@@ -39,4 +39,10 @@ # Client Storage | ||
* `OPFS`: [Origin Private File System](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system), specifically [virtual origin filesystem](https://developer.mozilla.org/en-US/docs/Web/API/StorageManager/getDirectory) | ||
* `opfs`: [Origin Private File System (OPFS)](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system), specifically [the virtual origin filesystem](https://developer.mozilla.org/en-US/docs/Web/API/StorageManager/getDirectory) | ||
**Warning:** [Browser support for `write()`](https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/write#browser_compatibility) into OPFS from the main thread (as this adapter does) is limited to desktop (not mobile!) Chromium and Firefox browsers. See `opfs-worker` for broader device/browser support. | ||
* `opfs-worker`: Uses a Web Worker (background thread) for OPFS access, specifically to [expand OPFS support to most devices/browsers ](https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createSyncAccessHandle#browser_compatibility) (via synchronous `write()` in a Web Worker or Service Worker). | ||
**Warning:** Web workers in some cases require modified security settings (for the site/app) -- for example, [a Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), specifically [the `worker-src` directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/worker-src). | ||
Each of these client-side storage mechanisms has its own pros/cons, so choice should be made carefully. | ||
@@ -54,3 +60,3 @@ | ||
try { | ||
set("session-jwt",sessionJWT); | ||
await set("session-jwt",sessionJWT); | ||
} | ||
@@ -84,8 +90,4 @@ catch (err) { | ||
The [Origin Private File System](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system) (OPFS) web feature can be used to read/write "files" in a virtual filesystem on the client's device (private to the page's origin). The `opfs` adapter provided with this library creates JSON "files" in this OPFS to store the vault data, one per vault. | ||
The [Origin Private File System (OPFS)](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system) web feature can be used to read/write "files" in a virtual filesystem on the client's device (private to the page's origin). The `opfs` and `opfs-worker` adapters provided with this library create JSON "files" in OPFS to store the vault data, one file per vault. | ||
Be aware: [the ability to asynchronously `write()`](https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/write#browser_compatibility) on the main browser thread, into OPFS, is currently only supported on desktop (not mobile!) Chromium and Firefox browsers. | ||
However, there is [widespread browser/device support for synchronous `write()`](https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createSyncAccessHandle#browser_compatibility) into OPFS, if done off-thread in a background worker (Web Worker, Service Worker). The `opfs` adapter does *not currently* support this approach, but it may in the future. | ||
## Deployment / Import | ||
@@ -112,3 +114,3 @@ | ||
The bundler tool should pick up and find whatever files (and dependencies) needed. | ||
The bundler tool should pick up and find whatever files (and dependencies) are needed. | ||
@@ -128,2 +130,3 @@ ### Without using a bundler | ||
"client-storage/opfs": "/path/to/js-assets/client-storage/adapter.opfs.mjs", | ||
"client-storage/opfs-worker": "/path/to/js-assets/client-storage/adapter.opfs-worker.mjs", | ||
@@ -130,0 +133,0 @@ "idb-keyval": "/path/to/js-assets/client-storage/external/idb-keyval.js" |
@@ -60,3 +60,3 @@ #!/usr/bin/env node | ||
(contents,outputPath,filename = path.basename(outputPath)) => prepareFileContents( | ||
contents.replace(/(\.\/util)\.js/,"$1.mjs"), | ||
contents.replace(/(\.\/util|worker\.opfs)\.js/g,"$1.mjs"), | ||
outputPath.replace(/\.js$/,".mjs"), | ||
@@ -63,0 +63,0 @@ filename.replace(/\.js$/,".mjs") |
@@ -7,2 +7,3 @@ import { safeJSONParse, isPromise, } from "./util.js"; | ||
var rootFS; | ||
var storageType = "opfs"; | ||
@@ -37,2 +38,3 @@ export { | ||
rootFS = isPromise(rootFS) ? await rootFS : rootFS; | ||
var keys = []; | ||
@@ -39,0 +41,0 @@ for await (let key of rootFS.keys()) { |
export { | ||
safeJSONParse, | ||
isPromise, | ||
getDeferred, | ||
}; | ||
@@ -19,1 +20,14 @@ | ||
} | ||
function getDeferred() { | ||
if (typeof Promise.withResolvers == "function") { | ||
return Promise.withResolvers(); | ||
} | ||
else { | ||
let resolve, reject, promise = new Promise((res,rej) => { | ||
resolve = res; | ||
reject = rej; | ||
}); | ||
return { promise, resolve, reject, }; | ||
} | ||
} |
// note: these module specifiers come from the import-map | ||
// in index.html; swap "src" for "dist" here to test | ||
// against the dist/* files | ||
import * as IDBStore from "client-storage/src/adapter-idb"; | ||
import * as LSStore from "client-storage/src/adapter-local-storage"; | ||
import * as SSStore from "client-storage/src/adapter-session-storage"; | ||
import * as CookieStore from "client-storage/src/adapter-cookie"; | ||
import * as OPFSStore from "client-storage/src/adapter-opfs"; | ||
import IDBStore from "client-storage/src/idb"; | ||
import LSStore from "client-storage/src/local-storage"; | ||
import SSStore from "client-storage/src/session-storage"; | ||
import CookieStore from "client-storage/src/cookie"; | ||
import OPFSStore from "client-storage/src/opfs"; | ||
import OPFSWorkerStore from "client-storage/src/opfs-worker"; | ||
@@ -19,2 +20,3 @@ | ||
"opfs": [ "Origin Private FS", OPFSStore, ], | ||
"opfs-worker": [ "OPFS-Worker", OPFSWorkerStore, ], | ||
}; | ||
@@ -106,2 +108,12 @@ | ||
[ "opfs", "keys(2)", [ "meaning", ], ], | ||
[ "opfs-worker", "has(1)", false ], | ||
[ "opfs-worker", "get(1)", null ], | ||
[ "opfs-worker", "set(1)", true ], | ||
[ "opfs-worker", "has(2)", true ], | ||
[ "opfs-worker", "get(2)", "world" ], | ||
[ "opfs-worker", "set(2)", true ], | ||
[ "opfs-worker", "keys(1)", [ "hello", "meaning", ], ], | ||
[ "opfs-worker", "entries", [ [ "hello", "world", ], [ "meaning", { ofLife: 42, }, ], ], ], | ||
[ "opfs-worker", "remove", true ], | ||
[ "opfs-worker", "keys(2)", [ "meaning", ], ], | ||
]; | ||
@@ -112,3 +124,3 @@ var testResults = []; | ||
var stores = [ IDBStore, LSStore, SSStore, CookieStore, OPFSStore ]; | ||
var stores = [ IDBStore, LSStore, SSStore, CookieStore, OPFSStore, OPFSWorkerStore, ]; | ||
for (let store of stores) { | ||
@@ -121,6 +133,7 @@ testResults.push([ storageTypes[store.storageType][0], "has(1)", await store.has("hello"), ]); | ||
testResults.push([ storageTypes[store.storageType][0], "set(2)", await store.set("meaning",{ ofLife: 42, }), ]); | ||
testResults.push([ storageTypes[store.storageType][0], "keys(1)", sortKeys(await store.keys()), ]); | ||
testResults.push([ storageTypes[store.storageType][0], "entries", sortKeys(await store.entries()), ]); | ||
testResults.push([ storageTypes[store.storageType][0], "keys(1)", sortKeys(filterLocalMetadata(await store.keys())), ]); | ||
testResults.push([ storageTypes[store.storageType][0], "entries", sortKeys(filterLocalMetadata(await store.entries())), ]); | ||
testResults.push([ storageTypes[store.storageType][0], "remove", await store.remove("hello"), ]); | ||
testResults.push([ storageTypes[store.storageType][0], "keys(2)", sortKeys(await store.keys()), ]); | ||
testResults.push([ storageTypes[store.storageType][0], "keys(2)", sortKeys(filterLocalMetadata(await store.keys())), ]); | ||
await store.remove("meaning"); | ||
} | ||
@@ -146,2 +159,19 @@ var testsPassed = true; | ||
function filterLocalMetadata(vals) { | ||
if (vals.length > 0) { | ||
// entries? | ||
if (Array.isArray(vals[0])) { | ||
return vals.filter(([ name, value ]) => ( | ||
!/^local-((vault-.+)|(identities))/.test(name) | ||
)); | ||
} | ||
else { | ||
return vals.filter(name => ( | ||
!/^local-((vault-.+)|(identities))/.test(name) | ||
)); | ||
} | ||
} | ||
return vals; | ||
} | ||
function sortKeys(vals) { | ||
@@ -148,0 +178,0 @@ if (vals.length > 0) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
58924
26
1226
218