diff --git a/packages/ui-extensions/src/surfaces/point-of-sale/types/storage.ts b/packages/ui-extensions/src/surfaces/point-of-sale/types/storage.ts index f3fded79bc..45cb2411e6 100644 --- a/packages/ui-extensions/src/surfaces/point-of-sale/types/storage.ts +++ b/packages/ui-extensions/src/surfaces/point-of-sale/types/storage.ts @@ -13,6 +13,25 @@ export class StorageError extends Error { export interface Storage< BaseStorageTypes extends Record = Record, > { + /** + * Reactive access to storage values as Subscribables. + * + * Each key is exposed as a `Subscribable`, enabling reactive + * updates across targets of the same extension. One target can subscribe to + * a key and react when another target updates it via `set()` or `delete()`. + * + * Only available on API version `2026-04` and later. + * + * @example + * ```typescript + * // Subscribe to changes from another target: + * const unsubscribe = shopify.storage.keys.syncStatus.subscribe((value) => { + * console.log('syncStatus changed:', value); + * }); + * ``` + */ + keys?: StorageKeys; + /** * Stores a value under the specified key, overwriting any existing value. Values must be JSON-serializable and return `StorageError` when storage limits are exceeded. Commonly used for storing user preferences, caching API responses, or passing contextual data from tiles to modals. * @@ -73,3 +92,31 @@ export interface Storage< Keys extends keyof StorageTypes = keyof StorageTypes, >(): Promise<[Keys, StorageTypes[Keys]][]>; } + +/** + * Represents a readonly value managed by the host that an extension can + * subscribe to for reactive updates. + */ +export interface Subscribable { + /** Synchronous access to the current value. */ + readonly value: Value; + /** Registers a callback that fires when the value changes. Returns an unsubscribe function. */ + subscribe: (callback: (value: Value) => void) => () => void; +} + +/** + * Provides reactive, subscribable access to individual storage keys. + * + * Each property is a `Subscribable` that reflects the current value of the + * corresponding storage key. Values are `undefined` when the key does not exist. + * + * Mutations are performed through the existing `Storage` methods (`set`, `delete`, + * `clear`, etc.) — `StorageKeys` is read-only and reactive. + */ +export type StorageKeys< + BaseStorageTypes extends Record = Record, +> = { + readonly [K in keyof BaseStorageTypes]: Subscribable< + BaseStorageTypes[K] | undefined + >; +};