@gudhub/core 1.2.4-beta.3 → 1.2.4-beta.30

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.
Files changed (43) hide show
  1. package/GUDHUB/AppProcessor/AppProcessor.js +62 -24
  2. package/GUDHUB/ChunksManager/ChunksManager.js +61 -61
  3. package/GUDHUB/ChunksManager/ChunksManager.test.js +8 -4
  4. package/GUDHUB/DataService/AppDataService.js +232 -0
  5. package/GUDHUB/DataService/ChunkDataService.js +10 -0
  6. package/GUDHUB/DataService/IndexedDB/IndexedDBAppService.js +799 -63
  7. package/GUDHUB/DataService/IndexedDB/IndexedDBChunkService.js +303 -46
  8. package/GUDHUB/DataService/IndexedDB/IndexedDBService.js +342 -2
  9. package/GUDHUB/DataService/IndexedDB/StoreManager/BaseStoreManager.js +124 -0
  10. package/GUDHUB/DataService/IndexedDB/StoreManager/managers.js +113 -0
  11. package/GUDHUB/DataService/IndexedDB/appDataConf.js +6 -3
  12. package/GUDHUB/DataService/IndexedDB/appRequestWorker.js +225 -0
  13. package/GUDHUB/DataService/IndexedDB/chunkDataConf.js +3 -3
  14. package/GUDHUB/DataService/IndexedDB/consts.js +3 -1
  15. package/GUDHUB/DataService/IndexedDB/init.js +15 -14
  16. package/GUDHUB/DataService/IndexedDB/storeManagerConf/chunkCacheStoreManagerConf.js +11 -0
  17. package/GUDHUB/DataService/IndexedDB/storeManagerConf/init.js +1 -0
  18. package/GUDHUB/DataService/export.js +8 -5
  19. package/GUDHUB/DataService/httpService/AppHttpService.js +22 -4
  20. package/GUDHUB/DataService/httpService/ChunkHttpService.js +19 -2
  21. package/GUDHUB/DataService/utils.js +104 -1
  22. package/GUDHUB/FileManager/FileManager.js +7 -3
  23. package/GUDHUB/GHConstructor/createAngularModuleInstance.js +3 -3
  24. package/GUDHUB/GHConstructor/createClassInstance.js +3 -3
  25. package/GUDHUB/ItemProcessor/ItemProcessor.js +24 -0
  26. package/GUDHUB/Storage/ModulesList.js +18 -2
  27. package/GUDHUB/Utils/AppsTemplateService/AppsTemplateService.js +37 -1
  28. package/GUDHUB/Utils/Utils.js +29 -1
  29. package/GUDHUB/Utils/merge_chunks/merge_chunks.js +36 -28
  30. package/GUDHUB/Utils/merge_chunks/merge_chunks.worker.js +78 -0
  31. package/GUDHUB/Utils/merge_compare_items/merge_compare_items.js +40 -9
  32. package/GUDHUB/WebSocket/WebSocket.js +2 -1
  33. package/GUDHUB/consts.js +21 -1
  34. package/GUDHUB/gudhub.js +39 -14
  35. package/appRequestWorker.js +1 -0
  36. package/appRequestWorker.js.LICENSE.txt +13 -0
  37. package/appRequestWorker.js.map +1 -0
  38. package/package.json +17 -6
  39. package/umd/appRequestWorker.js +1 -0
  40. package/umd/library.min.js +1 -300
  41. package/webpack.config.js +154 -0
  42. package/.vscode/launch.json +0 -31
  43. package/umd/library.min.js.map +0 -1
@@ -1,9 +1,349 @@
1
+ import { appsConf } from "./appDataConf.js";
2
+ import { chunksConf } from "./chunkDataConf.js";
3
+ import { dbName, dbVersion } from "./consts.js";
4
+ import { chunksMergeConf } from "./storeManagerConf/chunkCacheStoreManagerConf.js";
5
+
6
+
7
+ // этот класс для наследования был создан, т.е. надо подумать как его скомпоновать с IndexedDBManager
1
8
  export class IndexedDBService {
2
9
  constructor(conf) {
3
10
  this.store = conf.store;
4
11
  this.dbName = conf.dbName;
5
12
  this.dbVersion = conf.dbVersion;
6
13
 
7
- this.requestCache = new Map; // id -> promise
14
+ this.requestCache = new Map; // id -> promise ///TODO seems irrelevant to class IndexedDBManager (could be renamed to Facade already)
8
15
  }
9
- }
16
+ }
17
+
18
+
19
+ //Maybe rename to Facade
20
+ export class IndexedDBManager {
21
+ constructor(
22
+ dbName,
23
+ // dbVersion,
24
+ storeNameList,
25
+ ) {
26
+ if (
27
+ !IndexedDBManager.dbNameToInstanceMap
28
+ ) {
29
+ IndexedDBManager.dbNameToInstanceMap = new Map;
30
+ }
31
+
32
+ if (
33
+ IndexedDBManager.dbNameToInstanceMap.has(dbName)
34
+ ) return IndexedDBManager.dbNameToInstanceMap.get(dbName);
35
+
36
+ this.db = null;
37
+ // this.queue = [];
38
+ // this.isProcessing = false;
39
+
40
+ this.dbName = dbName;
41
+ // this.dbVersion = dbVersion;
42
+ this.storeNameList = storeNameList;
43
+ // this.storeNameList = [];
44
+
45
+ IndexedDBManager.dbNameToInstanceMap.set(dbName, this);
46
+
47
+
48
+ // this.db = new Promise((resolve, reject) => {
49
+
50
+ // });
51
+
52
+
53
+ // this.dbPrms = this.openDB();
54
+
55
+ this.db = null;
56
+
57
+
58
+ // this.db = this.openDB();
59
+
60
+ // this
61
+
62
+ // this.openDB();
63
+ }
64
+
65
+ // TODO also remove outdated stores
66
+ async checkAndCreateStore(storeName) {
67
+ const databases = await indexedDB.databases();
68
+ const dbInfo = databases.find(db => db.name === this.dbName);
69
+
70
+ let storeExists = false;
71
+
72
+ let self = this;
73
+
74
+ if (
75
+ dbInfo
76
+ ) {
77
+ storeExists = await new Promise((resolve, reject) => {
78
+ const request = indexedDB.open(self.dbName);
79
+
80
+ request.onsuccess = function(event) {
81
+ const db = event.target.result;
82
+ const exists = db.objectStoreNames.contains(storeName);
83
+ db.close();
84
+ resolve(exists);
85
+ };
86
+
87
+ request.onerror = function(event) {
88
+ reject(event.target.error);
89
+ };
90
+ });
91
+
92
+ //TODO try catch for promise reject
93
+ }
94
+
95
+ if (
96
+ !storeExists
97
+ ) {
98
+ return new Promise((resolve, reject) => {
99
+ const request = indexedDB.open(self.dbName, dbInfo ? dbInfo.version + 1 : 1);
100
+
101
+ request.onupgradeneeded = function(event) {
102
+ const db = event.target.result;
103
+ if (
104
+ !db.objectStoreNames.contains(storeName)
105
+ ) {
106
+ db.createObjectStore(storeName);
107
+ }
108
+ };
109
+
110
+ request.onsuccess = function(event) {
111
+ const db = event.target.result;
112
+ db.close();
113
+ resolve();
114
+ };
115
+
116
+ request.onerror = reject;
117
+ });
118
+
119
+
120
+ //TODO try catch for reject
121
+ }
122
+
123
+ //TODO maybe not return anything it will be ok for promise resolve
124
+ return true;
125
+ }
126
+
127
+ // // Usage example
128
+ // checkAndCreateStore('myDatabase', 'myObjectStore').then(() => {
129
+ // console.log('Check and creation (if necessary) complete.');
130
+ // }).catch(error => {
131
+ // console.error('Error checking and creating object store:', error);
132
+ // });
133
+
134
+
135
+ async openDB() {
136
+
137
+ // TODO remove outdated stores before also
138
+
139
+
140
+ if (this.db) return this.db;
141
+
142
+ let resolver, rejecter;
143
+
144
+ let dbPrms = new Promise((resolve, reject) => {
145
+ resolver = resolve;
146
+ rejecter = reject;
147
+ });
148
+
149
+ for (let storeName of this.storeNameList) {
150
+ await this.checkAndCreateStore(storeName);
151
+ }
152
+
153
+
154
+
155
+ let self = this;
156
+
157
+ // return new Promise((resolve, reject) => {
158
+ // const request = indexedDB.open(this.dbName, this.dbVersion);
159
+ const request = indexedDB.open(this.dbName);
160
+
161
+ // request.onupgradeneeded = (event) => {
162
+ // const db = event.target.result;
163
+
164
+ // this.storeNameList.forEach(storeName => {
165
+ // if (
166
+ // !db.objectStoreNames.contains(storeName)
167
+ // ) {
168
+ // db.createObjectStore(storeName);
169
+ // }
170
+ // });
171
+ // };
172
+
173
+ request.onsuccess = (event) => {
174
+ self.db = event.target.result;
175
+
176
+ // let version = this.db.version;
177
+
178
+ resolver(this.db);
179
+ };
180
+
181
+ request.onerror = rejecter;
182
+
183
+ return dbPrms;
184
+ // });
185
+ }
186
+
187
+ async executeOperation(storeName, operation) {
188
+
189
+ //this get executed more than 1 time
190
+ let db = await this.openDB();
191
+
192
+ // if (
193
+ // !this.db
194
+ // ) {
195
+ // throw new Error("Database not initialized. Call openDB first.");
196
+ // }
197
+
198
+
199
+ // await this.db;
200
+
201
+
202
+ // let self = this;
203
+
204
+ // await this.db;
205
+
206
+ return new Promise((resolve, reject) => {
207
+ const transaction = db.transaction(storeName, 'readwrite'); //TODO not all operations readwrite
208
+ const store = transaction.objectStore(storeName);
209
+
210
+ transaction.oncomplete = () => resolve();
211
+ transaction.onerror = (event) => reject(`Transaction failed: ${event.target.error}`);
212
+
213
+ try {
214
+ operation(store);
215
+ } catch (error) {
216
+ reject(`Operation failed: ${error.message}`);
217
+ }
218
+ });
219
+ }
220
+
221
+
222
+ // в инете пишут что индексдб сам хендлит транзакции, может не нужно вообще городить эти конструкции
223
+
224
+
225
+ // async enqueueOperation(storeName, type, operation) {
226
+ // await this.ensureStoreExists(storeName); // Ensure the store exists <-----------------------
227
+ // const db = await this.dbPromise;
228
+ // return new Promise((resolve, reject) => {
229
+ // const transaction = db.transaction(storeName, type);
230
+ // const store = transaction.objectStore(storeName);
231
+ // const request = operation(store);
232
+
233
+ // request.onsuccess = (event) => {
234
+ // resolve(event.target.result);
235
+ // };
236
+
237
+ // request.onerror = (event) => {
238
+ // reject(event.target.error);
239
+ // };
240
+ // });
241
+ // }
242
+
243
+
244
+ async enqueueOperation(storeName, operation) {
245
+ this.queue.push({ storeName, operation });
246
+
247
+ if (!this.isProcessing) {
248
+ this.isProcessing = true;
249
+ while (this.queue.length > 0) {
250
+ const { storeName, operation } = this.queue.shift();
251
+ try {
252
+ await this.executeOperation(storeName, operation);
253
+ } catch (error) {
254
+ console.error('Operation failed:', error);
255
+ }
256
+ }
257
+ this.isProcessing = false;
258
+ }
259
+ }
260
+
261
+ // единственное что тут не нравится - версия динамически меняется
262
+ async ensureStoreExists(storeName) {
263
+
264
+ }
265
+
266
+
267
+ // async ensureStoreExists(storeName) {
268
+ // const db = await this.dbPromise;
269
+ // if (!db.objectStoreNames.contains(storeName)) {
270
+ // this.db.close();
271
+ // const version = db.version + 1;
272
+ // const request = indexedDB.open(this.dbName, version);
273
+
274
+ // request.onupgradeneeded = (event) => {
275
+ // const upgradedDb = event.target.result;
276
+ // if (!upgradedDb.objectStoreNames.contains(storeName)) {
277
+ // upgradedDb.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true });
278
+ // }
279
+ // };
280
+
281
+ // return new Promise((resolve, reject) => {
282
+ // request.onsuccess = (event) => {
283
+ // this.db = event.target.result;
284
+ // this.dbPromise = Promise.resolve(this.db); // Update the dbPromise
285
+ // resolve(this.db);
286
+ // };
287
+
288
+ // request.onerror = (event) => {
289
+ // reject(event.target.error);
290
+ // };
291
+ // });
292
+ // }
293
+ // return Promise.resolve(db);
294
+ // }
295
+
296
+ async createObjectStore(storeName) {
297
+
298
+
299
+ // async createObjectStore(storeName) {
300
+ // const db = await this.dbPromise;
301
+ // if (!db.objectStoreNames.contains(storeName)) {
302
+ // db.close();
303
+ // const version = db.version + 1;
304
+ // const request = indexedDB.open(this.dbName, version);
305
+
306
+ // request.onupgradeneeded = (event) => {
307
+ // const upgradedDb = event.target.result;
308
+ // if (!upgradedDb.objectStoreNames.contains(storeName)) {
309
+ // upgradedDb.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true });
310
+ // }
311
+ // };
312
+
313
+ // return new Promise((resolve, reject) => {
314
+ // request.onsuccess = (event) => {
315
+ // this.db = event.target.result;
316
+ // resolve(this.db);
317
+ // };
318
+
319
+ // request.onerror = (event) => {
320
+ // reject(event.target.error);
321
+ // };
322
+ // });
323
+ // }
324
+ // return Promise.resolve(db);
325
+ // }
326
+
327
+ }
328
+ }
329
+
330
+ export const gudhubIndexedDBManager = new IndexedDBManager(
331
+ dbName,
332
+ // dbVersion,
333
+ [
334
+ appsConf.store,
335
+ chunksConf.store,
336
+ chunksMergeConf.store,
337
+ ],
338
+ );
339
+
340
+ // export default dbManager;
341
+
342
+
343
+
344
+ // последний ответ посмотри, там я спрашивал можно ли не закрывать и открывать дб из каждого сторменеджера
345
+
346
+
347
+ // await this.ensureStoreExists(storeName); // Ensure the store exists - вот этот код вроде ок, т.е. перед выполнением след операции проверка
348
+
349
+
@@ -0,0 +1,124 @@
1
+ export class BaseStoreManager {
2
+ // constructor(dbManager, dbName, storeName) {
3
+ constructor(dbManager, storeName) {
4
+ this.dbManager = dbManager;
5
+ // this.dbName = dbName;
6
+ this.storeName = storeName;
7
+ // this.dbManager.openDB(this.dbName, [this.storeName]);
8
+ // this.dbManager.ensureStoreExists(this.storeName);
9
+ }
10
+
11
+ async addItem(id, data) {
12
+ return new Promise(async (resolve, reject) => {
13
+
14
+ this.dbManager.executeOperation(this.storeName, (store) => {
15
+ const request = store.add(data, id);
16
+
17
+ request.onsuccess = resolve;
18
+ request.onerror = reject;
19
+ });
20
+
21
+ });
22
+ }
23
+
24
+ async putItem(id, data) {
25
+ return new Promise(async (resolve, reject) => {
26
+
27
+ this.dbManager.executeOperation(this.storeName, (store) => {
28
+ const request = store.put(data, id);
29
+
30
+ request.onsuccess = resolve;
31
+ request.onerror = reject;
32
+ });
33
+
34
+ });
35
+ }
36
+
37
+ async hasItem(id) {
38
+
39
+ // debugger
40
+
41
+ try {
42
+ let item = await this.getItem(id);
43
+
44
+ if (!item) return false;
45
+
46
+ return true;
47
+ } catch(e) {
48
+ //todo check error type and then rethrow maybe here
49
+
50
+ return false;
51
+ }
52
+
53
+ return new Promise(async (resolve, reject) => {
54
+
55
+ this.dbManager.executeOperation(this.storeName, (store) => {
56
+ const request = store.get(id);
57
+
58
+ request.onsuccess = () => {
59
+ const data = request.result;
60
+ resolve(data);
61
+ };
62
+
63
+ request.onerror = reject;
64
+ });
65
+
66
+ });
67
+ }
68
+
69
+ async getItem(id) {
70
+ return new Promise(async (resolve, reject) => {
71
+
72
+ this.dbManager.executeOperation(this.storeName, (store) => {
73
+ const request = store.get(id);
74
+
75
+ request.onsuccess = () => {
76
+ const data = request.result;
77
+ resolve(data);
78
+ };
79
+
80
+ request.onerror = reject;
81
+ });
82
+
83
+ });
84
+ }
85
+
86
+ async updateItem(id, updatedItem) {
87
+ return new Promise(async (resolve, reject) => {
88
+
89
+ this.dbManager.executeOperation(this.storeName, (store) => {
90
+ const request = store.get(id);
91
+
92
+ request.onsuccess = () => {
93
+ const data = request.result;
94
+ Object.assign(data, updatedItem);
95
+ store.put(data, id);
96
+
97
+ //TODO wait put operation before resolve
98
+ resolve();
99
+ };
100
+
101
+ request.onerror = reject;
102
+ });
103
+
104
+ });
105
+ }
106
+
107
+ async deleteItem(id) {
108
+ return new Promise(async (resolve, reject) => {
109
+
110
+ this.dbManager.executeOperation(this.storeName, (store) => {
111
+ const request = store.delete(id);
112
+
113
+ request.onsuccess = resolve;
114
+ request.onerror = reject;
115
+ });
116
+
117
+ });
118
+ }
119
+ }
120
+
121
+
122
+ //TODO move to base class here
123
+ // this.requestCache = new Map; // id -> promise ///TODO seems irrelevant to class IndexedDBManager (could be renamed to Facade already)
124
+
@@ -0,0 +1,113 @@
1
+ import { appsConf } from "../appDataConf.js";
2
+ import { chunksConf } from "../chunkDataConf.js";
3
+ // import { dbName } from "../consts";
4
+ import { gudhubIndexedDBManager } from "../IndexedDBService.js";
5
+ import { chunksMergeConf } from "../storeManagerConf/chunkCacheStoreManagerConf.js";
6
+ import { BaseStoreManager } from "./BaseStoreManager.js";
7
+
8
+ export class AppStoreManager extends BaseStoreManager {
9
+ constructor() {
10
+ super(gudhubIndexedDBManager, appsConf.store);
11
+ }
12
+
13
+ async getApp(id) {
14
+
15
+ return this.getItem(id);
16
+
17
+ // return dbManager.enqueueOperation('apps', 'readonly', (store) => store.get(id));
18
+ }
19
+
20
+ async addApp(id, data) {
21
+ return this.addItem(id, data);
22
+
23
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.add(app));
24
+ }
25
+
26
+ async putApp(id, data) {
27
+ return this.putItem(id, data);
28
+
29
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.add(app));
30
+ }
31
+
32
+ async hasApp(id) {
33
+ return this.hasItem(id);
34
+ }
35
+
36
+ async deleteApp(id) {
37
+ return this.deleteItem(id);
38
+
39
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.delete(id));
40
+ }
41
+
42
+ // Additional methods specific to AppStoreManager if necessary
43
+ }
44
+
45
+ export class ChunksStoreManager extends BaseStoreManager {
46
+ constructor() {
47
+ super(gudhubIndexedDBManager, chunksConf.store);
48
+ }
49
+
50
+
51
+ async getChunk(id) {
52
+
53
+ return this.getItem(id);
54
+
55
+ // return dbManager.enqueueOperation('apps', 'readonly', (store) => store.get(id));
56
+ }
57
+
58
+ async addChunk(id, chunk) {
59
+ return this.addItem(id, chunk);
60
+
61
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.add(app));
62
+ }
63
+
64
+ async putChunk(id, chunk) {
65
+ return this.putItem(id, chunk);
66
+
67
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.add(app));
68
+ }
69
+
70
+ async deleteChunk(id) {
71
+ return this.deleteItem(id);
72
+
73
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.delete(id));
74
+ }
75
+
76
+
77
+ //use item methods from BaseStoreManager !!!!!!!
78
+
79
+
80
+ // Additional methods specific to ChunksStoreManager if necessary
81
+ }
82
+
83
+ export class MergedChunksStoreManager extends BaseStoreManager {
84
+ constructor() {
85
+ super(gudhubIndexedDBManager, chunksMergeConf.store);
86
+ }
87
+
88
+ async get(id) {
89
+
90
+ return this.getItem(id);
91
+
92
+ // return dbManager.enqueueOperation('apps', 'readonly', (store) => store.get(id));
93
+ }
94
+
95
+ async add(id, chunk) {
96
+ return this.addItem(id, chunk);
97
+
98
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.add(app));
99
+ }
100
+
101
+ //TODO update here ok?
102
+ async put(id, chunk) {
103
+ return this.putItem(id, chunk);
104
+
105
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.add(app));
106
+ }
107
+
108
+ async delete(id) {
109
+ return this.deleteItem(id);
110
+
111
+ // return dbManager.enqueueOperation('apps', 'readwrite', (store) => store.delete(id));
112
+ }
113
+ }
@@ -1,7 +1,10 @@
1
- import { dbName, dbVersion } from "./consts.js";
1
+ // import { dbName } from "./consts.js";
2
+
3
+
4
+ // move to folder also remove chunksConf
2
5
 
3
6
  export const appsConf = {
4
- dbName,
5
- dbVersion,
7
+ // dbName,
8
+ // dbVersion,
6
9
  store: 'apps',
7
10
  };