From 7debdba936b67115d21e34c36395e1075cdb0887 Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 17 Jan 2024 10:43:07 -0500 Subject: [PATCH 1/4] feat: update storage initiation --- src/client.js | 32 ++++++++++++++++++----- src/storage/indexed-db-storage.js | 43 +++++++++++++++++++++---------- src/storage/memory-storage.js | 5 ++-- test/fallback.spec.js | 33 +++++++++++++++--------- 4 files changed, 80 insertions(+), 33 deletions(-) diff --git a/src/client.js b/src/client.js index 47ed46a..f443202 100644 --- a/src/client.js +++ b/src/client.js @@ -36,7 +36,8 @@ export class Saturn { * @param {number} [config.fallbackLimit] * @param {boolean} [config.experimental] * @param {string} [config.format] - * @param {import('./storage/index.js').Storage} [config.storage] + * @param {function():Promise} [config.storage] + * @param {function():Promise} [config.getStorage] */ constructor (config = {}) { this.config = Object.assign({}, { @@ -60,9 +61,9 @@ export class Saturn { if (this.reportingLogs && this.hasPerformanceAPI) { this._monitorPerformanceBuffer() } - this.storage = this.config.storage || memoryStorage() this.loadNodesPromise = this.config.experimental ? this._loadNodes(this.config) : null this.authLimiter = pLimit(1) + this._setStorage() } /** @@ -226,6 +227,25 @@ export class Saturn { return { res, controller, log } } + async _setStorage () { + const getMemoryStorage = async () => { + const memoryStorageFn = memoryStorage() + return await memoryStorageFn() + } + + if (!this.config.storage) { + this.storage = await getMemoryStorage() + return + } + + try { + const getStorage = this.config.storage + this.storage = await getStorage() + } catch (error) { + this.storage = await getMemoryStorage() + } + } + /** * @param {Response} res * @param {object} log @@ -601,10 +621,10 @@ export class Saturn { async _loadNodes (opts) { let origin = opts.orchURL - let cacheNodesListPromise - if (this.storage) { - cacheNodesListPromise = this.storage.get(Saturn.nodesListKey) + if (!this.storage) { + await this._setStorage() } + const cacheNodesListPromise = this.storage?.get(Saturn.nodesListKey) origin = addHttpPrefix(origin) @@ -639,7 +659,7 @@ export class Saturn { nodes = await orchNodesListPromise nodes = this._sortNodes(nodes) this.nodes = nodes - this.storage.set(Saturn.nodesListKey, nodes) + this.storage?.set(Saturn.nodesListKey, nodes) this.hashring = this.createHashring(nodes) } } diff --git a/src/storage/indexed-db-storage.js b/src/storage/indexed-db-storage.js index fa2437b..564fb28 100644 --- a/src/storage/indexed-db-storage.js +++ b/src/storage/indexed-db-storage.js @@ -8,22 +8,39 @@ const DEFAULT_SATURN_STORAGE_NAME = 'saturn-client' /** * @function indexedDbStorage - * @returns {import('./index.js').Storage} + * @returns {function():Promise} */ export function indexedDbStorage () { - const indexedDbExists = (typeof self !== 'undefined') && self?.indexedDB + const indexedDbExists = typeof self !== 'undefined' && self?.indexedDB let dbPromise - if (indexedDbExists) { - dbPromise = openDB(DEFAULT_IDB_STORAGE_NAME, DEFAULT_IDB_VERSION, { - upgrade (db) { - db.createObjectStore(DEFAULT_SATURN_STORAGE_NAME) - } - }) - } - return { - 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) + return async () => { + if (!indexedDbExists) { + throw Error('Indexed DB is not supported in this environment') + } + + if (indexedDbExists) { + dbPromise = await openDB(DEFAULT_IDB_STORAGE_NAME, DEFAULT_IDB_VERSION, { + upgrade (db) { + try { + db.createObjectStore(DEFAULT_SATURN_STORAGE_NAME) + } catch (error) { + throw Error(`Cannot initialize indexed DB Object store, error: ${error}`) + } + } + }) + } + + return { + 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) + } } } diff --git a/src/storage/memory-storage.js b/src/storage/memory-storage.js index 7a11c8e..91b3dce 100644 --- a/src/storage/memory-storage.js +++ b/src/storage/memory-storage.js @@ -2,14 +2,15 @@ /** * @function memoryStorage - * @returns {import('./index.js').Storage} + * @returns {function():Promise} */ export function memoryStorage () { const storageObject = {} - return { + const storage = { get: async (key) => storageObject[key], set: async (key, value) => { storageObject[key] = value }, delete: async (key) => { delete storageObject[key] } } + return async () => storage } diff --git a/test/fallback.spec.js b/test/fallback.spec.js index 3799f67..c4b9cf5 100644 --- a/test/fallback.spec.js +++ b/test/fallback.spec.js @@ -52,20 +52,19 @@ describe('Client Fallback', () => { const expectedNodes = generateNodes(2, TEST_ORIGIN_DOMAIN) - // Mocking storage object const mockStorage = { - get: async (key) => null, - set: async (key, value) => null, - delete: async (key) => null + get: async (key) => expectedNodes, + set: async (key, value) => { return null } } + // Mocking storage object + const storage = async () => mockStorage t.mock.method(mockStorage, 'get') t.mock.method(mockStorage, 'set') - const saturn = new Saturn({ storage: mockStorage, ...options }) + const saturn = new Saturn({ storage, ...options }) // Mocking options const mockOpts = { orchURL: TEST_DEFAULT_ORCH } - await saturn._loadNodes(mockOpts) // Assert that all the storage methods were called twice. @@ -98,7 +97,8 @@ describe('Client Fallback', () => { t.mock.method(mockStorage, 'get') t.mock.method(mockStorage, 'set') - const saturn = new Saturn({ storage: mockStorage, ...options }) + const storage = async () => mockStorage + const saturn = new Saturn({ storage, ...options }) // Mocking options const mockOpts = { orchURL: TEST_DEFAULT_ORCH } @@ -137,7 +137,8 @@ describe('Client Fallback', () => { t.mock.method(mockStorage, 'get') t.mock.method(mockStorage, 'set') - const saturn = new Saturn({ storage: mockStorage, ...options }) + const storage = async () => mockStorage + const saturn = new Saturn({ storage, ...options }) const cid = saturn.fetchContentWithFallback('bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4') @@ -167,10 +168,13 @@ describe('Client Fallback', () => { get: async (key) => expectedNodes, set: async (key, value) => { return null } } + t.mock.method(mockStorage, 'get') t.mock.method(mockStorage, 'set') - const saturn = new Saturn({ ...options }) + const storage = async () => mockStorage + + const saturn = new Saturn({ storage, ...options }) const cid = saturn.fetchContentWithFallback('bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4', { raceNodes: true }) @@ -203,7 +207,9 @@ describe('Client Fallback', () => { t.mock.method(mockStorage, 'get') t.mock.method(mockStorage, 'set') - const saturn = new Saturn({ ...options }) + const storage = async () => mockStorage + + const saturn = new Saturn({ storage, ...options }) await saturn.loadNodesPromise @@ -242,7 +248,8 @@ describe('Client Fallback', () => { t.mock.method(mockStorage, 'get') t.mock.method(mockStorage, 'set') - const saturn = new Saturn({ storage: mockStorage, ...options }) + const storage = async () => mockStorage + const saturn = new Saturn({ storage, ...options }) const cid = saturn.fetchContentWithFallback('bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4', { raceNodes: true }) @@ -336,7 +343,9 @@ describe('Client Fallback', () => { t.mock.method(mockStorage, 'get') t.mock.method(mockStorage, 'set') - const saturn = new Saturn({ storage: mockStorage, customerFallbackURL: TEST_CUSTOMER_ORIGIN, ...options }) + const storage = async () => mockStorage + + const saturn = new Saturn({ storage, customerFallbackURL: TEST_CUSTOMER_ORIGIN, ...options }) const cid = saturn.fetchContentWithFallback(TEST_CUSTOMER_ORIGIN, { raceNodes: true }) From 81e2ccfa40189c6e1989a726b7f7ad36a5385e89 Mon Sep 17 00:00:00 2001 From: ameanasad Date: Wed, 17 Jan 2024 10:54:48 -0500 Subject: [PATCH 2/4] remove extra config item --- src/client.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client.js b/src/client.js index f443202..b8d7119 100644 --- a/src/client.js +++ b/src/client.js @@ -37,7 +37,6 @@ export class Saturn { * @param {boolean} [config.experimental] * @param {string} [config.format] * @param {function():Promise} [config.storage] - * @param {function():Promise} [config.getStorage] */ constructor (config = {}) { this.config = Object.assign({}, { From e2f2d0256198733de82d0ca42886a856154031ac Mon Sep 17 00:00:00 2001 From: ameanasad Date: Fri, 19 Jan 2024 11:15:39 -0500 Subject: [PATCH 3/4] feat: change storage funcs --- src/client.js | 11 ++------ src/storage/indexed-db-storage.js | 46 +++++++++++++++---------------- src/storage/memory-storage.js | 7 ++--- 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/src/client.js b/src/client.js index b8d7119..7288785 100644 --- a/src/client.js +++ b/src/client.js @@ -60,9 +60,9 @@ export class Saturn { if (this.reportingLogs && this.hasPerformanceAPI) { this._monitorPerformanceBuffer() } + this._setStorage() this.loadNodesPromise = this.config.experimental ? this._loadNodes(this.config) : null this.authLimiter = pLimit(1) - this._setStorage() } /** @@ -227,13 +227,8 @@ export class Saturn { } async _setStorage () { - const getMemoryStorage = async () => { - const memoryStorageFn = memoryStorage() - return await memoryStorageFn() - } - if (!this.config.storage) { - this.storage = await getMemoryStorage() + this.storage = await memoryStorage() return } @@ -241,7 +236,7 @@ export class Saturn { const getStorage = this.config.storage this.storage = await getStorage() } catch (error) { - this.storage = await getMemoryStorage() + this.storage = await memoryStorage() } } diff --git a/src/storage/indexed-db-storage.js b/src/storage/indexed-db-storage.js index 564fb28..2c8252d 100644 --- a/src/storage/indexed-db-storage.js +++ b/src/storage/indexed-db-storage.js @@ -8,39 +8,37 @@ const DEFAULT_SATURN_STORAGE_NAME = 'saturn-client' /** * @function indexedDbStorage - * @returns {function():Promise} + * @returns {Promise} */ -export function indexedDbStorage () { +export async function indexedDbStorage () { const indexedDbExists = typeof self !== 'undefined' && self?.indexedDB let dbPromise - return async () => { - if (!indexedDbExists) { - throw Error('Indexed DB is not supported in this environment') - } + if (!indexedDbExists) { + throw Error('Indexed DB is not supported in this environment') + } - if (indexedDbExists) { - dbPromise = await openDB(DEFAULT_IDB_STORAGE_NAME, DEFAULT_IDB_VERSION, { - upgrade (db) { - try { - db.createObjectStore(DEFAULT_SATURN_STORAGE_NAME) - } catch (error) { - throw Error(`Cannot initialize indexed DB Object store, error: ${error}`) - } + if (indexedDbExists) { + dbPromise = await openDB(DEFAULT_IDB_STORAGE_NAME, DEFAULT_IDB_VERSION, { + upgrade (db) { + try { + db.createObjectStore(DEFAULT_SATURN_STORAGE_NAME) + } catch (error) { + throw Error(`Cannot initialize indexed DB Object store, error: ${error}`) } - }) - } + } + }) + } - return { - get: async (key) => - indexedDbExists && + return { + get: async (key) => + indexedDbExists && (await dbPromise).get(DEFAULT_SATURN_STORAGE_NAME, key), - set: async (key, value) => - indexedDbExists && + set: async (key, value) => + indexedDbExists && (await dbPromise).put(DEFAULT_SATURN_STORAGE_NAME, value, key), - delete: async (key) => - indexedDbExists && + delete: async (key) => + indexedDbExists && (await dbPromise).delete(DEFAULT_SATURN_STORAGE_NAME, key) - } } } diff --git a/src/storage/memory-storage.js b/src/storage/memory-storage.js index 91b3dce..6455fae 100644 --- a/src/storage/memory-storage.js +++ b/src/storage/memory-storage.js @@ -2,15 +2,14 @@ /** * @function memoryStorage - * @returns {function():Promise} + * @returns {Promise} */ -export function memoryStorage () { +export async function memoryStorage () { const storageObject = {} - const storage = { + return { get: async (key) => storageObject[key], set: async (key, value) => { storageObject[key] = value }, delete: async (key) => { delete storageObject[key] } } - return async () => storage } From a3f8c6642d3ab4be66e8fbfdf6e489a0d74ff413 Mon Sep 17 00:00:00 2001 From: ameanasad Date: Mon, 22 Jan 2024 09:58:22 -0500 Subject: [PATCH 4/4] address comments --- src/storage/index.js | 2 +- src/storage/indexed-db-storage.js | 31 +++++++++++-------------------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/storage/index.js b/src/storage/index.js index a8b52b8..aaf5397 100644 --- a/src/storage/index.js +++ b/src/storage/index.js @@ -6,7 +6,7 @@ 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,any):Promise} set - Sets a new value for the key. * @property {function(string):Promise} delete - Deletes the value associated with the key. */ diff --git a/src/storage/indexed-db-storage.js b/src/storage/indexed-db-storage.js index 2c8252d..7d3a570 100644 --- a/src/storage/indexed-db-storage.js +++ b/src/storage/indexed-db-storage.js @@ -12,33 +12,24 @@ const DEFAULT_SATURN_STORAGE_NAME = 'saturn-client' */ export async function indexedDbStorage () { const indexedDbExists = typeof self !== 'undefined' && self?.indexedDB - let dbPromise if (!indexedDbExists) { throw Error('Indexed DB is not supported in this environment') } - if (indexedDbExists) { - dbPromise = await openDB(DEFAULT_IDB_STORAGE_NAME, DEFAULT_IDB_VERSION, { - upgrade (db) { - try { - db.createObjectStore(DEFAULT_SATURN_STORAGE_NAME) - } catch (error) { - throw Error(`Cannot initialize indexed DB Object store, error: ${error}`) - } + const dbPromise = await openDB(DEFAULT_IDB_STORAGE_NAME, DEFAULT_IDB_VERSION, { + upgrade (db) { + try { + db.createObjectStore(DEFAULT_SATURN_STORAGE_NAME) + } catch (error) { + throw Error(`Cannot initialize indexed DB Object store, error: ${error}`) } - }) - } + } + }) return { - 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) + get: async (key) => (await dbPromise).get(DEFAULT_SATURN_STORAGE_NAME, key), + set: async (key, value) => (await dbPromise).put(DEFAULT_SATURN_STORAGE_NAME, value, key), + delete: async (key) => (await dbPromise).delete(DEFAULT_SATURN_STORAGE_NAME, key) } }