From a13f969c6fea201817e197fe498c3f0f83db49a7 Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 11 Oct 2023 14:00:52 -0400 Subject: [PATCH 1/7] feat: add storage interface + implement indexedDb --- package-lock.json | 11 +++++++++++ package.json | 1 + src/utils/storage.js | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 src/utils/storage.js diff --git a/package-lock.json b/package-lock.json index 84f9b3f..e91ec1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@ipld/dag-pb": "^2.1.18", "@multiformats/blake2": "^1.0.11", "browser-readablestream-to-it": "^2.0.4", + "idb": "^7.1.1", "ipfs-unixfs-exporter": "https://gitpkg.now.sh/filecoin-saturn/js-ipfs-unixfs/packages/ipfs-unixfs-exporter?build", "multiformats": "^12.1.1" }, @@ -2422,6 +2423,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -6246,6 +6252,11 @@ "has-symbols": "^1.0.2" } }, + "idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", diff --git a/package.json b/package.json index 0970456..81d1899 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@ipld/dag-pb": "^2.1.18", "@multiformats/blake2": "^1.0.11", "browser-readablestream-to-it": "^2.0.4", + "idb": "^7.1.1", "ipfs-unixfs-exporter": "https://gitpkg.now.sh/filecoin-saturn/js-ipfs-unixfs/packages/ipfs-unixfs-exporter?build", "multiformats": "^12.1.1" }, diff --git a/src/utils/storage.js b/src/utils/storage.js new file mode 100644 index 0000000..0c2954e --- /dev/null +++ b/src/utils/storage.js @@ -0,0 +1,38 @@ +// @ts-check + +import { openDB } from 'idb' + +const DEFAULT_IDB_VERSION = 1 +const DEFAULT_IDB_STORAGE_NAME = 'saturn-db' +const DEFAULT_SATURN_STORAGE_NAME = 'saturn-client' + +/** + * @typedef {object} Storage + * @property {function():boolean} check - Checks if the provided Storage is accessible + * @property {function(string):Promise} get - Retrieves the value associated with the key. + * @property {function(string,any):Promise} set - Sets a new value for the key. + * @property {function(string):Promise} delete - Deletes the value associated with the key. + */ + +/** + * @function indexedDbStorage + * @returns {Storage} + */ +export function indexedDbStorage () { + const indexedDbExists = (typeof window !== 'undefined') && window?.indexedDB + let dbPromise + if (indexedDbExists) { + dbPromise = openDB(DEFAULT_IDB_STORAGE_NAME, DEFAULT_IDB_VERSION, { + upgrade (db) { + db.createObjectStore(DEFAULT_SATURN_STORAGE_NAME) + } + }) + } + + return { + check: () => Boolean(indexedDbExists), + get: async (key) => indexedDbExists && (await dbPromise).get(DEFAULT_SATURN_STORAGE_NAME, key), + set: async (key, value) => indexedDbExists && (await dbPromise).put(DEFAULT_SATURN_STORAGE_NAME, value, key), + delete: async (key) => indexedDbExists && (await dbPromise).delete(DEFAULT_SATURN_STORAGE_NAME, key) + } +} From e462f286ad7d5cf23536ce932edcbb1139dadab1 Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 11 Oct 2023 14:21:19 -0400 Subject: [PATCH 2/7] fix: implement memoryStore and fallback --- src/index.js | 4 ++++ src/utils/storage.js | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/index.js b/src/index.js index 4729a1a..0ba8ead 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,7 @@ import { CID } from 'multiformats' import { extractVerifiedContent } from './utils/car.js' import { asAsyncIterable, asyncIteratorToBuffer } from './utils/itr.js' import { randomUUID } from './utils/uuid.js' +import { memoryStorage } from './utils/storage.js' class Saturn { /** @@ -12,6 +13,7 @@ class Saturn { * @param {string} [opts.cdnURL=saturn.ms] * @param {number} [opts.connectTimeout=5000] * @param {number} [opts.downloadTimeout=0] + * @param {import('./utils/storage.js').Storage} [opts.storage] */ constructor (opts = {}) { this.opts = Object.assign({}, { @@ -20,9 +22,11 @@ class Saturn { logURL: 'https://twb3qukm2i654i3tnvx36char40aymqq.lambda-url.us-west-2.on.aws/', connectTimeout: 5_000, downloadTimeout: 0 + }, opts) this.logs = [] + this.storage = this.opts.storage || memoryStorage() this.reportingLogs = process?.env?.NODE_ENV !== 'development' this.hasPerformanceAPI = typeof window !== 'undefined' && window?.performance if (this.reportingLogs && this.hasPerformanceAPI) { diff --git a/src/utils/storage.js b/src/utils/storage.js index 0c2954e..c011947 100644 --- a/src/utils/storage.js +++ b/src/utils/storage.js @@ -36,3 +36,24 @@ export function indexedDbStorage () { delete: async (key) => indexedDbExists && (await dbPromise).delete(DEFAULT_SATURN_STORAGE_NAME, key) } } + +/** + * @function memoryStorage + * @returns {Storage} + */ +export function memoryStorage () { + const storageObject = {} + + return { + check: () => true, // Memory storage is always accessible + get: (key) => Promise.resolve(storageObject[key]), + set: (key, value) => { + storageObject[key] = value + return Promise.resolve() + }, + delete: (key) => { + delete storageObject[key] + return Promise.resolve() + } + } +} From bffd64372d71b0ef6586de858a5cf9dafee3762b Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 11 Oct 2023 14:25:39 -0400 Subject: [PATCH 3/7] fix: remove check function --- src/utils/storage.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/utils/storage.js b/src/utils/storage.js index c011947..7f39175 100644 --- a/src/utils/storage.js +++ b/src/utils/storage.js @@ -8,7 +8,6 @@ const DEFAULT_SATURN_STORAGE_NAME = 'saturn-client' /** * @typedef {object} Storage - * @property {function():boolean} check - Checks if the provided Storage is accessible * @property {function(string):Promise} get - Retrieves the value associated with the key. * @property {function(string,any):Promise} set - Sets a new value for the key. * @property {function(string):Promise} delete - Deletes the value associated with the key. @@ -30,7 +29,6 @@ export function indexedDbStorage () { } return { - check: () => Boolean(indexedDbExists), get: async (key) => indexedDbExists && (await dbPromise).get(DEFAULT_SATURN_STORAGE_NAME, key), set: async (key, value) => indexedDbExists && (await dbPromise).put(DEFAULT_SATURN_STORAGE_NAME, value, key), delete: async (key) => indexedDbExists && (await dbPromise).delete(DEFAULT_SATURN_STORAGE_NAME, key) @@ -45,7 +43,6 @@ export function memoryStorage () { const storageObject = {} return { - check: () => true, // Memory storage is always accessible get: (key) => Promise.resolve(storageObject[key]), set: (key, value) => { storageObject[key] = value From 327feac87de4eaab0b0c61a3849d82bb48538300 Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 11 Oct 2023 14:27:25 -0400 Subject: [PATCH 4/7] fix --- src/utils/storage.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/utils/storage.js b/src/utils/storage.js index 7f39175..deddba7 100644 --- a/src/utils/storage.js +++ b/src/utils/storage.js @@ -43,14 +43,8 @@ export function memoryStorage () { const storageObject = {} return { - get: (key) => Promise.resolve(storageObject[key]), - set: (key, value) => { - storageObject[key] = value - return Promise.resolve() - }, - delete: (key) => { - delete storageObject[key] - return Promise.resolve() - } + get: async (key) => storageObject[key], + set: async (key, value) => { storageObject[key] = value }, + delete: async (key) => { delete storageObject[key] } } } From cd65d710a74707f2bc7f014cd8c98cd301a4ed23 Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 11 Oct 2023 14:50:10 -0400 Subject: [PATCH 5/7] feat: turn storage into modules --- src/index.js | 2 +- src/utils/storage/index.js | 17 ++++++++++++++ .../indexed-db-storage.js} | 23 +------------------ src/utils/storage/memory-storage.js | 14 +++++++++++ 4 files changed, 33 insertions(+), 23 deletions(-) create mode 100644 src/utils/storage/index.js rename src/utils/{storage.js => storage/indexed-db-storage.js} (57%) create mode 100644 src/utils/storage/memory-storage.js diff --git a/src/index.js b/src/index.js index 0ba8ead..55c1598 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,7 @@ import { CID } from 'multiformats' import { extractVerifiedContent } from './utils/car.js' import { asAsyncIterable, asyncIteratorToBuffer } from './utils/itr.js' import { randomUUID } from './utils/uuid.js' -import { memoryStorage } from './utils/storage.js' +import { memoryStorage } from './utils/storage/index.js' class Saturn { /** diff --git a/src/utils/storage/index.js b/src/utils/storage/index.js new file mode 100644 index 0000000..47256a5 --- /dev/null +++ b/src/utils/storage/index.js @@ -0,0 +1,17 @@ + +// @ts-check + +import { indexedDbStorage } from './indexed-db-storage.js' +import { memoryStorage } from './memory-storage.js' + +/** + * @typedef {object} Storage + * @property {function(string):Promise} get - Retrieves the value associated with the key. + * @property {function(string,any):Promise} set - Sets a new value for the key. + * @property {function(string):Promise} delete - Deletes the value associated with the key. + */ + +export { + indexedDbStorage, + memoryStorage +} diff --git a/src/utils/storage.js b/src/utils/storage/indexed-db-storage.js similarity index 57% rename from src/utils/storage.js rename to src/utils/storage/indexed-db-storage.js index deddba7..477ff1d 100644 --- a/src/utils/storage.js +++ b/src/utils/storage/indexed-db-storage.js @@ -6,16 +6,9 @@ const DEFAULT_IDB_VERSION = 1 const DEFAULT_IDB_STORAGE_NAME = 'saturn-db' const DEFAULT_SATURN_STORAGE_NAME = 'saturn-client' -/** - * @typedef {object} Storage - * @property {function(string):Promise} get - Retrieves the value associated with the key. - * @property {function(string,any):Promise} set - Sets a new value for the key. - * @property {function(string):Promise} delete - Deletes the value associated with the key. - */ - /** * @function indexedDbStorage - * @returns {Storage} + * @returns {import('./index.js').Storage} */ export function indexedDbStorage () { const indexedDbExists = (typeof window !== 'undefined') && window?.indexedDB @@ -34,17 +27,3 @@ export function indexedDbStorage () { delete: async (key) => indexedDbExists && (await dbPromise).delete(DEFAULT_SATURN_STORAGE_NAME, key) } } - -/** - * @function memoryStorage - * @returns {Storage} - */ -export function memoryStorage () { - const storageObject = {} - - return { - get: async (key) => storageObject[key], - set: async (key, value) => { storageObject[key] = value }, - delete: async (key) => { delete storageObject[key] } - } -} diff --git a/src/utils/storage/memory-storage.js b/src/utils/storage/memory-storage.js new file mode 100644 index 0000000..a834c4d --- /dev/null +++ b/src/utils/storage/memory-storage.js @@ -0,0 +1,14 @@ + +/** + * @function memoryStorage + * @returns {import('./index.js').Storage} + */ +export function memoryStorage () { + const storageObject = {} + + return { + get: async (key) => storageObject[key], + set: async (key, value) => { storageObject[key] = value }, + delete: async (key) => { delete storageObject[key] } + } +} From 7cd560db24e55015c3327aca8eed52d712f11adf Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 11 Oct 2023 15:00:51 -0400 Subject: [PATCH 6/7] fix: storage folder --- src/index.js | 2 +- src/{utils => }/storage/index.js | 0 src/{utils => }/storage/indexed-db-storage.js | 0 src/{utils => }/storage/memory-storage.js | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename src/{utils => }/storage/index.js (100%) rename src/{utils => }/storage/indexed-db-storage.js (100%) rename src/{utils => }/storage/memory-storage.js (100%) diff --git a/src/index.js b/src/index.js index 55c1598..8dcd443 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,7 @@ import { CID } from 'multiformats' import { extractVerifiedContent } from './utils/car.js' import { asAsyncIterable, asyncIteratorToBuffer } from './utils/itr.js' import { randomUUID } from './utils/uuid.js' -import { memoryStorage } from './utils/storage/index.js' +import { memoryStorage } from './storage/index.js' class Saturn { /** diff --git a/src/utils/storage/index.js b/src/storage/index.js similarity index 100% rename from src/utils/storage/index.js rename to src/storage/index.js diff --git a/src/utils/storage/indexed-db-storage.js b/src/storage/indexed-db-storage.js similarity index 100% rename from src/utils/storage/indexed-db-storage.js rename to src/storage/indexed-db-storage.js diff --git a/src/utils/storage/memory-storage.js b/src/storage/memory-storage.js similarity index 100% rename from src/utils/storage/memory-storage.js rename to src/storage/memory-storage.js From beca4d66027e326ab804f01d3cb465ee929857c8 Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 11 Oct 2023 15:02:11 -0400 Subject: [PATCH 7/7] fix --- src/storage/index.js | 1 - src/storage/memory-storage.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/index.js b/src/storage/index.js index 47256a5..a8b52b8 100644 --- a/src/storage/index.js +++ b/src/storage/index.js @@ -1,4 +1,3 @@ - // @ts-check import { indexedDbStorage } from './indexed-db-storage.js' diff --git a/src/storage/memory-storage.js b/src/storage/memory-storage.js index a834c4d..7a11c8e 100644 --- a/src/storage/memory-storage.js +++ b/src/storage/memory-storage.js @@ -1,3 +1,4 @@ +// @ts-check /** * @function memoryStorage