@seatlayer/core 0.38.0 → 0.40.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.
- package/dist/index.cjs +75 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -1
- package/dist/index.d.ts +67 -1
- package/dist/index.js +75 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1375,6 +1375,38 @@ interface HoldSelectionRequest {
|
|
|
1375
1375
|
interface BestAvailableResponse extends HoldResponse {
|
|
1376
1376
|
labels: string[];
|
|
1377
1377
|
}
|
|
1378
|
+
/** One unit's status as the realtime wire words it (`free`/`held`/`booked`/`blocked`/…). */
|
|
1379
|
+
interface PickerStatusChange {
|
|
1380
|
+
label: string;
|
|
1381
|
+
status: string;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Where a transport-owned realtime client pushes reconstructed inventory.
|
|
1385
|
+
*
|
|
1386
|
+
* Structurally identical to the SDK's `RealtimeSink` on purpose: this file is
|
|
1387
|
+
* mirrored byte-for-byte into `@seatlayer/core`, which the SDK's `@seatlayer/js`
|
|
1388
|
+
* depends on — so it can never import BuyerRealtimeClient without inverting that
|
|
1389
|
+
* dependency. Structural typing lets the SDK hand its client this object with no
|
|
1390
|
+
* import in either direction.
|
|
1391
|
+
*/
|
|
1392
|
+
interface PickerRealtimeSink {
|
|
1393
|
+
/** Apply a batch of label→status changes as ONE paint pass, not one per label. */
|
|
1394
|
+
applyStatuses(changes: PickerStatusChange[]): void;
|
|
1395
|
+
/** Re-pull authoritative state over HTTP (a frame that cannot be diffed). */
|
|
1396
|
+
resync(): void | Promise<void>;
|
|
1397
|
+
/** Section availability changed (hidden = stripped, closed = greyed). */
|
|
1398
|
+
onSections?(hidden: string[], closed: string[]): void;
|
|
1399
|
+
/** Scope-projected presence counters. Unused by the picker today. */
|
|
1400
|
+
onPresence?(counts: {
|
|
1401
|
+
shoppingSessions: number;
|
|
1402
|
+
activeHolds: number;
|
|
1403
|
+
}): void;
|
|
1404
|
+
}
|
|
1405
|
+
/** The live feed itself, owned by the transport. */
|
|
1406
|
+
interface PickerRealtimeConnection {
|
|
1407
|
+
start(): void;
|
|
1408
|
+
stop(): void;
|
|
1409
|
+
}
|
|
1378
1410
|
/** Swappable public-surface transport (SDK PubApi or a dashboard `api.pub.*` adapter). */
|
|
1379
1411
|
interface PickerTransport {
|
|
1380
1412
|
chart(key: string): Promise<{
|
|
@@ -1413,6 +1445,17 @@ interface PickerTransport {
|
|
|
1413
1445
|
* subscribe ticket via `Sec-WebSocket-Protocol`, realtime-protocol v1).
|
|
1414
1446
|
* Absent or empty means today's plain connection. */
|
|
1415
1447
|
socketProtocols?(key: string): string[];
|
|
1448
|
+
/**
|
|
1449
|
+
* Optional — the transport owns the live feed and hands back a client that
|
|
1450
|
+
* speaks the compact `seatlayer.v1` protocol (snapshot diffing, `sv.<n>`
|
|
1451
|
+
* resume, ping/pong liveness, jittered reconnect).
|
|
1452
|
+
*
|
|
1453
|
+
* When this returns a connection the controller does NOT open its own socket:
|
|
1454
|
+
* one socket client, one reconnect/backoff/resume implementation. Returning
|
|
1455
|
+
* null (or omitting the method) keeps the plain-WebSocket path below, which is
|
|
1456
|
+
* what a transport with no realtime client of its own still gets.
|
|
1457
|
+
*/
|
|
1458
|
+
createRealtime?(key: string, sink: PickerRealtimeSink): PickerRealtimeConnection | null;
|
|
1416
1459
|
}
|
|
1417
1460
|
interface PickerCallbacks extends RendererCallbacks {
|
|
1418
1461
|
/** Selection changed (manual clicks or a server best-available pick). */
|
|
@@ -1509,6 +1552,8 @@ declare class PickerController {
|
|
|
1509
1552
|
private confirmedVariableTables;
|
|
1510
1553
|
private groupedSelectionOverhead;
|
|
1511
1554
|
private ws;
|
|
1555
|
+
/** Transport-owned v1 client; mutually exclusive with `ws`. */
|
|
1556
|
+
private realtime;
|
|
1512
1557
|
private reconnectTimer;
|
|
1513
1558
|
private attempt;
|
|
1514
1559
|
private closed;
|
|
@@ -1813,7 +1858,28 @@ declare class PickerController {
|
|
|
1813
1858
|
*/
|
|
1814
1859
|
private attachVisibilityListener;
|
|
1815
1860
|
private detachVisibilityListener;
|
|
1861
|
+
/**
|
|
1862
|
+
* The sink a transport-owned v1 client pushes into.
|
|
1863
|
+
*
|
|
1864
|
+
* Deliberately byte-compatible with the inline socket handler below: the same
|
|
1865
|
+
* liveStatuses bookkeeping (which the hold-expiry verification reads), the
|
|
1866
|
+
* same one-call-per-status paint, the same free→taken flash rule that skips
|
|
1867
|
+
* the buyer's OWN just-held seats, the same keepLiveWhileHidden forceDraw, the
|
|
1868
|
+
* same clearBookedHoldIfSettled + onStatusChange ordering. Hosts see the same
|
|
1869
|
+
* callbacks in the same order whichever path is live.
|
|
1870
|
+
*/
|
|
1871
|
+
private realtimeSink;
|
|
1872
|
+
/** Paint one delta batch. Shared by the v1 sink and the plain-socket handler. */
|
|
1873
|
+
private applyStatusChanges;
|
|
1816
1874
|
private connect;
|
|
1875
|
+
/**
|
|
1876
|
+
* Backoff for the PLAIN-socket fallback (a transport with no v1 client of its
|
|
1877
|
+
* own). Full jitter, for the same reason BuyerRealtimeClient uses it: a
|
|
1878
|
+
* deterministic `2**attempt` schedule brings every browser that lost the same
|
|
1879
|
+
* socket back in the same millisecond, and an on-sale crowd reconnecting in
|
|
1880
|
+
* lockstep turns one blip into a thundering herd. The ceiling still doubles,
|
|
1881
|
+
* so a sustained outage still backs off.
|
|
1882
|
+
*/
|
|
1817
1883
|
private scheduleReconnect;
|
|
1818
1884
|
}
|
|
1819
1885
|
|
|
@@ -1968,4 +2034,4 @@ declare function formatMinor(minor: number, currency?: string): string;
|
|
|
1968
2034
|
/** Bare symbol for input adornments ("€", "$", "₹"). */
|
|
1969
2035
|
declare function currencySymbol(currency?: string): string;
|
|
1970
2036
|
|
|
1971
|
-
export { AccessibilityType, type AvailabilityRule, BoothObject, CategoryTier, ChartDoc, ChartObject, DEFAULT_CURRENCY, type Dict, type ExpandChartOptions, ExpandedSeat, Floor, GAAreaObject, GAInventorySegment, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, ISeatmapRenderer, LabelStyle, type Locale, LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerGAArea, type PickerOptions, type PickerSeat, type PickerTransport, Point, RENDERED_QUALITY_REPORT_VERSION, RectTableSeatCounts, RectTableSide, type RenderedEvidenceState, RenderedFreeTextEvidence, type RenderedQualityFinding, type RenderedQualityFindingCode, type RenderedQualityReport, type RenderedQualitySample, RendererCallbacks, RendererOptions, RendererQualityEvidence, RendererViewMode, RowObject, type RowSeatSlot, SUPPORTED_LOCALES, SeatCommercialAttributes, type SeatHoverDetails, SeatOverride, SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, SectionObject, type SectionSummary, TIER_HEIGHT_M, TableObject, type TableSeatSlot, type TableSelectionDetails, UNGROUPED_ID, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencyExponent, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, expandTableSlots, floorObjects, floorsOf, formatDate, formatMinor, formatMoney, fromMinorUnits, gaAreasOf, gaInventorySegments, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, growJoinedGAInventory, hiddenObjectIds, inspectRenderedQualityEvidence, isGaUnitLabel, isSectionHidden, loadLocale, objectCenter, owningSectionForObject, pointInPolygon, pointInPolygonWithHoles, polygonLabelPoint, resolveLocale, rowInventoryCount, rowSeatPositions, sectionGeometry, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount, tableInventoryCount, tableSeatCountsBySide, validGAInventorySegments };
|
|
2037
|
+
export { AccessibilityType, type AvailabilityRule, BoothObject, CategoryTier, ChartDoc, ChartObject, DEFAULT_CURRENCY, type Dict, type ExpandChartOptions, ExpandedSeat, Floor, GAAreaObject, GAInventorySegment, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, ISeatmapRenderer, LabelStyle, type Locale, LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerGAArea, type PickerOptions, type PickerRealtimeConnection, type PickerRealtimeSink, type PickerSeat, type PickerStatusChange, type PickerTransport, Point, RENDERED_QUALITY_REPORT_VERSION, RectTableSeatCounts, RectTableSide, type RenderedEvidenceState, RenderedFreeTextEvidence, type RenderedQualityFinding, type RenderedQualityFindingCode, type RenderedQualityReport, type RenderedQualitySample, RendererCallbacks, RendererOptions, RendererQualityEvidence, RendererViewMode, RowObject, type RowSeatSlot, SUPPORTED_LOCALES, SeatCommercialAttributes, type SeatHoverDetails, SeatOverride, SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, SectionObject, type SectionSummary, TIER_HEIGHT_M, TableObject, type TableSeatSlot, type TableSelectionDetails, UNGROUPED_ID, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencyExponent, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, expandTableSlots, floorObjects, floorsOf, formatDate, formatMinor, formatMoney, fromMinorUnits, gaAreasOf, gaInventorySegments, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, growJoinedGAInventory, hiddenObjectIds, inspectRenderedQualityEvidence, isGaUnitLabel, isSectionHidden, loadLocale, objectCenter, owningSectionForObject, pointInPolygon, pointInPolygonWithHoles, polygonLabelPoint, resolveLocale, rowInventoryCount, rowSeatPositions, sectionGeometry, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount, tableInventoryCount, tableSeatCountsBySide, validGAInventorySegments };
|
package/dist/index.d.ts
CHANGED
|
@@ -1375,6 +1375,38 @@ interface HoldSelectionRequest {
|
|
|
1375
1375
|
interface BestAvailableResponse extends HoldResponse {
|
|
1376
1376
|
labels: string[];
|
|
1377
1377
|
}
|
|
1378
|
+
/** One unit's status as the realtime wire words it (`free`/`held`/`booked`/`blocked`/…). */
|
|
1379
|
+
interface PickerStatusChange {
|
|
1380
|
+
label: string;
|
|
1381
|
+
status: string;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Where a transport-owned realtime client pushes reconstructed inventory.
|
|
1385
|
+
*
|
|
1386
|
+
* Structurally identical to the SDK's `RealtimeSink` on purpose: this file is
|
|
1387
|
+
* mirrored byte-for-byte into `@seatlayer/core`, which the SDK's `@seatlayer/js`
|
|
1388
|
+
* depends on — so it can never import BuyerRealtimeClient without inverting that
|
|
1389
|
+
* dependency. Structural typing lets the SDK hand its client this object with no
|
|
1390
|
+
* import in either direction.
|
|
1391
|
+
*/
|
|
1392
|
+
interface PickerRealtimeSink {
|
|
1393
|
+
/** Apply a batch of label→status changes as ONE paint pass, not one per label. */
|
|
1394
|
+
applyStatuses(changes: PickerStatusChange[]): void;
|
|
1395
|
+
/** Re-pull authoritative state over HTTP (a frame that cannot be diffed). */
|
|
1396
|
+
resync(): void | Promise<void>;
|
|
1397
|
+
/** Section availability changed (hidden = stripped, closed = greyed). */
|
|
1398
|
+
onSections?(hidden: string[], closed: string[]): void;
|
|
1399
|
+
/** Scope-projected presence counters. Unused by the picker today. */
|
|
1400
|
+
onPresence?(counts: {
|
|
1401
|
+
shoppingSessions: number;
|
|
1402
|
+
activeHolds: number;
|
|
1403
|
+
}): void;
|
|
1404
|
+
}
|
|
1405
|
+
/** The live feed itself, owned by the transport. */
|
|
1406
|
+
interface PickerRealtimeConnection {
|
|
1407
|
+
start(): void;
|
|
1408
|
+
stop(): void;
|
|
1409
|
+
}
|
|
1378
1410
|
/** Swappable public-surface transport (SDK PubApi or a dashboard `api.pub.*` adapter). */
|
|
1379
1411
|
interface PickerTransport {
|
|
1380
1412
|
chart(key: string): Promise<{
|
|
@@ -1413,6 +1445,17 @@ interface PickerTransport {
|
|
|
1413
1445
|
* subscribe ticket via `Sec-WebSocket-Protocol`, realtime-protocol v1).
|
|
1414
1446
|
* Absent or empty means today's plain connection. */
|
|
1415
1447
|
socketProtocols?(key: string): string[];
|
|
1448
|
+
/**
|
|
1449
|
+
* Optional — the transport owns the live feed and hands back a client that
|
|
1450
|
+
* speaks the compact `seatlayer.v1` protocol (snapshot diffing, `sv.<n>`
|
|
1451
|
+
* resume, ping/pong liveness, jittered reconnect).
|
|
1452
|
+
*
|
|
1453
|
+
* When this returns a connection the controller does NOT open its own socket:
|
|
1454
|
+
* one socket client, one reconnect/backoff/resume implementation. Returning
|
|
1455
|
+
* null (or omitting the method) keeps the plain-WebSocket path below, which is
|
|
1456
|
+
* what a transport with no realtime client of its own still gets.
|
|
1457
|
+
*/
|
|
1458
|
+
createRealtime?(key: string, sink: PickerRealtimeSink): PickerRealtimeConnection | null;
|
|
1416
1459
|
}
|
|
1417
1460
|
interface PickerCallbacks extends RendererCallbacks {
|
|
1418
1461
|
/** Selection changed (manual clicks or a server best-available pick). */
|
|
@@ -1509,6 +1552,8 @@ declare class PickerController {
|
|
|
1509
1552
|
private confirmedVariableTables;
|
|
1510
1553
|
private groupedSelectionOverhead;
|
|
1511
1554
|
private ws;
|
|
1555
|
+
/** Transport-owned v1 client; mutually exclusive with `ws`. */
|
|
1556
|
+
private realtime;
|
|
1512
1557
|
private reconnectTimer;
|
|
1513
1558
|
private attempt;
|
|
1514
1559
|
private closed;
|
|
@@ -1813,7 +1858,28 @@ declare class PickerController {
|
|
|
1813
1858
|
*/
|
|
1814
1859
|
private attachVisibilityListener;
|
|
1815
1860
|
private detachVisibilityListener;
|
|
1861
|
+
/**
|
|
1862
|
+
* The sink a transport-owned v1 client pushes into.
|
|
1863
|
+
*
|
|
1864
|
+
* Deliberately byte-compatible with the inline socket handler below: the same
|
|
1865
|
+
* liveStatuses bookkeeping (which the hold-expiry verification reads), the
|
|
1866
|
+
* same one-call-per-status paint, the same free→taken flash rule that skips
|
|
1867
|
+
* the buyer's OWN just-held seats, the same keepLiveWhileHidden forceDraw, the
|
|
1868
|
+
* same clearBookedHoldIfSettled + onStatusChange ordering. Hosts see the same
|
|
1869
|
+
* callbacks in the same order whichever path is live.
|
|
1870
|
+
*/
|
|
1871
|
+
private realtimeSink;
|
|
1872
|
+
/** Paint one delta batch. Shared by the v1 sink and the plain-socket handler. */
|
|
1873
|
+
private applyStatusChanges;
|
|
1816
1874
|
private connect;
|
|
1875
|
+
/**
|
|
1876
|
+
* Backoff for the PLAIN-socket fallback (a transport with no v1 client of its
|
|
1877
|
+
* own). Full jitter, for the same reason BuyerRealtimeClient uses it: a
|
|
1878
|
+
* deterministic `2**attempt` schedule brings every browser that lost the same
|
|
1879
|
+
* socket back in the same millisecond, and an on-sale crowd reconnecting in
|
|
1880
|
+
* lockstep turns one blip into a thundering herd. The ceiling still doubles,
|
|
1881
|
+
* so a sustained outage still backs off.
|
|
1882
|
+
*/
|
|
1817
1883
|
private scheduleReconnect;
|
|
1818
1884
|
}
|
|
1819
1885
|
|
|
@@ -1968,4 +2034,4 @@ declare function formatMinor(minor: number, currency?: string): string;
|
|
|
1968
2034
|
/** Bare symbol for input adornments ("€", "$", "₹"). */
|
|
1969
2035
|
declare function currencySymbol(currency?: string): string;
|
|
1970
2036
|
|
|
1971
|
-
export { AccessibilityType, type AvailabilityRule, BoothObject, CategoryTier, ChartDoc, ChartObject, DEFAULT_CURRENCY, type Dict, type ExpandChartOptions, ExpandedSeat, Floor, GAAreaObject, GAInventorySegment, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, ISeatmapRenderer, LabelStyle, type Locale, LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerGAArea, type PickerOptions, type PickerSeat, type PickerTransport, Point, RENDERED_QUALITY_REPORT_VERSION, RectTableSeatCounts, RectTableSide, type RenderedEvidenceState, RenderedFreeTextEvidence, type RenderedQualityFinding, type RenderedQualityFindingCode, type RenderedQualityReport, type RenderedQualitySample, RendererCallbacks, RendererOptions, RendererQualityEvidence, RendererViewMode, RowObject, type RowSeatSlot, SUPPORTED_LOCALES, SeatCommercialAttributes, type SeatHoverDetails, SeatOverride, SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, SectionObject, type SectionSummary, TIER_HEIGHT_M, TableObject, type TableSeatSlot, type TableSelectionDetails, UNGROUPED_ID, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencyExponent, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, expandTableSlots, floorObjects, floorsOf, formatDate, formatMinor, formatMoney, fromMinorUnits, gaAreasOf, gaInventorySegments, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, growJoinedGAInventory, hiddenObjectIds, inspectRenderedQualityEvidence, isGaUnitLabel, isSectionHidden, loadLocale, objectCenter, owningSectionForObject, pointInPolygon, pointInPolygonWithHoles, polygonLabelPoint, resolveLocale, rowInventoryCount, rowSeatPositions, sectionGeometry, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount, tableInventoryCount, tableSeatCountsBySide, validGAInventorySegments };
|
|
2037
|
+
export { AccessibilityType, type AvailabilityRule, BoothObject, CategoryTier, ChartDoc, ChartObject, DEFAULT_CURRENCY, type Dict, type ExpandChartOptions, ExpandedSeat, Floor, GAAreaObject, GAInventorySegment, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, ISeatmapRenderer, LabelStyle, type Locale, LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerGAArea, type PickerOptions, type PickerRealtimeConnection, type PickerRealtimeSink, type PickerSeat, type PickerStatusChange, type PickerTransport, Point, RENDERED_QUALITY_REPORT_VERSION, RectTableSeatCounts, RectTableSide, type RenderedEvidenceState, RenderedFreeTextEvidence, type RenderedQualityFinding, type RenderedQualityFindingCode, type RenderedQualityReport, type RenderedQualitySample, RendererCallbacks, RendererOptions, RendererQualityEvidence, RendererViewMode, RowObject, type RowSeatSlot, SUPPORTED_LOCALES, SeatCommercialAttributes, type SeatHoverDetails, SeatOverride, SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, SectionObject, type SectionSummary, TIER_HEIGHT_M, TableObject, type TableSeatSlot, type TableSelectionDetails, UNGROUPED_ID, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencyExponent, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, expandTableSlots, floorObjects, floorsOf, formatDate, formatMinor, formatMoney, fromMinorUnits, gaAreasOf, gaInventorySegments, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, growJoinedGAInventory, hiddenObjectIds, inspectRenderedQualityEvidence, isGaUnitLabel, isSectionHidden, loadLocale, objectCenter, owningSectionForObject, pointInPolygon, pointInPolygonWithHoles, polygonLabelPoint, resolveLocale, rowInventoryCount, rowSeatPositions, sectionGeometry, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount, tableInventoryCount, tableSeatCountsBySide, validGAInventorySegments };
|
package/dist/index.js
CHANGED
|
@@ -6611,6 +6611,8 @@ var PickerController = class {
|
|
|
6611
6611
|
this.groupedSelectionOverhead = 0;
|
|
6612
6612
|
// realtime socket
|
|
6613
6613
|
this.ws = null;
|
|
6614
|
+
/** Transport-owned v1 client; mutually exclusive with `ws`. */
|
|
6615
|
+
this.realtime = null;
|
|
6614
6616
|
this.reconnectTimer = null;
|
|
6615
6617
|
this.attempt = 0;
|
|
6616
6618
|
this.closed = false;
|
|
@@ -7660,6 +7662,13 @@ var PickerController = class {
|
|
|
7660
7662
|
clearTimeout(this.expiryTimer);
|
|
7661
7663
|
this.expiryTimer = null;
|
|
7662
7664
|
}
|
|
7665
|
+
if (this.realtime) {
|
|
7666
|
+
try {
|
|
7667
|
+
this.realtime.stop();
|
|
7668
|
+
} catch {
|
|
7669
|
+
}
|
|
7670
|
+
this.realtime = null;
|
|
7671
|
+
}
|
|
7663
7672
|
if (this.ws) {
|
|
7664
7673
|
try {
|
|
7665
7674
|
this.ws.close();
|
|
@@ -7948,10 +7957,66 @@ var PickerController = class {
|
|
|
7948
7957
|
}
|
|
7949
7958
|
this.onVisibilityChange = null;
|
|
7950
7959
|
}
|
|
7960
|
+
/**
|
|
7961
|
+
* The sink a transport-owned v1 client pushes into.
|
|
7962
|
+
*
|
|
7963
|
+
* Deliberately byte-compatible with the inline socket handler below: the same
|
|
7964
|
+
* liveStatuses bookkeeping (which the hold-expiry verification reads), the
|
|
7965
|
+
* same one-call-per-status paint, the same free→taken flash rule that skips
|
|
7966
|
+
* the buyer's OWN just-held seats, the same keepLiveWhileHidden forceDraw, the
|
|
7967
|
+
* same clearBookedHoldIfSettled + onStatusChange ordering. Hosts see the same
|
|
7968
|
+
* callbacks in the same order whichever path is live.
|
|
7969
|
+
*/
|
|
7970
|
+
realtimeSink() {
|
|
7971
|
+
return {
|
|
7972
|
+
applyStatuses: (changes) => this.applyStatusChanges(changes),
|
|
7973
|
+
resync: () => this.resnapshot(),
|
|
7974
|
+
onSections: (hidden, closed) => {
|
|
7975
|
+
const rebuilt = this.syncHidden(hidden);
|
|
7976
|
+
const restyled = this.syncClosed(closed);
|
|
7977
|
+
if (rebuilt) void this.resnapshot();
|
|
7978
|
+
if (rebuilt || restyled) this.opts.onStatusChange?.();
|
|
7979
|
+
}
|
|
7980
|
+
};
|
|
7981
|
+
}
|
|
7982
|
+
/** Paint one delta batch. Shared by the v1 sink and the plain-socket handler. */
|
|
7983
|
+
applyStatusChanges(changes) {
|
|
7984
|
+
const r = this.renderer;
|
|
7985
|
+
if (!r) return;
|
|
7986
|
+
for (const ch of changes) {
|
|
7987
|
+
this.liveStatuses.set(ch.label, ch.status);
|
|
7988
|
+
const ids = this.idsForLabel(ch.label);
|
|
7989
|
+
if (!ids.length) continue;
|
|
7990
|
+
const next = mapStatus(ch.status);
|
|
7991
|
+
if (this.opts.flashOnLiveChange && next !== "free" && ids.some((id) => r.getStatus(id) === "free") && !this.hold_?.labels.includes(ch.label)) {
|
|
7992
|
+
ids.forEach((id) => r.flashSeat(id, next === "held" ? "#f4b740" : "#f43f5e"));
|
|
7993
|
+
}
|
|
7994
|
+
r.setStatus(ids, next);
|
|
7995
|
+
}
|
|
7996
|
+
if (this.opts.keepLiveWhileHidden && typeof document !== "undefined" && document.visibilityState === "hidden") {
|
|
7997
|
+
r.forceDraw();
|
|
7998
|
+
}
|
|
7999
|
+
this.clearBookedHoldIfSettled();
|
|
8000
|
+
this.opts.onStatusChange?.();
|
|
8001
|
+
}
|
|
7951
8002
|
connect() {
|
|
7952
8003
|
if (this.closed) return;
|
|
7953
8004
|
const url = this.api.socketUrl(this.key);
|
|
7954
8005
|
if (!url) return;
|
|
8006
|
+
if (!this.realtime && this.api.createRealtime) {
|
|
8007
|
+
let connection = null;
|
|
8008
|
+
try {
|
|
8009
|
+
connection = this.api.createRealtime(this.key, this.realtimeSink());
|
|
8010
|
+
} catch {
|
|
8011
|
+
connection = null;
|
|
8012
|
+
}
|
|
8013
|
+
if (connection) {
|
|
8014
|
+
this.realtime = connection;
|
|
8015
|
+
connection.start();
|
|
8016
|
+
return;
|
|
8017
|
+
}
|
|
8018
|
+
}
|
|
8019
|
+
if (this.realtime) return;
|
|
7955
8020
|
let ws;
|
|
7956
8021
|
try {
|
|
7957
8022
|
const protocols = this.api.socketProtocols?.(this.key);
|
|
@@ -7986,21 +8051,7 @@ var PickerController = class {
|
|
|
7986
8051
|
if (m.seats && typeof m.seats === "object") {
|
|
7987
8052
|
this.applySeatsMap(m.seats);
|
|
7988
8053
|
} else if (Array.isArray(m.changes)) {
|
|
7989
|
-
|
|
7990
|
-
this.liveStatuses.set(ch.label, ch.status);
|
|
7991
|
-
const ids = this.idsForLabel(ch.label);
|
|
7992
|
-
if (!ids.length) continue;
|
|
7993
|
-
const next = mapStatus(ch.status);
|
|
7994
|
-
if (this.opts.flashOnLiveChange && next !== "free" && ids.some((id) => r.getStatus(id) === "free") && !this.hold_?.labels.includes(ch.label)) {
|
|
7995
|
-
ids.forEach((id) => r.flashSeat(id, next === "held" ? "#f4b740" : "#f43f5e"));
|
|
7996
|
-
}
|
|
7997
|
-
r.setStatus(ids, next);
|
|
7998
|
-
}
|
|
7999
|
-
if (this.opts.keepLiveWhileHidden && typeof document !== "undefined" && document.visibilityState === "hidden") {
|
|
8000
|
-
r.forceDraw();
|
|
8001
|
-
}
|
|
8002
|
-
this.clearBookedHoldIfSettled();
|
|
8003
|
-
this.opts.onStatusChange?.();
|
|
8054
|
+
this.applyStatusChanges(m.changes);
|
|
8004
8055
|
}
|
|
8005
8056
|
};
|
|
8006
8057
|
ws.onclose = () => {
|
|
@@ -8014,10 +8065,18 @@ var PickerController = class {
|
|
|
8014
8065
|
}
|
|
8015
8066
|
};
|
|
8016
8067
|
}
|
|
8068
|
+
/**
|
|
8069
|
+
* Backoff for the PLAIN-socket fallback (a transport with no v1 client of its
|
|
8070
|
+
* own). Full jitter, for the same reason BuyerRealtimeClient uses it: a
|
|
8071
|
+
* deterministic `2**attempt` schedule brings every browser that lost the same
|
|
8072
|
+
* socket back in the same millisecond, and an on-sale crowd reconnecting in
|
|
8073
|
+
* lockstep turns one blip into a thundering herd. The ceiling still doubles,
|
|
8074
|
+
* so a sustained outage still backs off.
|
|
8075
|
+
*/
|
|
8017
8076
|
scheduleReconnect() {
|
|
8018
8077
|
if (this.closed || this.reconnectTimer) return;
|
|
8019
8078
|
const attempt = Math.min(this.attempt++, 5);
|
|
8020
|
-
const delay = Math.min(1e3 * 2 ** attempt, MAX_BACKOFF_MS);
|
|
8079
|
+
const delay = Math.random() * Math.min(1e3 * 2 ** attempt, MAX_BACKOFF_MS);
|
|
8021
8080
|
this.reconnectTimer = setTimeout(() => {
|
|
8022
8081
|
this.reconnectTimer = null;
|
|
8023
8082
|
this.connect();
|