@tiledev/sdk-apptile-live-selling 0.13.0 → 0.14.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.
Files changed (111) hide show
  1. package/README.md +94 -12
  2. package/dist/giveawayPrizeLines.d.ts +10 -0
  3. package/dist/giveawayPrizeLines.d.ts.map +1 -1
  4. package/dist/giveawayPrizeLines.js +11 -1
  5. package/dist/giveawayPrizeLines.js.map +1 -1
  6. package/dist/hiddenShows.d.ts +10 -0
  7. package/dist/hiddenShows.d.ts.map +1 -1
  8. package/dist/hiddenShows.js +11 -0
  9. package/dist/hiddenShows.js.map +1 -1
  10. package/dist/index.d.ts +7 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +32 -2
  13. package/dist/index.js.map +1 -1
  14. package/dist/livePages.d.ts +79 -0
  15. package/dist/livePages.d.ts.map +1 -0
  16. package/dist/livePages.js +90 -0
  17. package/dist/livePages.js.map +1 -0
  18. package/dist/liveRoom.d.ts +21 -0
  19. package/dist/liveRoom.d.ts.map +1 -0
  20. package/dist/liveRoom.js +28 -0
  21. package/dist/liveRoom.js.map +1 -0
  22. package/dist/pageOptions.d.ts +100 -0
  23. package/dist/pageOptions.d.ts.map +1 -0
  24. package/dist/pageOptions.js +82 -0
  25. package/dist/pageOptions.js.map +1 -0
  26. package/dist/pageTypes.d.ts +127 -0
  27. package/dist/pageTypes.d.ts.map +1 -0
  28. package/dist/pageTypes.js +3 -0
  29. package/dist/pageTypes.js.map +1 -0
  30. package/dist/react/LiveSellingProvider.d.ts +23 -1
  31. package/dist/react/LiveSellingProvider.d.ts.map +1 -1
  32. package/dist/react/LiveSellingProvider.js +26 -2
  33. package/dist/react/LiveSellingProvider.js.map +1 -1
  34. package/dist/react/index.d.ts +10 -0
  35. package/dist/react/index.d.ts.map +1 -1
  36. package/dist/react/index.js +29 -1
  37. package/dist/react/index.js.map +1 -1
  38. package/dist/react/index.web.d.ts +11 -32
  39. package/dist/react/index.web.d.ts.map +1 -1
  40. package/dist/react/index.web.js +46 -139
  41. package/dist/react/index.web.js.map +1 -1
  42. package/dist/react/navigation.d.ts +13 -0
  43. package/dist/react/navigation.d.ts.map +1 -0
  44. package/dist/react/navigation.js +7 -0
  45. package/dist/react/navigation.js.map +1 -0
  46. package/dist/react/platformSession.d.ts +16 -0
  47. package/dist/react/platformSession.d.ts.map +1 -0
  48. package/dist/react/platformSession.js +28 -0
  49. package/dist/react/platformSession.js.map +1 -0
  50. package/dist/react/platformSession.web.d.ts +35 -0
  51. package/dist/react/platformSession.web.d.ts.map +1 -0
  52. package/dist/react/platformSession.web.js +148 -0
  53. package/dist/react/platformSession.web.js.map +1 -0
  54. package/dist/react/replayPlayer.d.ts +74 -0
  55. package/dist/react/replayPlayer.d.ts.map +1 -0
  56. package/dist/react/replayPlayer.js +279 -0
  57. package/dist/react/replayPlayer.js.map +1 -0
  58. package/dist/react/shopifyProviders.d.ts +68 -0
  59. package/dist/react/shopifyProviders.d.ts.map +1 -0
  60. package/dist/react/shopifyProviders.js +98 -0
  61. package/dist/react/shopifyProviders.js.map +1 -0
  62. package/dist/react/useKeepScreenAwake.d.ts +2 -0
  63. package/dist/react/useKeepScreenAwake.d.ts.map +1 -0
  64. package/dist/react/useKeepScreenAwake.js +34 -0
  65. package/dist/react/useKeepScreenAwake.js.map +1 -0
  66. package/dist/react/useLiveAuction.d.ts +104 -0
  67. package/dist/react/useLiveAuction.d.ts.map +1 -0
  68. package/dist/react/useLiveAuction.js +244 -0
  69. package/dist/react/useLiveAuction.js.map +1 -0
  70. package/dist/react/useLiveChat.d.ts +75 -0
  71. package/dist/react/useLiveChat.d.ts.map +1 -0
  72. package/dist/react/useLiveChat.js +131 -0
  73. package/dist/react/useLiveChat.js.map +1 -0
  74. package/dist/react/useLiveGiveawaysAndPolls.d.ts +84 -0
  75. package/dist/react/useLiveGiveawaysAndPolls.d.ts.map +1 -0
  76. package/dist/react/useLiveGiveawaysAndPolls.js +180 -0
  77. package/dist/react/useLiveGiveawaysAndPolls.js.map +1 -0
  78. package/dist/react/useLivePage.d.ts +113 -0
  79. package/dist/react/useLivePage.d.ts.map +1 -0
  80. package/dist/react/useLivePage.js +264 -0
  81. package/dist/react/useLivePage.js.map +1 -0
  82. package/dist/react/useLiveShop.d.ts +83 -0
  83. package/dist/react/useLiveShop.d.ts.map +1 -0
  84. package/dist/react/useLiveShop.js +165 -0
  85. package/dist/react/useLiveShop.js.map +1 -0
  86. package/dist/react/useReplayPage.d.ts +117 -0
  87. package/dist/react/useReplayPage.d.ts.map +1 -0
  88. package/dist/react/useReplayPage.js +504 -0
  89. package/dist/react/useReplayPage.js.map +1 -0
  90. package/dist/showCredit.d.ts +87 -0
  91. package/dist/showCredit.d.ts.map +1 -0
  92. package/dist/showCredit.js +120 -0
  93. package/dist/showCredit.js.map +1 -0
  94. package/dist/ui/BubbleFrame.d.ts +38 -0
  95. package/dist/ui/BubbleFrame.d.ts.map +1 -0
  96. package/dist/ui/BubbleFrame.js +181 -0
  97. package/dist/ui/BubbleFrame.js.map +1 -0
  98. package/dist/ui/LiveBubble.d.ts +37 -0
  99. package/dist/ui/LiveBubble.d.ts.map +1 -0
  100. package/dist/ui/LiveBubble.js +101 -0
  101. package/dist/ui/LiveBubble.js.map +1 -0
  102. package/dist/ui/ReplayBubble.d.ts +23 -0
  103. package/dist/ui/ReplayBubble.d.ts.map +1 -0
  104. package/dist/ui/ReplayBubble.js +65 -0
  105. package/dist/ui/ReplayBubble.js.map +1 -0
  106. package/dist/ui.d.ts +27 -0
  107. package/dist/ui.d.ts.map +1 -0
  108. package/dist/ui.js +34 -0
  109. package/dist/ui.js.map +1 -0
  110. package/package.json +36 -5
  111. package/ui/package.json +6 -0
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SHEET_HANDOFF_MS = exports.NativeVideoView = exports.isNativeVideoSupported = exports.IDLE_SESSION = void 0;
4
+ exports.LiveSessionProvider = LiveSessionProvider;
5
+ exports.useLiveSession = useLiveSession;
6
+ exports.useLiveShow = useLiveShow;
7
+ exports.LiveVideoTarget = LiveVideoTarget;
8
+ exports.useAuctionBidGate = useAuctionBidGate;
9
+ exports.useAuctionWins = useAuctionWins;
10
+ /**
11
+ * The session and what draws it, on the **web** (0.14.0: moved here from `index.web.ts`, which
12
+ * re-exports them): an idle session, a show that is always `ended`, a `View` for the video, a bid gate
13
+ * that never blocks and no wins. Metro serves this file in place of `platformSession.ts` on the web,
14
+ * so the page hooks, the Shopify session provider and the `/ui` bubbles, which read the session from
15
+ * `./platformSession`, run here over these stand-ins and never reach the Zego module. `index.web.ts`
16
+ * says why each is what it is.
17
+ *
18
+ * `createElement` rather than JSX, like the rest of the package, so this stays a plain `.ts`.
19
+ */
20
+ const react_1 = require("react");
21
+ const react_native_1 = require("react-native");
22
+ const liveShow_1 = require("../liveShow");
23
+ const sessionTypes_1 = require("../sessionTypes");
24
+ // ─── The session ─────────────────────────────────────────────────────────────
25
+ /** Every action, resolved and doing nothing. There is no room to send any of it to. */
26
+ const IDLE_ACTIONS = {
27
+ bindVideoView: () => undefined,
28
+ sendComment: async () => undefined,
29
+ sendReaction: async () => undefined,
30
+ announceAddToCart: async () => undefined,
31
+ voteInPoll: async () => undefined,
32
+ chooseViewerName: async () => null,
33
+ addToCart: async () => false,
34
+ joinAsGuest: () => Promise.reject(new Error('Co-hosting needs a device build.')),
35
+ leaveGuest: async () => undefined,
36
+ setGuestMicMuted: async () => undefined,
37
+ setGuestCameraOff: async () => undefined,
38
+ flipGuestCamera: async () => undefined,
39
+ bindGuestPreview: () => undefined,
40
+ bindGuestHostView: () => undefined,
41
+ setMuted: () => undefined,
42
+ setOutputMuted: () => undefined,
43
+ setPipHandover: () => undefined,
44
+ holdStream: () => undefined,
45
+ releaseStream: () => undefined,
46
+ enterPip: () => undefined,
47
+ exitPip: () => undefined,
48
+ placeBid: async () => ({ sent: false, reason: 'noShow' }),
49
+ enterGiveaway: async () => ({ entered: false, reason: 'noGiveaway' }),
50
+ dismissAuctionWin: () => undefined,
51
+ dismissGiveawayResult: () => undefined,
52
+ };
53
+ /** A stream that is over: the one state every surface already knows how to draw. */
54
+ exports.IDLE_SESSION = {
55
+ status: 'ended',
56
+ stream: null,
57
+ viewerCount: 0,
58
+ rawViewerCount: 0,
59
+ reactionStyle: 'single',
60
+ comments: [],
61
+ activeProduct: null,
62
+ products: [],
63
+ sold: [],
64
+ cartAnnouncements: [],
65
+ reactions: [],
66
+ poll: null,
67
+ muted: true,
68
+ videoTag: null,
69
+ pipMode: 'none',
70
+ guest: {
71
+ mode: false,
72
+ status: 'idle',
73
+ slot: null,
74
+ mutedByHost: false,
75
+ cameraOffByHost: false,
76
+ mixerLayout: null,
77
+ },
78
+ viewerName: null,
79
+ auction: sessionTypes_1.IDLE_AUCTION,
80
+ giveaway: sessionTypes_1.IDLE_GIVEAWAY,
81
+ pinnedComment: null,
82
+ error: null,
83
+ actions: IDLE_ACTIONS,
84
+ };
85
+ const LiveSessionContext = (0, react_1.createContext)(null);
86
+ function LiveSessionProvider({ children }) {
87
+ return (0, react_1.createElement)(LiveSessionContext.Provider, { value: exports.IDLE_SESSION }, children);
88
+ }
89
+ /**
90
+ * The idle session, read without touching the context: a surface rendered outside the provider
91
+ * behaves the same as one inside it, because on the web there is only ever this one session.
92
+ */
93
+ function useLiveSession() {
94
+ return exports.IDLE_SESSION;
95
+ }
96
+ /** The idle session's show: none, and `ended`. One object, as the session never changes here. */
97
+ const IDLE_SHOW = (0, liveShow_1.liveShowFor)(exports.IDLE_SESSION, null);
98
+ /** `useLiveShow` over the idle session: always `ended`, with no show, whatever the id. */
99
+ function useLiveShow(_streamingId) {
100
+ return IDLE_SHOW;
101
+ }
102
+ // ─── The video ───────────────────────────────────────────────────────────────
103
+ exports.isNativeVideoSupported = false;
104
+ /**
105
+ * A plain `View`, which is what the native file falls back to on a build without the Zego SDK:
106
+ * callers position this and draw a poster over it, so returning null would collapse the layout the
107
+ * poster depends on.
108
+ */
109
+ exports.NativeVideoView = (0, react_1.forwardRef)(function NativeVideoView(props, _ref) {
110
+ return (0, react_1.createElement)(react_native_1.View, props);
111
+ });
112
+ function LiveVideoTarget({ style, children }) {
113
+ return (0, react_1.createElement)(react_native_1.View, { style: style !== null && style !== void 0 ? style : { flex: 1 } }, children);
114
+ }
115
+ // ─── Auctions ────────────────────────────────────────────────────────────────
116
+ exports.SHEET_HANDOFF_MS = 380;
117
+ /** Never blocks, because there is no bid to gate — `placeBid` above resolves without sending. */
118
+ function useAuctionBidGate(_options) {
119
+ return (0, react_1.useMemo)(() => ({
120
+ blocker: null,
121
+ variantId: null,
122
+ requestBid: () => undefined,
123
+ acceptTerms: () => undefined,
124
+ chooseVariant: () => undefined,
125
+ dismiss: () => undefined,
126
+ refreshUnpaidWins: () => undefined,
127
+ refusal: null,
128
+ bidOnItsWay: false,
129
+ }), []);
130
+ }
131
+ /**
132
+ * An empty tab rather than a failure. The wins metafield is readable from a browser, but settling one
133
+ * mints a cart and sends the shopper to checkout — not something a preview should be able to start.
134
+ */
135
+ function useAuctionWins(_options) {
136
+ return (0, react_1.useMemo)(() => ({
137
+ rows: [],
138
+ giveawayVariantIds: new Set(),
139
+ totalBids: 0,
140
+ streamingId: null,
141
+ loading: false,
142
+ checkingOut: false,
143
+ error: null,
144
+ refresh: () => undefined,
145
+ checkout: async () => null,
146
+ }), []);
147
+ }
148
+ //# sourceMappingURL=platformSession.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platformSession.web.js","sourceRoot":"","sources":["../../src/react/platformSession.web.ts"],"names":[],"mappings":";;;AAyFA,kDAEC;AAMD,wCAEC;AAMD,kCAEC;AAeD,0CAEC;AAOD,8CAeC;AAMD,wCAiBC;AAzKD;;;;;;;;;GASG;AACH,iCAA0E;AAC1E,+CAAoC;AAIpC,0CAAyD;AACzD,kDAA8D;AAO9D,gFAAgF;AAEhF,uFAAuF;AACvF,MAAM,YAAY,GAAuB;IACvC,aAAa,EAAE,GAAG,EAAE,CAAC,SAAS;IAC9B,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IAClC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IACnC,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IACxC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IACjC,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;IAClC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK;IAC5B,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAChF,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IACjC,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IACvC,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IACxC,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IACtC,gBAAgB,EAAE,GAAG,EAAE,CAAC,SAAS;IACjC,iBAAiB,EAAE,GAAG,EAAE,CAAC,SAAS;IAClC,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS;IACzB,cAAc,EAAE,GAAG,EAAE,CAAC,SAAS;IAC/B,cAAc,EAAE,GAAG,EAAE,CAAC,SAAS;IAC/B,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;IAC3B,aAAa,EAAE,GAAG,EAAE,CAAC,SAAS;IAC9B,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS;IACzB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;IACxB,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACzD,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IACrE,iBAAiB,EAAE,GAAG,EAAE,CAAC,SAAS;IAClC,qBAAqB,EAAE,GAAG,EAAE,CAAC,SAAS;CACvC,CAAC;AAEF,oFAAoF;AACvE,QAAA,YAAY,GAAgB;IACvC,MAAM,EAAE,OAAO;IACf,MAAM,EAAE,IAAI;IACZ,WAAW,EAAE,CAAC;IACd,cAAc,EAAE,CAAC;IACjB,aAAa,EAAE,QAAQ;IACvB,QAAQ,EAAE,EAAE;IACZ,aAAa,EAAE,IAAI;IACnB,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,EAAE;IACR,iBAAiB,EAAE,EAAE;IACrB,SAAS,EAAE,EAAE;IACb,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,MAAM;IACf,KAAK,EAAE;QACL,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,KAAK;QAClB,eAAe,EAAE,KAAK;QACtB,WAAW,EAAE,IAAI;KAClB;IACD,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,2BAAY;IACrB,QAAQ,EAAE,4BAAa;IACvB,aAAa,EAAE,IAAI;IACnB,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,YAAY;CACtB,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAA,qBAAa,EAAqB,IAAI,CAAC,CAAC;AAEnE,SAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAA4B;IACxE,OAAO,IAAA,qBAAa,EAAC,kBAAkB,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,oBAAY,EAAE,EAAE,QAAQ,CAAC,CAAC;AACvF,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc;IAC5B,OAAO,oBAAiC,CAAC;AAC3C,CAAC;AAED,iGAAiG;AACjG,MAAM,SAAS,GAAa,IAAA,sBAAW,EAAC,oBAAY,EAAE,IAAI,CAAC,CAAC;AAE5D,0FAA0F;AAC1F,SAAgB,WAAW,CAAC,YAAuC;IACjE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,gFAAgF;AAEnE,QAAA,sBAAsB,GAAG,KAAK,CAAC;AAE5C;;;;GAIG;AACU,QAAA,eAAe,GAAG,IAAA,kBAAU,EAAqB,SAAS,eAAe,CAAC,KAAK,EAAE,IAAI;IAChG,OAAO,IAAA,qBAAa,EAAC,mBAAI,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC;AAEH,SAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAwB;IACvE,OAAO,IAAA,qBAAa,EAAC,mBAAI,EAAE,EAAE,KAAK,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,QAAqB,CAAC,CAAC;AACrF,CAAC;AAED,gFAAgF;AAEnE,QAAA,gBAAgB,GAAG,GAAG,CAAC;AAEpC,iGAAiG;AACjG,SAAgB,iBAAiB,CAAC,QAAkC;IAClE,OAAO,IAAA,eAAO,EACZ,GAAG,EAAE,CAAC,CAAC;QACL,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;QAC3B,WAAW,EAAE,GAAG,EAAE,CAAC,SAAS;QAC5B,aAAa,EAAE,GAAG,EAAE,CAAC,SAAS;QAC9B,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;QACxB,iBAAiB,EAAE,GAAG,EAAE,CAAC,SAAS;QAClC,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,KAAK;KACnB,CAAC,EACF,EAAE,CACH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAC5B,QAAgC;IAEhC,OAAO,IAAA,eAAO,EACZ,GAAG,EAAE,CAAC,CAAC;QACL,IAAI,EAAE,EAA2B;QACjC,kBAAkB,EAAE,IAAI,GAAG,EAAU;QACrC,SAAS,EAAE,CAAC;QACZ,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,KAAK;QAClB,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;QACxB,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;KAC3B,CAAC,EACF,EAAE,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The app's one player for recorded shows (0.14.0, moved from amore-v2's
3
+ * `src/core/providers/replayPlayer.tsx`: the old app's `ReplayPipProvider`, rebuilt; decided 2026-10-05,
4
+ * Head of Engineering: a picture-in-picture button and a cart on the Replay screen, with an in-app
5
+ * bubble). `useReplayPage` borrows it, and the `/ui` entry's `ReplayBubble` draws it.
6
+ *
7
+ * `createElement` rather than JSX, like the rest of the package, so this stays a plain `.ts`.
8
+ */
9
+ import { type VideoPlayer, type VideoPlayerStatus } from 'expo-video';
10
+ import type { ReactNode } from 'react';
11
+ import type { Replay } from '../types';
12
+ export interface ReplayPlayerState {
13
+ /** The app's one video player for recorded shows: the Replay screen and the bubble both draw it. */
14
+ player: VideoPlayer;
15
+ /** The recording the player holds, or null when it holds nothing. */
16
+ recording: Replay | null;
17
+ /** That recording's video, the player's source. */
18
+ videoUrl: string | null;
19
+ /** The video has its first picture, so a poster over it can come off. */
20
+ videoReady: boolean;
21
+ status: VideoPlayerStatus;
22
+ playing: boolean;
23
+ muted: boolean;
24
+ /** The shopper paused the recording; a new recording starts unpaused. */
25
+ pausedByShopper: boolean;
26
+ /** The floating bubble shows the video, over whatever screen is open. */
27
+ bubbleShown: boolean;
28
+ /** Puts this recording in the player, from the start. Nothing changes if the player already holds it. */
29
+ openRecording: (recording: Replay) => void;
30
+ /** Whether the player holds this video now (read at the moment it is asked, not at the last render). */
31
+ holdsVideo: (videoUrl: string | null) => boolean;
32
+ /** Pauses, takes the video out of the player and closes the bubble. */
33
+ stop: () => void;
34
+ /** The video moves into the bubble. Nothing happens when the player holds nothing. */
35
+ showBubble: () => void;
36
+ /** The bubble closes and the video goes on playing, for the Replay screen to show. */
37
+ hideBubble: () => void;
38
+ setMuted: (muted: boolean) => void;
39
+ setPausedByShopper: (paused: boolean) => void;
40
+ /** A view drew the video's first picture. */
41
+ markVideoReady: () => void;
42
+ /** A Replay screen (its route key) is on show with the player's recording, or no longer is. */
43
+ setScreenShowing: (screenKey: string, showing: boolean) => void;
44
+ /** A Replay screen closed: the video stops, unless the bubble or another Replay screen shows it. */
45
+ screenClosed: (screenKey: string) => void;
46
+ }
47
+ /** The app's replay player, for the Replay screen's hook and the bubble. Only inside `ReplayPlayerProvider`. */
48
+ export declare function useReplayPlayer(): ReplayPlayerState;
49
+ /**
50
+ * The app's one player for recorded shows. Mount it above the navigator, because the bubble outlives
51
+ * the screen that opened it: a player made in the screen is released when the screen closes, which is
52
+ * exactly when the bubble needs it. The Replay screen borrows it (`useReplayPage`); nothing is loaded
53
+ * until a recording is opened, so a session that never opens one has an idle player and no requests.
54
+ *
55
+ * - **One recording at a time,** one source per recording: opening the one the player already holds
56
+ * changes nothing, so a recording coming back from the bubble plays on where it was.
57
+ * - **When it plays:** it holds a recording, the shopper hasn't paused it, and something shows it, the
58
+ * bubble or the Replay screen of that recording while that screen is on show (a sheet over it, like
59
+ * the variant page, counts as on show). Anything else pauses it.
60
+ * - **One view at a time:** while the bubble is up only the bubble draws the video; the Replay screen
61
+ * draws it again once the bubble closes. A second view on the same player would have two native
62
+ * views competing for it.
63
+ * - **Stopping** (the bubble's ✕, the screen's close, the recording ending in the bubble, or the last
64
+ * Replay screen closing with no bubble) pauses, takes the video out, closes the bubble and puts the
65
+ * sound back to how a recording starts.
66
+ * - **On web** a view is a `<video>` element of its own that starts at 0, so moving between the screen
67
+ * and the bubble carries the time across by hand.
68
+ * - **No system picture-in-picture**: it needs expo-video's picture-in-picture flag, the audio
69
+ * background mode and a native build.
70
+ */
71
+ export declare function ReplayPlayerProvider({ children }: {
72
+ children: ReactNode;
73
+ }): import("react").FunctionComponentElement<import("react").ProviderProps<ReplayPlayerState | null>>;
74
+ //# sourceMappingURL=replayPlayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replayPlayer.d.ts","sourceRoot":"","sources":["../../src/react/replayPlayer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAcvC,MAAM,WAAW,iBAAiB;IAChC,oGAAoG;IACpG,MAAM,EAAE,WAAW,CAAC;IACpB,qEAAqE;IACrE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,yEAAyE;IACzE,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,yEAAyE;IACzE,eAAe,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,WAAW,EAAE,OAAO,CAAC;IACrB,yGAAyG;IACzG,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,wGAAwG;IACxG,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC;IACjD,uEAAuE;IACvE,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,sFAAsF;IACtF,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,sFAAsF;IACtF,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,kBAAkB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,6CAA6C;IAC7C,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,+FAA+F;IAC/F,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChE,oGAAoG;IACpG,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAID,gHAAgH;AAChH,wBAAgB,eAAe,IAAI,iBAAiB,CAInD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,qGAqOzE"}
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useReplayPlayer = useReplayPlayer;
4
+ exports.ReplayPlayerProvider = ReplayPlayerProvider;
5
+ /**
6
+ * The app's one player for recorded shows (0.14.0, moved from amore-v2's
7
+ * `src/core/providers/replayPlayer.tsx`: the old app's `ReplayPipProvider`, rebuilt; decided 2026-10-05,
8
+ * Head of Engineering: a picture-in-picture button and a cart on the Replay screen, with an in-app
9
+ * bubble). `useReplayPage` borrows it, and the `/ui` entry's `ReplayBubble` draws it.
10
+ *
11
+ * `createElement` rather than JSX, like the rest of the package, so this stays a plain `.ts`.
12
+ */
13
+ const expo_video_1 = require("expo-video");
14
+ const react_1 = require("react");
15
+ const react_native_1 = require("react-native");
16
+ /** The poster comes off by now even if the video never says it has a picture. */
17
+ const POSTER_AT_MOST_MS = 4000;
18
+ /** Web: how long after the video moves to another view it is played again (see the play effect). */
19
+ const WEB_PLAY_AGAIN_MS = 300;
20
+ /**
21
+ * A recording starts with sound on a phone, as old Amore. Browsers refuse to start a video with sound
22
+ * before the visitor has touched the page (Chrome's autoplay policy; the dashboard preview opens screens
23
+ * without a tap, and the refusal is an unhandled `NotAllowedError` inside expo-video's web `play()`), so
24
+ * on web it starts muted, the sound button a tap away.
25
+ */
26
+ const STARTS_MUTED = react_native_1.Platform.OS === 'web';
27
+ const ReplayPlayerContext = (0, react_1.createContext)(null);
28
+ /** The app's replay player, for the Replay screen's hook and the bubble. Only inside `ReplayPlayerProvider`. */
29
+ function useReplayPlayer() {
30
+ const value = (0, react_1.useContext)(ReplayPlayerContext);
31
+ if (!value)
32
+ throw new Error('useReplayPlayer must be used inside ReplayPlayerProvider');
33
+ return value;
34
+ }
35
+ /**
36
+ * The app's one player for recorded shows. Mount it above the navigator, because the bubble outlives
37
+ * the screen that opened it: a player made in the screen is released when the screen closes, which is
38
+ * exactly when the bubble needs it. The Replay screen borrows it (`useReplayPage`); nothing is loaded
39
+ * until a recording is opened, so a session that never opens one has an idle player and no requests.
40
+ *
41
+ * - **One recording at a time,** one source per recording: opening the one the player already holds
42
+ * changes nothing, so a recording coming back from the bubble plays on where it was.
43
+ * - **When it plays:** it holds a recording, the shopper hasn't paused it, and something shows it, the
44
+ * bubble or the Replay screen of that recording while that screen is on show (a sheet over it, like
45
+ * the variant page, counts as on show). Anything else pauses it.
46
+ * - **One view at a time:** while the bubble is up only the bubble draws the video; the Replay screen
47
+ * draws it again once the bubble closes. A second view on the same player would have two native
48
+ * views competing for it.
49
+ * - **Stopping** (the bubble's ✕, the screen's close, the recording ending in the bubble, or the last
50
+ * Replay screen closing with no bubble) pauses, takes the video out, closes the bubble and puts the
51
+ * sound back to how a recording starts.
52
+ * - **On web** a view is a `<video>` element of its own that starts at 0, so moving between the screen
53
+ * and the bubble carries the time across by hand.
54
+ * - **No system picture-in-picture**: it needs expo-video's picture-in-picture flag, the audio
55
+ * background mode and a native build.
56
+ */
57
+ function ReplayPlayerProvider({ children }) {
58
+ var _a;
59
+ const player = (0, expo_video_1.useVideoPlayer)(null, (created) => {
60
+ created.loop = false;
61
+ // Muted from the start on web: the first source starts playing as it is applied.
62
+ created.muted = STARTS_MUTED;
63
+ });
64
+ const [recording, setRecording] = (0, react_1.useState)(null);
65
+ const [bubbleShown, setBubbleShown] = (0, react_1.useState)(false);
66
+ /** The route key of the Replay screen on show with the player's recording, if one is. */
67
+ const [screenShowingKey, setScreenShowingKey] = (0, react_1.useState)(null);
68
+ const [muted, setMuted] = (0, react_1.useState)(STARTS_MUTED);
69
+ const [pausedByShopper, setPausedByShopper] = (0, react_1.useState)(false);
70
+ const [playing, setPlaying] = (0, react_1.useState)(player.playing);
71
+ const [status, setStatus] = (0, react_1.useState)(player.status);
72
+ const [videoReady, setVideoReady] = (0, react_1.useState)(false);
73
+ const videoUrl = (_a = recording === null || recording === void 0 ? void 0 : recording.videoUrl) !== null && _a !== void 0 ? _a : null;
74
+ const shouldPlay = !!videoUrl && !pausedByShopper && (bubbleShown || screenShowingKey !== null);
75
+ // Read by callbacks the moment they run: a screen closing straight after `showBubble`, or a load
76
+ // finishing, must see what was just decided, not the last render.
77
+ const videoUrlNow = (0, react_1.useRef)(null);
78
+ const bubbleShownNow = (0, react_1.useRef)(false);
79
+ const screenShowingKeyNow = (0, react_1.useRef)(null);
80
+ const shouldPlayNow = (0, react_1.useRef)(shouldPlay);
81
+ shouldPlayNow.current = shouldPlay;
82
+ /** The status the player reports next belongs to this source only once it has left the last one's "ready". */
83
+ const statusIsThisSource = (0, react_1.useRef)(false);
84
+ /** Web only: where the video was when it moved between the screen and the bubble, for the new view. */
85
+ const handover = (0, react_1.useRef)(null);
86
+ const timeNow = (0, react_1.useCallback)(() => {
87
+ try {
88
+ return player.currentTime || 0;
89
+ }
90
+ catch {
91
+ return 0;
92
+ }
93
+ }, [player]);
94
+ const openRecording = (0, react_1.useCallback)((next) => {
95
+ const nextUrl = next.videoUrl;
96
+ if (!nextUrl || videoUrlNow.current === nextUrl)
97
+ return;
98
+ videoUrlNow.current = nextUrl;
99
+ handover.current = null;
100
+ statusIsThisSource.current = player.status !== 'readyToPlay';
101
+ setVideoReady(false);
102
+ setPausedByShopper(false);
103
+ setRecording(next);
104
+ player
105
+ .replaceAsync(nextUrl)
106
+ .then(() => {
107
+ if (videoUrlNow.current === nextUrl && shouldPlayNow.current)
108
+ player.play();
109
+ })
110
+ // A source that won't open reports `error` through its status.
111
+ .catch(() => undefined);
112
+ }, [player]);
113
+ const holdsVideo = (0, react_1.useCallback)((url) => !!url && videoUrlNow.current === url, []);
114
+ const stop = (0, react_1.useCallback)(() => {
115
+ const held = videoUrlNow.current;
116
+ videoUrlNow.current = null;
117
+ bubbleShownNow.current = false;
118
+ handover.current = null;
119
+ try {
120
+ player.pause();
121
+ }
122
+ catch {
123
+ // Already released (the app is closing).
124
+ }
125
+ if (held)
126
+ void player.replaceAsync(null).catch(() => undefined);
127
+ setRecording(null);
128
+ setBubbleShown(false);
129
+ setPausedByShopper(false);
130
+ setVideoReady(false);
131
+ setMuted(STARTS_MUTED);
132
+ }, [player]);
133
+ const showBubble = (0, react_1.useCallback)(() => {
134
+ if (!videoUrlNow.current || bubbleShownNow.current)
135
+ return;
136
+ handover.current = { videoUrl: videoUrlNow.current, atSeconds: timeNow() };
137
+ bubbleShownNow.current = true;
138
+ setBubbleShown(true);
139
+ }, [timeNow]);
140
+ const hideBubble = (0, react_1.useCallback)(() => {
141
+ if (!bubbleShownNow.current)
142
+ return;
143
+ if (videoUrlNow.current)
144
+ handover.current = { videoUrl: videoUrlNow.current, atSeconds: timeNow() };
145
+ bubbleShownNow.current = false;
146
+ setBubbleShown(false);
147
+ }, [timeNow]);
148
+ const setScreenShowing = (0, react_1.useCallback)((screenKey, showing) => {
149
+ if (showing) {
150
+ screenShowingKeyNow.current = screenKey;
151
+ setScreenShowingKey(screenKey);
152
+ }
153
+ else if (screenShowingKeyNow.current === screenKey) {
154
+ screenShowingKeyNow.current = null;
155
+ setScreenShowingKey(null);
156
+ }
157
+ }, []);
158
+ const screenClosed = (0, react_1.useCallback)((screenKey) => {
159
+ setScreenShowing(screenKey, false);
160
+ // Nothing left to show the video: it stops rather than stay loaded, paused, out of sight.
161
+ if (!bubbleShownNow.current && screenShowingKeyNow.current === null)
162
+ stop();
163
+ }, [setScreenShowing, stop]);
164
+ const markVideoReady = (0, react_1.useCallback)(() => setVideoReady(true), []);
165
+ // Web: the view that now shows the video is a new `<video>` element at 0; it starts where the last
166
+ // one was. Declared before the play effect, so the time is set before it plays.
167
+ (0, react_1.useEffect)(() => {
168
+ const moved = handover.current;
169
+ handover.current = null;
170
+ if (react_native_1.Platform.OS !== 'web' || !moved || moved.videoUrl !== videoUrlNow.current)
171
+ return;
172
+ try {
173
+ player.currentTime = moved.atSeconds;
174
+ }
175
+ catch {
176
+ // No view yet: it starts from the beginning.
177
+ }
178
+ }, [player, bubbleShown, screenShowingKey]);
179
+ // Also when the view showing it changes: on web the player plays through the view it is shown in.
180
+ (0, react_1.useEffect)(() => {
181
+ if (!videoUrl)
182
+ return;
183
+ if (!shouldPlay) {
184
+ player.pause();
185
+ return;
186
+ }
187
+ player.play();
188
+ if (react_native_1.Platform.OS !== 'web')
189
+ return;
190
+ // Web: the `<video>` element that just went away pauses as the browser removes it, and expo-video's
191
+ // web player passes that pause on to every view it has, the new one included (seen in the preview:
192
+ // the bubble came up paused). Played again once that has happened.
193
+ const timer = setTimeout(() => {
194
+ if (shouldPlayNow.current)
195
+ player.play();
196
+ }, WEB_PLAY_AGAIN_MS);
197
+ return () => clearTimeout(timer);
198
+ }, [player, videoUrl, shouldPlay, bubbleShown, screenShowingKey]);
199
+ (0, react_1.useEffect)(() => {
200
+ player.muted = muted;
201
+ }, [player, muted]);
202
+ // The phone pauses the video when the app goes to the background; coming back picks it up again.
203
+ (0, react_1.useEffect)(() => {
204
+ const subscription = react_native_1.AppState.addEventListener('change', (state) => {
205
+ if (state === 'active' && shouldPlayNow.current)
206
+ player.play();
207
+ });
208
+ return () => subscription.remove();
209
+ }, [player]);
210
+ (0, react_1.useEffect)(() => {
211
+ const playingChange = player.addListener('playingChange', ({ isPlaying }) => setPlaying(isPlaying));
212
+ const statusChange = player.addListener('statusChange', ({ status: next }) => {
213
+ setStatus(next);
214
+ if (next !== 'readyToPlay')
215
+ statusIsThisSource.current = true;
216
+ else if (statusIsThisSource.current)
217
+ setVideoReady(true);
218
+ });
219
+ // The bubble outlives the screen, so nothing else would take it down at the end of the recording:
220
+ // it would sit over the app on a frozen last frame.
221
+ const ended = player.addListener('playToEnd', () => {
222
+ if (bubbleShownNow.current)
223
+ stop();
224
+ });
225
+ return () => {
226
+ playingChange.remove();
227
+ statusChange.remove();
228
+ ended.remove();
229
+ };
230
+ }, [player, stop]);
231
+ // The poster's backstop, unless the video failed: then the poster stays rather than a black picture.
232
+ (0, react_1.useEffect)(() => {
233
+ if (videoReady || !videoUrl || status === 'error')
234
+ return;
235
+ const timer = setTimeout(() => setVideoReady(true), POSTER_AT_MOST_MS);
236
+ return () => clearTimeout(timer);
237
+ }, [videoReady, videoUrl, status]);
238
+ const value = (0, react_1.useMemo)(() => ({
239
+ player,
240
+ recording,
241
+ videoUrl,
242
+ videoReady,
243
+ status,
244
+ playing,
245
+ muted,
246
+ pausedByShopper,
247
+ bubbleShown,
248
+ openRecording,
249
+ holdsVideo,
250
+ stop,
251
+ showBubble,
252
+ hideBubble,
253
+ setMuted,
254
+ setPausedByShopper,
255
+ markVideoReady,
256
+ setScreenShowing,
257
+ screenClosed,
258
+ }), [
259
+ player,
260
+ recording,
261
+ videoUrl,
262
+ videoReady,
263
+ status,
264
+ playing,
265
+ muted,
266
+ pausedByShopper,
267
+ bubbleShown,
268
+ openRecording,
269
+ holdsVideo,
270
+ stop,
271
+ showBubble,
272
+ hideBubble,
273
+ markVideoReady,
274
+ setScreenShowing,
275
+ screenClosed,
276
+ ]);
277
+ return (0, react_1.createElement)(ReplayPlayerContext.Provider, { value }, children);
278
+ }
279
+ //# sourceMappingURL=replayPlayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replayPlayer.js","sourceRoot":"","sources":["../../src/react/replayPlayer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type ShopifyImageTransform } from '../shopifyCommerce';
3
+ import type { LiveSellingConfig, StorageAdapter } from '../types';
4
+ import { type LiveSellingProviderProps } from './LiveSellingProvider';
5
+ import type { LiveSessionProviderProps } from './useLiveSession';
6
+ /**
7
+ * The gateway's config as `ShopifyLiveSellingProvider` takes it: everything but what it builds from
8
+ * sdk-shopify (`identity`, `customerAccountRequest`, `commerce`), with `storage` optional.
9
+ */
10
+ export type ShopifyLiveSellingConfig = Omit<LiveSellingConfig, 'storage' | 'identity' | 'customerAccountRequest' | 'commerce'> & {
11
+ /** Where poll votes, a signed-out shopper's name and the accepted terms are kept. Default: AsyncStorage. */
12
+ storage?: StorageAdapter;
13
+ };
14
+ export interface ShopifyLiveSellingProviderProps extends Omit<LiveSellingProviderProps, 'config' | 'viewerEmail'> {
15
+ /**
16
+ * The gateway (`apiUrl`, `companyId`, `videoCollectionId`, `zegoAppId`…), `haptics` and `hiddenShows`
17
+ * (`REHEARSALS` for the Apptile team's practice shows). Read when the provider mounts and when one
18
+ * of these props changes; the client itself reconfigures only when `apiUrl`, `companyId` or
19
+ * `videoCollectionId` does.
20
+ */
21
+ config: ShopifyLiveSellingConfig;
22
+ /** `source_name` on the wins cart: which app the order came from (`createShopifyLiveCommerce`'s `cartSourceName`). */
23
+ cartSourceName: string;
24
+ /**
25
+ * The line attribute that marks a prize in the wins cart (`GIVEAWAY_PRIZE_KEY` on the Tile apps'
26
+ * stores). No default, as `createShopifyLiveCommerce` has none: a wrong key gets the prize charged.
27
+ */
28
+ prizeWriteKey: string;
29
+ /** The products' photo size. Default: sdk-shopify's `CARD_IMAGE`, the product cards' size. */
30
+ imageTransform?: ShopifyImageTransform;
31
+ }
32
+ /**
33
+ * `LiveSellingProvider` on the app's sdk-shopify client and customer (the README's §4 "On Shopify"):
34
+ * products from Shopify at the card photo size; the wins checkout, a cart of its own (a won lot stamped
35
+ * `_winningBid`, a prize `prizeWriteKey`) with `source_name`, `source_type: "auction"` and `auction_id`
36
+ * for the order webhook; and the bidder, the customer's numeric id, only for a Shopify sign-in (the
37
+ * winner's record is on the Customer Account API). The phone's storage keeps the poll votes, a
38
+ * signed-out shopper's name and the accepted terms across relaunches. Hidden shows (`hiddenShows`) are
39
+ * hidden from every shopper whose email isn't the team's: the signed-in customer's email is the
40
+ * provider's `viewerEmail`, so a sign-in reaches every screen at once.
41
+ *
42
+ * Mount it inside sdk-shopify's `ShopifyProvider`, above the navigator. `routes`, `track`, `onWarning`
43
+ * and `shopName` pass through to `LiveSellingProvider`.
44
+ */
45
+ export declare function ShopifyLiveSellingProvider({ children, config, cartSourceName, prizeWriteKey, imageTransform, ...pageProps }: ShopifyLiveSellingProviderProps): import("react").FunctionComponentElement<LiveSellingProviderProps>;
46
+ export interface ShopifyLiveSessionProviderProps extends Omit<LiveSessionProviderProps, 'viewerName' | 'children'> {
47
+ children: ReactNode;
48
+ }
49
+ /**
50
+ * The app's one live session (`LiveSessionProvider`; decided 2026-10-05 by amore-v2's Head of
51
+ * Engineering: joined app-wide, as Freckled Poppy). Mount it above the navigator, inside
52
+ * `ShopifyLiveSellingProvider`, because Zego's engine holds exactly one room and several places show
53
+ * the same show: the Live tab's card, the Live screen and the bubble. Each binds to the picture with
54
+ * `LiveVideoTarget`; none owns the room.
55
+ *
56
+ * - **`viewerName`** is the signed-in shopper's (`viewerNameFor`: first and last name, else whichever
57
+ * the account has; never an email nor its part before the @), so a name edited on Account reaches the
58
+ * room without a restart. Null with no name on the account, or signed out, so a name the shopper typed
59
+ * on this phone stays in charge (the comment box asks for one: `useLivePage`'s chat).
60
+ * - **`blockedNames`** passes through: the names nobody watching may go by (Host and Moderator unless
61
+ * the app says otherwise).
62
+ * - **`onPipRestore`**: the phone's picture-in-picture window, opened from the Live screen and then
63
+ * expanded (or, on iOS, left up when the shopper came back by the app's icon), comes back to the Live
64
+ * screen (`routes.openLive`). A window opened from the bubble goes back to the bubble instead, which
65
+ * the session does itself without calling this. An `onPipRestore` of the app's own replaces it.
66
+ */
67
+ export declare function ShopifyLiveSessionProvider({ children, onPipRestore, ...props }: ShopifyLiveSessionProviderProps): import("react").FunctionComponentElement<LiveSessionProviderProps>;
68
+ //# sourceMappingURL=shopifyProviders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shopifyProviders.d.ts","sourceRoot":"","sources":["../../src/react/shopifyProviders.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAA6B,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAG3F,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,EAA2C,KAAK,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAE/G,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAEjE;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,UAAU,GAAG,wBAAwB,GAAG,UAAU,CAAC,GAAG;IAC/H,4GAA4G;IAC5G,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,+BAAgC,SAAQ,IAAI,CAAC,wBAAwB,EAAE,QAAQ,GAAG,aAAa,CAAC;IAC/G;;;;;OAKG;IACH,MAAM,EAAE,wBAAwB,CAAC;IACjC,sHAAsH;IACtH,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,cAAc,CAAC,EAAE,qBAAqB,CAAC;CACxC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,QAAQ,EACR,MAAM,EACN,cAAc,EACd,aAAa,EACb,cAA2B,EAC3B,GAAG,SAAS,EACb,EAAE,+BAA+B,sEA4BjC;AAED,MAAM,WAAW,+BAAgC,SAAQ,IAAI,CAAC,wBAAwB,EAAE,YAAY,GAAG,UAAU,CAAC;IAChH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,EAAE,+BAA+B,sEAiB/G"}