@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/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?: Readonly<Record<string, number>>;
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 = "ACCEPTED" | "REJECTED_PERMANENT" | "RETRYABLE_ERROR";
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?: Readonly<Record<string, number>>;
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 = "ACCEPTED" | "REJECTED_PERMANENT" | "RETRYABLE_ERROR";
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 };