@vnejs/plugins.core.storage 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ export const SUBSCRIBE_EVENTS = {
2
+ SET: "vne:storage:set",
3
+ SET_ALL: "vne:storage:set_all",
4
+ GET: "vne:storage:get",
5
+ GET_ALL: "vne:storage:get_all",
6
+ RM: "vne:storage:rm",
7
+ CHANGED: "vne:storage:changed",
8
+ IMPORT: "vne:storage:import",
9
+ EXPORT: "vne:storage:export",
10
+ CLEAR: "vne:storage:clear",
11
+ };
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import { regPlugin } from "@vnejs/shared";
2
+
3
+ import { SUBSCRIBE_EVENTS } from "./const/events";
4
+
5
+ import { Storage } from "./modules/storage";
6
+
7
+ regPlugin("STORAGE", { events: SUBSCRIBE_EVENTS }, [Storage]);
@@ -0,0 +1,126 @@
1
+ import localforage from "localforage";
2
+
3
+ import { Module } from "@vnejs/module";
4
+
5
+ export class Storage extends Module {
6
+ name = "storage";
7
+
8
+ subscribe = () => {
9
+ this.on(this.EVENTS.STORAGE.SET, this.onStorageSet);
10
+ this.on(this.EVENTS.STORAGE.SET_ALL, this.onStorageSetAll);
11
+ this.on(this.EVENTS.STORAGE.GET, this.onStorageGet);
12
+ this.on(this.EVENTS.STORAGE.RM, this.onStorageRm);
13
+ this.on(this.EVENTS.STORAGE.EXPORT, this.onStorageExport);
14
+ this.on(this.EVENTS.STORAGE.IMPORT, this.onStorageImport);
15
+ this.on(this.EVENTS.STORAGE.CLEAR, this.onStorageClear);
16
+ };
17
+ init = () =>
18
+ new Promise((resolve) => {
19
+ const { version = 0, gameName = "defaultGameName" } = this.options?.global || {};
20
+ const name = `vne_store_${gameName}`;
21
+ localforage.ready(resolve);
22
+ localforage.config({ driver: localforage.INDEXEDDB, name, storeName: name, description: name, version });
23
+ });
24
+
25
+ onStorageSet = async ({ prefix, key, value }) => {
26
+ if (!this.isReady) await this.waitIsReady();
27
+
28
+ await localforage.setItem(prefix ? `${prefix}.${key}` : key, value);
29
+
30
+ this.emit(this.EVENTS.STORAGE.CHANGED);
31
+ };
32
+
33
+ onStorageSetAll = async ({ storage }) => {
34
+ if (!this.isReady) await this.waitIsReady();
35
+
36
+ let wasChanged = false;
37
+
38
+ await Promise.all(
39
+ Object.keys(storage).map(async (key) => {
40
+ const value = await localforage.getItem(key);
41
+ if (value !== storage[key]) {
42
+ wasChanged = true;
43
+ await localforage.setItem(key, storage[key]);
44
+ }
45
+ })
46
+ );
47
+
48
+ const keys = await localforage.keys();
49
+
50
+ await Promise.all(
51
+ keys.map(async (key) => {
52
+ if (storage[key] === undefined) {
53
+ wasChanged = true;
54
+ await localforage.removeItem(key);
55
+ }
56
+ })
57
+ );
58
+
59
+ await this.emit(this.EVENTS.STORAGE.CHANGED);
60
+
61
+ return wasChanged;
62
+ };
63
+
64
+ onStorageGet = async ({ prefix = "", key = "" } = {}) => {
65
+ if (!this.isReady) await this.waitIsReady();
66
+
67
+ const result = {};
68
+
69
+ if (key) {
70
+ const keyWithPrefix = prefix ? `${prefix}.${key}` : key;
71
+
72
+ result[key] = await localforage.getItem(keyWithPrefix);
73
+ } else {
74
+ const keys = await localforage.keys();
75
+ const realKeys = prefix ? keys.filter((key) => key.startsWith(prefix)) : keys;
76
+
77
+ await Promise.all(
78
+ realKeys.map(async (key) => {
79
+ result[prefix ? key.slice(prefix.length + 1) : key] = await localforage.getItem(key);
80
+ })
81
+ );
82
+ }
83
+
84
+ return result;
85
+ };
86
+
87
+ onStorageRm = async ({ prefix, key }) => {
88
+ if (!this.isReady) await this.waitIsReady();
89
+
90
+ localforage.removeItem(`${prefix}.${key}`);
91
+
92
+ this.emit(this.EVENTS.STORAGE.CHANGED);
93
+ };
94
+
95
+ onStorageExport = async () => {
96
+ if (!this.isReady) await this.waitIsReady();
97
+
98
+ const state = await this.onStorageGet();
99
+
100
+ await this.emit(this.EVENTS.SYSTEM.FILE_LOAD, { obj: state, name: "state" });
101
+
102
+ return state;
103
+ };
104
+
105
+ onStorageImport = async () => {
106
+ if (!this.isReady) await this.waitIsReady();
107
+
108
+ const [newStorage] = await this.emit(this.EVENTS.SYSTEM.FILE_READ);
109
+ if (!newStorage) return;
110
+
111
+ const keys = await localforage.keys();
112
+ await Promise.all(keys.map((key) => localforage.removeItem(key)));
113
+ await Promise.all(Object.keys(newStorage).map((key) => localforage.setItem(key, newStorage[key])));
114
+
115
+ await this.emit(this.EVENTS.SYSTEM.RELOAD);
116
+ };
117
+
118
+ onStorageClear = async () => {
119
+ if (!this.isReady) await this.waitIsReady();
120
+
121
+ const keys = await localforage.keys();
122
+ await Promise.all(keys.map((key) => localforage.removeItem(key)));
123
+
124
+ await this.emit(this.EVENTS.SYSTEM.RELOAD);
125
+ };
126
+ }
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@vnejs/plugins.core.storage",
3
+ "version": "0.0.1",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "publish:major": "npm version major && npm publish --access public",
8
+ "publish:minor": "npm version minor && npm publish --access public",
9
+ "publish:patch": "npm version patch && npm publish --access public"
10
+ },
11
+ "author": "",
12
+ "license": "ISC",
13
+ "description": "",
14
+ "dependencies": {
15
+ "localforage": "1.10.0"
16
+ },
17
+ "peerDependencies": {
18
+ "@vnejs/shared": "*",
19
+ "@vnejs/module": "*"
20
+ }
21
+ }