Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions packages/ui-extensions/src/surfaces/point-of-sale/types/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ export class StorageError extends Error {
export interface Storage<
BaseStorageTypes extends Record<string, any> = Record<string, unknown>,
> {
/**
* Reactive access to storage values as Subscribables.
*
* Each key is exposed as a `Subscribable<T | undefined>`, 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<BaseStorageTypes>;

/**
* 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.
*
Expand Down Expand Up @@ -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<Value = unknown> {
/** 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<string, any> = Record<string, unknown>,
> = {
readonly [K in keyof BaseStorageTypes]: Subscribable<
BaseStorageTypes[K] | undefined
>;
};
Loading