consul/ui/packages/consul-ui/app/services/local-storage.js

132 lines
3.0 KiB
JavaScript
Raw Permalink Normal View History

/**
* Copyright (c) HashiCorp, Inc.
[COMPLIANCE] License changes (#18443) * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 13:12:13 +00:00
* SPDX-License-Identifier: BUSL-1.1
*/
import Service from '@ember/service';
import { getOwner } from '@ember/application';
import ENV from 'consul-ui/config/environment';
export function storageFor(key) {
return function () {
return {
get() {
const owner = getOwner(this);
const localStorageService = owner.lookup('service:localStorage');
return localStorageService.getBucket(key);
},
};
};
}
/**
* An in-memory stub of window.localStorage. Ideally this would
* implement the [Storage](https://developer.mozilla.org/en-US/docs/Web/API/Storage)-interface that localStorage implements
* as well.
*
* We use this implementation during testing to not pollute `window.localStorage`
*/
class MemoryStorage {
constructor() {
this.data = new Map();
}
getItem(key) {
return this.data.get(key);
}
setItem(key, value) {
return this.data.set(key, value.toString());
}
/**
* A function to seed data into MemoryStorage. This expects an object to be
* passed. The passed values will be persisted as a string - i.e. the values
* passed will call their `toString()`-method before writing to storage. You need
* to take this into account when you want to persist complex values, like arrays
* or objects:
*
* Example:
*
* ```js
* const storage = new MemoryStorage();
* storage.seed({ notices: ['notice-a', 'notice-b']});
*
* storage.getItem('notices') // => 'notice-a,notice-b'
*
* // won't work
* storage.seed({
* user: { name: 'Tomster' }
* })
*
* storage.getItem('user') // => '[object Object]'
*
* // this works
* storage.seed({
* . user: JSON.stringify({name: 'Tomster'})
* })
*
* storage.getItem('user') // => '{ "name": "Tomster" }'
* ```
* @param {object} data - the data to seed
*/
seed(data) {
const newData = new Map();
const keys = Object.keys(data);
keys.forEach((key) => {
newData.set(key, data[key].toString());
});
this.data = newData;
}
}
/**
* There might be better ways to do this but this is good enough for now.
* During testing we want to use MemoryStorage not window.localStorage.
*/
function initStorage() {
if (ENV.environment === 'test') {
return new MemoryStorage();
} else {
return window.localStorage;
}
}
/**
* A service that wraps access to local-storage. We wrap
* local-storage to not pollute local-storage during testing.
*/
export default class LocalStorageService extends Service {
constructor() {
super(...arguments);
this.storage = initStorage();
this.buckets = new Map();
}
getBucket(key) {
const bucket = this.buckets.get(key);
if (bucket) {
return bucket;
} else {
return this._setupBucket(key);
}
}
_setupBucket(key) {
const owner = getOwner(this);
const Klass = owner.factoryFor(`storage:${key}`).class;
const storage = new Klass(key, this.storage);
this.buckets.set(key, storage);
return storage;
}
}