react-achievements 3.3.0 → 3.4.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.
- package/README.md +186 -1
- package/dist/index.d.ts +210 -57
- package/dist/index.js +690 -21
- package/dist/index.js.map +1 -1
- package/dist/types/core/errors/AchievementErrors.d.ts +7 -3
- package/dist/types/core/storage/AsyncStorageAdapter.d.ts +48 -0
- package/dist/types/core/storage/IndexedDBStorage.d.ts +29 -0
- package/dist/types/core/storage/OfflineQueueStorage.d.ts +42 -0
- package/dist/types/core/storage/RestApiStorage.d.ts +20 -0
- package/dist/types/core/types.d.ts +13 -2
- package/dist/types/core/utils/dataExport.d.ts +1 -1
- package/dist/types/index.d.ts +6 -1
- package/dist/types/providers/AchievementProvider.d.ts +4 -2
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -322,6 +322,10 @@ See the [examples directory](./stories/examples) for detailed implementations an
|
|
|
322
322
|
- Toast notifications
|
|
323
323
|
- Confetti animations
|
|
324
324
|
- TypeScript support
|
|
325
|
+
- **NEW in v3.4.0**: Async storage support (IndexedDB, REST API, Offline Queue)
|
|
326
|
+
- **NEW in v3.4.0**: 50MB+ storage capacity with IndexedDB
|
|
327
|
+
- **NEW in v3.4.0**: Server-side sync with REST API storage
|
|
328
|
+
- **NEW in v3.4.0**: Offline-first capabilities with automatic queue sync
|
|
325
329
|
- **NEW in v3.3.0**: Comprehensive error handling system
|
|
326
330
|
- **NEW in v3.3.0**: Data export/import for achievement portability
|
|
327
331
|
- **NEW in v3.3.0**: Type-safe error classes with recovery guidance
|
|
@@ -416,9 +420,185 @@ const achievements = {
|
|
|
416
420
|
|
|
417
421
|
The library provides a small set of essential fallback icons for system use (error states, loading, etc.). These are automatically used when needed and don't require any configuration.
|
|
418
422
|
|
|
423
|
+
## Async Storage (NEW in v3.4.0)
|
|
424
|
+
|
|
425
|
+
React Achievements now supports async storage backends for modern applications that need large data capacity, server sync, or offline-first capabilities.
|
|
426
|
+
|
|
427
|
+
### IndexedDB Storage
|
|
428
|
+
|
|
429
|
+
Browser-native storage with 50MB+ capacity (vs localStorage's 5-10MB limit):
|
|
430
|
+
|
|
431
|
+
```tsx
|
|
432
|
+
import { AchievementProvider, StorageType } from 'react-achievements';
|
|
433
|
+
|
|
434
|
+
const App = () => {
|
|
435
|
+
return (
|
|
436
|
+
<AchievementProvider
|
|
437
|
+
achievements={gameAchievements}
|
|
438
|
+
storage={StorageType.IndexedDB} // Use IndexedDB for large data
|
|
439
|
+
>
|
|
440
|
+
<Game />
|
|
441
|
+
</AchievementProvider>
|
|
442
|
+
);
|
|
443
|
+
};
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**Benefits:**
|
|
447
|
+
- ✅ 10x larger capacity than localStorage
|
|
448
|
+
- ✅ Structured data storage
|
|
449
|
+
- ✅ Better performance for large datasets
|
|
450
|
+
- ✅ Non-blocking async operations
|
|
451
|
+
|
|
452
|
+
### REST API Storage
|
|
453
|
+
|
|
454
|
+
Sync achievements with your backend server:
|
|
455
|
+
|
|
456
|
+
```tsx
|
|
457
|
+
import { AchievementProvider, StorageType } from 'react-achievements';
|
|
458
|
+
|
|
459
|
+
const App = () => {
|
|
460
|
+
return (
|
|
461
|
+
<AchievementProvider
|
|
462
|
+
achievements={gameAchievements}
|
|
463
|
+
storage={StorageType.RestAPI}
|
|
464
|
+
restApiConfig={{
|
|
465
|
+
baseUrl: 'https://api.example.com',
|
|
466
|
+
userId: getCurrentUserId(),
|
|
467
|
+
headers: {
|
|
468
|
+
'Authorization': `Bearer ${getAuthToken()}`
|
|
469
|
+
},
|
|
470
|
+
timeout: 10000 // Optional, default 10s
|
|
471
|
+
}}
|
|
472
|
+
>
|
|
473
|
+
<Game />
|
|
474
|
+
</AchievementProvider>
|
|
475
|
+
);
|
|
476
|
+
};
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
**API Endpoints Expected:**
|
|
480
|
+
```
|
|
481
|
+
GET /users/:userId/achievements/metrics
|
|
482
|
+
PUT /users/:userId/achievements/metrics
|
|
483
|
+
GET /users/:userId/achievements/unlocked
|
|
484
|
+
PUT /users/:userId/achievements/unlocked
|
|
485
|
+
DELETE /users/:userId/achievements
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Benefits:**
|
|
489
|
+
- ✅ Cross-device synchronization
|
|
490
|
+
- ✅ Server-side backup
|
|
491
|
+
- ✅ User authentication support
|
|
492
|
+
- ✅ Centralized data management
|
|
493
|
+
|
|
494
|
+
### Offline Queue Storage
|
|
495
|
+
|
|
496
|
+
Offline-first storage with automatic sync when back online:
|
|
497
|
+
|
|
498
|
+
```tsx
|
|
499
|
+
import {
|
|
500
|
+
AchievementProvider,
|
|
501
|
+
OfflineQueueStorage,
|
|
502
|
+
RestApiStorage
|
|
503
|
+
} from 'react-achievements';
|
|
504
|
+
|
|
505
|
+
// Wrap REST API storage with offline queue
|
|
506
|
+
const restApi = new RestApiStorage({
|
|
507
|
+
baseUrl: 'https://api.example.com',
|
|
508
|
+
userId: 'user123',
|
|
509
|
+
headers: { 'Authorization': 'Bearer token' }
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
const offlineStorage = new OfflineQueueStorage(restApi);
|
|
513
|
+
|
|
514
|
+
const App = () => {
|
|
515
|
+
return (
|
|
516
|
+
<AchievementProvider
|
|
517
|
+
achievements={gameAchievements}
|
|
518
|
+
storage={offlineStorage}
|
|
519
|
+
>
|
|
520
|
+
<Game />
|
|
521
|
+
</AchievementProvider>
|
|
522
|
+
);
|
|
523
|
+
};
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
**Benefits:**
|
|
527
|
+
- ✅ Works offline - queues operations locally
|
|
528
|
+
- ✅ Automatic sync when connection restored
|
|
529
|
+
- ✅ Persistent queue survives page refreshes
|
|
530
|
+
- ✅ Graceful degradation for poor connectivity
|
|
531
|
+
|
|
532
|
+
### Custom Async Storage
|
|
533
|
+
|
|
534
|
+
You can create custom async storage by implementing the `AsyncAchievementStorage` interface:
|
|
535
|
+
|
|
536
|
+
```tsx
|
|
537
|
+
import {
|
|
538
|
+
AsyncAchievementStorage,
|
|
539
|
+
AchievementMetrics,
|
|
540
|
+
AsyncStorageAdapter,
|
|
541
|
+
AchievementProvider
|
|
542
|
+
} from 'react-achievements';
|
|
543
|
+
|
|
544
|
+
class MyCustomAsyncStorage implements AsyncAchievementStorage {
|
|
545
|
+
async getMetrics(): Promise<AchievementMetrics> {
|
|
546
|
+
// Your async implementation (e.g., fetch from database)
|
|
547
|
+
const response = await fetch('/my-api/metrics');
|
|
548
|
+
return response.json();
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
async setMetrics(metrics: AchievementMetrics): Promise<void> {
|
|
552
|
+
await fetch('/my-api/metrics', {
|
|
553
|
+
method: 'PUT',
|
|
554
|
+
body: JSON.stringify(metrics)
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
async getUnlockedAchievements(): Promise<string[]> {
|
|
559
|
+
const response = await fetch('/my-api/unlocked');
|
|
560
|
+
return response.json();
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
async setUnlockedAchievements(achievements: string[]): Promise<void> {
|
|
564
|
+
await fetch('/my-api/unlocked', {
|
|
565
|
+
method: 'PUT',
|
|
566
|
+
body: JSON.stringify(achievements)
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
async clear(): Promise<void> {
|
|
571
|
+
await fetch('/my-api/clear', { method: 'DELETE' });
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Wrap with adapter for optimistic updates
|
|
576
|
+
const customStorage = new MyCustomAsyncStorage();
|
|
577
|
+
const adapter = new AsyncStorageAdapter(customStorage, {
|
|
578
|
+
onError: (error) => console.error('Storage error:', error)
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
const App = () => {
|
|
582
|
+
return (
|
|
583
|
+
<AchievementProvider
|
|
584
|
+
achievements={gameAchievements}
|
|
585
|
+
storage={adapter}
|
|
586
|
+
>
|
|
587
|
+
<Game />
|
|
588
|
+
</AchievementProvider>
|
|
589
|
+
);
|
|
590
|
+
};
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
**How AsyncStorageAdapter Works:**
|
|
594
|
+
- **Optimistic Updates**: Returns cached data immediately (no waiting)
|
|
595
|
+
- **Eager Loading**: Preloads data during initialization
|
|
596
|
+
- **Background Writes**: All writes happen async without blocking UI
|
|
597
|
+
- **Error Handling**: Optional error callback for failed operations
|
|
598
|
+
|
|
419
599
|
## Custom Storage
|
|
420
600
|
|
|
421
|
-
You can implement your own storage solution by implementing the `AchievementStorage` interface:
|
|
601
|
+
You can implement your own synchronous storage solution by implementing the `AchievementStorage` interface:
|
|
422
602
|
|
|
423
603
|
```tsx
|
|
424
604
|
import { AchievementStorage, AchievementMetrics, AchievementProvider } from 'react-achievements';
|
|
@@ -946,7 +1126,9 @@ const result = importAchievementData(data, {
|
|
|
946
1126
|
strategy: 'replace',
|
|
947
1127
|
achievements
|
|
948
1128
|
});
|
|
1129
|
+
```
|
|
949
1130
|
|
|
1131
|
+
```tsx
|
|
950
1132
|
// Merge: Combine imported and existing data
|
|
951
1133
|
// - Takes maximum values for metrics
|
|
952
1134
|
// - Combines unlocked achievements
|
|
@@ -954,6 +1136,9 @@ const result = importAchievementData(data, {
|
|
|
954
1136
|
strategy: 'merge',
|
|
955
1137
|
achievements
|
|
956
1138
|
});
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
```tsx
|
|
957
1142
|
|
|
958
1143
|
// Preserve: Only import new achievements, keep existing data
|
|
959
1144
|
const result = importAchievementData(data, {
|
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,15 @@ interface AchievementStorage {
|
|
|
51
51
|
setUnlockedAchievements(achievements: string[]): void;
|
|
52
52
|
clear(): void;
|
|
53
53
|
}
|
|
54
|
+
interface AsyncAchievementStorage {
|
|
55
|
+
getMetrics(): Promise<AchievementMetrics>;
|
|
56
|
+
setMetrics(metrics: AchievementMetrics): Promise<void>;
|
|
57
|
+
getUnlockedAchievements(): Promise<string[]>;
|
|
58
|
+
setUnlockedAchievements(achievements: string[]): Promise<void>;
|
|
59
|
+
clear(): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
type AnyAchievementStorage = AchievementStorage | AsyncAchievementStorage;
|
|
62
|
+
declare function isAsyncStorage(storage: AnyAchievementStorage): storage is AsyncAchievementStorage;
|
|
54
63
|
interface AchievementContextValue {
|
|
55
64
|
updateMetrics: (metrics: AchievementMetrics | ((prev: AchievementMetrics) => AchievementMetrics)) => void;
|
|
56
65
|
unlockedAchievements: string[];
|
|
@@ -84,8 +93,10 @@ interface AchievementProviderProps$1 {
|
|
|
84
93
|
onAchievementUnlocked?: (achievement: AchievementDetails) => void;
|
|
85
94
|
}
|
|
86
95
|
declare enum StorageType {
|
|
87
|
-
Local = "local"
|
|
88
|
-
Memory = "memory"
|
|
96
|
+
Local = "local",// Synchronous localStorage
|
|
97
|
+
Memory = "memory",// Synchronous in-memory storage
|
|
98
|
+
IndexedDB = "indexeddb",// Asynchronous IndexedDB storage
|
|
99
|
+
RestAPI = "restapi"
|
|
89
100
|
}
|
|
90
101
|
|
|
91
102
|
declare class LocalStorage implements AchievementStorage {
|
|
@@ -115,6 +126,199 @@ declare class MemoryStorage implements AchievementStorage {
|
|
|
115
126
|
clear(): void;
|
|
116
127
|
}
|
|
117
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Base error class for all achievement-related errors
|
|
131
|
+
*/
|
|
132
|
+
declare class AchievementError extends Error {
|
|
133
|
+
code: string;
|
|
134
|
+
recoverable: boolean;
|
|
135
|
+
remedy?: string | undefined;
|
|
136
|
+
constructor(message: string, code: string, recoverable: boolean, remedy?: string | undefined);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Error thrown when browser storage quota is exceeded
|
|
140
|
+
*/
|
|
141
|
+
declare class StorageQuotaError extends AchievementError {
|
|
142
|
+
bytesNeeded: number;
|
|
143
|
+
constructor(bytesNeeded: number);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Error thrown when imported data fails validation
|
|
147
|
+
*/
|
|
148
|
+
declare class ImportValidationError extends AchievementError {
|
|
149
|
+
validationErrors: string[];
|
|
150
|
+
constructor(validationErrors: string[]);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Error thrown when storage operations fail
|
|
154
|
+
*/
|
|
155
|
+
declare class StorageError extends AchievementError {
|
|
156
|
+
originalError?: Error | undefined;
|
|
157
|
+
constructor(message: string, originalError?: Error | undefined);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Error thrown when configuration is invalid
|
|
161
|
+
*/
|
|
162
|
+
declare class ConfigurationError extends AchievementError {
|
|
163
|
+
constructor(message: string);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Error thrown when network sync operations fail
|
|
167
|
+
*/
|
|
168
|
+
declare class SyncError extends AchievementError {
|
|
169
|
+
readonly statusCode?: number;
|
|
170
|
+
readonly timeout?: number;
|
|
171
|
+
constructor(message: string, details?: {
|
|
172
|
+
statusCode?: number;
|
|
173
|
+
timeout?: number;
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Type guard to check if an error is an AchievementError
|
|
178
|
+
*/
|
|
179
|
+
declare function isAchievementError(error: unknown): error is AchievementError;
|
|
180
|
+
/**
|
|
181
|
+
* Type guard to check if an error is recoverable
|
|
182
|
+
*/
|
|
183
|
+
declare function isRecoverableError(error: unknown): boolean;
|
|
184
|
+
|
|
185
|
+
declare class AsyncStorageAdapter implements AchievementStorage {
|
|
186
|
+
private asyncStorage;
|
|
187
|
+
private cache;
|
|
188
|
+
private pendingWrites;
|
|
189
|
+
private onError?;
|
|
190
|
+
constructor(asyncStorage: AsyncAchievementStorage, options?: {
|
|
191
|
+
onError?: (error: AchievementError) => void;
|
|
192
|
+
});
|
|
193
|
+
/**
|
|
194
|
+
* Initialize cache by loading from async storage
|
|
195
|
+
* This happens in the background during construction
|
|
196
|
+
*/
|
|
197
|
+
private initializeCache;
|
|
198
|
+
/**
|
|
199
|
+
* Wait for cache to be loaded (used internally)
|
|
200
|
+
* Returns immediately if already loaded, otherwise waits
|
|
201
|
+
*/
|
|
202
|
+
private ensureCacheLoaded;
|
|
203
|
+
/**
|
|
204
|
+
* SYNC READ: Returns cached metrics immediately
|
|
205
|
+
* Cache is loaded eagerly during construction
|
|
206
|
+
*/
|
|
207
|
+
getMetrics(): AchievementMetrics;
|
|
208
|
+
/**
|
|
209
|
+
* SYNC WRITE: Updates cache immediately, writes to storage in background
|
|
210
|
+
* Uses optimistic updates - assumes write will succeed
|
|
211
|
+
*/
|
|
212
|
+
setMetrics(metrics: AchievementMetrics): void;
|
|
213
|
+
/**
|
|
214
|
+
* SYNC READ: Returns cached unlocked achievements immediately
|
|
215
|
+
*/
|
|
216
|
+
getUnlockedAchievements(): string[];
|
|
217
|
+
/**
|
|
218
|
+
* SYNC WRITE: Updates cache immediately, writes to storage in background
|
|
219
|
+
*/
|
|
220
|
+
setUnlockedAchievements(achievements: string[]): void;
|
|
221
|
+
/**
|
|
222
|
+
* SYNC CLEAR: Clears cache immediately, clears storage in background
|
|
223
|
+
*/
|
|
224
|
+
clear(): void;
|
|
225
|
+
/**
|
|
226
|
+
* Wait for all pending writes to complete (useful for testing/cleanup)
|
|
227
|
+
* NOT part of AchievementStorage interface - utility method
|
|
228
|
+
*/
|
|
229
|
+
flush(): Promise<void>;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
declare class IndexedDBStorage implements AsyncAchievementStorage {
|
|
233
|
+
private dbName;
|
|
234
|
+
private storeName;
|
|
235
|
+
private db;
|
|
236
|
+
private initPromise;
|
|
237
|
+
constructor(dbName?: string);
|
|
238
|
+
/**
|
|
239
|
+
* Initialize IndexedDB database and object store
|
|
240
|
+
*/
|
|
241
|
+
private initDB;
|
|
242
|
+
/**
|
|
243
|
+
* Generic get operation from IndexedDB
|
|
244
|
+
*/
|
|
245
|
+
private get;
|
|
246
|
+
/**
|
|
247
|
+
* Generic set operation to IndexedDB
|
|
248
|
+
*/
|
|
249
|
+
private set;
|
|
250
|
+
/**
|
|
251
|
+
* Delete operation from IndexedDB
|
|
252
|
+
*/
|
|
253
|
+
private delete;
|
|
254
|
+
getMetrics(): Promise<AchievementMetrics>;
|
|
255
|
+
setMetrics(metrics: AchievementMetrics): Promise<void>;
|
|
256
|
+
getUnlockedAchievements(): Promise<string[]>;
|
|
257
|
+
setUnlockedAchievements(achievements: string[]): Promise<void>;
|
|
258
|
+
clear(): Promise<void>;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
interface RestApiStorageConfig {
|
|
262
|
+
baseUrl: string;
|
|
263
|
+
userId: string;
|
|
264
|
+
headers?: Record<string, string>;
|
|
265
|
+
timeout?: number;
|
|
266
|
+
}
|
|
267
|
+
declare class RestApiStorage implements AsyncAchievementStorage {
|
|
268
|
+
private config;
|
|
269
|
+
constructor(config: RestApiStorageConfig);
|
|
270
|
+
/**
|
|
271
|
+
* Generic fetch wrapper with timeout and error handling
|
|
272
|
+
*/
|
|
273
|
+
private fetchWithTimeout;
|
|
274
|
+
getMetrics(): Promise<AchievementMetrics>;
|
|
275
|
+
setMetrics(metrics: AchievementMetrics): Promise<void>;
|
|
276
|
+
getUnlockedAchievements(): Promise<string[]>;
|
|
277
|
+
setUnlockedAchievements(achievements: string[]): Promise<void>;
|
|
278
|
+
clear(): Promise<void>;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
interface QueuedOperation {
|
|
282
|
+
id: string;
|
|
283
|
+
type: 'setMetrics' | 'setUnlockedAchievements' | 'clear';
|
|
284
|
+
data?: any;
|
|
285
|
+
timestamp: number;
|
|
286
|
+
}
|
|
287
|
+
declare class OfflineQueueStorage implements AsyncAchievementStorage {
|
|
288
|
+
private innerStorage;
|
|
289
|
+
private queue;
|
|
290
|
+
private isOnline;
|
|
291
|
+
private isSyncing;
|
|
292
|
+
private queueStorageKey;
|
|
293
|
+
constructor(innerStorage: AsyncAchievementStorage);
|
|
294
|
+
private loadQueue;
|
|
295
|
+
private saveQueue;
|
|
296
|
+
private handleOnline;
|
|
297
|
+
private handleOffline;
|
|
298
|
+
private processQueue;
|
|
299
|
+
private queueOperation;
|
|
300
|
+
getMetrics(): Promise<AchievementMetrics>;
|
|
301
|
+
setMetrics(metrics: AchievementMetrics): Promise<void>;
|
|
302
|
+
getUnlockedAchievements(): Promise<string[]>;
|
|
303
|
+
setUnlockedAchievements(achievements: string[]): Promise<void>;
|
|
304
|
+
clear(): Promise<void>;
|
|
305
|
+
/**
|
|
306
|
+
* Manually trigger queue processing (useful for testing)
|
|
307
|
+
*/
|
|
308
|
+
sync(): Promise<void>;
|
|
309
|
+
/**
|
|
310
|
+
* Get current queue status (useful for debugging)
|
|
311
|
+
*/
|
|
312
|
+
getQueueStatus(): {
|
|
313
|
+
pending: number;
|
|
314
|
+
operations: QueuedOperation[];
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* Cleanup listeners (call on unmount)
|
|
318
|
+
*/
|
|
319
|
+
destroy(): void;
|
|
320
|
+
}
|
|
321
|
+
|
|
118
322
|
interface BadgesButtonProps {
|
|
119
323
|
onClick: () => void;
|
|
120
324
|
position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
@@ -187,58 +391,6 @@ interface ImportResult {
|
|
|
187
391
|
*/
|
|
188
392
|
declare function importAchievementData(jsonString: string, currentMetrics: AchievementMetrics, currentUnlocked: string[], options?: ImportOptions): ImportResult;
|
|
189
393
|
|
|
190
|
-
/**
|
|
191
|
-
* Base error class for all achievement-related errors
|
|
192
|
-
*/
|
|
193
|
-
declare class AchievementError extends Error {
|
|
194
|
-
code: string;
|
|
195
|
-
recoverable: boolean;
|
|
196
|
-
remedy?: string | undefined;
|
|
197
|
-
constructor(message: string, code: string, recoverable: boolean, remedy?: string | undefined);
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Error thrown when browser storage quota is exceeded
|
|
201
|
-
*/
|
|
202
|
-
declare class StorageQuotaError extends AchievementError {
|
|
203
|
-
bytesNeeded: number;
|
|
204
|
-
constructor(bytesNeeded: number);
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Error thrown when imported data fails validation
|
|
208
|
-
*/
|
|
209
|
-
declare class ImportValidationError extends AchievementError {
|
|
210
|
-
validationErrors: string[];
|
|
211
|
-
constructor(validationErrors: string[]);
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Error thrown when storage operations fail
|
|
215
|
-
*/
|
|
216
|
-
declare class StorageError extends AchievementError {
|
|
217
|
-
originalError?: Error | undefined;
|
|
218
|
-
constructor(message: string, originalError?: Error | undefined);
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Error thrown when configuration is invalid
|
|
222
|
-
*/
|
|
223
|
-
declare class ConfigurationError extends AchievementError {
|
|
224
|
-
constructor(message: string);
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Error thrown when sync operations fail (for async storage backends)
|
|
228
|
-
*/
|
|
229
|
-
declare class SyncError extends AchievementError {
|
|
230
|
-
originalError?: Error | undefined;
|
|
231
|
-
constructor(message: string, originalError?: Error | undefined);
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Type guard to check if an error is an AchievementError
|
|
235
|
-
*/
|
|
236
|
-
declare function isAchievementError(error: unknown): error is AchievementError;
|
|
237
|
-
/**
|
|
238
|
-
* Type guard to check if an error is recoverable
|
|
239
|
-
*/
|
|
240
|
-
declare function isRecoverableError(error: unknown): boolean;
|
|
241
|
-
|
|
242
394
|
interface AchievementContextType {
|
|
243
395
|
update: (metrics: Record<string, any>) => void;
|
|
244
396
|
achievements: {
|
|
@@ -256,10 +408,11 @@ interface AchievementContextType {
|
|
|
256
408
|
declare const AchievementContext: React$1.Context<AchievementContextType | undefined>;
|
|
257
409
|
interface AchievementProviderProps {
|
|
258
410
|
achievements: AchievementConfigurationType;
|
|
259
|
-
storage?: AchievementStorage | StorageType;
|
|
411
|
+
storage?: AchievementStorage | AsyncAchievementStorage | StorageType;
|
|
260
412
|
children: React$1.ReactNode;
|
|
261
413
|
icons?: Record<string, string>;
|
|
262
414
|
onError?: (error: AchievementError) => void;
|
|
415
|
+
restApiConfig?: RestApiStorageConfig;
|
|
263
416
|
}
|
|
264
417
|
declare const AchievementProvider: React$1.FC<AchievementProviderProps>;
|
|
265
418
|
|
|
@@ -492,7 +645,7 @@ interface ExportedData {
|
|
|
492
645
|
*
|
|
493
646
|
* @example
|
|
494
647
|
* ```typescript
|
|
495
|
-
* const json = exportAchievementData(
|
|
648
|
+
* const json = exportAchievementData(_metrics, ['score_100', 'level_5']);
|
|
496
649
|
* // Save json to file or send to server
|
|
497
650
|
* ```
|
|
498
651
|
*/
|
|
@@ -506,4 +659,4 @@ declare function exportAchievementData(metrics: AchievementMetrics, unlocked: st
|
|
|
506
659
|
*/
|
|
507
660
|
declare function createConfigHash(config: any): string;
|
|
508
661
|
|
|
509
|
-
export { AchievementBuilder, AchievementCondition, AchievementConfiguration, AchievementConfigurationType, AchievementContext, AchievementContextValue, AchievementDetails, AchievementError, AchievementMetricArrayValue, AchievementMetricValue, AchievementMetrics, AchievementProvider, AchievementProviderProps$1 as AchievementProviderProps, AchievementState, AchievementStorage, AwardDetails, BadgesButton, BadgesModal, ConfettiWrapper, ConfigurationError, CustomAchievementDetails, ExportedData, ImportOptions, ImportResult, ImportValidationError, InitialAchievementMetrics, LocalStorage, MemoryStorage, SimpleAchievementConfig, SimpleAchievementDetails, StorageError, StorageQuotaError, StorageType, StylesProps, SyncError, createConfigHash, defaultAchievementIcons, defaultStyles, exportAchievementData, importAchievementData, isAchievementError, isRecoverableError, isSimpleConfig, normalizeAchievements, useAchievements, useSimpleAchievements };
|
|
662
|
+
export { AchievementBuilder, AchievementCondition, AchievementConfiguration, AchievementConfigurationType, AchievementContext, AchievementContextValue, AchievementDetails, AchievementError, AchievementMetricArrayValue, AchievementMetricValue, AchievementMetrics, AchievementProvider, AchievementProviderProps$1 as AchievementProviderProps, AchievementState, AchievementStorage, AnyAchievementStorage, AsyncAchievementStorage, AsyncStorageAdapter, AwardDetails, BadgesButton, BadgesModal, ConfettiWrapper, ConfigurationError, CustomAchievementDetails, ExportedData, ImportOptions, ImportResult, ImportValidationError, IndexedDBStorage, InitialAchievementMetrics, LocalStorage, MemoryStorage, OfflineQueueStorage, RestApiStorage, RestApiStorageConfig, SimpleAchievementConfig, SimpleAchievementDetails, StorageError, StorageQuotaError, StorageType, StylesProps, SyncError, createConfigHash, defaultAchievementIcons, defaultStyles, exportAchievementData, importAchievementData, isAchievementError, isAsyncStorage, isRecoverableError, isSimpleConfig, normalizeAchievements, useAchievements, useSimpleAchievements };
|