@stamprally/core 0.14.0 → 0.16.0
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 +7 -3
- package/dist/index.cjs +370 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -3
- package/dist/index.d.ts +59 -3
- package/dist/index.js +369 -47
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.d.cts
CHANGED
|
@@ -97,6 +97,13 @@ type RewardUnlockCondition = {
|
|
|
97
97
|
type RewardType = "digital" | "in_person";
|
|
98
98
|
type RedemptionMethod = "manual_slide" | "staff_passcode" | "view_only" | "server_claim";
|
|
99
99
|
type InventoryAggregationMode = "shared" | "per_reward";
|
|
100
|
+
type RallyInventory = Readonly<Record<string, number>> & {
|
|
101
|
+
readonly sharedStock?: number;
|
|
102
|
+
};
|
|
103
|
+
interface RallyInventoryState {
|
|
104
|
+
readonly sharedRemaining?: number;
|
|
105
|
+
readonly rewardRemaining?: Readonly<Record<string, number>>;
|
|
106
|
+
}
|
|
100
107
|
interface Reward<TLocale extends string = string> {
|
|
101
108
|
readonly id: string;
|
|
102
109
|
readonly title: LocalizedText<TLocale>;
|
|
@@ -121,7 +128,7 @@ interface AdminRallyConfig<TLocale extends string = string, TMeta extends Record
|
|
|
121
128
|
readonly spots: ReadonlyArray<SpotItem<TLocale, TMeta>>;
|
|
122
129
|
readonly rewards: ReadonlyArray<Reward<TLocale>>;
|
|
123
130
|
readonly staffPasscode?: string;
|
|
124
|
-
readonly inventory?:
|
|
131
|
+
readonly inventory?: RallyInventory;
|
|
125
132
|
/** How the optional top-level inventory limit is aggregated. */
|
|
126
133
|
readonly inventoryMode?: InventoryAggregationMode;
|
|
127
134
|
readonly serverMetadata?: Readonly<Record<string, unknown>>;
|
|
@@ -167,6 +174,7 @@ interface StampRallyState {
|
|
|
167
174
|
readonly userId: string | null;
|
|
168
175
|
readonly records: ReadonlyArray<StampRecord>;
|
|
169
176
|
readonly rewards: ReadonlyArray<RewardState>;
|
|
177
|
+
readonly inventory?: RallyInventoryState;
|
|
170
178
|
readonly updatedAt: string;
|
|
171
179
|
}
|
|
172
180
|
type UserRallyState = StampRallyState;
|
|
@@ -364,12 +372,18 @@ interface ProcessStampValue {
|
|
|
364
372
|
}
|
|
365
373
|
declare function processStamp(state: StampRallyState, config: AdminRallyConfig, spotId: string, context: VerificationContext, now: string): Result<ProcessStampValue, StampError>;
|
|
366
374
|
|
|
375
|
+
type QueueOperationStatus = "PENDING" | "IN_FLIGHT" | "ACCEPTED" | "REJECTED_PERMANENT" | "FAILED_RETRYABLE";
|
|
376
|
+
type OfflineQueueCapability = "indexeddb" | "localstorage" | "memory" | "custom";
|
|
367
377
|
type OfflineOperation = {
|
|
368
378
|
readonly kind: "checkIn";
|
|
369
379
|
readonly request: CheckInRequest;
|
|
380
|
+
readonly status?: QueueOperationStatus;
|
|
381
|
+
readonly attempts?: number;
|
|
370
382
|
} | {
|
|
371
383
|
readonly kind: "claimReward";
|
|
372
384
|
readonly request: ClaimRequest;
|
|
385
|
+
readonly status?: QueueOperationStatus;
|
|
386
|
+
readonly attempts?: number;
|
|
373
387
|
};
|
|
374
388
|
type OfflineResult = CheckInResult | ClaimResult | UserRallyState;
|
|
375
389
|
type SyncState = "idle" | "syncing" | "error";
|
|
@@ -382,6 +396,8 @@ interface OfflineConflictResult {
|
|
|
382
396
|
interface OfflineQueueStorage {
|
|
383
397
|
load(key: string): Promise<ReadonlyArray<OfflineOperation>>;
|
|
384
398
|
save(key: string, operations: ReadonlyArray<OfflineOperation>): Promise<void>;
|
|
399
|
+
loadRejectedHistory?(key: string): Promise<ReadonlyArray<RejectedOperationHistoryEntry>>;
|
|
400
|
+
saveRejectedHistory?(key: string, history: ReadonlyArray<RejectedOperationHistoryEntry>): Promise<void>;
|
|
385
401
|
}
|
|
386
402
|
interface OfflineQueueOptions {
|
|
387
403
|
readonly storage?: OfflineQueueStorage;
|
|
@@ -400,6 +416,15 @@ interface OfflineQueueOptions {
|
|
|
400
416
|
readonly onSyncConflict?: SyncConflictPolicy | ((context: OfflineConflict) => SyncConflictPolicy | Promise<SyncConflictPolicy>);
|
|
401
417
|
/** Enables storage-event/BroadcastChannel synchronization when browser APIs exist. */
|
|
402
418
|
readonly synchronizeInstances?: boolean;
|
|
419
|
+
readonly retryOptions?: SyncRetryOptions;
|
|
420
|
+
readonly retry?: SyncRetryOptions;
|
|
421
|
+
/** Alias accepted for callers that configure retry behavior at sync time. */
|
|
422
|
+
readonly syncRetryOptions?: SyncRetryOptions;
|
|
423
|
+
}
|
|
424
|
+
interface SyncRetryOptions {
|
|
425
|
+
readonly maxRetries?: number;
|
|
426
|
+
readonly initialIntervalMs?: number;
|
|
427
|
+
readonly backoffMultiplier?: number;
|
|
403
428
|
}
|
|
404
429
|
interface OfflineConflict {
|
|
405
430
|
readonly operation: OfflineOperation;
|
|
@@ -407,12 +432,21 @@ interface OfflineConflict {
|
|
|
407
432
|
readonly serverState: UserRallyState;
|
|
408
433
|
}
|
|
409
434
|
type OfflineSender = (operation: OfflineOperation) => Promise<OfflineResult | OfflineConflictResult | OfflineOperationResponse>;
|
|
410
|
-
type OfflineOperationStatus =
|
|
435
|
+
type OfflineOperationStatus = QueueOperationStatus | "REJECTED" | "RETRYABLE_ERROR";
|
|
436
|
+
type OfflineOperationLifecycleStatus = QueueOperationStatus;
|
|
411
437
|
interface OfflineOperationError {
|
|
412
438
|
readonly code: string;
|
|
413
439
|
readonly message: string;
|
|
414
440
|
readonly [key: string]: unknown;
|
|
415
441
|
}
|
|
442
|
+
interface RejectedOperationHistoryEntry {
|
|
443
|
+
readonly operation: OfflineOperation;
|
|
444
|
+
readonly reason: OfflineOperationError;
|
|
445
|
+
readonly errorCode: string;
|
|
446
|
+
readonly rejectedAt: string;
|
|
447
|
+
readonly attempts: number;
|
|
448
|
+
}
|
|
449
|
+
type RejectedOperation = RejectedOperationHistoryEntry;
|
|
416
450
|
type OfflineOperationResponse = {
|
|
417
451
|
readonly status: "ACCEPTED";
|
|
418
452
|
readonly result?: OfflineResult | OfflineConflictResult;
|
|
@@ -439,6 +473,8 @@ declare class MemoryQueueStorage implements OfflineQueueStorage {
|
|
|
439
473
|
#private;
|
|
440
474
|
load(key: string): Promise<ReadonlyArray<OfflineOperation>>;
|
|
441
475
|
save(key: string, operations: ReadonlyArray<OfflineOperation>): Promise<void>;
|
|
476
|
+
loadRejectedHistory(key: string): Promise<ReadonlyArray<RejectedOperationHistoryEntry>>;
|
|
477
|
+
saveRejectedHistory(key: string, history: ReadonlyArray<RejectedOperationHistoryEntry>): Promise<void>;
|
|
442
478
|
}
|
|
443
479
|
interface IndexedDBOfflineQueueOptions {
|
|
444
480
|
readonly indexedDB?: IDBFactory | null;
|
|
@@ -449,13 +485,18 @@ declare class IndexedDBOfflineQueueStorage implements OfflineQueueStorage {
|
|
|
449
485
|
constructor(options?: IndexedDBOfflineQueueOptions);
|
|
450
486
|
load(key: string): Promise<ReadonlyArray<OfflineOperation>>;
|
|
451
487
|
save(key: string, operations: ReadonlyArray<OfflineOperation>): Promise<void>;
|
|
488
|
+
loadRejectedHistory(key: string): Promise<ReadonlyArray<RejectedOperationHistoryEntry>>;
|
|
489
|
+
saveRejectedHistory(key: string, history: ReadonlyArray<RejectedOperationHistoryEntry>): Promise<void>;
|
|
452
490
|
}
|
|
491
|
+
declare function offlineOperationId(operation: OfflineOperation): string;
|
|
453
492
|
/** Durable, sequential retry queue for operations created while disconnected. */
|
|
454
493
|
declare class OfflineQueue {
|
|
455
494
|
#private;
|
|
456
495
|
constructor(options?: OfflineQueueOptions);
|
|
457
496
|
get syncState(): SyncState;
|
|
458
497
|
get pendingCount(): number;
|
|
498
|
+
get queueCapability(): OfflineQueueCapability;
|
|
499
|
+
get rejectedHistory(): ReadonlyArray<RejectedOperationHistoryEntry>;
|
|
459
500
|
get error(): Error | null;
|
|
460
501
|
get operations(): ReadonlyArray<OfflineOperation>;
|
|
461
502
|
get conflictPolicy(): SyncConflictPolicy;
|
|
@@ -474,6 +515,11 @@ declare class OfflineQueue {
|
|
|
474
515
|
enqueueCheckIn(request: CheckInRequest): Promise<void>;
|
|
475
516
|
enqueueClaimReward(request: ClaimRequest): Promise<void>;
|
|
476
517
|
clear(): Promise<void>;
|
|
518
|
+
discardRejected(operationId: string): Promise<boolean>;
|
|
519
|
+
retryRejected(operationId: string): Promise<boolean>;
|
|
520
|
+
discardRejectedOperation(operationId: string): Promise<boolean>;
|
|
521
|
+
retryRejectedOperation(operationId: string): Promise<boolean>;
|
|
522
|
+
clearRejectedHistory(): Promise<void>;
|
|
477
523
|
sync(sender?: OfflineSender | undefined): Promise<void>;
|
|
478
524
|
retrySync(sender?: OfflineSender | undefined): Promise<void>;
|
|
479
525
|
resolveConflict(operation: OfflineOperation, localState: UserRallyState, serverState: UserRallyState): Promise<UserRallyState>;
|
|
@@ -519,6 +565,7 @@ declare class InMemoryStorage implements StampStorage {
|
|
|
519
565
|
remove(rallyId: string, userId: string | null): Promise<void>;
|
|
520
566
|
}
|
|
521
567
|
declare function storageKey(rallyId: string, userId: string | null): string;
|
|
568
|
+
declare function createAnonymousSessionId(storage?: StorageLike | null): string;
|
|
522
569
|
interface LocalStorageAdapterOptions {
|
|
523
570
|
readonly storage?: StorageLike | null;
|
|
524
571
|
readonly keyPrefix?: string;
|
|
@@ -607,6 +654,7 @@ interface CheckInRequest {
|
|
|
607
654
|
readonly idempotencyKey: string;
|
|
608
655
|
readonly now: string;
|
|
609
656
|
readonly state: UserRallyState;
|
|
657
|
+
readonly anonymousSessionId?: string;
|
|
610
658
|
}
|
|
611
659
|
interface ClaimRequest {
|
|
612
660
|
readonly rallyId: string;
|
|
@@ -616,6 +664,7 @@ interface ClaimRequest {
|
|
|
616
664
|
readonly now: string;
|
|
617
665
|
readonly options: ClaimOptions;
|
|
618
666
|
readonly state: UserRallyState;
|
|
667
|
+
readonly anonymousSessionId?: string;
|
|
619
668
|
}
|
|
620
669
|
interface SyncAdapter {
|
|
621
670
|
readonly checkIn?: (request: CheckInRequest) => Promise<CheckInResult>;
|
|
@@ -624,6 +673,7 @@ interface SyncAdapter {
|
|
|
624
673
|
readonly rallyId: string;
|
|
625
674
|
readonly userId: string | null;
|
|
626
675
|
readonly state: UserRallyState;
|
|
676
|
+
readonly anonymousSessionId?: string;
|
|
627
677
|
}) => Promise<UserRallyState>;
|
|
628
678
|
}
|
|
629
679
|
interface ClientOptions {
|
|
@@ -633,6 +683,7 @@ interface ClientOptions {
|
|
|
633
683
|
readonly customValidators?: Readonly<Record<string, Validator>>;
|
|
634
684
|
readonly clock?: () => string;
|
|
635
685
|
readonly userId?: string | null;
|
|
686
|
+
readonly anonymousSessionId?: string;
|
|
636
687
|
readonly offlineQueue?: OfflineQueue;
|
|
637
688
|
}
|
|
638
689
|
type StorageOrOptions = StampStorage | ClientOptions;
|
|
@@ -642,8 +693,13 @@ declare class StampRallyClient {
|
|
|
642
693
|
getConfig(): RallyConfig;
|
|
643
694
|
getState(): UserRallyState | null;
|
|
644
695
|
getUserId(): string | null;
|
|
696
|
+
getAnonymousSessionId(): string;
|
|
645
697
|
get syncState(): SyncState;
|
|
646
698
|
get pendingCount(): number;
|
|
699
|
+
get rejectedHistory(): ReadonlyArray<RejectedOperationHistoryEntry>;
|
|
700
|
+
get queueCapability(): OfflineQueueCapability;
|
|
701
|
+
discardRejected(operationId: string): Promise<boolean>;
|
|
702
|
+
retryRejected(operationId: string): Promise<boolean>;
|
|
647
703
|
subscribe(listener: ClientListener): () => void;
|
|
648
704
|
subscribeEvents(listener: ClientEventListener): () => void;
|
|
649
705
|
init(): Promise<UserRallyState>;
|
|
@@ -764,4 +820,4 @@ type SnapshotTokenVerification<T extends SnapshotTokenPayload = SnapshotTokenPay
|
|
|
764
820
|
declare function createSignedSnapshotToken<T extends SnapshotTokenPayload>(payload: T, secretKey: SnapshotSecretKey): Promise<string>;
|
|
765
821
|
declare function verifySnapshotToken<T extends SnapshotTokenPayload = SnapshotTokenPayload>(token: string, secretKey: SnapshotSecretKey, now?: number): Promise<SnapshotTokenVerification<T>>;
|
|
766
822
|
|
|
767
|
-
export { type AdminRallyConfig, type CheckInCondition, type CheckInOptions, type CheckInRequest, type CheckInResult, type CheckInSuccess, type ClaimOptions, type ClaimRequest, type ClaimResult, type ClaimSuccess, type ClaimTicketOptions, type ClientError, type ClientEvent, type ClientEventListener, type ClientListener, type ClientOptions, type CompositeConditionFailure, type ConditionMatch, type ConditionMismatch, ConfigValidationError, type ConsumeResult, type ConsumeRewardParams, type CustomValidationContext, type CustomValidator, DEFAULT_SHEET_THEME, type DetectorError, type DetectorErrorCode, type DetectorKind, type DetectorResult, type ExternalReference, type FontFamily, type GeoDetectorOptions, type GeoVerificationContext, MemoryQueueStorage as InMemoryOfflineQueueStorage, InMemoryStorage, IndexedDBAdapter, type IndexedDBAdapterOptions, type IndexedDBOfflineQueueOptions, IndexedDBOfflineQueueStorage, type InventoryAggregationMode, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocaleDictionary, type LocalizedString, type LocalizedText, type MergeConflictOptions, type NfcDetectorOptions, type NfcVerificationContext, type OfflineConflict, type OfflineConflictResult, type OfflineOperation, type OfflineOperationError, type OfflineOperationResponse, type OfflineOperationStatus, OfflineQueue, type OfflineQueueOptions, type OfflineQueueStorage, type OfflineResult, type OfflineSender, type OfflineSyncResultEvent, type OfflineSyncResultListener, type ParseResult, type PasscodeCondition$1 as PasscodeCondition, type ProcessStampValue, type PublicCheckInCondition, type PublicConfigSafety, type PublicRallyConfig, type PublicReward, type PublicSpotItem, type QrDetectorOptions, type QrVerificationContext, type RallyConfig, type RallySnapshot, type RedemptionMethod, type Result, type Reward, type RewardConsumeError, type RewardState, type RewardStatus, type RewardType, type RewardUnlockCondition, type SecureTokenError, type SecureTokenErrorCode, type SecureTokenOptions, type SecureTokenPayload, type SecureTokenSecretKey, type SecureTokenVerification, type SheetTheme, type SlotShape, type SnapshotSecretKey, type SnapshotTokenError, type SnapshotTokenErrorCode, type SnapshotTokenPayload, type SnapshotTokenVerification, type SpotItem, type SpotStatus, type StampError, StampRallyClient, type StampRallyProgress, type StampRallyState, type StampRecord, type StampStorage, StorageAdapterError, type StorageAdapterErrorCode, type StorageLike, type StorageOperation, type StorageWarningHandler, type SupportedLocale, type SyncAdapter, type SyncConflictPolicy, type SyncState, THEME_PRESETS, type ThemePreset, type ThemePresetId, type UserRallyState, type ValidationError, type Validator, type VerificationContext, assertPublicConfig, calculateDistanceMeters, calculateProgress, consumeReward, createClaimTicketNumber, createSecureToken, createSignedSnapshotToken, createUniqueClaimTicketNumber, evaluateCondition, evaluateConditionDetailed, evaluateSpotStatus, exportProgressToken, getCurrentGeoContext, getOrderedSpots, getSpotStatus, importProgressToken, isGeolocationSupported, isNfcSupported, isPublicConfig, isQrSupported, isRewardState, isStampRallyState, issueClaimTicketNumber, normalizePasscode, parseAdminConfig, parsePublicConfig, processStamp, readNfcContext, readQrContext, reconcileRewardStates, resolveLocalizedText, resolveRallyStateConflict, safeParseAdminConfig, safeParsePublicConfig, sanitizeAdminConfig, storageKey, toLocalizedString, toPublicConfig, updateLocalizedField, validatePublicConfigSafety, validateRallyConfigRelations, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
|
823
|
+
export { type AdminRallyConfig, type CheckInCondition, type CheckInOptions, type CheckInRequest, type CheckInResult, type CheckInSuccess, type ClaimOptions, type ClaimRequest, type ClaimResult, type ClaimSuccess, type ClaimTicketOptions, type ClientError, type ClientEvent, type ClientEventListener, type ClientListener, type ClientOptions, type CompositeConditionFailure, type ConditionMatch, type ConditionMismatch, ConfigValidationError, type ConsumeResult, type ConsumeRewardParams, type CustomValidationContext, type CustomValidator, DEFAULT_SHEET_THEME, type DetectorError, type DetectorErrorCode, type DetectorKind, type DetectorResult, type ExternalReference, type FontFamily, type GeoDetectorOptions, type GeoVerificationContext, MemoryQueueStorage as InMemoryOfflineQueueStorage, InMemoryStorage, IndexedDBAdapter, type IndexedDBAdapterOptions, type IndexedDBOfflineQueueOptions, IndexedDBOfflineQueueStorage, type InventoryAggregationMode, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocaleDictionary, type LocalizedString, type LocalizedText, type MergeConflictOptions, type NfcDetectorOptions, type NfcVerificationContext, type OfflineConflict, type OfflineConflictResult, type OfflineOperation, type OfflineOperationError, type OfflineOperationLifecycleStatus, type OfflineOperationResponse, type OfflineOperationStatus, OfflineQueue, type OfflineQueueCapability, type OfflineQueueOptions, type OfflineQueueStorage, type OfflineResult, type OfflineSender, type OfflineSyncResultEvent, type OfflineSyncResultListener, type ParseResult, type PasscodeCondition$1 as PasscodeCondition, type ProcessStampValue, type PublicCheckInCondition, type PublicConfigSafety, type PublicRallyConfig, type PublicReward, type PublicSpotItem, type QrDetectorOptions, type QrVerificationContext, type QueueOperationStatus, type RallyConfig, type RallyInventory, type RallyInventoryState, type RallySnapshot, type RedemptionMethod, type RejectedOperation, type RejectedOperationHistoryEntry, type Result, type Reward, type RewardConsumeError, type RewardState, type RewardStatus, type RewardType, type RewardUnlockCondition, type SecureTokenError, type SecureTokenErrorCode, type SecureTokenOptions, type SecureTokenPayload, type SecureTokenSecretKey, type SecureTokenVerification, type SheetTheme, type SlotShape, type SnapshotSecretKey, type SnapshotTokenError, type SnapshotTokenErrorCode, type SnapshotTokenPayload, type SnapshotTokenVerification, type SpotItem, type SpotStatus, type StampError, StampRallyClient, type StampRallyProgress, type StampRallyState, type StampRecord, type StampStorage, StorageAdapterError, type StorageAdapterErrorCode, type StorageLike, type StorageOperation, type StorageWarningHandler, type SupportedLocale, type SyncAdapter, type SyncConflictPolicy, type SyncRetryOptions, type SyncState, THEME_PRESETS, type ThemePreset, type ThemePresetId, type UserRallyState, type ValidationError, type Validator, type VerificationContext, assertPublicConfig, calculateDistanceMeters, calculateProgress, consumeReward, createAnonymousSessionId, createClaimTicketNumber, createSecureToken, createSignedSnapshotToken, createUniqueClaimTicketNumber, evaluateCondition, evaluateConditionDetailed, evaluateSpotStatus, exportProgressToken, getCurrentGeoContext, getOrderedSpots, getSpotStatus, importProgressToken, isGeolocationSupported, isNfcSupported, isPublicConfig, isQrSupported, isRewardState, isStampRallyState, issueClaimTicketNumber, normalizePasscode, offlineOperationId, parseAdminConfig, parsePublicConfig, processStamp, readNfcContext, readQrContext, reconcileRewardStates, resolveLocalizedText, resolveRallyStateConflict, safeParseAdminConfig, safeParsePublicConfig, sanitizeAdminConfig, storageKey, toLocalizedString, toPublicConfig, updateLocalizedField, validatePublicConfigSafety, validateRallyConfigRelations, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
package/dist/index.d.ts
CHANGED
|
@@ -97,6 +97,13 @@ type RewardUnlockCondition = {
|
|
|
97
97
|
type RewardType = "digital" | "in_person";
|
|
98
98
|
type RedemptionMethod = "manual_slide" | "staff_passcode" | "view_only" | "server_claim";
|
|
99
99
|
type InventoryAggregationMode = "shared" | "per_reward";
|
|
100
|
+
type RallyInventory = Readonly<Record<string, number>> & {
|
|
101
|
+
readonly sharedStock?: number;
|
|
102
|
+
};
|
|
103
|
+
interface RallyInventoryState {
|
|
104
|
+
readonly sharedRemaining?: number;
|
|
105
|
+
readonly rewardRemaining?: Readonly<Record<string, number>>;
|
|
106
|
+
}
|
|
100
107
|
interface Reward<TLocale extends string = string> {
|
|
101
108
|
readonly id: string;
|
|
102
109
|
readonly title: LocalizedText<TLocale>;
|
|
@@ -121,7 +128,7 @@ interface AdminRallyConfig<TLocale extends string = string, TMeta extends Record
|
|
|
121
128
|
readonly spots: ReadonlyArray<SpotItem<TLocale, TMeta>>;
|
|
122
129
|
readonly rewards: ReadonlyArray<Reward<TLocale>>;
|
|
123
130
|
readonly staffPasscode?: string;
|
|
124
|
-
readonly inventory?:
|
|
131
|
+
readonly inventory?: RallyInventory;
|
|
125
132
|
/** How the optional top-level inventory limit is aggregated. */
|
|
126
133
|
readonly inventoryMode?: InventoryAggregationMode;
|
|
127
134
|
readonly serverMetadata?: Readonly<Record<string, unknown>>;
|
|
@@ -167,6 +174,7 @@ interface StampRallyState {
|
|
|
167
174
|
readonly userId: string | null;
|
|
168
175
|
readonly records: ReadonlyArray<StampRecord>;
|
|
169
176
|
readonly rewards: ReadonlyArray<RewardState>;
|
|
177
|
+
readonly inventory?: RallyInventoryState;
|
|
170
178
|
readonly updatedAt: string;
|
|
171
179
|
}
|
|
172
180
|
type UserRallyState = StampRallyState;
|
|
@@ -364,12 +372,18 @@ interface ProcessStampValue {
|
|
|
364
372
|
}
|
|
365
373
|
declare function processStamp(state: StampRallyState, config: AdminRallyConfig, spotId: string, context: VerificationContext, now: string): Result<ProcessStampValue, StampError>;
|
|
366
374
|
|
|
375
|
+
type QueueOperationStatus = "PENDING" | "IN_FLIGHT" | "ACCEPTED" | "REJECTED_PERMANENT" | "FAILED_RETRYABLE";
|
|
376
|
+
type OfflineQueueCapability = "indexeddb" | "localstorage" | "memory" | "custom";
|
|
367
377
|
type OfflineOperation = {
|
|
368
378
|
readonly kind: "checkIn";
|
|
369
379
|
readonly request: CheckInRequest;
|
|
380
|
+
readonly status?: QueueOperationStatus;
|
|
381
|
+
readonly attempts?: number;
|
|
370
382
|
} | {
|
|
371
383
|
readonly kind: "claimReward";
|
|
372
384
|
readonly request: ClaimRequest;
|
|
385
|
+
readonly status?: QueueOperationStatus;
|
|
386
|
+
readonly attempts?: number;
|
|
373
387
|
};
|
|
374
388
|
type OfflineResult = CheckInResult | ClaimResult | UserRallyState;
|
|
375
389
|
type SyncState = "idle" | "syncing" | "error";
|
|
@@ -382,6 +396,8 @@ interface OfflineConflictResult {
|
|
|
382
396
|
interface OfflineQueueStorage {
|
|
383
397
|
load(key: string): Promise<ReadonlyArray<OfflineOperation>>;
|
|
384
398
|
save(key: string, operations: ReadonlyArray<OfflineOperation>): Promise<void>;
|
|
399
|
+
loadRejectedHistory?(key: string): Promise<ReadonlyArray<RejectedOperationHistoryEntry>>;
|
|
400
|
+
saveRejectedHistory?(key: string, history: ReadonlyArray<RejectedOperationHistoryEntry>): Promise<void>;
|
|
385
401
|
}
|
|
386
402
|
interface OfflineQueueOptions {
|
|
387
403
|
readonly storage?: OfflineQueueStorage;
|
|
@@ -400,6 +416,15 @@ interface OfflineQueueOptions {
|
|
|
400
416
|
readonly onSyncConflict?: SyncConflictPolicy | ((context: OfflineConflict) => SyncConflictPolicy | Promise<SyncConflictPolicy>);
|
|
401
417
|
/** Enables storage-event/BroadcastChannel synchronization when browser APIs exist. */
|
|
402
418
|
readonly synchronizeInstances?: boolean;
|
|
419
|
+
readonly retryOptions?: SyncRetryOptions;
|
|
420
|
+
readonly retry?: SyncRetryOptions;
|
|
421
|
+
/** Alias accepted for callers that configure retry behavior at sync time. */
|
|
422
|
+
readonly syncRetryOptions?: SyncRetryOptions;
|
|
423
|
+
}
|
|
424
|
+
interface SyncRetryOptions {
|
|
425
|
+
readonly maxRetries?: number;
|
|
426
|
+
readonly initialIntervalMs?: number;
|
|
427
|
+
readonly backoffMultiplier?: number;
|
|
403
428
|
}
|
|
404
429
|
interface OfflineConflict {
|
|
405
430
|
readonly operation: OfflineOperation;
|
|
@@ -407,12 +432,21 @@ interface OfflineConflict {
|
|
|
407
432
|
readonly serverState: UserRallyState;
|
|
408
433
|
}
|
|
409
434
|
type OfflineSender = (operation: OfflineOperation) => Promise<OfflineResult | OfflineConflictResult | OfflineOperationResponse>;
|
|
410
|
-
type OfflineOperationStatus =
|
|
435
|
+
type OfflineOperationStatus = QueueOperationStatus | "REJECTED" | "RETRYABLE_ERROR";
|
|
436
|
+
type OfflineOperationLifecycleStatus = QueueOperationStatus;
|
|
411
437
|
interface OfflineOperationError {
|
|
412
438
|
readonly code: string;
|
|
413
439
|
readonly message: string;
|
|
414
440
|
readonly [key: string]: unknown;
|
|
415
441
|
}
|
|
442
|
+
interface RejectedOperationHistoryEntry {
|
|
443
|
+
readonly operation: OfflineOperation;
|
|
444
|
+
readonly reason: OfflineOperationError;
|
|
445
|
+
readonly errorCode: string;
|
|
446
|
+
readonly rejectedAt: string;
|
|
447
|
+
readonly attempts: number;
|
|
448
|
+
}
|
|
449
|
+
type RejectedOperation = RejectedOperationHistoryEntry;
|
|
416
450
|
type OfflineOperationResponse = {
|
|
417
451
|
readonly status: "ACCEPTED";
|
|
418
452
|
readonly result?: OfflineResult | OfflineConflictResult;
|
|
@@ -439,6 +473,8 @@ declare class MemoryQueueStorage implements OfflineQueueStorage {
|
|
|
439
473
|
#private;
|
|
440
474
|
load(key: string): Promise<ReadonlyArray<OfflineOperation>>;
|
|
441
475
|
save(key: string, operations: ReadonlyArray<OfflineOperation>): Promise<void>;
|
|
476
|
+
loadRejectedHistory(key: string): Promise<ReadonlyArray<RejectedOperationHistoryEntry>>;
|
|
477
|
+
saveRejectedHistory(key: string, history: ReadonlyArray<RejectedOperationHistoryEntry>): Promise<void>;
|
|
442
478
|
}
|
|
443
479
|
interface IndexedDBOfflineQueueOptions {
|
|
444
480
|
readonly indexedDB?: IDBFactory | null;
|
|
@@ -449,13 +485,18 @@ declare class IndexedDBOfflineQueueStorage implements OfflineQueueStorage {
|
|
|
449
485
|
constructor(options?: IndexedDBOfflineQueueOptions);
|
|
450
486
|
load(key: string): Promise<ReadonlyArray<OfflineOperation>>;
|
|
451
487
|
save(key: string, operations: ReadonlyArray<OfflineOperation>): Promise<void>;
|
|
488
|
+
loadRejectedHistory(key: string): Promise<ReadonlyArray<RejectedOperationHistoryEntry>>;
|
|
489
|
+
saveRejectedHistory(key: string, history: ReadonlyArray<RejectedOperationHistoryEntry>): Promise<void>;
|
|
452
490
|
}
|
|
491
|
+
declare function offlineOperationId(operation: OfflineOperation): string;
|
|
453
492
|
/** Durable, sequential retry queue for operations created while disconnected. */
|
|
454
493
|
declare class OfflineQueue {
|
|
455
494
|
#private;
|
|
456
495
|
constructor(options?: OfflineQueueOptions);
|
|
457
496
|
get syncState(): SyncState;
|
|
458
497
|
get pendingCount(): number;
|
|
498
|
+
get queueCapability(): OfflineQueueCapability;
|
|
499
|
+
get rejectedHistory(): ReadonlyArray<RejectedOperationHistoryEntry>;
|
|
459
500
|
get error(): Error | null;
|
|
460
501
|
get operations(): ReadonlyArray<OfflineOperation>;
|
|
461
502
|
get conflictPolicy(): SyncConflictPolicy;
|
|
@@ -474,6 +515,11 @@ declare class OfflineQueue {
|
|
|
474
515
|
enqueueCheckIn(request: CheckInRequest): Promise<void>;
|
|
475
516
|
enqueueClaimReward(request: ClaimRequest): Promise<void>;
|
|
476
517
|
clear(): Promise<void>;
|
|
518
|
+
discardRejected(operationId: string): Promise<boolean>;
|
|
519
|
+
retryRejected(operationId: string): Promise<boolean>;
|
|
520
|
+
discardRejectedOperation(operationId: string): Promise<boolean>;
|
|
521
|
+
retryRejectedOperation(operationId: string): Promise<boolean>;
|
|
522
|
+
clearRejectedHistory(): Promise<void>;
|
|
477
523
|
sync(sender?: OfflineSender | undefined): Promise<void>;
|
|
478
524
|
retrySync(sender?: OfflineSender | undefined): Promise<void>;
|
|
479
525
|
resolveConflict(operation: OfflineOperation, localState: UserRallyState, serverState: UserRallyState): Promise<UserRallyState>;
|
|
@@ -519,6 +565,7 @@ declare class InMemoryStorage implements StampStorage {
|
|
|
519
565
|
remove(rallyId: string, userId: string | null): Promise<void>;
|
|
520
566
|
}
|
|
521
567
|
declare function storageKey(rallyId: string, userId: string | null): string;
|
|
568
|
+
declare function createAnonymousSessionId(storage?: StorageLike | null): string;
|
|
522
569
|
interface LocalStorageAdapterOptions {
|
|
523
570
|
readonly storage?: StorageLike | null;
|
|
524
571
|
readonly keyPrefix?: string;
|
|
@@ -607,6 +654,7 @@ interface CheckInRequest {
|
|
|
607
654
|
readonly idempotencyKey: string;
|
|
608
655
|
readonly now: string;
|
|
609
656
|
readonly state: UserRallyState;
|
|
657
|
+
readonly anonymousSessionId?: string;
|
|
610
658
|
}
|
|
611
659
|
interface ClaimRequest {
|
|
612
660
|
readonly rallyId: string;
|
|
@@ -616,6 +664,7 @@ interface ClaimRequest {
|
|
|
616
664
|
readonly now: string;
|
|
617
665
|
readonly options: ClaimOptions;
|
|
618
666
|
readonly state: UserRallyState;
|
|
667
|
+
readonly anonymousSessionId?: string;
|
|
619
668
|
}
|
|
620
669
|
interface SyncAdapter {
|
|
621
670
|
readonly checkIn?: (request: CheckInRequest) => Promise<CheckInResult>;
|
|
@@ -624,6 +673,7 @@ interface SyncAdapter {
|
|
|
624
673
|
readonly rallyId: string;
|
|
625
674
|
readonly userId: string | null;
|
|
626
675
|
readonly state: UserRallyState;
|
|
676
|
+
readonly anonymousSessionId?: string;
|
|
627
677
|
}) => Promise<UserRallyState>;
|
|
628
678
|
}
|
|
629
679
|
interface ClientOptions {
|
|
@@ -633,6 +683,7 @@ interface ClientOptions {
|
|
|
633
683
|
readonly customValidators?: Readonly<Record<string, Validator>>;
|
|
634
684
|
readonly clock?: () => string;
|
|
635
685
|
readonly userId?: string | null;
|
|
686
|
+
readonly anonymousSessionId?: string;
|
|
636
687
|
readonly offlineQueue?: OfflineQueue;
|
|
637
688
|
}
|
|
638
689
|
type StorageOrOptions = StampStorage | ClientOptions;
|
|
@@ -642,8 +693,13 @@ declare class StampRallyClient {
|
|
|
642
693
|
getConfig(): RallyConfig;
|
|
643
694
|
getState(): UserRallyState | null;
|
|
644
695
|
getUserId(): string | null;
|
|
696
|
+
getAnonymousSessionId(): string;
|
|
645
697
|
get syncState(): SyncState;
|
|
646
698
|
get pendingCount(): number;
|
|
699
|
+
get rejectedHistory(): ReadonlyArray<RejectedOperationHistoryEntry>;
|
|
700
|
+
get queueCapability(): OfflineQueueCapability;
|
|
701
|
+
discardRejected(operationId: string): Promise<boolean>;
|
|
702
|
+
retryRejected(operationId: string): Promise<boolean>;
|
|
647
703
|
subscribe(listener: ClientListener): () => void;
|
|
648
704
|
subscribeEvents(listener: ClientEventListener): () => void;
|
|
649
705
|
init(): Promise<UserRallyState>;
|
|
@@ -764,4 +820,4 @@ type SnapshotTokenVerification<T extends SnapshotTokenPayload = SnapshotTokenPay
|
|
|
764
820
|
declare function createSignedSnapshotToken<T extends SnapshotTokenPayload>(payload: T, secretKey: SnapshotSecretKey): Promise<string>;
|
|
765
821
|
declare function verifySnapshotToken<T extends SnapshotTokenPayload = SnapshotTokenPayload>(token: string, secretKey: SnapshotSecretKey, now?: number): Promise<SnapshotTokenVerification<T>>;
|
|
766
822
|
|
|
767
|
-
export { type AdminRallyConfig, type CheckInCondition, type CheckInOptions, type CheckInRequest, type CheckInResult, type CheckInSuccess, type ClaimOptions, type ClaimRequest, type ClaimResult, type ClaimSuccess, type ClaimTicketOptions, type ClientError, type ClientEvent, type ClientEventListener, type ClientListener, type ClientOptions, type CompositeConditionFailure, type ConditionMatch, type ConditionMismatch, ConfigValidationError, type ConsumeResult, type ConsumeRewardParams, type CustomValidationContext, type CustomValidator, DEFAULT_SHEET_THEME, type DetectorError, type DetectorErrorCode, type DetectorKind, type DetectorResult, type ExternalReference, type FontFamily, type GeoDetectorOptions, type GeoVerificationContext, MemoryQueueStorage as InMemoryOfflineQueueStorage, InMemoryStorage, IndexedDBAdapter, type IndexedDBAdapterOptions, type IndexedDBOfflineQueueOptions, IndexedDBOfflineQueueStorage, type InventoryAggregationMode, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocaleDictionary, type LocalizedString, type LocalizedText, type MergeConflictOptions, type NfcDetectorOptions, type NfcVerificationContext, type OfflineConflict, type OfflineConflictResult, type OfflineOperation, type OfflineOperationError, type OfflineOperationResponse, type OfflineOperationStatus, OfflineQueue, type OfflineQueueOptions, type OfflineQueueStorage, type OfflineResult, type OfflineSender, type OfflineSyncResultEvent, type OfflineSyncResultListener, type ParseResult, type PasscodeCondition$1 as PasscodeCondition, type ProcessStampValue, type PublicCheckInCondition, type PublicConfigSafety, type PublicRallyConfig, type PublicReward, type PublicSpotItem, type QrDetectorOptions, type QrVerificationContext, type RallyConfig, type RallySnapshot, type RedemptionMethod, type Result, type Reward, type RewardConsumeError, type RewardState, type RewardStatus, type RewardType, type RewardUnlockCondition, type SecureTokenError, type SecureTokenErrorCode, type SecureTokenOptions, type SecureTokenPayload, type SecureTokenSecretKey, type SecureTokenVerification, type SheetTheme, type SlotShape, type SnapshotSecretKey, type SnapshotTokenError, type SnapshotTokenErrorCode, type SnapshotTokenPayload, type SnapshotTokenVerification, type SpotItem, type SpotStatus, type StampError, StampRallyClient, type StampRallyProgress, type StampRallyState, type StampRecord, type StampStorage, StorageAdapterError, type StorageAdapterErrorCode, type StorageLike, type StorageOperation, type StorageWarningHandler, type SupportedLocale, type SyncAdapter, type SyncConflictPolicy, type SyncState, THEME_PRESETS, type ThemePreset, type ThemePresetId, type UserRallyState, type ValidationError, type Validator, type VerificationContext, assertPublicConfig, calculateDistanceMeters, calculateProgress, consumeReward, createClaimTicketNumber, createSecureToken, createSignedSnapshotToken, createUniqueClaimTicketNumber, evaluateCondition, evaluateConditionDetailed, evaluateSpotStatus, exportProgressToken, getCurrentGeoContext, getOrderedSpots, getSpotStatus, importProgressToken, isGeolocationSupported, isNfcSupported, isPublicConfig, isQrSupported, isRewardState, isStampRallyState, issueClaimTicketNumber, normalizePasscode, parseAdminConfig, parsePublicConfig, processStamp, readNfcContext, readQrContext, reconcileRewardStates, resolveLocalizedText, resolveRallyStateConflict, safeParseAdminConfig, safeParsePublicConfig, sanitizeAdminConfig, storageKey, toLocalizedString, toPublicConfig, updateLocalizedField, validatePublicConfigSafety, validateRallyConfigRelations, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
|
823
|
+
export { type AdminRallyConfig, type CheckInCondition, type CheckInOptions, type CheckInRequest, type CheckInResult, type CheckInSuccess, type ClaimOptions, type ClaimRequest, type ClaimResult, type ClaimSuccess, type ClaimTicketOptions, type ClientError, type ClientEvent, type ClientEventListener, type ClientListener, type ClientOptions, type CompositeConditionFailure, type ConditionMatch, type ConditionMismatch, ConfigValidationError, type ConsumeResult, type ConsumeRewardParams, type CustomValidationContext, type CustomValidator, DEFAULT_SHEET_THEME, type DetectorError, type DetectorErrorCode, type DetectorKind, type DetectorResult, type ExternalReference, type FontFamily, type GeoDetectorOptions, type GeoVerificationContext, MemoryQueueStorage as InMemoryOfflineQueueStorage, InMemoryStorage, IndexedDBAdapter, type IndexedDBAdapterOptions, type IndexedDBOfflineQueueOptions, IndexedDBOfflineQueueStorage, type InventoryAggregationMode, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocaleDictionary, type LocalizedString, type LocalizedText, type MergeConflictOptions, type NfcDetectorOptions, type NfcVerificationContext, type OfflineConflict, type OfflineConflictResult, type OfflineOperation, type OfflineOperationError, type OfflineOperationLifecycleStatus, type OfflineOperationResponse, type OfflineOperationStatus, OfflineQueue, type OfflineQueueCapability, type OfflineQueueOptions, type OfflineQueueStorage, type OfflineResult, type OfflineSender, type OfflineSyncResultEvent, type OfflineSyncResultListener, type ParseResult, type PasscodeCondition$1 as PasscodeCondition, type ProcessStampValue, type PublicCheckInCondition, type PublicConfigSafety, type PublicRallyConfig, type PublicReward, type PublicSpotItem, type QrDetectorOptions, type QrVerificationContext, type QueueOperationStatus, type RallyConfig, type RallyInventory, type RallyInventoryState, type RallySnapshot, type RedemptionMethod, type RejectedOperation, type RejectedOperationHistoryEntry, type Result, type Reward, type RewardConsumeError, type RewardState, type RewardStatus, type RewardType, type RewardUnlockCondition, type SecureTokenError, type SecureTokenErrorCode, type SecureTokenOptions, type SecureTokenPayload, type SecureTokenSecretKey, type SecureTokenVerification, type SheetTheme, type SlotShape, type SnapshotSecretKey, type SnapshotTokenError, type SnapshotTokenErrorCode, type SnapshotTokenPayload, type SnapshotTokenVerification, type SpotItem, type SpotStatus, type StampError, StampRallyClient, type StampRallyProgress, type StampRallyState, type StampRecord, type StampStorage, StorageAdapterError, type StorageAdapterErrorCode, type StorageLike, type StorageOperation, type StorageWarningHandler, type SupportedLocale, type SyncAdapter, type SyncConflictPolicy, type SyncRetryOptions, type SyncState, THEME_PRESETS, type ThemePreset, type ThemePresetId, type UserRallyState, type ValidationError, type Validator, type VerificationContext, assertPublicConfig, calculateDistanceMeters, calculateProgress, consumeReward, createAnonymousSessionId, createClaimTicketNumber, createSecureToken, createSignedSnapshotToken, createUniqueClaimTicketNumber, evaluateCondition, evaluateConditionDetailed, evaluateSpotStatus, exportProgressToken, getCurrentGeoContext, getOrderedSpots, getSpotStatus, importProgressToken, isGeolocationSupported, isNfcSupported, isPublicConfig, isQrSupported, isRewardState, isStampRallyState, issueClaimTicketNumber, normalizePasscode, offlineOperationId, parseAdminConfig, parsePublicConfig, processStamp, readNfcContext, readQrContext, reconcileRewardStates, resolveLocalizedText, resolveRallyStateConflict, safeParseAdminConfig, safeParsePublicConfig, sanitizeAdminConfig, storageKey, toLocalizedString, toPublicConfig, updateLocalizedField, validatePublicConfigSafety, validateRallyConfigRelations, verifyPasscode, verifySecureToken, verifySnapshotToken };
|