@stamprally/core 0.12.0 → 0.13.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 +13 -0
- package/dist/index.cjs +152 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -4
- package/dist/index.d.ts +42 -4
- package/dist/index.js +151 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -147,6 +147,7 @@ interface StampRecord {
|
|
|
147
147
|
readonly acquiredAt: string;
|
|
148
148
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
149
149
|
}
|
|
150
|
+
type SpotStatus = "UNCLAIMED" | "CLAIMED" | "LOCKED" | "VERIFYING";
|
|
150
151
|
type RewardStatus = "LOCKED" | "AVAILABLE" | "CONSUMED" | "EXPIRED";
|
|
151
152
|
interface RewardState {
|
|
152
153
|
readonly rewardId: string;
|
|
@@ -292,6 +293,11 @@ declare function parsePublicConfig(input: unknown): PublicRallyConfig;
|
|
|
292
293
|
declare function calculateDistanceMeters(aLat: number, aLon: number, bLat: number, bLon: number): number;
|
|
293
294
|
declare function evaluateConditionDetailed(condition: CheckInCondition, context: VerificationContext): Result<ConditionMatch, ConditionMismatch>;
|
|
294
295
|
declare function evaluateCondition(condition: CheckInCondition, context: VerificationContext): boolean;
|
|
296
|
+
/** Derives a viewer-safe spot status without changing the supplied state. */
|
|
297
|
+
declare function evaluateSpotStatus(spot: Pick<SpotItem, "id" | "prerequisites">, state: Pick<UserRallyState, "records">, options?: {
|
|
298
|
+
readonly verifying?: boolean;
|
|
299
|
+
}): SpotStatus;
|
|
300
|
+
declare const getSpotStatus: typeof evaluateSpotStatus;
|
|
295
301
|
|
|
296
302
|
declare function getOrderedSpots<TLocale extends string, TMeta extends Record<string, unknown>>(spots: ReadonlyArray<SpotItem<TLocale, TMeta>>): ReadonlyArray<SpotItem<TLocale, TMeta>>;
|
|
297
303
|
|
|
@@ -380,6 +386,10 @@ interface OfflineQueueOptions {
|
|
|
380
386
|
removeItem?(key: string): void;
|
|
381
387
|
} | null;
|
|
382
388
|
readonly key?: string;
|
|
389
|
+
/** Rally scope used by the default durable key. */
|
|
390
|
+
readonly rallyId?: string;
|
|
391
|
+
/** User scope used by the default durable key. */
|
|
392
|
+
readonly userId?: string | null;
|
|
383
393
|
readonly databaseName?: string;
|
|
384
394
|
readonly conflictPolicy?: SyncConflictPolicy;
|
|
385
395
|
readonly onSyncConflict?: SyncConflictPolicy | ((context: OfflineConflict) => SyncConflictPolicy | Promise<SyncConflictPolicy>);
|
|
@@ -389,10 +399,32 @@ interface OfflineConflict {
|
|
|
389
399
|
readonly localState: UserRallyState;
|
|
390
400
|
readonly serverState: UserRallyState;
|
|
391
401
|
}
|
|
392
|
-
type OfflineSender = (operation: OfflineOperation) => Promise<OfflineResult | OfflineConflictResult>;
|
|
402
|
+
type OfflineSender = (operation: OfflineOperation) => Promise<OfflineResult | OfflineConflictResult | OfflineOperationResponse>;
|
|
403
|
+
type OfflineOperationStatus = "ACCEPTED" | "REJECTED_PERMANENT" | "RETRYABLE_ERROR";
|
|
404
|
+
interface OfflineOperationError {
|
|
405
|
+
readonly code: string;
|
|
406
|
+
readonly message: string;
|
|
407
|
+
readonly [key: string]: unknown;
|
|
408
|
+
}
|
|
409
|
+
type OfflineOperationResponse = {
|
|
410
|
+
readonly status: "ACCEPTED";
|
|
411
|
+
readonly result?: OfflineResult | OfflineConflictResult;
|
|
412
|
+
readonly state?: UserRallyState;
|
|
413
|
+
} | {
|
|
414
|
+
readonly status: "REJECTED_PERMANENT";
|
|
415
|
+
readonly error?: ClientError | OfflineOperationError;
|
|
416
|
+
readonly reason?: ClientError | OfflineOperationError;
|
|
417
|
+
readonly state?: UserRallyState;
|
|
418
|
+
} | {
|
|
419
|
+
readonly status: "RETRYABLE_ERROR";
|
|
420
|
+
readonly error?: ClientError | OfflineOperationError;
|
|
421
|
+
readonly reason?: ClientError | OfflineOperationError;
|
|
422
|
+
};
|
|
393
423
|
interface OfflineSyncResultEvent {
|
|
394
424
|
readonly operation: OfflineOperation;
|
|
395
|
-
readonly result
|
|
425
|
+
readonly result?: OfflineResult | OfflineConflictResult;
|
|
426
|
+
readonly status?: OfflineOperationStatus;
|
|
427
|
+
readonly error?: ClientError | OfflineOperationError;
|
|
396
428
|
readonly state?: UserRallyState;
|
|
397
429
|
}
|
|
398
430
|
type OfflineSyncResultListener = (event: OfflineSyncResultEvent) => void | Promise<void>;
|
|
@@ -420,8 +452,14 @@ declare class OfflineQueue {
|
|
|
420
452
|
get error(): Error | null;
|
|
421
453
|
get operations(): ReadonlyArray<OfflineOperation>;
|
|
422
454
|
get conflictPolicy(): SyncConflictPolicy;
|
|
455
|
+
get storageKey(): string;
|
|
456
|
+
get rallyId(): string | undefined;
|
|
457
|
+
get userId(): string | null;
|
|
423
458
|
setSyncResultListener(listener: OfflineSyncResultListener | undefined): void;
|
|
424
459
|
initialize(): Promise<void>;
|
|
460
|
+
/** Selects a rally/user queue scope and loads its pending operations. */
|
|
461
|
+
setScope(rallyId: string, userId: string | null): Promise<void>;
|
|
462
|
+
switchUser(newUserId: string | null): Promise<void>;
|
|
425
463
|
setSender(sender: OfflineSender): void;
|
|
426
464
|
enqueue(operation: OfflineOperation): Promise<void>;
|
|
427
465
|
enqueueCheckIn(request: CheckInRequest): Promise<void>;
|
|
@@ -548,7 +586,7 @@ type ClientEvent = {
|
|
|
548
586
|
readonly state: UserRallyState;
|
|
549
587
|
} | {
|
|
550
588
|
readonly type: "error";
|
|
551
|
-
readonly error: ClientError;
|
|
589
|
+
readonly error: ClientError | OfflineOperationError;
|
|
552
590
|
};
|
|
553
591
|
type ClientListener = (state: UserRallyState) => void;
|
|
554
592
|
type ClientEventListener = (event: ClientEvent) => void;
|
|
@@ -717,4 +755,4 @@ type SnapshotTokenVerification<T extends SnapshotTokenPayload = SnapshotTokenPay
|
|
|
717
755
|
declare function createSignedSnapshotToken<T extends SnapshotTokenPayload>(payload: T, secretKey: SnapshotSecretKey): Promise<string>;
|
|
718
756
|
declare function verifySnapshotToken<T extends SnapshotTokenPayload = SnapshotTokenPayload>(token: string, secretKey: SnapshotSecretKey, now?: number): Promise<SnapshotTokenVerification<T>>;
|
|
719
757
|
|
|
720
|
-
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, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocaleDictionary, type LocalizedString, type LocalizedText, type MergeConflictOptions, type NfcDetectorOptions, type NfcVerificationContext, type OfflineConflict, type OfflineConflictResult, type OfflineOperation, 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 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, exportProgressToken, getCurrentGeoContext, getOrderedSpots, 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, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
|
758
|
+
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, 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, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
package/dist/index.d.ts
CHANGED
|
@@ -147,6 +147,7 @@ interface StampRecord {
|
|
|
147
147
|
readonly acquiredAt: string;
|
|
148
148
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
149
149
|
}
|
|
150
|
+
type SpotStatus = "UNCLAIMED" | "CLAIMED" | "LOCKED" | "VERIFYING";
|
|
150
151
|
type RewardStatus = "LOCKED" | "AVAILABLE" | "CONSUMED" | "EXPIRED";
|
|
151
152
|
interface RewardState {
|
|
152
153
|
readonly rewardId: string;
|
|
@@ -292,6 +293,11 @@ declare function parsePublicConfig(input: unknown): PublicRallyConfig;
|
|
|
292
293
|
declare function calculateDistanceMeters(aLat: number, aLon: number, bLat: number, bLon: number): number;
|
|
293
294
|
declare function evaluateConditionDetailed(condition: CheckInCondition, context: VerificationContext): Result<ConditionMatch, ConditionMismatch>;
|
|
294
295
|
declare function evaluateCondition(condition: CheckInCondition, context: VerificationContext): boolean;
|
|
296
|
+
/** Derives a viewer-safe spot status without changing the supplied state. */
|
|
297
|
+
declare function evaluateSpotStatus(spot: Pick<SpotItem, "id" | "prerequisites">, state: Pick<UserRallyState, "records">, options?: {
|
|
298
|
+
readonly verifying?: boolean;
|
|
299
|
+
}): SpotStatus;
|
|
300
|
+
declare const getSpotStatus: typeof evaluateSpotStatus;
|
|
295
301
|
|
|
296
302
|
declare function getOrderedSpots<TLocale extends string, TMeta extends Record<string, unknown>>(spots: ReadonlyArray<SpotItem<TLocale, TMeta>>): ReadonlyArray<SpotItem<TLocale, TMeta>>;
|
|
297
303
|
|
|
@@ -380,6 +386,10 @@ interface OfflineQueueOptions {
|
|
|
380
386
|
removeItem?(key: string): void;
|
|
381
387
|
} | null;
|
|
382
388
|
readonly key?: string;
|
|
389
|
+
/** Rally scope used by the default durable key. */
|
|
390
|
+
readonly rallyId?: string;
|
|
391
|
+
/** User scope used by the default durable key. */
|
|
392
|
+
readonly userId?: string | null;
|
|
383
393
|
readonly databaseName?: string;
|
|
384
394
|
readonly conflictPolicy?: SyncConflictPolicy;
|
|
385
395
|
readonly onSyncConflict?: SyncConflictPolicy | ((context: OfflineConflict) => SyncConflictPolicy | Promise<SyncConflictPolicy>);
|
|
@@ -389,10 +399,32 @@ interface OfflineConflict {
|
|
|
389
399
|
readonly localState: UserRallyState;
|
|
390
400
|
readonly serverState: UserRallyState;
|
|
391
401
|
}
|
|
392
|
-
type OfflineSender = (operation: OfflineOperation) => Promise<OfflineResult | OfflineConflictResult>;
|
|
402
|
+
type OfflineSender = (operation: OfflineOperation) => Promise<OfflineResult | OfflineConflictResult | OfflineOperationResponse>;
|
|
403
|
+
type OfflineOperationStatus = "ACCEPTED" | "REJECTED_PERMANENT" | "RETRYABLE_ERROR";
|
|
404
|
+
interface OfflineOperationError {
|
|
405
|
+
readonly code: string;
|
|
406
|
+
readonly message: string;
|
|
407
|
+
readonly [key: string]: unknown;
|
|
408
|
+
}
|
|
409
|
+
type OfflineOperationResponse = {
|
|
410
|
+
readonly status: "ACCEPTED";
|
|
411
|
+
readonly result?: OfflineResult | OfflineConflictResult;
|
|
412
|
+
readonly state?: UserRallyState;
|
|
413
|
+
} | {
|
|
414
|
+
readonly status: "REJECTED_PERMANENT";
|
|
415
|
+
readonly error?: ClientError | OfflineOperationError;
|
|
416
|
+
readonly reason?: ClientError | OfflineOperationError;
|
|
417
|
+
readonly state?: UserRallyState;
|
|
418
|
+
} | {
|
|
419
|
+
readonly status: "RETRYABLE_ERROR";
|
|
420
|
+
readonly error?: ClientError | OfflineOperationError;
|
|
421
|
+
readonly reason?: ClientError | OfflineOperationError;
|
|
422
|
+
};
|
|
393
423
|
interface OfflineSyncResultEvent {
|
|
394
424
|
readonly operation: OfflineOperation;
|
|
395
|
-
readonly result
|
|
425
|
+
readonly result?: OfflineResult | OfflineConflictResult;
|
|
426
|
+
readonly status?: OfflineOperationStatus;
|
|
427
|
+
readonly error?: ClientError | OfflineOperationError;
|
|
396
428
|
readonly state?: UserRallyState;
|
|
397
429
|
}
|
|
398
430
|
type OfflineSyncResultListener = (event: OfflineSyncResultEvent) => void | Promise<void>;
|
|
@@ -420,8 +452,14 @@ declare class OfflineQueue {
|
|
|
420
452
|
get error(): Error | null;
|
|
421
453
|
get operations(): ReadonlyArray<OfflineOperation>;
|
|
422
454
|
get conflictPolicy(): SyncConflictPolicy;
|
|
455
|
+
get storageKey(): string;
|
|
456
|
+
get rallyId(): string | undefined;
|
|
457
|
+
get userId(): string | null;
|
|
423
458
|
setSyncResultListener(listener: OfflineSyncResultListener | undefined): void;
|
|
424
459
|
initialize(): Promise<void>;
|
|
460
|
+
/** Selects a rally/user queue scope and loads its pending operations. */
|
|
461
|
+
setScope(rallyId: string, userId: string | null): Promise<void>;
|
|
462
|
+
switchUser(newUserId: string | null): Promise<void>;
|
|
425
463
|
setSender(sender: OfflineSender): void;
|
|
426
464
|
enqueue(operation: OfflineOperation): Promise<void>;
|
|
427
465
|
enqueueCheckIn(request: CheckInRequest): Promise<void>;
|
|
@@ -548,7 +586,7 @@ type ClientEvent = {
|
|
|
548
586
|
readonly state: UserRallyState;
|
|
549
587
|
} | {
|
|
550
588
|
readonly type: "error";
|
|
551
|
-
readonly error: ClientError;
|
|
589
|
+
readonly error: ClientError | OfflineOperationError;
|
|
552
590
|
};
|
|
553
591
|
type ClientListener = (state: UserRallyState) => void;
|
|
554
592
|
type ClientEventListener = (event: ClientEvent) => void;
|
|
@@ -717,4 +755,4 @@ type SnapshotTokenVerification<T extends SnapshotTokenPayload = SnapshotTokenPay
|
|
|
717
755
|
declare function createSignedSnapshotToken<T extends SnapshotTokenPayload>(payload: T, secretKey: SnapshotSecretKey): Promise<string>;
|
|
718
756
|
declare function verifySnapshotToken<T extends SnapshotTokenPayload = SnapshotTokenPayload>(token: string, secretKey: SnapshotSecretKey, now?: number): Promise<SnapshotTokenVerification<T>>;
|
|
719
757
|
|
|
720
|
-
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, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocaleDictionary, type LocalizedString, type LocalizedText, type MergeConflictOptions, type NfcDetectorOptions, type NfcVerificationContext, type OfflineConflict, type OfflineConflictResult, type OfflineOperation, 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 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, exportProgressToken, getCurrentGeoContext, getOrderedSpots, 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, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
|
758
|
+
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, 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, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
package/dist/index.js
CHANGED
|
@@ -39,6 +39,14 @@ function evaluateConditionDetailed(condition2, context) {
|
|
|
39
39
|
function evaluateCondition(condition2, context) {
|
|
40
40
|
return evaluateConditionDetailed(condition2, context).ok;
|
|
41
41
|
}
|
|
42
|
+
function evaluateSpotStatus(spot2, state, options = {}) {
|
|
43
|
+
if (options.verifying === true) return "VERIFYING";
|
|
44
|
+
if (state.records.some((record) => record.stampId === spot2.id)) return "CLAIMED";
|
|
45
|
+
const acquired = new Set(state.records.map((record) => record.stampId));
|
|
46
|
+
if (spot2.prerequisites?.some((prerequisite) => !acquired.has(prerequisite))) return "LOCKED";
|
|
47
|
+
return "UNCLAIMED";
|
|
48
|
+
}
|
|
49
|
+
var getSpotStatus = evaluateSpotStatus;
|
|
42
50
|
|
|
43
51
|
// src/engine/order.ts
|
|
44
52
|
function getOrderedSpots(spots) {
|
|
@@ -115,24 +123,53 @@ function mergeRewardStates(serverRewards, localRewards) {
|
|
|
115
123
|
merged.set(localReward.rewardId, localReward);
|
|
116
124
|
continue;
|
|
117
125
|
}
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
const winner = localReward.status === "CONSUMED" && serverReward.status !== "CONSUMED" ? localReward : serverReward;
|
|
127
|
+
merged.set(localReward.rewardId, {
|
|
128
|
+
...winner,
|
|
129
|
+
...serverReward.unlockedAt === void 0 && localReward.unlockedAt === void 0 ? {} : {
|
|
130
|
+
unlockedAt: serverReward.unlockedAt === void 0 ? localReward.unlockedAt : localReward.unlockedAt === void 0 ? serverReward.unlockedAt : latestTimestamp(serverReward.unlockedAt, localReward.unlockedAt)
|
|
131
|
+
},
|
|
132
|
+
...serverReward.consumedAt === void 0 && localReward.consumedAt === void 0 ? {} : {
|
|
133
|
+
consumedAt: serverReward.consumedAt === void 0 ? localReward.consumedAt : localReward.consumedAt === void 0 ? serverReward.consumedAt : latestTimestamp(serverReward.consumedAt, localReward.consumedAt)
|
|
134
|
+
},
|
|
135
|
+
...serverReward.redeemedCount === void 0 && localReward.redeemedCount === void 0 ? {} : {
|
|
136
|
+
redeemedCount: Math.max(
|
|
137
|
+
serverReward.redeemedCount ?? 0,
|
|
138
|
+
localReward.redeemedCount ?? 0
|
|
139
|
+
)
|
|
140
|
+
},
|
|
141
|
+
...serverReward.userRedemptionCount === void 0 && localReward.userRedemptionCount === void 0 ? {} : {
|
|
142
|
+
userRedemptionCount: Math.max(
|
|
143
|
+
serverReward.userRedemptionCount ?? 0,
|
|
144
|
+
localReward.userRedemptionCount ?? 0
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
});
|
|
120
148
|
}
|
|
121
149
|
return [...merged.values()];
|
|
122
150
|
}
|
|
123
|
-
function
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
knownStamps.add(record.stampId);
|
|
151
|
+
function mergeStampRecords(serverRecords, localRecords) {
|
|
152
|
+
const merged = /* @__PURE__ */ new Map();
|
|
153
|
+
for (const record of [...serverRecords, ...localRecords]) {
|
|
154
|
+
const current = merged.get(record.stampId);
|
|
155
|
+
if (current === void 0) {
|
|
156
|
+
merged.set(record.stampId, record);
|
|
157
|
+
continue;
|
|
131
158
|
}
|
|
159
|
+
const acquiredAt = latestTimestamp(current.acquiredAt, record.acquiredAt);
|
|
160
|
+
merged.set(record.stampId, {
|
|
161
|
+
...current,
|
|
162
|
+
...acquiredAt === current.acquiredAt ? {} : { acquiredAt },
|
|
163
|
+
...current.metadata === void 0 && record.metadata !== void 0 ? { metadata: record.metadata } : {}
|
|
164
|
+
});
|
|
132
165
|
}
|
|
166
|
+
return [...merged.values()];
|
|
167
|
+
}
|
|
168
|
+
function resolveRallyStateConflict(serverState, localState, options = { policy: "merge" }) {
|
|
169
|
+
if (options.policy === "server_wins") return serverState;
|
|
133
170
|
return {
|
|
134
171
|
...serverState,
|
|
135
|
-
records,
|
|
172
|
+
records: mergeStampRecords(serverState.records, localState.records),
|
|
136
173
|
rewards: mergeRewardStates(serverState.rewards, localState.rewards),
|
|
137
174
|
updatedAt: latestTimestamp(serverState.updatedAt, localState.updatedAt)
|
|
138
175
|
};
|
|
@@ -1070,7 +1107,10 @@ var StampRallyClient = class {
|
|
|
1070
1107
|
initialize() {
|
|
1071
1108
|
if (this.#state !== null) return Promise.resolve(this.#state);
|
|
1072
1109
|
if (this.#initialization === null) {
|
|
1073
|
-
this.#initialization =
|
|
1110
|
+
this.#initialization = (async () => {
|
|
1111
|
+
await this.#offlineQueue?.setScope(this.#config.id, this.#userId);
|
|
1112
|
+
return this.#storage.load(this.#config.id, this.#userId);
|
|
1113
|
+
})().then((state) => {
|
|
1074
1114
|
const next = state === null ? emptyState(this.#config, this.#userId, this.#now()) : this.#reconcile(state);
|
|
1075
1115
|
this.#state = next;
|
|
1076
1116
|
this.#emit(next);
|
|
@@ -1088,6 +1128,7 @@ var StampRallyClient = class {
|
|
|
1088
1128
|
this.#userId = newUserId;
|
|
1089
1129
|
this.#state = null;
|
|
1090
1130
|
this.#initialization = null;
|
|
1131
|
+
await this.#offlineQueue?.switchUser(newUserId);
|
|
1091
1132
|
return this.initialize();
|
|
1092
1133
|
});
|
|
1093
1134
|
}
|
|
@@ -1336,7 +1377,8 @@ var StampRallyClient = class {
|
|
|
1336
1377
|
this.#state = next;
|
|
1337
1378
|
this.#emit(next);
|
|
1338
1379
|
}
|
|
1339
|
-
if ("
|
|
1380
|
+
if (event.error !== void 0) this.#emitEvent({ type: "error", error: event.error });
|
|
1381
|
+
else if (event.result !== void 0 && "ok" in event.result && !event.result.ok)
|
|
1340
1382
|
this.#emitEvent({ type: "error", error: event.result.error });
|
|
1341
1383
|
}
|
|
1342
1384
|
#now() {
|
|
@@ -1464,9 +1506,27 @@ function defaultStorage(databaseName) {
|
|
|
1464
1506
|
function operationId(operation) {
|
|
1465
1507
|
return operation.kind === "checkIn" ? `checkIn:${operation.request.rallyId}:${operation.request.userId ?? "anonymous"}:${operation.request.idempotencyKey}` : `claimReward:${operation.request.rallyId}:${operation.request.userId ?? "anonymous"}:${operation.request.idempotencyKey}`;
|
|
1466
1508
|
}
|
|
1509
|
+
function requestScope(operation) {
|
|
1510
|
+
return {
|
|
1511
|
+
rallyId: operation.request.rallyId,
|
|
1512
|
+
userId: operation.request.userId
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
function errorValue(value, fallbackCode) {
|
|
1516
|
+
if (typeof value === "object" && value !== null) {
|
|
1517
|
+
const candidate = value;
|
|
1518
|
+
if (typeof candidate.code === "string" && typeof candidate.message === "string")
|
|
1519
|
+
return { ...candidate, code: candidate.code, message: candidate.message };
|
|
1520
|
+
}
|
|
1521
|
+
if (value instanceof Error) return { code: fallbackCode, message: value.message };
|
|
1522
|
+
if (typeof value === "string") return { code: fallbackCode, message: value };
|
|
1523
|
+
return { code: fallbackCode, message: "Offline operation was rejected." };
|
|
1524
|
+
}
|
|
1467
1525
|
var OfflineQueue = class {
|
|
1468
1526
|
#storage;
|
|
1469
|
-
#
|
|
1527
|
+
#configuredKey;
|
|
1528
|
+
#rallyId;
|
|
1529
|
+
#userId;
|
|
1470
1530
|
#conflictPolicy;
|
|
1471
1531
|
#onSyncConflict;
|
|
1472
1532
|
#operations = [];
|
|
@@ -1481,7 +1541,9 @@ var OfflineQueue = class {
|
|
|
1481
1541
|
else if (options.storageLike !== void 0 && options.storageLike !== null)
|
|
1482
1542
|
this.#storage = new LocalStorageQueueStorage(options.storageLike);
|
|
1483
1543
|
else this.#storage = defaultStorage(options.databaseName);
|
|
1484
|
-
this.#
|
|
1544
|
+
this.#configuredKey = options.key;
|
|
1545
|
+
this.#rallyId = options.rallyId;
|
|
1546
|
+
this.#userId = options.userId ?? null;
|
|
1485
1547
|
this.#conflictPolicy = options.conflictPolicy ?? "server_wins";
|
|
1486
1548
|
this.#onSyncConflict = options.onSyncConflict;
|
|
1487
1549
|
}
|
|
@@ -1500,23 +1562,57 @@ var OfflineQueue = class {
|
|
|
1500
1562
|
get conflictPolicy() {
|
|
1501
1563
|
return this.#conflictPolicy;
|
|
1502
1564
|
}
|
|
1565
|
+
get storageKey() {
|
|
1566
|
+
return this.#storageKey();
|
|
1567
|
+
}
|
|
1568
|
+
get rallyId() {
|
|
1569
|
+
return this.#rallyId;
|
|
1570
|
+
}
|
|
1571
|
+
get userId() {
|
|
1572
|
+
return this.#userId;
|
|
1573
|
+
}
|
|
1503
1574
|
setSyncResultListener(listener) {
|
|
1504
1575
|
this.#syncResultListener = listener;
|
|
1505
1576
|
}
|
|
1506
1577
|
async initialize() {
|
|
1507
1578
|
if (this.#loaded) return;
|
|
1508
|
-
this.#operations = [...await this.#storage.load(this.#
|
|
1579
|
+
this.#operations = [...await this.#storage.load(this.#storageKey())];
|
|
1509
1580
|
this.#loaded = true;
|
|
1510
1581
|
}
|
|
1582
|
+
/** Selects a rally/user queue scope and loads its pending operations. */
|
|
1583
|
+
async setScope(rallyId, userId) {
|
|
1584
|
+
if (this.#configuredKey !== void 0) {
|
|
1585
|
+
this.#rallyId = rallyId;
|
|
1586
|
+
this.#userId = userId;
|
|
1587
|
+
return this.initialize();
|
|
1588
|
+
}
|
|
1589
|
+
if (this.#rallyId === rallyId && this.#userId === userId && this.#loaded) return;
|
|
1590
|
+
this.#rallyId = rallyId;
|
|
1591
|
+
this.#userId = userId;
|
|
1592
|
+
this.#operations = [];
|
|
1593
|
+
this.#loaded = false;
|
|
1594
|
+
await this.initialize();
|
|
1595
|
+
}
|
|
1596
|
+
async switchUser(newUserId) {
|
|
1597
|
+
if (this.#rallyId === void 0)
|
|
1598
|
+
throw new Error("OfflineQueue.switchUser requires a rally scope.");
|
|
1599
|
+
await this.setScope(this.#rallyId, newUserId);
|
|
1600
|
+
}
|
|
1511
1601
|
setSender(sender) {
|
|
1512
1602
|
this.#sender = sender;
|
|
1513
1603
|
}
|
|
1514
1604
|
async enqueue(operation) {
|
|
1605
|
+
if (this.#configuredKey === void 0) {
|
|
1606
|
+
const scope = requestScope(operation);
|
|
1607
|
+
if (this.#rallyId === void 0) await this.setScope(scope.rallyId, scope.userId);
|
|
1608
|
+
if (this.#rallyId !== scope.rallyId || this.#userId !== scope.userId)
|
|
1609
|
+
throw new Error("Offline operation belongs to another rally or user queue.");
|
|
1610
|
+
}
|
|
1515
1611
|
await this.initialize();
|
|
1516
1612
|
const id2 = operationId(operation);
|
|
1517
1613
|
if (this.#operations.some((item) => operationId(item) === id2)) return;
|
|
1518
1614
|
this.#operations = [...this.#operations, operation];
|
|
1519
|
-
await this.#storage.save(this.#
|
|
1615
|
+
await this.#storage.save(this.#storageKey(), this.#operations);
|
|
1520
1616
|
}
|
|
1521
1617
|
async enqueueCheckIn(request) {
|
|
1522
1618
|
return this.enqueue({ kind: "checkIn", request });
|
|
@@ -1527,7 +1623,7 @@ var OfflineQueue = class {
|
|
|
1527
1623
|
async clear() {
|
|
1528
1624
|
await this.initialize();
|
|
1529
1625
|
this.#operations = [];
|
|
1530
|
-
await this.#storage.save(this.#
|
|
1626
|
+
await this.#storage.save(this.#storageKey(), this.#operations);
|
|
1531
1627
|
}
|
|
1532
1628
|
async sync(sender = this.#sender) {
|
|
1533
1629
|
await this.initialize();
|
|
@@ -1549,20 +1645,30 @@ var OfflineQueue = class {
|
|
|
1549
1645
|
while (this.#operations.length > 0) {
|
|
1550
1646
|
const operation = this.#operations[0];
|
|
1551
1647
|
if (operation === void 0) break;
|
|
1552
|
-
let
|
|
1648
|
+
let rawResult;
|
|
1553
1649
|
try {
|
|
1554
|
-
|
|
1650
|
+
rawResult = await sender(operation);
|
|
1555
1651
|
} catch (cause) {
|
|
1556
|
-
throw
|
|
1652
|
+
throw new Error(errorValue(cause, "RETRYABLE_ERROR").message);
|
|
1653
|
+
}
|
|
1654
|
+
const response = this.#normalizeResponse(rawResult);
|
|
1655
|
+
if (response.status === "RETRYABLE_ERROR") {
|
|
1656
|
+
const error2 = errorValue(response.error ?? response.reason, "RETRYABLE_ERROR");
|
|
1657
|
+
await this.#syncResultListener?.({ operation, status: response.status, error: error2 });
|
|
1658
|
+
throw new Error(error2.message);
|
|
1557
1659
|
}
|
|
1558
|
-
const
|
|
1660
|
+
const result = response.result;
|
|
1661
|
+
const state = response.state ?? (result !== void 0 && "conflict" in result && result.conflict === true ? await this.resolveConflict(operation, result.localState, result.serverState) : result !== void 0 && "ok" in result && result.ok ? result.value.state : void 0);
|
|
1662
|
+
const error = response.status === "REJECTED_PERMANENT" ? errorValue(response.error ?? response.reason, "REJECTED_PERMANENT") : void 0;
|
|
1663
|
+
this.#operations = this.#operations.slice(1);
|
|
1664
|
+
await this.#storage.save(this.#storageKey(), this.#operations);
|
|
1559
1665
|
await this.#syncResultListener?.({
|
|
1560
1666
|
operation,
|
|
1561
|
-
result,
|
|
1667
|
+
...result === void 0 ? {} : { result },
|
|
1668
|
+
status: response.status,
|
|
1669
|
+
...error === void 0 ? {} : { error },
|
|
1562
1670
|
...state === void 0 ? {} : { state }
|
|
1563
1671
|
});
|
|
1564
|
-
this.#operations = this.#operations.slice(1);
|
|
1565
|
-
await this.#storage.save(this.#key, this.#operations);
|
|
1566
1672
|
}
|
|
1567
1673
|
this.#state = "idle";
|
|
1568
1674
|
} catch (cause) {
|
|
@@ -1571,6 +1677,25 @@ var OfflineQueue = class {
|
|
|
1571
1677
|
throw this.#error;
|
|
1572
1678
|
}
|
|
1573
1679
|
}
|
|
1680
|
+
#storageKey() {
|
|
1681
|
+
if (this.#configuredKey !== void 0) return this.#configuredKey;
|
|
1682
|
+
return `stamprally:queue:${this.#rallyId ?? "unscoped"}:${this.#userId ?? "anonymous"}`;
|
|
1683
|
+
}
|
|
1684
|
+
#normalizeResponse(value) {
|
|
1685
|
+
if ("ok" in value) {
|
|
1686
|
+
if (value.ok === false) {
|
|
1687
|
+
if ("status" in value && value.status === "RETRYABLE_ERROR")
|
|
1688
|
+
return { status: "RETRYABLE_ERROR", error: errorValue(value.error, "RETRYABLE_ERROR") };
|
|
1689
|
+
return { status: "REJECTED_PERMANENT", result: value };
|
|
1690
|
+
}
|
|
1691
|
+
return { status: "ACCEPTED", result: value };
|
|
1692
|
+
}
|
|
1693
|
+
if ("status" in value) {
|
|
1694
|
+
if (value.status === "ACCEPTED") return value;
|
|
1695
|
+
return value;
|
|
1696
|
+
}
|
|
1697
|
+
return { status: "ACCEPTED", result: value };
|
|
1698
|
+
}
|
|
1574
1699
|
async resolveConflict(operation, localState, serverState) {
|
|
1575
1700
|
const configured = this.#onSyncConflict;
|
|
1576
1701
|
const policy = (typeof configured === "function" ? await configured({ operation, localState, serverState }) : configured) ?? this.#conflictPolicy;
|
|
@@ -2463,6 +2588,6 @@ async function verifySnapshotToken(token, secretKey, now = Date.now()) {
|
|
|
2463
2588
|
}
|
|
2464
2589
|
}
|
|
2465
2590
|
|
|
2466
|
-
export { ConfigValidationError, DEFAULT_SHEET_THEME, MemoryQueueStorage as InMemoryOfflineQueueStorage, InMemoryStorage, IndexedDBAdapter, IndexedDBOfflineQueueStorage, LocalStorageAdapter, OfflineQueue, StampRallyClient, StorageAdapterError, THEME_PRESETS, assertPublicConfig, calculateDistanceMeters, calculateProgress, consumeReward, createClaimTicketNumber, createSecureToken, createSignedSnapshotToken, createUniqueClaimTicketNumber, evaluateCondition, evaluateConditionDetailed, exportProgressToken, getCurrentGeoContext, getOrderedSpots, 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, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
|
2591
|
+
export { ConfigValidationError, DEFAULT_SHEET_THEME, MemoryQueueStorage as InMemoryOfflineQueueStorage, InMemoryStorage, IndexedDBAdapter, IndexedDBOfflineQueueStorage, LocalStorageAdapter, OfflineQueue, StampRallyClient, StorageAdapterError, THEME_PRESETS, 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, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
|
2467
2592
|
//# sourceMappingURL=index.js.map
|
|
2468
2593
|
//# sourceMappingURL=index.js.map
|