@ticketlayer/live 0.2.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 (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +198 -0
  3. package/dist/auto.d.ts +31 -0
  4. package/dist/auto.d.ts.map +1 -0
  5. package/dist/auto.js +78 -0
  6. package/dist/auto.js.map +1 -0
  7. package/dist/client.d.ts +538 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +495 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/clientHeader.d.ts +4 -0
  12. package/dist/clientHeader.d.ts.map +1 -0
  13. package/dist/clientHeader.js +25 -0
  14. package/dist/clientHeader.js.map +1 -0
  15. package/dist/core/liveClient.d.ts +176 -0
  16. package/dist/core/liveClient.d.ts.map +1 -0
  17. package/dist/core/liveClient.js +372 -0
  18. package/dist/core/liveClient.js.map +1 -0
  19. package/dist/createLiveClient.d.ts +49 -0
  20. package/dist/createLiveClient.d.ts.map +1 -0
  21. package/dist/createLiveClient.js +91 -0
  22. package/dist/createLiveClient.js.map +1 -0
  23. package/dist/elements.d.ts +88 -0
  24. package/dist/elements.d.ts.map +1 -0
  25. package/dist/elements.js +165 -0
  26. package/dist/elements.js.map +1 -0
  27. package/dist/generated/types.d.ts +6110 -0
  28. package/dist/generated/types.d.ts.map +1 -0
  29. package/dist/generated/types.js +6 -0
  30. package/dist/generated/types.js.map +1 -0
  31. package/dist/index.d.ts +35 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +18 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/native/asyncStorageStorage.d.ts +24 -0
  36. package/dist/native/asyncStorageStorage.d.ts.map +1 -0
  37. package/dist/native/asyncStorageStorage.js +24 -0
  38. package/dist/native/asyncStorageStorage.js.map +1 -0
  39. package/dist/native/checkoutUrl.d.ts +85 -0
  40. package/dist/native/checkoutUrl.d.ts.map +1 -0
  41. package/dist/native/checkoutUrl.js +147 -0
  42. package/dist/native/checkoutUrl.js.map +1 -0
  43. package/dist/native/index.d.ts +119 -0
  44. package/dist/native/index.d.ts.map +1 -0
  45. package/dist/native/index.js +145 -0
  46. package/dist/native/index.js.map +1 -0
  47. package/dist/native/secureStoreStorage.d.ts +33 -0
  48. package/dist/native/secureStoreStorage.d.ts.map +1 -0
  49. package/dist/native/secureStoreStorage.js +39 -0
  50. package/dist/native/secureStoreStorage.js.map +1 -0
  51. package/dist/native/storage.d.ts +29 -0
  52. package/dist/native/storage.d.ts.map +1 -0
  53. package/dist/native/storage.js +24 -0
  54. package/dist/native/storage.js.map +1 -0
  55. package/dist/server.d.ts +95 -0
  56. package/dist/server.d.ts.map +1 -0
  57. package/dist/server.js +188 -0
  58. package/dist/server.js.map +1 -0
  59. package/dist/state/buyModal.d.ts +24 -0
  60. package/dist/state/buyModal.d.ts.map +1 -0
  61. package/dist/state/buyModal.js +56 -0
  62. package/dist/state/buyModal.js.map +1 -0
  63. package/dist/state/checkoutModal.d.ts +26 -0
  64. package/dist/state/checkoutModal.d.ts.map +1 -0
  65. package/dist/state/checkoutModal.js +126 -0
  66. package/dist/state/checkoutModal.js.map +1 -0
  67. package/dist/state/emitter.d.ts +21 -0
  68. package/dist/state/emitter.d.ts.map +1 -0
  69. package/dist/state/emitter.js +26 -0
  70. package/dist/state/emitter.js.map +1 -0
  71. package/dist/state/loadElements.d.ts +8 -0
  72. package/dist/state/loadElements.d.ts.map +1 -0
  73. package/dist/state/loadElements.js +39 -0
  74. package/dist/state/loadElements.js.map +1 -0
  75. package/dist/state/registry.d.ts +39 -0
  76. package/dist/state/registry.d.ts.map +1 -0
  77. package/dist/state/registry.js +65 -0
  78. package/dist/state/registry.js.map +1 -0
  79. package/dist/state/theme.d.ts +20 -0
  80. package/dist/state/theme.d.ts.map +1 -0
  81. package/dist/state/theme.js +47 -0
  82. package/dist/state/theme.js.map +1 -0
  83. package/dist/ticketlayer.js +5 -0
  84. package/dist/ticketlayer.js.map +7 -0
  85. package/dist/version.d.ts +7 -0
  86. package/dist/version.d.ts.map +1 -0
  87. package/dist/version.js +7 -0
  88. package/dist/version.js.map +1 -0
  89. package/package.json +80 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @ticketlayer/live/server - catalogue reads for server-side rendering.
3
+ *
4
+ * A stateless client for Node/edge runtimes (Next.js server components, route
5
+ * handlers, build-time data fetching): no DOM, no window guards, no Elements,
6
+ * no token storage. It reads the channel catalogue (listings, event detail,
7
+ * theme) with plain fetch and a small in-memory TTL cache that callers can
8
+ * disable.
9
+ *
10
+ * Credentials, one of:
11
+ * - `publishableKey` / `channelKey` (embed style): sent as `Authorization:
12
+ * Bearer tlpk_...` on every read. No session is created.
13
+ * - `domain` (hosted style): the channel's publishable key is resolved ONCE
14
+ * via `GET /channel?domain=...` and cached; reads then use it as above.
15
+ *
16
+ * `session.create()` is available for callers that need a Live session id (for
17
+ * example to hand off to a WebView checkout); catalogue reads never need one.
18
+ *
19
+ * Nothing here is imported by the browser entry (src/index.ts) or the CDN
20
+ * build (src/auto.ts), so the browser bundle is unchanged by this module.
21
+ */
22
+ import { LiveAPIError } from './client.js';
23
+ import type { components } from './generated/types.js';
24
+ type Schemas = components['schemas'];
25
+ export type Listing = Schemas['SalesListing'];
26
+ export type EventDetail = Schemas['SalesEventDetailResponse']['event'];
27
+ export type Theme = Schemas['Theme'];
28
+ export type ChannelSummary = Schemas['SalesChannelSummary'];
29
+ export { LiveAPIError };
30
+ /** Minimal fetch signature so callers can inject their own (Next, undici, a mock). */
31
+ export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
32
+ export interface ServerCacheOptions {
33
+ /** How long a successful read is served from memory. Default 60s. */
34
+ ttlMs?: number;
35
+ }
36
+ export interface ServerClientOptions {
37
+ /** Base URL of the Live API (server-side/internal host is fine). */
38
+ apiUrl: string;
39
+ /** Embed style: the channel publishable key (tlpk_...). */
40
+ publishableKey?: string;
41
+ /** Alias of publishableKey, matching the /session body field name. */
42
+ channelKey?: string;
43
+ /** Hosted style: resolve the channel by storefront domain instead of a key. */
44
+ domain?: string;
45
+ /** fetch implementation; defaults to the global fetch (Node 18+). */
46
+ fetch?: FetchLike;
47
+ /** In-memory response cache. `false` disables it. Default: 60s TTL. */
48
+ cache?: false | ServerCacheOptions;
49
+ /** How long a domain-resolved publishable key is kept. Default 10 minutes. */
50
+ credentialTtlMs?: number;
51
+ /** Override the dated API version sent as TL-Version. */
52
+ apiVersion?: string;
53
+ /** RequestInit merged into every request (headers are merged, not replaced). */
54
+ requestInit?: RequestInit;
55
+ }
56
+ export interface ServerRequestOptions {
57
+ /**
58
+ * RequestInit merged into this one request - e.g. Next's
59
+ * `{ next: { revalidate: 300, tags: ['events'] } }`.
60
+ */
61
+ fetchInit?: RequestInit;
62
+ /** Bypass the in-memory cache for this call (still stores the result). */
63
+ noCache?: boolean;
64
+ }
65
+ export interface ServerSession {
66
+ sessionToken: string;
67
+ channel: {
68
+ id: string;
69
+ name?: string;
70
+ slug?: string;
71
+ };
72
+ customer: unknown | null;
73
+ }
74
+ export interface ServerClient {
75
+ events: {
76
+ /** The channel's active listings (event card summaries). */
77
+ list(opts?: ServerRequestOptions): Promise<Listing[]>;
78
+ /** One storefront event detail. Throws LiveAPIError (404) when not listed. */
79
+ get(eventId: string, opts?: ServerRequestOptions): Promise<EventDetail>;
80
+ };
81
+ theme: {
82
+ /** The channel's resolved theme. Throws LiveAPIError (404) when none is assigned. */
83
+ get(opts?: ServerRequestOptions): Promise<Theme>;
84
+ };
85
+ session: {
86
+ /** Mint a Live session for this channel (POST /session). Never cached. */
87
+ create(opts?: ServerRequestOptions): Promise<ServerSession>;
88
+ };
89
+ /** GET any Live path and return the unwrapped JSend `data`. Cached like the reads above. */
90
+ get<T>(path: string, opts?: ServerRequestOptions): Promise<T>;
91
+ /** Drop every cached response (and the domain-resolved credential). */
92
+ clearCache(): void;
93
+ }
94
+ export declare function createServerClient(options: ServerClientOptions): ServerClient;
95
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js ADDED
@@ -0,0 +1,188 @@
1
+ /**
2
+ * @ticketlayer/live/server - catalogue reads for server-side rendering.
3
+ *
4
+ * A stateless client for Node/edge runtimes (Next.js server components, route
5
+ * handlers, build-time data fetching): no DOM, no window guards, no Elements,
6
+ * no token storage. It reads the channel catalogue (listings, event detail,
7
+ * theme) with plain fetch and a small in-memory TTL cache that callers can
8
+ * disable.
9
+ *
10
+ * Credentials, one of:
11
+ * - `publishableKey` / `channelKey` (embed style): sent as `Authorization:
12
+ * Bearer tlpk_...` on every read. No session is created.
13
+ * - `domain` (hosted style): the channel's publishable key is resolved ONCE
14
+ * via `GET /channel?domain=...` and cached; reads then use it as above.
15
+ *
16
+ * `session.create()` is available for callers that need a Live session id (for
17
+ * example to hand off to a WebView checkout); catalogue reads never need one.
18
+ *
19
+ * Nothing here is imported by the browser entry (src/index.ts) or the CDN
20
+ * build (src/auto.ts), so the browser bundle is unchanged by this module.
21
+ */
22
+ import { LiveAPIError, API_DATED_VERSION } from './client.js';
23
+ import { SDK_CLIENT_HEADER } from './clientHeader.js';
24
+ export { LiveAPIError };
25
+ const DEFAULT_CACHE_TTL_MS = 60 * 1000;
26
+ const DEFAULT_CREDENTIAL_TTL_MS = 10 * 60 * 1000;
27
+ /** Tiny promise cache: concurrent callers share one in-flight request. */
28
+ class TtlCache {
29
+ constructor(ttlMs) {
30
+ this.ttlMs = ttlMs;
31
+ this.entries = new Map();
32
+ }
33
+ get(key) {
34
+ const hit = this.entries.get(key);
35
+ if (!hit)
36
+ return undefined;
37
+ if (hit.expiresAt <= Date.now()) {
38
+ this.entries.delete(key);
39
+ return undefined;
40
+ }
41
+ return hit.value;
42
+ }
43
+ set(key, value) {
44
+ this.entries.set(key, { value, expiresAt: Date.now() + this.ttlMs });
45
+ // A failed read must not be served from cache.
46
+ value.catch(() => this.entries.delete(key));
47
+ return value;
48
+ }
49
+ clear() {
50
+ this.entries.clear();
51
+ }
52
+ }
53
+ function mergeInit(base, extra) {
54
+ if (!base)
55
+ return extra ?? {};
56
+ if (!extra)
57
+ return base;
58
+ const headers = { ...toHeaderRecord(base.headers), ...toHeaderRecord(extra.headers) };
59
+ return { ...base, ...extra, headers };
60
+ }
61
+ function toHeaderRecord(headers) {
62
+ const out = {};
63
+ if (!headers)
64
+ return out;
65
+ new Headers(headers).forEach((value, key) => {
66
+ out[key] = value;
67
+ });
68
+ return out;
69
+ }
70
+ /** Parse a Live response: unwrap JSend `data`, or throw LiveAPIError. */
71
+ async function readJson(response, path) {
72
+ const text = await response.text();
73
+ let json = null;
74
+ try {
75
+ json = text ? JSON.parse(text) : null;
76
+ }
77
+ catch {
78
+ json = null;
79
+ }
80
+ if (!response.ok) {
81
+ throw new LiveAPIError(json?.error?.message ?? `Request failed (${response.status}) for ${path}`, json?.error?.code ?? 'REQUEST_FAILED', response.status);
82
+ }
83
+ if (json && json.status === 'success' && json.data !== undefined)
84
+ return json.data;
85
+ return json;
86
+ }
87
+ export function createServerClient(options) {
88
+ const apiUrl = options.apiUrl.replace(/\/$/, '');
89
+ const fetchImpl = options.fetch ??
90
+ ((input, init) => {
91
+ if (typeof fetch !== 'function') {
92
+ throw new Error('[live/server] No fetch available - pass one in createServerClient({ fetch })');
93
+ }
94
+ return fetch(input, init);
95
+ });
96
+ const apiVersion = options.apiVersion ?? API_DATED_VERSION;
97
+ const fixedKey = options.publishableKey ?? options.channelKey;
98
+ const domain = options.domain;
99
+ if (!fixedKey && !domain) {
100
+ throw new Error('[live/server] createServerClient needs a publishableKey/channelKey or a domain');
101
+ }
102
+ const cache = options.cache === false ? null : new TtlCache(options.cache?.ttlMs ?? DEFAULT_CACHE_TTL_MS);
103
+ const credentialTtlMs = options.credentialTtlMs ?? DEFAULT_CREDENTIAL_TTL_MS;
104
+ // Domain mode: the resolved publishable key, cached with its own TTL.
105
+ let resolvedKey = null;
106
+ const baseHeaders = () => ({
107
+ Accept: 'application/json',
108
+ 'TL-Version': apiVersion,
109
+ 'TL-Client': SDK_CLIENT_HEADER,
110
+ });
111
+ const resolveKey = (force = false) => {
112
+ if (fixedKey)
113
+ return Promise.resolve(fixedKey);
114
+ if (!force && resolvedKey && resolvedKey.expiresAt > Date.now())
115
+ return resolvedKey.value;
116
+ const value = (async () => {
117
+ const path = `/channel?domain=${encodeURIComponent(domain)}`;
118
+ const res = await fetchImpl(`${apiUrl}${path}`, mergeInit(options.requestInit, { method: 'GET', headers: baseHeaders() }));
119
+ const data = await readJson(res, path);
120
+ if (!data?.publishableKey) {
121
+ throw new LiveAPIError(`No publishable key for domain ${domain}`, 'CHANNEL_NOT_FOUND', 404);
122
+ }
123
+ return data.publishableKey;
124
+ })();
125
+ resolvedKey = { value, expiresAt: Date.now() + credentialTtlMs };
126
+ value.catch(() => {
127
+ resolvedKey = null;
128
+ });
129
+ return value;
130
+ };
131
+ const fetchPath = async (path, opts) => {
132
+ const attempt = async (key) => fetchImpl(`${apiUrl}${path}`, mergeInit(mergeInit(options.requestInit, {
133
+ method: 'GET',
134
+ headers: { ...baseHeaders(), Authorization: `Bearer ${key}` },
135
+ }), opts?.fetchInit));
136
+ let res = await attempt(await resolveKey());
137
+ // A domain-resolved key can be rotated under us; refresh it once.
138
+ if (res.status === 401 && !fixedKey) {
139
+ res = await attempt(await resolveKey(true));
140
+ }
141
+ return readJson(res, path);
142
+ };
143
+ const get = (path, opts) => {
144
+ if (!cache)
145
+ return fetchPath(path, opts);
146
+ if (!opts?.noCache) {
147
+ const hit = cache.get(path);
148
+ if (hit)
149
+ return hit;
150
+ }
151
+ return cache.set(path, fetchPath(path, opts));
152
+ };
153
+ return {
154
+ events: {
155
+ list: async (opts) => {
156
+ const data = await get('/sales/listings', opts);
157
+ return data?.listings ?? [];
158
+ },
159
+ get: async (eventId, opts) => {
160
+ const data = await get(`/sales/events/${encodeURIComponent(eventId)}`, opts);
161
+ return data.event;
162
+ },
163
+ },
164
+ theme: {
165
+ get: async (opts) => {
166
+ const data = await get('/sales/theme', opts);
167
+ return data.theme;
168
+ },
169
+ },
170
+ session: {
171
+ create: async (opts) => {
172
+ const body = fixedKey ? { channelKey: fixedKey } : { domain };
173
+ const res = await fetchImpl(`${apiUrl}/session`, mergeInit(mergeInit(options.requestInit, {
174
+ method: 'POST',
175
+ headers: { ...baseHeaders(), 'Content-Type': 'application/json' },
176
+ body: JSON.stringify(body),
177
+ }), opts?.fetchInit));
178
+ return readJson(res, '/session');
179
+ },
180
+ },
181
+ get,
182
+ clearCache: () => {
183
+ cache?.clear();
184
+ resolvedKey = null;
185
+ },
186
+ };
187
+ }
188
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Buy-tickets modal manager (in-page, native Elements).
3
+ *
4
+ * The buy funnel (occurrence → ticket selection → add to cart) is pure
5
+ * browse/cart with no PCI surface, so - unlike checkout - it does NOT need a
6
+ * cross-origin iframe. This manager simply mounts the `<tl-buy-modal>` Element
7
+ * on demand when something emits `ui:event-modal-requested` (a
8
+ * `tl-buy-tickets-button`, a calendar date click, etc.) and removes it on close.
9
+ * Because the modal is a normal Element bound to the same `window.Ticketlayer`,
10
+ * it works identically on HBO and on any third-party embed.
11
+ *
12
+ * When the user proceeds to checkout, the manager hands the funnel over by
13
+ * re-emitting `ui:checkout-requested` (forwarding the original caller's
14
+ * callbacks): on a third-party embed the checkout modal opens the hosted
15
+ * checkout in an iframe; on HBO the host navigates to /checkout in-page.
16
+ */
17
+ import type { TicketlayerLive } from '../createLiveClient.js';
18
+ export interface BuyModalOptions {
19
+ /** Override the custom-element tag (default `tl-buy-modal`). */
20
+ tag?: string;
21
+ }
22
+ /** Wire the buy modal to the bus; returns an uninstall function. */
23
+ export declare function installBuyModal(tl: TicketlayerLive, opts?: BuyModalOptions): () => void;
24
+ //# sourceMappingURL=buyModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buyModal.d.ts","sourceRoot":"","sources":["../../src/state/buyModal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAUD,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,EAAE,EAAE,eAAe,EAAE,IAAI,GAAE,eAAoB,GAAG,MAAM,IAAI,CA6D3F"}
@@ -0,0 +1,56 @@
1
+ /** Wire the buy modal to the bus; returns an uninstall function. */
2
+ export function installBuyModal(tl, opts = {}) {
3
+ if (typeof window === 'undefined' || typeof document === 'undefined')
4
+ return () => { };
5
+ const TAG = opts.tag || 'tl-buy-modal';
6
+ let el = null;
7
+ let current = null;
8
+ const remove = () => {
9
+ if (el) {
10
+ el.remove();
11
+ el = null;
12
+ }
13
+ current = null;
14
+ };
15
+ const open = (intent) => {
16
+ if (!intent?.eventId)
17
+ return;
18
+ remove();
19
+ current = intent;
20
+ const node = document.createElement(TAG);
21
+ // Set as attributes (strings) so they apply before the element upgrades.
22
+ node.setAttribute('event-id', intent.eventId);
23
+ if (intent.occurrenceId)
24
+ node.setAttribute('occurrence-id', intent.occurrenceId);
25
+ node.addEventListener('tlClose', () => {
26
+ const i = current;
27
+ remove();
28
+ i?.onClose?.();
29
+ });
30
+ node.addEventListener('tlError', (e) => {
31
+ const message = e.detail?.message || 'Could not load this event';
32
+ current?.onError?.(new Error(message));
33
+ });
34
+ node.addEventListener('tlCheckout', () => {
35
+ const i = current;
36
+ remove();
37
+ // Hand off to the checkout intent, forwarding the caller's callbacks so a
38
+ // third-party site's onComplete still fires when the order completes.
39
+ tl.emit('ui:checkout-requested', {
40
+ onComplete: i?.onComplete,
41
+ onError: i?.onError,
42
+ onClose: i?.onClose,
43
+ });
44
+ });
45
+ document.body.appendChild(node);
46
+ el = node;
47
+ };
48
+ const offOpen = tl.on('ui:event-modal-requested', (p) => open(p ?? {}));
49
+ const offClose = tl.on('ui:modal-close-requested', () => remove());
50
+ return () => {
51
+ offOpen();
52
+ offClose();
53
+ remove();
54
+ };
55
+ }
56
+ //# sourceMappingURL=buyModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buyModal.js","sourceRoot":"","sources":["../../src/state/buyModal.ts"],"names":[],"mappings":"AA+BA,oEAAoE;AACpE,MAAM,UAAU,eAAe,CAAC,EAAmB,EAAE,OAAwB,EAAE;IAC7E,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAEtF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,cAAc,CAAC;IACvC,IAAI,EAAE,GAAuB,IAAI,CAAC;IAClC,IAAI,OAAO,GAAqB,IAAI,CAAC;IAErC,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,IAAI,EAAE,EAAE,CAAC;YACP,EAAE,CAAC,MAAM,EAAE,CAAC;YACZ,EAAE,GAAG,IAAI,CAAC;QACZ,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,CAAC,MAAiB,EAAE,EAAE;QACjC,IAAI,CAAC,MAAM,EAAE,OAAO;YAAE,OAAO;QAC7B,MAAM,EAAE,CAAC;QACT,OAAO,GAAG,MAAM,CAAC;QAEjB,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACzC,yEAAyE;QACzE,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,YAAY;YAAE,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QAEjF,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE;YACpC,MAAM,CAAC,GAAG,OAAO,CAAC;YAClB,MAAM,EAAE,CAAC;YACT,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAQ,EAAE,EAAE;YAC5C,MAAM,OAAO,GACV,CAAuC,CAAC,MAAM,EAAE,OAAO,IAAI,2BAA2B,CAAC;YAC1F,OAAO,EAAE,OAAO,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;YACvC,MAAM,CAAC,GAAG,OAAO,CAAC;YAClB,MAAM,EAAE,CAAC;YACT,0EAA0E;YAC1E,sEAAsE;YACtE,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE;gBAC/B,UAAU,EAAE,CAAC,EAAE,UAAU;gBACzB,OAAO,EAAE,CAAC,EAAE,OAAO;gBACnB,OAAO,EAAE,CAAC,EAAE,OAAO;aACpB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAChC,EAAE,GAAG,IAAI,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,0BAA0B,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAE,CAAe,IAAK,EAAgB,CAAC,CAAC,CAAC;IACtG,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAEnE,OAAO,GAAG,EAAE;QACV,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,CAAC;IACX,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Checkout modal manager (third-party embeds).
3
+ *
4
+ * On a third-party site, Elements build the cart in-page and emit
5
+ * `ui:checkout-requested`. This opens the hosted checkout in an iframe overlay
6
+ * pointing at HBO's `/embed/checkout`, handing off the current session token so
7
+ * the iframe sees the same cart (and so card data stays on HBO's origin - PCI
8
+ * isolation). It bridges the `tl:*` postMessage protocol back to the caller's
9
+ * onComplete/onError/onClose callbacks (which rode in on the intent payload).
10
+ *
11
+ * The iframe URL carries `parent_origin=<this page's origin>` so HBO can pin
12
+ * its postMessage target to us (it never posts to '*'), and incoming messages
13
+ * are only accepted from the checkout's own origin. The message set is
14
+ * documented in HBO's docs/embed-checkout-contract.md.
15
+ *
16
+ * HBO itself does NOT use this - it handles `ui:checkout-requested` by
17
+ * navigating in-page to /checkout.
18
+ */
19
+ import type { TicketlayerLive } from '../createLiveClient.js';
20
+ export interface CheckoutModalOptions {
21
+ /** Base URL of the HBO instance serving /embed/checkout. Defaults to origin. */
22
+ embedBaseUrl?: string;
23
+ }
24
+ /** Wire the modal to the bus; returns an uninstall function. */
25
+ export declare function installCheckoutModal(tl: TicketlayerLive, opts?: CheckoutModalOptions): () => void;
26
+ //# sourceMappingURL=checkoutModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkoutModal.d.ts","sourceRoot":"","sources":["../../src/state/checkoutModal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA2CD,gEAAgE;AAChE,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,eAAe,EACnB,IAAI,GAAE,oBAAyB,GAC9B,MAAM,IAAI,CAqHZ"}
@@ -0,0 +1,126 @@
1
+ const OVERLAY_ID = 'tl-checkout-overlay';
2
+ const PRIVACY_URL = 'https://ticketlayer.com/privacy';
3
+ const REPORT_URL = 'https://ticketlayer.com/report-abuse';
4
+ const SITE_URL = 'https://ticketlayer.com';
5
+ /** Floating-chrome markup: platform links (left) + Powered by Ticketlayer (right). */
6
+ function footerHtml() {
7
+ const logo = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true" style="display:block;">' +
8
+ '<path d="M4 7.5A1.5 1.5 0 0 1 5.5 6h13A1.5 1.5 0 0 1 20 7.5v2a2 2 0 0 0 0 5v2a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 4 16.5v-2a2 2 0 0 0 0-5v-2Z" fill="currentColor"/>' +
9
+ '<path d="M13 7v10" stroke="rgba(255,255,255,0.5)" stroke-width="1.2" stroke-dasharray="1.5 1.8" stroke-linecap="round"/></svg>';
10
+ const link = (href, label) => `<a href="${href}" target="_blank" rel="noopener noreferrer" style="color:inherit;text-decoration:none;opacity:0.85;">${label}</a>`;
11
+ return (`<div style="display:flex;gap:16px;align-items:center;">${link(PRIVACY_URL, 'Privacy Policy')}${link(REPORT_URL, 'Report Abuse')}</div>` +
12
+ `<a href="${SITE_URL}" target="_blank" rel="noopener noreferrer" style="color:inherit;text-decoration:none;display:inline-flex;align-items:center;gap:6px;opacity:0.92;">` +
13
+ `<span style="opacity:0.7;">Powered by</span>${logo}<span style="font-weight:700;letter-spacing:0.01em;">Ticketlayer</span></a>`);
14
+ }
15
+ /** Wire the modal to the bus; returns an uninstall function. */
16
+ export function installCheckoutModal(tl, opts = {}) {
17
+ if (typeof window === 'undefined' || typeof document === 'undefined')
18
+ return () => { };
19
+ let onMessage = null;
20
+ const close = () => {
21
+ document.getElementById(OVERLAY_ID)?.remove();
22
+ if (onMessage) {
23
+ window.removeEventListener('message', onMessage);
24
+ onMessage = null;
25
+ }
26
+ };
27
+ const open = async (intent) => {
28
+ const token = await tl.getSessionToken().catch(() => null);
29
+ const base = (opts.embedBaseUrl || window.location.origin).replace(/\/$/, '');
30
+ const query = new URLSearchParams();
31
+ if (token)
32
+ query.set('session', token);
33
+ // Lets HBO pin its postMessage target origin to this page.
34
+ query.set('parent_origin', window.location.origin);
35
+ const url = `${base}/embed/checkout?${query.toString()}`;
36
+ const frameOrigin = new URL(url).origin;
37
+ close();
38
+ const overlay = document.createElement('div');
39
+ overlay.id = OVERLAY_ID;
40
+ // Blurred, dimmed backdrop so the underlying site recedes behind the modal.
41
+ overlay.style.cssText =
42
+ 'position:fixed;inset:0;z-index:2147483647;background:rgba(15,23,42,0.55);' +
43
+ 'backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);' +
44
+ 'display:flex;flex-direction:column;align-items:center;justify-content:center;' +
45
+ 'gap:12px;padding:16px;';
46
+ // Column wrapper: the modal panel + a floating chrome footer beneath it.
47
+ const wrapper = document.createElement('div');
48
+ wrapper.style.cssText =
49
+ 'width:100%;max-width:960px;display:flex;flex-direction:column;gap:10px;';
50
+ const frame = document.createElement('iframe');
51
+ frame.src = url;
52
+ frame.allow = 'payment';
53
+ // Wide enough for the two-column checkout (form left, order summary right);
54
+ // the embedded page stacks to one column on narrow viewports. Subtle theme
55
+ // border (matches the buy-tickets modal) + a soft lift off the backdrop.
56
+ frame.style.cssText =
57
+ 'width:100%;height:88vh;max-height:760px;border:1px solid var(--tl-border,#e5e7eb);' +
58
+ 'border-radius:16px;background:#fff;box-shadow:0 24px 64px rgba(0,0,0,0.45);';
59
+ // Floating chrome: platform links far-left, "Powered by Ticketlayer" far-right.
60
+ const footer = document.createElement('div');
61
+ footer.style.cssText =
62
+ 'display:flex;align-items:center;justify-content:space-between;gap:12px;' +
63
+ 'padding:0 8px;font:500 12px/1.4 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;' +
64
+ 'color:rgba(255,255,255,0.78);';
65
+ footer.innerHTML = footerHtml();
66
+ wrapper.appendChild(frame);
67
+ wrapper.appendChild(footer);
68
+ overlay.appendChild(wrapper);
69
+ overlay.addEventListener('click', (e) => {
70
+ if (e.target === overlay || e.target === wrapper) {
71
+ close();
72
+ intent.onClose?.();
73
+ }
74
+ });
75
+ document.body.appendChild(overlay);
76
+ onMessage = (e) => {
77
+ // Only the checkout page's own origin may drive the modal.
78
+ if (e.origin !== frameOrigin)
79
+ return;
80
+ const msg = e.data;
81
+ if (!msg || typeof msg !== 'object')
82
+ return;
83
+ switch (msg.type) {
84
+ case 'tl:complete': {
85
+ // v1 carries orderId/orderReference/accessToken at the top level and
86
+ // keeps the pre-v1 `order` object; merge so both shapes are served.
87
+ const legacy = (msg.order && typeof msg.order === 'object' ? msg.order : {});
88
+ const order = msg.orderId
89
+ ? {
90
+ ...legacy,
91
+ id: msg.orderId,
92
+ orderNumber: msg.orderReference,
93
+ ...(msg.accessToken ? { accessToken: msg.accessToken } : {}),
94
+ }
95
+ : msg.order;
96
+ intent.onComplete?.(order);
97
+ tl.emit('checkout:completed', order);
98
+ close();
99
+ break;
100
+ }
101
+ case 'tl:close':
102
+ case 'tl:cancel':
103
+ intent.onClose?.();
104
+ close();
105
+ break;
106
+ case 'tl:error': {
107
+ const err = new Error(msg.message || msg.code || 'Checkout failed');
108
+ if (msg.code)
109
+ err.code = msg.code;
110
+ intent.onError?.(err);
111
+ break;
112
+ }
113
+ // tl:ready and tl:height are informational; the overlay has a fixed size.
114
+ }
115
+ };
116
+ window.addEventListener('message', onMessage);
117
+ };
118
+ const offCheckout = tl.on('ui:checkout-requested', (p) => void open(p ?? {}));
119
+ const offClose = tl.on('ui:modal-close-requested', () => close());
120
+ return () => {
121
+ offCheckout();
122
+ offClose();
123
+ close();
124
+ };
125
+ }
126
+ //# sourceMappingURL=checkoutModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkoutModal.js","sourceRoot":"","sources":["../../src/state/checkoutModal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Bidirectional event bus shared by the SDK, Elements, and the host app.
3
+ *
4
+ * Two directions:
5
+ * - STATE events the SDK pushes OUT so Elements re-render (cart:updated, …).
6
+ * - UI INTENTS Elements/host push IN for someone else to act on
7
+ * (ui:checkout-requested, ui:event-modal-requested, …) - e.g. a
8
+ * tl-buy-tickets-button emits ui:event-modal-requested and HBO opens the
9
+ * modal. The SDK itself doesn't render UI; it just relays.
10
+ */
11
+ export type LiveEvent = 'session:changed' | 'cart:updated' | 'auth:changed' | 'checkout:completed' | 'error' | 'ui:event-modal-requested' | 'ui:checkout-requested' | 'ui:cart-requested' | 'ui:login-requested' | 'ui:modal-close-requested';
12
+ type Handler = (payload?: unknown) => void;
13
+ export declare class Emitter {
14
+ private handlers;
15
+ /** Subscribe; returns an unsubscribe function. */
16
+ on(event: LiveEvent, handler: Handler): () => void;
17
+ off(event: LiveEvent, handler: Handler): void;
18
+ emit(event: LiveEvent, payload?: unknown): void;
19
+ }
20
+ export {};
21
+ //# sourceMappingURL=emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/state/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAEjB,iBAAiB,GACjB,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,OAAO,GAEP,0BAA0B,GAC1B,uBAAuB,GACvB,mBAAmB,GACnB,oBAAoB,GACpB,0BAA0B,CAAC;AAE/B,KAAK,OAAO,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAE3C,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAsC;IAEtD,kDAAkD;IAClD,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,IAAI;IAMlD,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAI7C,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI;CAShD"}
@@ -0,0 +1,26 @@
1
+ export class Emitter {
2
+ constructor() {
3
+ this.handlers = new Map();
4
+ }
5
+ /** Subscribe; returns an unsubscribe function. */
6
+ on(event, handler) {
7
+ if (!this.handlers.has(event))
8
+ this.handlers.set(event, new Set());
9
+ this.handlers.get(event).add(handler);
10
+ return () => this.off(event, handler);
11
+ }
12
+ off(event, handler) {
13
+ this.handlers.get(event)?.delete(handler);
14
+ }
15
+ emit(event, payload) {
16
+ this.handlers.get(event)?.forEach((h) => {
17
+ try {
18
+ h(payload);
19
+ }
20
+ catch (err) {
21
+ console.error(`[live] handler for ${event} threw`, err);
22
+ }
23
+ });
24
+ }
25
+ }
26
+ //# sourceMappingURL=emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/state/emitter.ts"],"names":[],"mappings":"AA0BA,MAAM,OAAO,OAAO;IAApB;QACU,aAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;IAsBxD,CAAC;IApBC,kDAAkD;IAClD,EAAE,CAAC,KAAgB,EAAE,OAAgB;QACnC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,GAAG,CAAC,KAAgB,EAAE,OAAgB;QACpC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,CAAC,KAAgB,EAAE,OAAiB;QACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACtC,IAAI,CAAC;gBACH,CAAC,CAAC,OAAO,CAAC,CAAC;YACb,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,sBAAsB,KAAK,QAAQ,EAAE,GAAG,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ export interface LoadElementsOptions {
2
+ /** Enable runtime injection (default false - most hosts import Elements directly). */
3
+ elements?: boolean;
4
+ /** Override the Elements ESM bundle URL (e.g. a local dist in dev). */
5
+ elementsUrl?: string;
6
+ }
7
+ export declare function loadElements(opts?: LoadElementsOptions): Promise<void>;
8
+ //# sourceMappingURL=loadElements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadElements.d.ts","sourceRoot":"","sources":["../../src/state/loadElements.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,mBAAmB;IAClC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1E"}