@midscene/shared 0.28.10-beta-20250922071252.0 → 0.28.10

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,109 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) Object.defineProperty(obj, key, {
3
+ value: value,
4
+ enumerable: true,
5
+ configurable: true,
6
+ writable: true
7
+ });
8
+ else obj[key] = value;
9
+ return obj;
10
+ }
11
+ class IndexedDBManager {
12
+ initDB() {
13
+ return new Promise((resolve, reject)=>{
14
+ const request = indexedDB.open(this.dbName, this.version);
15
+ request.onerror = ()=>reject(request.error);
16
+ request.onsuccess = ()=>resolve(request.result);
17
+ request.onupgradeneeded = (event)=>{
18
+ const db = event.target.result;
19
+ this.storeConfigs.forEach(({ name, keyPath })=>{
20
+ if (!db.objectStoreNames.contains(name)) {
21
+ const store = db.createObjectStore(name, {
22
+ keyPath
23
+ });
24
+ store.createIndex('timestamp', 'timestamp', {
25
+ unique: false
26
+ });
27
+ }
28
+ });
29
+ };
30
+ });
31
+ }
32
+ async withTransaction(storeNames, mode, operation) {
33
+ const db = await this.dbPromise;
34
+ const transaction = db.transaction(storeNames, mode);
35
+ const stores = Array.isArray(storeNames) ? storeNames.map((name)=>transaction.objectStore(name)) : transaction.objectStore(storeNames);
36
+ return operation(stores);
37
+ }
38
+ promisifyRequest(request) {
39
+ return new Promise((resolve, reject)=>{
40
+ request.onsuccess = ()=>resolve(request.result);
41
+ request.onerror = ()=>reject(request.error);
42
+ });
43
+ }
44
+ async put(storeName, data) {
45
+ await this.withTransaction(storeName, 'readwrite', async (store)=>{
46
+ await this.promisifyRequest(store.put(data));
47
+ });
48
+ }
49
+ async get(storeName, key) {
50
+ return this.withTransaction(storeName, 'readonly', async (store)=>this.promisifyRequest(store.get(key)));
51
+ }
52
+ async getAll(storeName, sortByTimestamp = true) {
53
+ return this.withTransaction(storeName, 'readonly', async (store)=>{
54
+ const objectStore = store;
55
+ const results = sortByTimestamp ? await this.promisifyRequest(objectStore.index('timestamp').getAll()) : await this.promisifyRequest(objectStore.getAll());
56
+ return sortByTimestamp ? results.sort((a, b)=>a.timestamp - b.timestamp) : results;
57
+ });
58
+ }
59
+ async clear(storeName) {
60
+ await this.withTransaction(storeName, 'readwrite', async (store)=>{
61
+ await this.promisifyRequest(store.clear());
62
+ });
63
+ }
64
+ async delete(storeName, key) {
65
+ await this.withTransaction(storeName, 'readwrite', async (store)=>{
66
+ await this.promisifyRequest(store.delete(key));
67
+ });
68
+ }
69
+ async count(storeName) {
70
+ return this.withTransaction(storeName, 'readonly', async (store)=>this.promisifyRequest(store.count()));
71
+ }
72
+ getDBPromise() {
73
+ return this.dbPromise;
74
+ }
75
+ constructor(dbName, version, storeConfigs){
76
+ _define_property(this, "dbPromise", void 0);
77
+ _define_property(this, "dbName", void 0);
78
+ _define_property(this, "version", void 0);
79
+ _define_property(this, "storeConfigs", void 0);
80
+ this.dbName = dbName;
81
+ this.version = version;
82
+ this.storeConfigs = storeConfigs;
83
+ this.dbPromise = this.initDB();
84
+ }
85
+ }
86
+ const withErrorHandling = async (operation, errorMessage, defaultValue, onQuotaExceeded)=>{
87
+ try {
88
+ return await operation();
89
+ } catch (e) {
90
+ console.error(errorMessage, e);
91
+ if (e instanceof Error && 'QuotaExceededError' === e.name && onQuotaExceeded) {
92
+ console.log('Storage quota exceeded, running cleanup...');
93
+ await onQuotaExceeded();
94
+ }
95
+ return defaultValue;
96
+ }
97
+ };
98
+ const createCleanupFunction = (dbManager, storeName, maxItems)=>async ()=>{
99
+ try {
100
+ const results = await dbManager.getAll(storeName);
101
+ if (results.length > maxItems) {
102
+ const toDelete = results.sort((a, b)=>a.timestamp - b.timestamp).slice(0, results.length - maxItems);
103
+ await Promise.all(toDelete.map((item)=>dbManager.delete(storeName, item.id)));
104
+ }
105
+ } catch (e) {
106
+ console.error(`Failed to cleanup ${storeName}:`, e);
107
+ }
108
+ };
109
+ export { IndexedDBManager, createCleanupFunction, withErrorHandling };
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ IndexedDBManager: ()=>IndexedDBManager,
28
+ createCleanupFunction: ()=>createCleanupFunction,
29
+ withErrorHandling: ()=>withErrorHandling
30
+ });
31
+ function _define_property(obj, key, value) {
32
+ if (key in obj) Object.defineProperty(obj, key, {
33
+ value: value,
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true
37
+ });
38
+ else obj[key] = value;
39
+ return obj;
40
+ }
41
+ class IndexedDBManager {
42
+ initDB() {
43
+ return new Promise((resolve, reject)=>{
44
+ const request = indexedDB.open(this.dbName, this.version);
45
+ request.onerror = ()=>reject(request.error);
46
+ request.onsuccess = ()=>resolve(request.result);
47
+ request.onupgradeneeded = (event)=>{
48
+ const db = event.target.result;
49
+ this.storeConfigs.forEach(({ name, keyPath })=>{
50
+ if (!db.objectStoreNames.contains(name)) {
51
+ const store = db.createObjectStore(name, {
52
+ keyPath
53
+ });
54
+ store.createIndex('timestamp', 'timestamp', {
55
+ unique: false
56
+ });
57
+ }
58
+ });
59
+ };
60
+ });
61
+ }
62
+ async withTransaction(storeNames, mode, operation) {
63
+ const db = await this.dbPromise;
64
+ const transaction = db.transaction(storeNames, mode);
65
+ const stores = Array.isArray(storeNames) ? storeNames.map((name)=>transaction.objectStore(name)) : transaction.objectStore(storeNames);
66
+ return operation(stores);
67
+ }
68
+ promisifyRequest(request) {
69
+ return new Promise((resolve, reject)=>{
70
+ request.onsuccess = ()=>resolve(request.result);
71
+ request.onerror = ()=>reject(request.error);
72
+ });
73
+ }
74
+ async put(storeName, data) {
75
+ await this.withTransaction(storeName, 'readwrite', async (store)=>{
76
+ await this.promisifyRequest(store.put(data));
77
+ });
78
+ }
79
+ async get(storeName, key) {
80
+ return this.withTransaction(storeName, 'readonly', async (store)=>this.promisifyRequest(store.get(key)));
81
+ }
82
+ async getAll(storeName, sortByTimestamp = true) {
83
+ return this.withTransaction(storeName, 'readonly', async (store)=>{
84
+ const objectStore = store;
85
+ const results = sortByTimestamp ? await this.promisifyRequest(objectStore.index('timestamp').getAll()) : await this.promisifyRequest(objectStore.getAll());
86
+ return sortByTimestamp ? results.sort((a, b)=>a.timestamp - b.timestamp) : results;
87
+ });
88
+ }
89
+ async clear(storeName) {
90
+ await this.withTransaction(storeName, 'readwrite', async (store)=>{
91
+ await this.promisifyRequest(store.clear());
92
+ });
93
+ }
94
+ async delete(storeName, key) {
95
+ await this.withTransaction(storeName, 'readwrite', async (store)=>{
96
+ await this.promisifyRequest(store.delete(key));
97
+ });
98
+ }
99
+ async count(storeName) {
100
+ return this.withTransaction(storeName, 'readonly', async (store)=>this.promisifyRequest(store.count()));
101
+ }
102
+ getDBPromise() {
103
+ return this.dbPromise;
104
+ }
105
+ constructor(dbName, version, storeConfigs){
106
+ _define_property(this, "dbPromise", void 0);
107
+ _define_property(this, "dbName", void 0);
108
+ _define_property(this, "version", void 0);
109
+ _define_property(this, "storeConfigs", void 0);
110
+ this.dbName = dbName;
111
+ this.version = version;
112
+ this.storeConfigs = storeConfigs;
113
+ this.dbPromise = this.initDB();
114
+ }
115
+ }
116
+ const withErrorHandling = async (operation, errorMessage, defaultValue, onQuotaExceeded)=>{
117
+ try {
118
+ return await operation();
119
+ } catch (e) {
120
+ console.error(errorMessage, e);
121
+ if (e instanceof Error && 'QuotaExceededError' === e.name && onQuotaExceeded) {
122
+ console.log('Storage quota exceeded, running cleanup...');
123
+ await onQuotaExceeded();
124
+ }
125
+ return defaultValue;
126
+ }
127
+ };
128
+ const createCleanupFunction = (dbManager, storeName, maxItems)=>async ()=>{
129
+ try {
130
+ const results = await dbManager.getAll(storeName);
131
+ if (results.length > maxItems) {
132
+ const toDelete = results.sort((a, b)=>a.timestamp - b.timestamp).slice(0, results.length - maxItems);
133
+ await Promise.all(toDelete.map((item)=>dbManager.delete(storeName, item.id)));
134
+ }
135
+ } catch (e) {
136
+ console.error(`Failed to cleanup ${storeName}:`, e);
137
+ }
138
+ };
139
+ exports.IndexedDBManager = __webpack_exports__.IndexedDBManager;
140
+ exports.createCleanupFunction = __webpack_exports__.createCleanupFunction;
141
+ exports.withErrorHandling = __webpack_exports__.withErrorHandling;
142
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
143
+ "IndexedDBManager",
144
+ "createCleanupFunction",
145
+ "withErrorHandling"
146
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
147
+ Object.defineProperty(exports, '__esModule', {
148
+ value: true
149
+ });
@@ -0,0 +1,25 @@
1
+ export declare class IndexedDBManager {
2
+ private dbPromise;
3
+ private dbName;
4
+ private version;
5
+ private storeConfigs;
6
+ constructor(dbName: string, version: number, storeConfigs: Array<{
7
+ name: string;
8
+ keyPath: string;
9
+ }>);
10
+ private initDB;
11
+ private withTransaction;
12
+ private promisifyRequest;
13
+ put<T>(storeName: string, data: T): Promise<void>;
14
+ get<T>(storeName: string, key: string): Promise<T | undefined>;
15
+ getAll<T>(storeName: string, sortByTimestamp?: boolean): Promise<T[]>;
16
+ clear(storeName: string): Promise<void>;
17
+ delete(storeName: string, key: string): Promise<void>;
18
+ count(storeName: string): Promise<number>;
19
+ getDBPromise(): Promise<IDBDatabase>;
20
+ }
21
+ export declare const withErrorHandling: <T>(operation: () => Promise<T>, errorMessage: string, defaultValue?: T, onQuotaExceeded?: () => Promise<void>) => Promise<T | undefined>;
22
+ export declare const createCleanupFunction: <T extends {
23
+ id: string;
24
+ timestamp: number;
25
+ }>(dbManager: IndexedDBManager, storeName: string, maxItems: number) => () => Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/shared",
3
- "version": "0.28.10-beta-20250922071252.0",
3
+ "version": "0.28.10",
4
4
  "repository": "https://github.com/web-infra-dev/midscene",
5
5
  "homepage": "https://midscenejs.com/",
6
6
  "types": "./dist/types/index.d.ts",
package/src/baseDB.ts ADDED
@@ -0,0 +1,158 @@
1
+ // Generic database operations class
2
+ export class IndexedDBManager {
3
+ private dbPromise: Promise<IDBDatabase>;
4
+ private dbName: string;
5
+ private version: number;
6
+ private storeConfigs: Array<{ name: string; keyPath: string }>;
7
+
8
+ constructor(
9
+ dbName: string,
10
+ version: number,
11
+ storeConfigs: Array<{ name: string; keyPath: string }>,
12
+ ) {
13
+ this.dbName = dbName;
14
+ this.version = version;
15
+ this.storeConfigs = storeConfigs;
16
+ this.dbPromise = this.initDB();
17
+ }
18
+
19
+ private initDB(): Promise<IDBDatabase> {
20
+ return new Promise((resolve, reject) => {
21
+ const request = indexedDB.open(this.dbName, this.version);
22
+
23
+ request.onerror = () => reject(request.error);
24
+ request.onsuccess = () => resolve(request.result);
25
+
26
+ request.onupgradeneeded = (event) => {
27
+ const db = (event.target as IDBOpenDBRequest).result;
28
+
29
+ // Create stores if they don't exist
30
+ this.storeConfigs.forEach(({ name, keyPath }) => {
31
+ if (!db.objectStoreNames.contains(name)) {
32
+ const store = db.createObjectStore(name, { keyPath });
33
+ store.createIndex('timestamp', 'timestamp', { unique: false });
34
+ }
35
+ });
36
+ };
37
+ });
38
+ }
39
+
40
+ private async withTransaction<T>(
41
+ storeNames: string | string[],
42
+ mode: IDBTransactionMode,
43
+ operation: (stores: IDBObjectStore | IDBObjectStore[]) => Promise<T>,
44
+ ): Promise<T> {
45
+ const db = await this.dbPromise;
46
+ const transaction = db.transaction(storeNames, mode);
47
+
48
+ const stores = Array.isArray(storeNames)
49
+ ? storeNames.map((name) => transaction.objectStore(name))
50
+ : transaction.objectStore(storeNames);
51
+
52
+ return operation(stores);
53
+ }
54
+
55
+ private promisifyRequest<T>(request: IDBRequest<T>): Promise<T> {
56
+ return new Promise((resolve, reject) => {
57
+ request.onsuccess = () => resolve(request.result);
58
+ request.onerror = () => reject(request.error);
59
+ });
60
+ }
61
+
62
+ async put<T>(storeName: string, data: T): Promise<void> {
63
+ await this.withTransaction(storeName, 'readwrite', async (store) => {
64
+ await this.promisifyRequest((store as IDBObjectStore).put(data));
65
+ });
66
+ }
67
+
68
+ async get<T>(storeName: string, key: string): Promise<T | undefined> {
69
+ return this.withTransaction(storeName, 'readonly', async (store) => {
70
+ return this.promisifyRequest((store as IDBObjectStore).get(key));
71
+ });
72
+ }
73
+
74
+ async getAll<T>(storeName: string, sortByTimestamp = true): Promise<T[]> {
75
+ return this.withTransaction(storeName, 'readonly', async (store) => {
76
+ const objectStore = store as IDBObjectStore;
77
+ const results = sortByTimestamp
78
+ ? await this.promisifyRequest(objectStore.index('timestamp').getAll())
79
+ : await this.promisifyRequest(objectStore.getAll());
80
+
81
+ return sortByTimestamp
82
+ ? results.sort((a: any, b: any) => a.timestamp - b.timestamp)
83
+ : results;
84
+ });
85
+ }
86
+
87
+ async clear(storeName: string): Promise<void> {
88
+ await this.withTransaction(storeName, 'readwrite', async (store) => {
89
+ await this.promisifyRequest((store as IDBObjectStore).clear());
90
+ });
91
+ }
92
+
93
+ async delete(storeName: string, key: string): Promise<void> {
94
+ await this.withTransaction(storeName, 'readwrite', async (store) => {
95
+ await this.promisifyRequest((store as IDBObjectStore).delete(key));
96
+ });
97
+ }
98
+
99
+ async count(storeName: string): Promise<number> {
100
+ return this.withTransaction(storeName, 'readonly', async (store) => {
101
+ return this.promisifyRequest((store as IDBObjectStore).count());
102
+ });
103
+ }
104
+
105
+ getDBPromise(): Promise<IDBDatabase> {
106
+ return this.dbPromise;
107
+ }
108
+ }
109
+
110
+ // Generic error handler wrapper
111
+ export const withErrorHandling = async <T>(
112
+ operation: () => Promise<T>,
113
+ errorMessage: string,
114
+ defaultValue?: T,
115
+ onQuotaExceeded?: () => Promise<void>,
116
+ ): Promise<T | undefined> => {
117
+ try {
118
+ return await operation();
119
+ } catch (e) {
120
+ console.error(errorMessage, e);
121
+ if (
122
+ e instanceof Error &&
123
+ e.name === 'QuotaExceededError' &&
124
+ onQuotaExceeded
125
+ ) {
126
+ console.log('Storage quota exceeded, running cleanup...');
127
+ await onQuotaExceeded();
128
+ }
129
+ return defaultValue;
130
+ }
131
+ };
132
+
133
+ // Base cleanup function for managing storage space
134
+ export const createCleanupFunction = <
135
+ T extends { id: string; timestamp: number },
136
+ >(
137
+ dbManager: IndexedDBManager,
138
+ storeName: string,
139
+ maxItems: number,
140
+ ) => {
141
+ return async (): Promise<void> => {
142
+ try {
143
+ const results = await dbManager.getAll<T>(storeName);
144
+
145
+ if (results.length > maxItems) {
146
+ const toDelete = results
147
+ .sort((a, b) => a.timestamp - b.timestamp)
148
+ .slice(0, results.length - maxItems);
149
+
150
+ await Promise.all(
151
+ toDelete.map((item) => dbManager.delete(storeName, item.id)),
152
+ );
153
+ }
154
+ } catch (e) {
155
+ console.error(`Failed to cleanup ${storeName}:`, e);
156
+ }
157
+ };
158
+ };