canvasframework 0.5.16 → 0.5.18

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 (112) hide show
  1. package/dist/canvasframework.js +2 -0
  2. package/dist/canvasframework.js.LICENSE.txt +1 -0
  3. package/package.json +18 -17
  4. package/components/Accordion.js +0 -265
  5. package/components/AndroidDatePickerDialog.js +0 -406
  6. package/components/AppBar.js +0 -398
  7. package/components/AudioPlayer.js +0 -611
  8. package/components/Avatar.js +0 -202
  9. package/components/Banner.js +0 -342
  10. package/components/BottomNavigationBar.js +0 -433
  11. package/components/BottomSheet.js +0 -234
  12. package/components/Button.js +0 -360
  13. package/components/Camera.js +0 -644
  14. package/components/Card.js +0 -193
  15. package/components/Chart.js +0 -700
  16. package/components/Checkbox.js +0 -166
  17. package/components/Chip.js +0 -212
  18. package/components/CircularProgress.js +0 -327
  19. package/components/ContextMenu.js +0 -116
  20. package/components/DatePicker.js +0 -298
  21. package/components/Dialog.js +0 -337
  22. package/components/Divider.js +0 -125
  23. package/components/Drawer.js +0 -276
  24. package/components/FAB.js +0 -270
  25. package/components/FileUpload.js +0 -315
  26. package/components/FloatedCamera.js +0 -644
  27. package/components/IOSDatePickerWheel.js +0 -430
  28. package/components/ImageCarousel.js +0 -219
  29. package/components/ImageComponent.js +0 -223
  30. package/components/Input.js +0 -831
  31. package/components/InputDatalist.js +0 -723
  32. package/components/InputTags.js +0 -624
  33. package/components/List.js +0 -95
  34. package/components/ListItem.js +0 -269
  35. package/components/Modal.js +0 -364
  36. package/components/MorphingFAB.js +0 -428
  37. package/components/MultiSelectDialog.js +0 -206
  38. package/components/NumberInput.js +0 -271
  39. package/components/PasswordInput.js +0 -462
  40. package/components/ProgressBar.js +0 -88
  41. package/components/QRCodeReader.js +0 -539
  42. package/components/RadioButton.js +0 -151
  43. package/components/SearchInput.js +0 -315
  44. package/components/SegmentedControl.js +0 -357
  45. package/components/Select.js +0 -199
  46. package/components/SelectDialog.js +0 -255
  47. package/components/Slider.js +0 -113
  48. package/components/SliverAppBar.js +0 -139
  49. package/components/Snackbar.js +0 -243
  50. package/components/SpeedDialFAB.js +0 -397
  51. package/components/Stepper.js +0 -281
  52. package/components/SwipeableListItem.js +0 -327
  53. package/components/Switch.js +0 -147
  54. package/components/Table.js +0 -492
  55. package/components/Tabs.js +0 -423
  56. package/components/Text.js +0 -141
  57. package/components/TextField.js +0 -151
  58. package/components/TimePicker.js +0 -934
  59. package/components/Toast.js +0 -236
  60. package/components/TreeView.js +0 -420
  61. package/components/Video.js +0 -397
  62. package/components/View.js +0 -140
  63. package/components/VirtualList.js +0 -120
  64. package/core/CanvasFramework.js +0 -3034
  65. package/core/Component.js +0 -243
  66. package/core/ThemeManager.js +0 -358
  67. package/core/UIBuilder.js +0 -267
  68. package/core/WebGLCanvasAdapter.js +0 -782
  69. package/features/Column.js +0 -43
  70. package/features/Grid.js +0 -47
  71. package/features/LayoutComponent.js +0 -43
  72. package/features/OpenStreetMap.js +0 -310
  73. package/features/Positioned.js +0 -33
  74. package/features/PullToRefresh.js +0 -328
  75. package/features/Row.js +0 -40
  76. package/features/SignaturePad.js +0 -257
  77. package/features/Skeleton.js +0 -193
  78. package/features/Stack.js +0 -21
  79. package/index.js +0 -119
  80. package/manager/AccessibilityManager.js +0 -107
  81. package/manager/ErrorHandler.js +0 -59
  82. package/manager/FeatureFlags.js +0 -60
  83. package/manager/MemoryManager.js +0 -107
  84. package/manager/PerformanceMonitor.js +0 -84
  85. package/manager/SecurityManager.js +0 -54
  86. package/utils/AnimationEngine.js +0 -734
  87. package/utils/CryptoManager.js +0 -303
  88. package/utils/DataStore.js +0 -403
  89. package/utils/DevTools.js +0 -1618
  90. package/utils/DevToolsConsole.js +0 -201
  91. package/utils/EventBus.js +0 -407
  92. package/utils/FetchClient.js +0 -74
  93. package/utils/FirebaseAuth.js +0 -653
  94. package/utils/FirebaseCore.js +0 -246
  95. package/utils/FirebaseFirestore.js +0 -581
  96. package/utils/FirebaseFunctions.js +0 -97
  97. package/utils/FirebaseRealtimeDB.js +0 -498
  98. package/utils/FirebaseStorage.js +0 -612
  99. package/utils/FormValidator.js +0 -355
  100. package/utils/GeoLocationService.js +0 -62
  101. package/utils/I18n.js +0 -207
  102. package/utils/IndexedDBManager.js +0 -273
  103. package/utils/InspectionOverlay.js +0 -308
  104. package/utils/NotificationManager.js +0 -60
  105. package/utils/OfflineSyncManager.js +0 -342
  106. package/utils/PayPalPayment.js +0 -678
  107. package/utils/QueryBuilder.js +0 -478
  108. package/utils/SafeArea.js +0 -64
  109. package/utils/SecureStorage.js +0 -289
  110. package/utils/StateManager.js +0 -207
  111. package/utils/StripePayment.js +0 -552
  112. package/utils/WebSocketClient.js +0 -66
@@ -1,303 +0,0 @@
1
- /**
2
- * Gestionnaire de cryptographie pour le Canvas Framework
3
- * Utilise l'API Web Crypto (SubtleCrypto) pour un chiffrement sécurisé
4
- * @class
5
- */
6
- class CryptoManager {
7
- constructor() {
8
- // Vérifier la disponibilité de l'API Crypto
9
- if (!window.crypto || !window.crypto.subtle) {
10
- throw new Error('Web Crypto API is not available in this browser');
11
- }
12
-
13
- this.crypto = window.crypto.subtle;
14
-
15
- // Algorithme par défaut
16
- this.algorithm = {
17
- name: 'AES-GCM',
18
- length: 256
19
- };
20
-
21
- // Stockage des clés en mémoire (pas dans localStorage !)
22
- this._keys = new Map();
23
- }
24
-
25
- /**
26
- * Génère une clé de chiffrement aléatoire
27
- * @param {string} keyName - Nom de la clé pour référence ultérieure
28
- * @returns {Promise<CryptoKey>}
29
- */
30
- async generateKey(keyName = 'default') {
31
- const key = await this.crypto.generateKey(
32
- {
33
- name: this.algorithm.name,
34
- length: this.algorithm.length
35
- },
36
- true, // extractable
37
- ['encrypt', 'decrypt']
38
- );
39
-
40
- this._keys.set(keyName, key);
41
- return key;
42
- }
43
-
44
- /**
45
- * Importe une clé depuis une chaîne (base64)
46
- * @param {string} keyString - Clé au format base64
47
- * @param {string} keyName - Nom de la clé
48
- * @returns {Promise<CryptoKey>}
49
- */
50
- async importKey(keyString, keyName = 'default') {
51
- const keyBuffer = this._base64ToBuffer(keyString);
52
-
53
- const key = await this.crypto.importKey(
54
- 'raw',
55
- keyBuffer,
56
- { name: this.algorithm.name },
57
- true,
58
- ['encrypt', 'decrypt']
59
- );
60
-
61
- this._keys.set(keyName, key);
62
- return key;
63
- }
64
-
65
- /**
66
- * Exporte une clé au format base64
67
- * @param {string} keyName - Nom de la clé
68
- * @returns {Promise<string>}
69
- */
70
- async exportKey(keyName = 'default') {
71
- const key = this._keys.get(keyName);
72
- if (!key) {
73
- throw new Error(`Key "${keyName}" not found`);
74
- }
75
-
76
- const exported = await this.crypto.exportKey('raw', key);
77
- return this._bufferToBase64(exported);
78
- }
79
-
80
- /**
81
- * Dérive une clé depuis un mot de passe
82
- * @param {string} password - Mot de passe
83
- * @param {string} keyName - Nom de la clé
84
- * @param {string} salt - Salt (optionnel, généré automatiquement)
85
- * @returns {Promise<{key: CryptoKey, salt: string}>}
86
- */
87
- async deriveKeyFromPassword(password, keyName = 'default', salt = null) {
88
- // Générer ou utiliser le salt fourni
89
- const saltBuffer = salt
90
- ? this._base64ToBuffer(salt)
91
- : window.crypto.getRandomValues(new Uint8Array(16));
92
-
93
- // Encoder le mot de passe
94
- const encoder = new TextEncoder();
95
- const passwordBuffer = encoder.encode(password);
96
-
97
- // Importer le mot de passe comme clé
98
- const keyMaterial = await this.crypto.importKey(
99
- 'raw',
100
- passwordBuffer,
101
- { name: 'PBKDF2' },
102
- false,
103
- ['deriveBits', 'deriveKey']
104
- );
105
-
106
- // Dériver la clé
107
- const key = await this.crypto.deriveKey(
108
- {
109
- name: 'PBKDF2',
110
- salt: saltBuffer,
111
- iterations: 100000,
112
- hash: 'SHA-256'
113
- },
114
- keyMaterial,
115
- { name: this.algorithm.name, length: this.algorithm.length },
116
- true,
117
- ['encrypt', 'decrypt']
118
- );
119
-
120
- this._keys.set(keyName, key);
121
-
122
- return {
123
- key,
124
- salt: this._bufferToBase64(saltBuffer)
125
- };
126
- }
127
-
128
- /**
129
- * Chiffre des données
130
- * @param {any} data - Données à chiffrer (sera converti en JSON)
131
- * @param {string} keyName - Nom de la clé à utiliser
132
- * @returns {Promise<{encrypted: string, iv: string}>}
133
- */
134
- async encrypt(data, keyName = 'default') {
135
- const key = this._keys.get(keyName);
136
- if (!key) {
137
- throw new Error(`Key "${keyName}" not found. Generate or import a key first.`);
138
- }
139
-
140
- // Convertir les données en JSON puis en buffer
141
- const dataString = typeof data === 'string' ? data : JSON.stringify(data);
142
- const encoder = new TextEncoder();
143
- const dataBuffer = encoder.encode(dataString);
144
-
145
- // Générer un IV (Initialization Vector) aléatoire
146
- const iv = window.crypto.getRandomValues(new Uint8Array(12));
147
-
148
- // Chiffrer
149
- const encryptedBuffer = await this.crypto.encrypt(
150
- {
151
- name: this.algorithm.name,
152
- iv: iv
153
- },
154
- key,
155
- dataBuffer
156
- );
157
-
158
- return {
159
- encrypted: this._bufferToBase64(encryptedBuffer),
160
- iv: this._bufferToBase64(iv)
161
- };
162
- }
163
-
164
- /**
165
- * Déchiffre des données
166
- * @param {string} encryptedData - Données chiffrées (base64)
167
- * @param {string} iv - IV utilisé lors du chiffrement (base64)
168
- * @param {string} keyName - Nom de la clé à utiliser
169
- * @param {boolean} parseJson - Parser le résultat en JSON (true par défaut)
170
- * @returns {Promise<any>}
171
- */
172
- async decrypt(encryptedData, iv, keyName = 'default', parseJson = true) {
173
- const key = this._keys.get(keyName);
174
- if (!key) {
175
- throw new Error(`Key "${keyName}" not found. Generate or import a key first.`);
176
- }
177
-
178
- // Convertir les chaînes base64 en buffers
179
- const encryptedBuffer = this._base64ToBuffer(encryptedData);
180
- const ivBuffer = this._base64ToBuffer(iv);
181
-
182
- // Déchiffrer
183
- const decryptedBuffer = await this.crypto.decrypt(
184
- {
185
- name: this.algorithm.name,
186
- iv: ivBuffer
187
- },
188
- key,
189
- encryptedBuffer
190
- );
191
-
192
- // Convertir le buffer en string
193
- const decoder = new TextDecoder();
194
- const decryptedString = decoder.decode(decryptedBuffer);
195
-
196
- // Parser en JSON si demandé
197
- if (parseJson) {
198
- try {
199
- return JSON.parse(decryptedString);
200
- } catch (e) {
201
- // Si le parsing échoue, retourner la chaîne brute
202
- return decryptedString;
203
- }
204
- }
205
-
206
- return decryptedString;
207
- }
208
-
209
- /**
210
- * Chiffre et encode en une seule chaîne (pratique pour stockage)
211
- * @param {any} data - Données à chiffrer
212
- * @param {string} keyName - Nom de la clé
213
- * @returns {Promise<string>} - Chaîne contenant données chiffrées + IV
214
- */
215
- async encryptToString(data, keyName = 'default') {
216
- const { encrypted, iv } = await this.encrypt(data, keyName);
217
- return `${encrypted}.${iv}`;
218
- }
219
-
220
- /**
221
- * Déchiffre depuis une chaîne créée par encryptToString
222
- * @param {string} encryptedString - Chaîne chiffrée
223
- * @param {string} keyName - Nom de la clé
224
- * @param {boolean} parseJson - Parser en JSON
225
- * @returns {Promise<any>}
226
- */
227
- async decryptFromString(encryptedString, keyName = 'default', parseJson = true) {
228
- const [encrypted, iv] = encryptedString.split('.');
229
- if (!encrypted || !iv) {
230
- throw new Error('Invalid encrypted string format');
231
- }
232
- return this.decrypt(encrypted, iv, keyName, parseJson);
233
- }
234
-
235
- /**
236
- * Hash une chaîne (non réversible)
237
- * @param {string} data - Données à hasher
238
- * @param {string} algorithm - Algorithme (SHA-256, SHA-384, SHA-512)
239
- * @returns {Promise<string>} - Hash en base64
240
- */
241
- async hash(data, algorithm = 'SHA-256') {
242
- const encoder = new TextEncoder();
243
- const dataBuffer = encoder.encode(data);
244
-
245
- const hashBuffer = await this.crypto.digest(algorithm, dataBuffer);
246
- return this._bufferToBase64(hashBuffer);
247
- }
248
-
249
- /**
250
- * Génère un token aléatoire sécurisé
251
- * @param {number} length - Longueur en octets (32 par défaut)
252
- * @returns {string} - Token en base64
253
- */
254
- generateToken(length = 32) {
255
- const buffer = window.crypto.getRandomValues(new Uint8Array(length));
256
- return this._bufferToBase64(buffer);
257
- }
258
-
259
- /**
260
- * Supprime une clé de la mémoire
261
- * @param {string} keyName - Nom de la clé
262
- */
263
- deleteKey(keyName) {
264
- this._keys.delete(keyName);
265
- }
266
-
267
- /**
268
- * Supprime toutes les clés
269
- */
270
- deleteAllKeys() {
271
- this._keys.clear();
272
- }
273
-
274
- /**
275
- * Liste les clés disponibles
276
- * @returns {string[]}
277
- */
278
- listKeys() {
279
- return Array.from(this._keys.keys());
280
- }
281
-
282
- // ===== Méthodes utilitaires =====
283
-
284
- _bufferToBase64(buffer) {
285
- const bytes = new Uint8Array(buffer);
286
- let binary = '';
287
- for (let i = 0; i < bytes.length; i++) {
288
- binary += String.fromCharCode(bytes[i]);
289
- }
290
- return btoa(binary);
291
- }
292
-
293
- _base64ToBuffer(base64) {
294
- const binary = atob(base64);
295
- const bytes = new Uint8Array(binary.length);
296
- for (let i = 0; i < binary.length; i++) {
297
- bytes[i] = binary.charCodeAt(i);
298
- }
299
- return bytes.buffer;
300
- }
301
- }
302
-
303
- export default CryptoManager;
@@ -1,403 +0,0 @@
1
- /**
2
- * Cache local avec TTL (Time To Live) et gestion avancée
3
- * @class
4
- * @property {Map} store - Stockage interne
5
- * @property {number} defaultTTL - TTL par défaut en ms
6
- * @property {number} maxSize - Taille max du cache
7
- * @property {Object} stats - Statistiques du cache
8
- */
9
- class DataStore {
10
- /**
11
- * Crée une instance de DataStore
12
- * @param {Object} [options={}] - Options
13
- * @param {number} [options.defaultTTL=3600000] - TTL par défaut (1h)
14
- * @param {number} [options.maxSize=100] - Taille max du cache
15
- * @param {boolean} [options.enableStats=true] - Activer les stats
16
- */
17
- constructor(options = {}) {
18
- this.store = new Map();
19
- this.defaultTTL = options.defaultTTL || 3600000; // 1 heure par défaut
20
- this.maxSize = options.maxSize || 100;
21
- this.enableStats = options.enableStats !== false;
22
-
23
- // Statistiques
24
- this.stats = {
25
- hits: 0,
26
- misses: 0,
27
- sets: 0,
28
- deletes: 0,
29
- evictions: 0
30
- };
31
-
32
- // Nettoyage périodique
33
- this.startCleanupInterval();
34
- }
35
-
36
- /**
37
- * Stocke une valeur avec TTL
38
- * @param {string} key - Clé
39
- * @param {*} value - Valeur
40
- * @param {number} [ttl] - TTL en ms (optionnel)
41
- * @returns {DataStore} Instance pour chaînage
42
- */
43
- set(key, value, ttl) {
44
- const expiresAt = Date.now() + (ttl || this.defaultTTL);
45
-
46
- // Si le cache est plein, supprimer l'élément le plus ancien
47
- if (this.store.size >= this.maxSize && !this.store.has(key)) {
48
- this.evictOldest();
49
- }
50
-
51
- this.store.set(key, {
52
- value,
53
- expiresAt,
54
- createdAt: Date.now(),
55
- accessCount: 0
56
- });
57
-
58
- if (this.enableStats) this.stats.sets++;
59
-
60
- return this;
61
- }
62
-
63
- /**
64
- * Récupère une valeur
65
- * @param {string} key - Clé
66
- * @param {*} [defaultValue=null] - Valeur par défaut
67
- * @returns {*} Valeur ou null
68
- */
69
- get(key, defaultValue = null) {
70
- const item = this.store.get(key);
71
-
72
- if (!item) {
73
- if (this.enableStats) this.stats.misses++;
74
- return defaultValue;
75
- }
76
-
77
- // Vérifier l'expiration
78
- if (Date.now() > item.expiresAt) {
79
- this.delete(key);
80
- if (this.enableStats) this.stats.misses++;
81
- return defaultValue;
82
- }
83
-
84
- // Mettre à jour les stats d'accès
85
- item.accessCount++;
86
-
87
- if (this.enableStats) this.stats.hits++;
88
-
89
- return item.value;
90
- }
91
-
92
- /**
93
- * Vérifie si une clé existe et n'est pas expirée
94
- * @param {string} key - Clé
95
- * @returns {boolean} True si existe et valide
96
- */
97
- has(key) {
98
- const item = this.store.get(key);
99
-
100
- if (!item) return false;
101
-
102
- if (Date.now() > item.expiresAt) {
103
- this.delete(key);
104
- return false;
105
- }
106
-
107
- return true;
108
- }
109
-
110
- /**
111
- * Supprime une entrée
112
- * @param {string} key - Clé
113
- * @returns {boolean} True si supprimé
114
- */
115
- delete(key) {
116
- const deleted = this.store.delete(key);
117
- if (deleted && this.enableStats) this.stats.deletes++;
118
- return deleted;
119
- }
120
-
121
- /**
122
- * Vide tout le cache
123
- */
124
- clear() {
125
- this.store.clear();
126
- if (this.enableStats) {
127
- this.stats = {
128
- hits: 0,
129
- misses: 0,
130
- sets: 0,
131
- deletes: 0,
132
- evictions: 0
133
- };
134
- }
135
- }
136
-
137
- /**
138
- * Récupère ou calcule une valeur (memoization)
139
- * @param {string} key - Clé
140
- * @param {Function} factory - Fonction qui retourne la valeur
141
- * @param {number} [ttl] - TTL optionnel
142
- * @returns {Promise<*>} Valeur
143
- */
144
- async getOrSet(key, factory, ttl) {
145
- if (this.has(key)) {
146
- return this.get(key);
147
- }
148
-
149
- const value = await factory();
150
- this.set(key, value, ttl);
151
- return value;
152
- }
153
-
154
- /**
155
- * Récupère plusieurs valeurs
156
- * @param {Array<string>} keys - Clés
157
- * @returns {Object} Objet clé-valeur
158
- */
159
- getMany(keys) {
160
- const result = {};
161
-
162
- for (let key of keys) {
163
- const value = this.get(key);
164
- if (value !== null) {
165
- result[key] = value;
166
- }
167
- }
168
-
169
- return result;
170
- }
171
-
172
- /**
173
- * Stocke plusieurs valeurs
174
- * @param {Object} items - Objet clé-valeur
175
- * @param {number} [ttl] - TTL optionnel
176
- * @returns {DataStore} Instance pour chaînage
177
- */
178
- setMany(items, ttl) {
179
- for (let key in items) {
180
- this.set(key, items[key], ttl);
181
- }
182
- return this;
183
- }
184
-
185
- /**
186
- * Supprime plusieurs entrées
187
- * @param {Array<string>} keys - Clés
188
- * @returns {number} Nombre de suppressions
189
- */
190
- deleteMany(keys) {
191
- let count = 0;
192
- for (let key of keys) {
193
- if (this.delete(key)) count++;
194
- }
195
- return count;
196
- }
197
-
198
- /**
199
- * Met à jour le TTL d'une entrée
200
- * @param {string} key - Clé
201
- * @param {number} ttl - Nouveau TTL en ms
202
- * @returns {boolean} True si mis à jour
203
- */
204
- touch(key, ttl) {
205
- const item = this.store.get(key);
206
-
207
- if (!item) return false;
208
-
209
- item.expiresAt = Date.now() + (ttl || this.defaultTTL);
210
- return true;
211
- }
212
-
213
- /**
214
- * Obtient le TTL restant
215
- * @param {string} key - Clé
216
- * @returns {number} TTL en ms, ou -1 si n'existe pas
217
- */
218
- ttl(key) {
219
- const item = this.store.get(key);
220
-
221
- if (!item) return -1;
222
-
223
- const remaining = item.expiresAt - Date.now();
224
- return remaining > 0 ? remaining : -1;
225
- }
226
-
227
- /**
228
- * Évince l'élément le plus ancien (LRU)
229
- * @private
230
- */
231
- evictOldest() {
232
- let oldestKey = null;
233
- let oldestTime = Infinity;
234
-
235
- for (let [key, item] of this.store.entries()) {
236
- // Utiliser l'accès le moins récent comme critère
237
- const priority = item.createdAt - (item.accessCount * 1000);
238
-
239
- if (priority < oldestTime) {
240
- oldestTime = priority;
241
- oldestKey = key;
242
- }
243
- }
244
-
245
- if (oldestKey) {
246
- this.store.delete(oldestKey);
247
- if (this.enableStats) this.stats.evictions++;
248
- }
249
- }
250
-
251
- /**
252
- * Nettoie les entrées expirées
253
- * @returns {number} Nombre d'entrées nettoyées
254
- */
255
- cleanup() {
256
- const now = Date.now();
257
- let cleaned = 0;
258
-
259
- for (let [key, item] of this.store.entries()) {
260
- if (now > item.expiresAt) {
261
- this.store.delete(key);
262
- cleaned++;
263
- }
264
- }
265
-
266
- return cleaned;
267
- }
268
-
269
- /**
270
- * Démarre le nettoyage automatique
271
- * @param {number} [interval=60000] - Intervalle en ms (1 minute)
272
- * @private
273
- */
274
- startCleanupInterval(interval = 60000) {
275
- if (this.cleanupTimer) {
276
- clearInterval(this.cleanupTimer);
277
- }
278
-
279
- this.cleanupTimer = setInterval(() => {
280
- this.cleanup();
281
- }, interval);
282
- }
283
-
284
- /**
285
- * Arrête le nettoyage automatique
286
- */
287
- stopCleanupInterval() {
288
- if (this.cleanupTimer) {
289
- clearInterval(this.cleanupTimer);
290
- this.cleanupTimer = null;
291
- }
292
- }
293
-
294
- /**
295
- * Obtient toutes les clés
296
- * @param {boolean} [includeExpired=false] - Inclure les expirées
297
- * @returns {Array<string>} Liste des clés
298
- */
299
- keys(includeExpired = false) {
300
- const keys = [];
301
- const now = Date.now();
302
-
303
- for (let [key, item] of this.store.entries()) {
304
- if (includeExpired || now <= item.expiresAt) {
305
- keys.push(key);
306
- }
307
- }
308
-
309
- return keys;
310
- }
311
-
312
- /**
313
- * Obtient la taille du cache
314
- * @returns {number} Nombre d'entrées
315
- */
316
- size() {
317
- return this.store.size;
318
- }
319
-
320
- /**
321
- * Obtient les statistiques
322
- * @returns {Object} Statistiques
323
- */
324
- getStats() {
325
- const hitRate = this.stats.hits + this.stats.misses > 0
326
- ? (this.stats.hits / (this.stats.hits + this.stats.misses) * 100).toFixed(2)
327
- : 0;
328
-
329
- return {
330
- ...this.stats,
331
- size: this.store.size,
332
- hitRate: `${hitRate}%`,
333
- maxSize: this.maxSize
334
- };
335
- }
336
-
337
- /**
338
- * Réinitialise les statistiques
339
- */
340
- resetStats() {
341
- this.stats = {
342
- hits: 0,
343
- misses: 0,
344
- sets: 0,
345
- deletes: 0,
346
- evictions: 0
347
- };
348
- }
349
-
350
- /**
351
- * Exporte le cache en JSON
352
- * @returns {string} JSON
353
- */
354
- export() {
355
- const data = {};
356
-
357
- for (let [key, item] of this.store.entries()) {
358
- data[key] = {
359
- value: item.value,
360
- expiresAt: item.expiresAt,
361
- createdAt: item.createdAt
362
- };
363
- }
364
-
365
- return JSON.stringify(data);
366
- }
367
-
368
- /**
369
- * Importe un cache depuis JSON
370
- * @param {string} json - JSON
371
- */
372
- import(json) {
373
- const data = JSON.parse(json);
374
- const now = Date.now();
375
-
376
- for (let key in data) {
377
- const item = data[key];
378
-
379
- // Ne pas importer les entrées expirées
380
- if (item.expiresAt > now) {
381
- this.store.set(key, {
382
- value: item.value,
383
- expiresAt: item.expiresAt,
384
- createdAt: item.createdAt,
385
- accessCount: 0
386
- });
387
- }
388
- }
389
- }
390
-
391
- /**
392
- * Détruit le store
393
- */
394
- destroy() {
395
- this.stopCleanupInterval();
396
- this.clear();
397
- }
398
- }
399
-
400
- // Instance globale par défaut
401
- DataStore.global = new DataStore();
402
-
403
- export default DataStore;