Skip to content

Commit 2e56dda

Browse files
committed
Implement indexed DB storage
1 parent c695ccf commit 2e56dda

9 files changed

Lines changed: 269 additions & 156 deletions

composables/useIndexedDb.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { get, set, del } from 'idb-keyval';
2+
import { useStorageAsync } from '@vueuse/core';
3+
4+
export default function (key, initialValue) {
5+
return useStorageAsync(key, initialValue, {
6+
async getItem(key) {
7+
return await get(key);
8+
},
9+
async setItem(key, value) {
10+
return await set(key, value);
11+
},
12+
async removeItem(key) {
13+
return await del(key);
14+
},
15+
});
16+
}

composables/useProjectStoreFactory.js

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,25 @@ import download from 'downloadjs';
22
import { v4 as uuid } from 'uuid';
33
import { cloneDeep, replace } from 'lodash';
44
import { defineStore } from 'pinia';
5+
import useIndexedDb from './useIndexedDb';
56
import { namespace } from './useProjectStores';
6-
import { useLocalStorage } from '@vueuse/core';
77
import useTemplateStore from './useTemplateStore';
88

9-
export default function (id) {
10-
const storage = useLocalStorage(id, {
11-
version: '1.10.0',
12-
page: {},
13-
settings: {},
14-
tab: {
15-
order: 0,
16-
name: null,
17-
created_at: new Date(),
18-
id: replace(id, namespace, ''),
19-
},
20-
});
9+
export default function (id, initialValue = null) {
10+
const storage = useIndexedDb(
11+
id,
12+
initialValue ?? {
13+
version: '1.10.0',
14+
page: {},
15+
settings: {},
16+
tab: {
17+
order: 0,
18+
name: null,
19+
created_at: new Date(),
20+
id: replace(id, namespace, ''),
21+
},
22+
}
23+
);
2124

2225
return defineStore(id, {
2326
state: () => storage.value,
@@ -44,8 +47,6 @@ export default function (id) {
4447
*/
4548
clear() {
4649
storage.value = null;
47-
48-
window.localStorage.removeItem(`${namespace}/${this.tab.id}`);
4950
},
5051

5152
/**

composables/useProjectStores.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Store } from 'pinia';
22
import { v4 as uuid } from 'uuid';
3+
import { entries } from 'idb-keyval';
34
import { fileDialog } from 'file-select-dialog';
45
import { has, head, sortBy, debounce, startsWith, cloneDeep } from 'lodash';
56
import useCurrentTab from './useCurrentTab';
@@ -9,8 +10,10 @@ import { computed, ref, useContext } from '@nuxtjs/composition-api';
910

1011
export const namespace = 'pages/';
1112

12-
const getPagesFromStorage = () => {
13-
return Object.keys(window.localStorage).filter((key) => key.startsWith(namespace));
13+
const getPagesFromStorage = async () => {
14+
return (await entries())
15+
.filter(([key]) => key.startsWith(namespace))
16+
.map(([key, value]) => [key, JSON.parse(value)]);
1417
};
1518

1619
export default function () {
@@ -38,17 +41,18 @@ export default function () {
3841
* Make a new project store.
3942
*
4043
* @param {String} id
44+
* @param {Object|null} initialValue
4145
*
4246
* @returns {Store}
4347
*/
44-
const makeProjectStore = (id = null) => {
48+
const makeProjectStore = (id = null, initialValue = null) => {
4549
id = id ?? uuid();
4650

4751
const name = startsWith(id, namespace) ? id : namespace + id;
4852

49-
const factory = useProjectStoreFactory(name);
53+
const make = useProjectStoreFactory(name, initialValue);
5054

51-
const store = factory();
55+
const store = make();
5256

5357
store.load();
5458

@@ -195,8 +199,10 @@ export default function () {
195199
/**
196200
* Hydrate the projects from local storage.
197201
*/
198-
const hydrateFromStorage = () => {
199-
const stored = getPagesFromStorage().map((id) => makeProjectStore(id));
202+
const hydrateFromStorage = async () => {
203+
const stored = (await getPagesFromStorage()).map(([key, value]) =>
204+
makeProjectStore(key, value)
205+
);
200206

201207
projects.value = sortBy(stored, ({ tab }) => tab.order ?? tab.created_at);
202208
};

composables/useSettingsStore.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isArray } from 'lodash';
22
import collect from 'collect.js';
33
import { defineStore } from 'pinia';
4-
import { useLocalStorage } from '@vueuse/core';
4+
import useIndexedDb from './useIndexedDb';
55

66
const mapBackgroundsToArray = (backgrounds) => {
77
return collect(backgrounds)
@@ -16,13 +16,13 @@ const getOldBackgrounds = () => {
1616
return mapBackgroundsToArray(JSON.parse(localStorage.getItem('settings/backgrounds') ?? '[]'));
1717
};
1818

19+
const state = useIndexedDb('settings', {
20+
tab: '',
21+
backgrounds: getOldBackgrounds(),
22+
});
23+
1924
export default defineStore('settings', {
2025
state: () => {
21-
const state = useLocalStorage('settings', {
22-
tab: '',
23-
backgrounds: getOldBackgrounds(),
24-
});
25-
2626
if (!isArray(state.value.backgrounds)) {
2727
state.value.backgrounds = mapBackgroundsToArray(state.value.backgrounds);
2828
}

composables/useTemplateStore.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import { defineStore } from 'pinia';
2-
import { useLocalStorage } from '@vueuse/core';
2+
import useIndexedDb from './useIndexedDb';
33

4-
const getOldTemplates = () => {
5-
const keys = Object.keys(window.localStorage).filter((key) => key.startsWith('templates/'));
4+
const oldLocalTemplates = window.localStorage.getItem('templates') ?? '[]';
65

7-
return keys.map((k) => JSON.parse(window.localStorage.getItem(k)));
8-
};
6+
const state = useIndexedDb('templates', JSON.parse(oldLocalTemplates));
97

108
export default defineStore('templates', {
11-
state: () => useLocalStorage('templates', getOldTemplates()),
9+
state: () => state,
1210

1311
actions: {
1412
/**

license.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2021 Steve Bauman
3+
Copyright (c) 2022 Steve Bauman
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

0 commit comments

Comments
 (0)