Skip to content

Commit 06eeda4

Browse files
vctrchuclaude
andcommitted
feat(pos): add addEventListener/removeEventListener and PosEventMap to DataTargetApi
Adds type-safe event listener support for the pos.app.ready.data background target. PosEventMap defines three discrete events: transaction_complete, cash_tracking_session_start, cash_tracking_session_complete. The generic AddEventListener/RemoveEventListener types follow the TAG proposal (ui-api-design PR #1418) and match the existing Navigation API pattern. Cart changes are intentionally excluded — they are state, not events, and should use shopify.cart.current.subscribe() instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2d36a20 commit 06eeda4

2 files changed

Lines changed: 79 additions & 1 deletion

File tree

packages/ui-extensions/src/surfaces/point-of-sale/api.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ export type {ActionApi, ActionApiContent} from './api/action-api/action-api';
1313

1414
export type {StandardApi} from './api/standard/standard-api';
1515
export type {ActionTargetApi} from './api/action-target-api/action-target-api';
16-
export type {DataTargetApi} from './api/data-target-api/data-target-api';
16+
export type {
17+
DataTargetApi,
18+
PosEventMap,
19+
AddEventListener,
20+
RemoveEventListener,
21+
} from './api/data-target-api/data-target-api';
1722

1823
export type {
1924
CameraApi,

packages/ui-extensions/src/surfaces/point-of-sale/api/data-target-api/data-target-api.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,86 @@ import {ProductSearchApi} from '../product-search-api/product-search-api';
66
import {SessionApi} from '../session-api/session-api';
77
import {StorageApi} from '../storage-api/storage-api';
88
import type {I18n} from '../../../../api';
9+
import type {SaleTransactionData} from '../../event/data/SaleTransactionData';
10+
import type {ReturnTransactionData} from '../../event/data/ReturnTransactionData';
11+
import type {ExchangeTransactionData} from '../../event/data/ExchangeTransactionData';
12+
13+
/**
14+
* Maps POS event names to their callback payload types.
15+
*
16+
* Used with `addEventListener` / `removeEventListener` to provide type-safe
17+
* event observation. These are discrete events — for state changes like cart
18+
* contents, use `shopify.cart.current.subscribe()` instead.
19+
*/
20+
export type PosEventMap = {
21+
/**
22+
* Fires after a sale, return, or exchange transaction completes.
23+
*/
24+
transaction_complete: {
25+
transaction:
26+
| SaleTransactionData
27+
| ReturnTransactionData
28+
| ExchangeTransactionData;
29+
};
30+
/**
31+
* Fires when a cash tracking session (shift) is opened.
32+
*/
33+
cash_tracking_session_start: {
34+
cashTrackingSessionStart: {
35+
/** Unique identifier for this cash tracking session. */
36+
id: number;
37+
/** ISO 8601 timestamp when the session was opened. */
38+
openingTime: string;
39+
};
40+
};
41+
/**
42+
* Fires when a cash tracking session (shift) is closed.
43+
*/
44+
cash_tracking_session_complete: {
45+
cashTrackingSessionComplete: {
46+
/** Unique identifier for this cash tracking session. */
47+
id: number;
48+
/** ISO 8601 timestamp when the session was opened. */
49+
openingTime: string;
50+
/** ISO 8601 timestamp when the session was closed. */
51+
closingTime: string;
52+
};
53+
};
54+
};
55+
56+
/**
57+
* Registers a listener for a POS host event. The listener is called each time
58+
* the event fires. This is passive and fire-and-forget — the host does not wait
59+
* for the listener and ignores return values.
60+
*/
61+
export type AddEventListener<EventMap extends {[key: string]: unknown}> = <
62+
K extends keyof EventMap,
63+
>(
64+
type: K,
65+
listener: (event: EventMap[K]) => void,
66+
) => void;
67+
68+
/**
69+
* Removes a previously registered event listener. The `type` and `listener`
70+
* must match those passed to `addEventListener` (same function reference).
71+
*/
72+
export type RemoveEventListener<EventMap extends {[key: string]: unknown}> = <
73+
K extends keyof EventMap,
74+
>(
75+
type: K,
76+
listener: (event: EventMap[K]) => void,
77+
) => void;
978

1079
/**
1180
* API surface for non-rendering data extension targets.
1281
*/
1382
export type DataTargetApi<T> = {
1483
extensionPoint: T;
1584
i18n: I18n;
85+
/** Register a listener for discrete POS events. */
86+
addEventListener: AddEventListener<PosEventMap>;
87+
/** Remove a previously registered event listener. */
88+
removeEventListener: RemoveEventListener<PosEventMap>;
1689
} & SessionApi &
1790
StorageApi &
1891
LocaleApi &

0 commit comments

Comments
 (0)