Skip to content

feat(pos): add storage.latest subscribable types to Storage interface#4235

Draft
vctrchu wants to merge 7 commits into2026-07-rcfrom
vchu/storage-keys-subscribable-types
Draft

feat(pos): add storage.latest subscribable types to Storage interface#4235
vctrchu wants to merge 7 commits into2026-07-rcfrom
vchu/storage-keys-subscribable-types

Conversation

@vctrchu
Copy link
Copy Markdown
Contributor

@vctrchu vctrchu commented Mar 27, 2026

What

Add SubscribableStorage type and optional current property to the POS Storage interface for reactive cross-target communication.

Why

Extensions running across multiple targets (tile, modal, background) need to share state reactively. The storage.current subscribable enables one target to subscribe to a key and react when another target updates it via set() or delete().

TAG PR: ui-api-design#1416
Issue: shop/issues-retail#26020

How

Changes to packages/ui-extensions/src/surfaces/point-of-sale/types/storage.ts:

  • SubscribableStorage<T> — mapped type where each key maps to ReadonlySignalLike<T | undefined>, reusing the existing signal type from shared.ts (consistent with cart, connectivity, scanner, locale APIs)
  • current?: SubscribableStorage<BaseStorageTypes> — optional property on Storage interface exposing each storage key as a subscribable
// Synchronous access to the current value:
const status = shopify.storage.current.syncStatus.value;

// Subscribe to changes from another target:
const unsubscribe = shopify.storage.current.syncStatus.subscribe((value) => {
  console.log('syncStatus changed:', value);
});

Also updates ui-extensions-tester mock (createStorage()) with a Proxy-based current implementation.

Companion PR

  • pos-mobile runtime: shop/world#554969 — signal registry + proxy + storageApi integration

Base Branch

2026-07-rc — ships with the 2026-07 API version.

@github-actions
Copy link
Copy Markdown
Contributor

🚨🚨🚨 Docs migration in progress 🚨🚨🚨

We are actively migrating UI extension reference docs to MDX in the areas/platforms/shopify-dev zone of the monorepo. This impacts docs for the following surfaces:

During this migration, please be aware of the following:

.doc.ts files are being deprecated. Changes to .doc.ts files in this repo will not be reflected in the new MDX-based docs. If you need to update docs for a reference that has already been migrated, make your changes directly in the areas/platforms/shopify-dev zone of the monorepo instead.

Doc comments in .ts source files (the comment blocks above types and functions) are also affected. Generating docs from these comments currently requires a newer version of the @shopify/generate-docs library that isn't yet available. Updates to doc comments may not produce the expected output until the migration is complete.

Examples that previously lived in this repo are being moved to the areas/platforms/shopify-dev zone of the monorepo and should be authored there going forward.

What should I do?

  • If your PR includes changes to .doc.ts files, doc comments, or examples, please reach out to us in #devtools-proj-templated-refs so we can help ensure your updates are captured correctly.
  • If your PR is limited to source code changes (non-docs), you can ignore this notice.

Thanks for your patience while we complete the migration! 🙏

@vctrchu vctrchu requested review from a team and NathanJolly March 31, 2026 01:15
@vctrchu vctrchu self-assigned this Mar 31, 2026
@vctrchu vctrchu force-pushed the vchu/storage-keys-subscribable-types branch 2 times, most recently from 5a42408 to 36bfa6a Compare March 31, 2026 02:10
@vctrchu vctrchu marked this pull request as ready for review March 31, 2026 02:12
@vctrchu vctrchu marked this pull request as draft March 31, 2026 23:27
@vctrchu vctrchu changed the title feat(pos): add storage.keys subscribable types to Storage interface feat(pos): add storage.latest subscribable types to Storage interface Apr 2, 2026
@vctrchu vctrchu force-pushed the vchu/storage-keys-subscribable-types branch from 5a8ffb8 to a384c73 Compare April 2, 2026 18:30
Comment thread packages/ui-extensions-tester/src/point-of-sale/index.ts Outdated
@vctrchu vctrchu changed the base branch from 2026-04-rc to 2026-07-rc April 15, 2026 23:10
vctrchu and others added 3 commits April 15, 2026 16:10
Add Subscribable, StorageKeys types and optional keys property to the
POS Storage interface. Each key is exposed as Subscribable<T | undefined>
for reactive cross-target communication within the same extension.

Available on API version 2026-04 and later.

Part of: shop/issues-retail#26020
TAG PR: Shopify/ui-api-design#1416

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…le type

Replace custom Subscribable interface with the existing ReadonlySignalLike
from shared.ts — identical shape, already used by cart, connectivity,
scanner, and locale APIs. Fix @example to use api.storage instead of
shopify.storage.
Aligns with ui-api-design#1416 rename. Updates JSDoc with cross-target
reactivity example and .value/.subscribe() documentation. Updates
tester mock with Proxy-based latest implementation.
@vctrchu vctrchu force-pushed the vchu/storage-keys-subscribable-types branch from f914706 to 14999ed Compare April 15, 2026 23:11
vctrchu and others added 4 commits April 15, 2026 16:14
Rename `latest` → `current` to match `shopify.cart.current` pattern,
rename `StorageKeys` → `SubscribableStorage` per kumar303 suggestion,
and make `current` optional per TAG decision.

Ref: Shopify/ui-api-design#1416

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use non-null assertion for optional `current` property in tests
- Rename single-char storage keys to satisfy id-length lint rule

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…sertions

The createStorage factory always provides `current`, so narrow the
return type to Required<Storage<T>> rather than forcing tests to
use non-null assertions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Storage interface has `current` as optional since not all API
versions support it. Tests should use optional chaining (?.) to
mirror how real extension code accesses the property, rather than
hiding optionality behind Required<> or non-null assertions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vctrchu
Copy link
Copy Markdown
Contributor Author

vctrchu commented Apr 16, 2026

/snapit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants