@preference-sl/prefconfigurator-wasm 0.1.61-2 → 0.1.61-3

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 (2) hide show
  1. package/js/gltf-storage.js +70 -60
  2. package/package.json +1 -1
@@ -1,5 +1,15 @@
1
1
  // wwwroot/js/gltf-storage.js
2
2
 
3
+ function _getStorageState() {
4
+ const root = (globalThis.PrefConfigurator ??= {});
5
+ return (root._state ??= {});
6
+ }
7
+ function _getDbOrThrow() {
8
+ const db = _getStorageState().gltfStoreDb;
9
+ if (!db) throw new Error('Database not initialized');
10
+ return db;
11
+ }
12
+
3
13
  // Inicializar IndexedDB
4
14
  export async function initDb(dbName, storeName) {
5
15
  return new Promise((resolve, reject) => {
@@ -10,7 +20,11 @@ export async function initDb(dbName, storeName) {
10
20
  const db = event.target.result;
11
21
 
12
22
  // Verificar si la store existe
13
- if (!db.objectStoreNames.contains(storeName)) {
23
+ if (db.objectStoreNames.contains(storeName)) {
24
+ _getStorageState().gltfStoreDb = db;
25
+ resolve();
26
+ }
27
+ else {
14
28
  db.close();
15
29
 
16
30
  // Reabrir con nueva versión para crear la store
@@ -19,19 +33,16 @@ export async function initDb(dbName, storeName) {
19
33
 
20
34
  upgradeRequest.onerror = () => reject(upgradeRequest.error);
21
35
  upgradeRequest.onsuccess = () => {
22
- window.gltfDB = upgradeRequest.result;
36
+ _getStorageState().gltfStoreDb = upgradeRequest.result;
23
37
  resolve();
24
38
  };
25
39
 
26
40
  upgradeRequest.onupgradeneeded = (upgradeEvent) => {
27
41
  const upgradeDb = upgradeEvent.target.result;
28
42
  const store = upgradeDb.createObjectStore(storeName, { keyPath: 'id' });
29
- store.createIndex('type', 'type', { unique: false });
30
- store.createIndex('timestamp', 'timestamp', { unique: false });
43
+ // crear indices para mejorar rendimiento
44
+ store.createIndex('expirationTimeStamp', 'expirationTimeStamp', { unique: false });
31
45
  };
32
- } else {
33
- window.gltfDB = db;
34
- resolve();
35
46
  }
36
47
  };
37
48
  });
@@ -40,10 +51,8 @@ export async function initDb(dbName, storeName) {
40
51
  // Guardar modelo
41
52
  export async function saveModel(modelDataStr, storeName) {
42
53
  return new Promise((resolve, reject) => {
43
- if (!window.gltfDB) {
44
- reject(new Error('Database not initialized'));
45
- return;
46
- }
54
+ let db;
55
+ try { db = _getDbOrThrow(); } catch (e) { reject(e); return; }
47
56
 
48
57
  // Convertir Uint8Array a base64 para almacenamiento (mas lento)
49
58
  //const base64Data = this._arrayBufferToBase64(modelData.data);
@@ -52,11 +61,10 @@ export async function saveModel(modelDataStr, storeName) {
52
61
  const dataToStore = {
53
62
  ...modelData,
54
63
  data: modelData.data,
55
- size: modelData.data.length,
56
- timestamp: new Date().toISOString()
64
+ size: modelData.data.length
57
65
  };
58
66
 
59
- const transaction = window.gltfDB.transaction([storeName], 'readwrite');
67
+ const transaction = db.transaction([storeName], 'readwrite');
60
68
  const store = transaction.objectStore(storeName);
61
69
  const request = store.put(dataToStore);
62
70
 
@@ -68,11 +76,10 @@ export async function saveModel(modelDataStr, storeName) {
68
76
  // Cargar modelo
69
77
  export function loadModel(modelId, storeName) {
70
78
  return new Promise((resolve, reject) => {
71
- if (!globalThis.gltfDB) {
72
- reject(new Error('Database not initialized'));
73
- return;
74
- }
75
- const tx = globalThis.gltfDB.transaction([storeName], 'readonly');
79
+ let db;
80
+ try { db = _getDbOrThrow(); } catch (e) { reject(e); return; }
81
+
82
+ const tx = db.transaction([storeName], 'readonly');
76
83
  const store = tx.objectStore(storeName);
77
84
  const req = store.get(modelId);
78
85
  req.onerror = () => reject(req.error);
@@ -86,18 +93,16 @@ export function downloadFileFromBytes(fileName, bytesBase64, mimeType) {
86
93
  link.href = `data:${mimeType};base64,${bytesBase64}`;
87
94
  document.body.appendChild(link);
88
95
  link.click();
89
- document.body.removeChild(link);
96
+ link.remove();
90
97
  }
91
98
 
92
99
  // Obtener todos los modelos (solo metadata)
93
100
  export async function getAllModels(storeName) {
94
101
  return new Promise((resolve, reject) => {
95
- if (!window.gltfDB) {
96
- reject(new Error('Database not initialized'));
97
- return;
98
- }
102
+ let db;
103
+ try { db = _getDbOrThrow(); } catch (e) { reject(e); return; }
99
104
 
100
- const transaction = window.gltfDB.transaction([storeName], 'readonly');
105
+ const transaction = db.transaction([storeName], 'readonly');
101
106
  const store = transaction.objectStore(storeName);
102
107
  const request = store.getAll();
103
108
 
@@ -107,9 +112,8 @@ export async function getAllModels(storeName) {
107
112
  const results = request.result.map(item => ({
108
113
  id: item.id,
109
114
  metadata: item.metadata,
110
- timestamp: item.timestamp,
111
- size: item.size,
112
- type: item.type
115
+ timeStamp: item.timeStamp,
116
+ size: item.size
113
117
  }));
114
118
  resolve(JSON.stringify(results));
115
119
  };
@@ -119,12 +123,10 @@ export async function getAllModels(storeName) {
119
123
  // Eliminar modelo
120
124
  export async function deleteModel(modelId, storeName) {
121
125
  return new Promise((resolve, reject) => {
122
- if (!window.gltfDB) {
123
- reject(new Error('Database not initialized'));
124
- return;
125
- }
126
+ let db;
127
+ try { db = _getDbOrThrow(); } catch (e) { reject(e); return; }
126
128
 
127
- const transaction = window.gltfDB.transaction([storeName], 'readwrite');
129
+ const transaction = db.transaction([storeName], 'readwrite');
128
130
  const store = transaction.objectStore(storeName);
129
131
  const request = store.delete(modelId);
130
132
 
@@ -136,12 +138,10 @@ export async function deleteModel(modelId, storeName) {
136
138
  // Limpiar toda la base de datos
137
139
  export async function clearAll(storeName) {
138
140
  return new Promise((resolve, reject) => {
139
- if (!window.gltfDB) {
140
- reject(new Error('Database not initialized'));
141
- return;
142
- }
141
+ let db;
142
+ try { db = _getDbOrThrow(); } catch (e) { reject(e); return; }
143
143
 
144
- const transaction = window.gltfDB.transaction([storeName], 'readwrite');
144
+ const transaction = db.transaction([storeName], 'readwrite');
145
145
  const store = transaction.objectStore(storeName);
146
146
  const request = store.clear();
147
147
 
@@ -150,6 +150,36 @@ export async function clearAll(storeName) {
150
150
  });
151
151
  }
152
152
 
153
+ export async function cleanExpiredModels(storeName) {
154
+ return new Promise((resolve, reject) => {
155
+ let db;
156
+ try { db = _getDbOrThrow(); } catch (e) { reject(e); return; }
157
+
158
+ const transaction = db.transaction([storeName], 'readwrite');
159
+ const store = transaction.objectStore(storeName);
160
+
161
+ // usar el indice expirationTimeStamp para busqueda eficiente
162
+ const index = store.index('expirationTimeStamp');
163
+ const now = Date.now();
164
+
165
+ // Buscar solo registros con expirationTimeStamp menor que now
166
+ const range = IDBKeyRange.upperBound(now);
167
+ const cursorRequest = index.openCursor(range);
168
+
169
+ cursorRequest.onsuccess = (event) => {
170
+ const cursor = event.target.result;
171
+ if (cursor) {
172
+ cursor.delete();
173
+ cursor.continue();
174
+ }
175
+ };
176
+
177
+ transaction.oncomplete = () => {
178
+ resolve();
179
+ };
180
+ });
181
+ }
182
+
153
183
  (function attachPublicAPI(global) {
154
184
  const root = (global.PrefConfigurator ??= {});
155
185
  const storage = {
@@ -159,32 +189,12 @@ export async function clearAll(storeName) {
159
189
  getAllModels,
160
190
  deleteModel,
161
191
  clearAll,
192
+ cleanExpiredModels,
162
193
  downloadFileFromBytes,
163
194
  };
164
195
 
165
196
  // versionado del módulo público
166
197
  root.version = root.version ?? '1.0.0';
167
198
  root.storage = Object.freeze(storage);
199
+ root._state = root._state ?? {};
168
200
  })(globalThis);
169
-
170
- // Utilidades
171
- //_arrayBufferToBase64: function (buffer) {
172
- // let binary = '';
173
- // const bytes = new Uint8Array(buffer);
174
- // const len = bytes.byteLength;
175
- // for (let i = 0; i < len; i++) {
176
- // binary += String.fromCharCode(bytes[i]);
177
- // }
178
- // return btoa(binary);
179
- //},
180
-
181
- //_base64ToArrayBuffer: function (base64) {
182
- // const binaryString = atob(base64);
183
- // const len = binaryString.length;
184
- // const bytes = new Uint8Array(len);
185
- // for (let i = 0; i < len; i++) {
186
- // bytes[i] = binaryString.charCodeAt(i);
187
- // }
188
- // return bytes.buffer;
189
- //}
190
- //};
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "postinstall": "node scripts/postinstall.js"
4
4
  },
5
5
  "description": ".NET WebAssembly runtime package that centralizes logic for building product configurators, exposing a simple API for integration into ecommerce platforms.",
6
- "version": "0.1.61-2",
6
+ "version": "0.1.61-3",
7
7
  "files": [
8
8
  "_framework/**",
9
9
  "**/*.js",