@seatlayer/core 0.27.0 → 0.28.1
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 +110 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +110 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2538,6 +2538,22 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
|
|
|
2538
2538
|
* debounced cacheSeatLayer() and the synchronous forceDraw() catch-up. */
|
|
2539
2539
|
private rebuildSeatCache;
|
|
2540
2540
|
private cacheSeatLayer;
|
|
2541
|
+
/**
|
|
2542
|
+
* Drop the seat-layer overview bitmap while PRESERVING every descendant's
|
|
2543
|
+
* cached local transform + clientRect.
|
|
2544
|
+
*
|
|
2545
|
+
* Konva's public `Layer.clearCache()` releases the bitmap and then runs a deep
|
|
2546
|
+
* `_clearSelfAndDescendantCache()` that clears those caches on all 14k seat
|
|
2547
|
+
* nodes. Recomputing them on the single frame the melt first reveals a section's
|
|
2548
|
+
* live seats is the ~480ms first-drill stall (OV-80). A camera glide only marks
|
|
2549
|
+
* each seat's ABSOLUTE_TRANSFORM dirty (recomputed lazily at ordinary pan cost)
|
|
2550
|
+
* and never moves a seat's LOCAL transform, so the local caches stay valid —
|
|
2551
|
+
* keeping them lets the first melt paint at pan cost, matching the ~17ms of
|
|
2552
|
+
* every subsequent glide on the same section. Any edit that actually moves a
|
|
2553
|
+
* seat invalidates its own transform cache through the attr setter, so only
|
|
2554
|
+
* still-valid caches survive here.
|
|
2555
|
+
*/
|
|
2556
|
+
private releaseSeatLayerBitmap;
|
|
2541
2557
|
/**
|
|
2542
2558
|
* SYNCHRONOUS repaint that bypasses requestAnimationFrame — see the
|
|
2543
2559
|
* ISeatmapRenderer.forceDraw() contract. Chrome pauses rAF (and therefore
|
|
@@ -2872,6 +2888,21 @@ declare class PickerController {
|
|
|
2872
2888
|
private idsForLabels;
|
|
2873
2889
|
/** Resolve a physical chair id (or table inventory label) to its table unit. */
|
|
2874
2890
|
tableSelection(seatIdOrLabel: string): TableSelectionDetails | null;
|
|
2891
|
+
/**
|
|
2892
|
+
* Buyer-facing name + type word for a checkout line item, resolved from the
|
|
2893
|
+
* SAME author overrides the tray/tooltip already render. `label` stays the
|
|
2894
|
+
* booking identity; a host builds its own order summary from `displayLabel`/
|
|
2895
|
+
* `displayType` so the buyer sees the designer's copy, not the internal label.
|
|
2896
|
+
* Absent fields = no override (host falls back to `label`).
|
|
2897
|
+
*/
|
|
2898
|
+
lineItemDisplay(item: {
|
|
2899
|
+
label: string;
|
|
2900
|
+
objectId: string;
|
|
2901
|
+
objectType: 'seat' | 'booth' | 'ga' | 'table';
|
|
2902
|
+
}): {
|
|
2903
|
+
displayLabel?: string;
|
|
2904
|
+
displayType?: string;
|
|
2905
|
+
};
|
|
2875
2906
|
/** Fetch chart, build label maps, mount the renderer, seed statuses, go live. */
|
|
2876
2907
|
render(host: HTMLDivElement): Promise<{
|
|
2877
2908
|
doc: ChartDoc;
|
package/dist/index.d.ts
CHANGED
|
@@ -2538,6 +2538,22 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
|
|
|
2538
2538
|
* debounced cacheSeatLayer() and the synchronous forceDraw() catch-up. */
|
|
2539
2539
|
private rebuildSeatCache;
|
|
2540
2540
|
private cacheSeatLayer;
|
|
2541
|
+
/**
|
|
2542
|
+
* Drop the seat-layer overview bitmap while PRESERVING every descendant's
|
|
2543
|
+
* cached local transform + clientRect.
|
|
2544
|
+
*
|
|
2545
|
+
* Konva's public `Layer.clearCache()` releases the bitmap and then runs a deep
|
|
2546
|
+
* `_clearSelfAndDescendantCache()` that clears those caches on all 14k seat
|
|
2547
|
+
* nodes. Recomputing them on the single frame the melt first reveals a section's
|
|
2548
|
+
* live seats is the ~480ms first-drill stall (OV-80). A camera glide only marks
|
|
2549
|
+
* each seat's ABSOLUTE_TRANSFORM dirty (recomputed lazily at ordinary pan cost)
|
|
2550
|
+
* and never moves a seat's LOCAL transform, so the local caches stay valid —
|
|
2551
|
+
* keeping them lets the first melt paint at pan cost, matching the ~17ms of
|
|
2552
|
+
* every subsequent glide on the same section. Any edit that actually moves a
|
|
2553
|
+
* seat invalidates its own transform cache through the attr setter, so only
|
|
2554
|
+
* still-valid caches survive here.
|
|
2555
|
+
*/
|
|
2556
|
+
private releaseSeatLayerBitmap;
|
|
2541
2557
|
/**
|
|
2542
2558
|
* SYNCHRONOUS repaint that bypasses requestAnimationFrame — see the
|
|
2543
2559
|
* ISeatmapRenderer.forceDraw() contract. Chrome pauses rAF (and therefore
|
|
@@ -2872,6 +2888,21 @@ declare class PickerController {
|
|
|
2872
2888
|
private idsForLabels;
|
|
2873
2889
|
/** Resolve a physical chair id (or table inventory label) to its table unit. */
|
|
2874
2890
|
tableSelection(seatIdOrLabel: string): TableSelectionDetails | null;
|
|
2891
|
+
/**
|
|
2892
|
+
* Buyer-facing name + type word for a checkout line item, resolved from the
|
|
2893
|
+
* SAME author overrides the tray/tooltip already render. `label` stays the
|
|
2894
|
+
* booking identity; a host builds its own order summary from `displayLabel`/
|
|
2895
|
+
* `displayType` so the buyer sees the designer's copy, not the internal label.
|
|
2896
|
+
* Absent fields = no override (host falls back to `label`).
|
|
2897
|
+
*/
|
|
2898
|
+
lineItemDisplay(item: {
|
|
2899
|
+
label: string;
|
|
2900
|
+
objectId: string;
|
|
2901
|
+
objectType: 'seat' | 'booth' | 'ga' | 'table';
|
|
2902
|
+
}): {
|
|
2903
|
+
displayLabel?: string;
|
|
2904
|
+
displayType?: string;
|
|
2905
|
+
};
|
|
2875
2906
|
/** Fetch chart, build label maps, mount the renderer, seed statuses, go live. */
|
|
2876
2907
|
render(host: HTMLDivElement): Promise<{
|
|
2877
2908
|
doc: ChartDoc;
|
package/dist/index.js
CHANGED
|
@@ -1034,7 +1034,30 @@ function isBookableLabelLegibleAtScale(fontSize, effectiveScale) {
|
|
|
1034
1034
|
return fontSize * effectiveScale >= MIN_VISIBLE_BOOKABLE_LABEL_PX;
|
|
1035
1035
|
}
|
|
1036
1036
|
var ACCESS_GLYPH_VIEWBOX = 24;
|
|
1037
|
-
var
|
|
1037
|
+
var ACCESS_TYPE_GLYPH_PATHS = {
|
|
1038
|
+
// ISO-style wheelchair: seated figure (head + L-shaped body) over a ring wheel.
|
|
1039
|
+
wheelchair: "M7.8 4.5a2.2 2.2 0 1 0 4.4 0a2.2 2.2 0 1 0 -4.4 0zM8 7L10.5 7L10.5 15L8 15ZM8 12.5L18 12.5L18 15L8 15ZM16 15L18 15L18 18L16 18ZM5.5 16a5.5 5.5 0 1 0 11 0a5.5 5.5 0 1 0 -11 0zM8 16a3 3 0 1 1 6 0a3 3 0 1 1 -6 0z",
|
|
1040
|
+
// Companion: two overlapping head-and-shoulders figures (seat + a guest).
|
|
1041
|
+
companion: "M5.5 6.5a3 3 0 1 0 6 0a3 3 0 1 0 -6 0zM4.5 18.5L6 11.5L11 11.5L12.5 18.5ZM12.5 7.5a3 3 0 1 0 6 0a3 3 0 1 0 -6 0zM11.5 19L13 12.5L18 12.5L19.5 19Z",
|
|
1042
|
+
// Semi-ambulatory: walking figure leaning on a cane at its right side.
|
|
1043
|
+
"semi-ambulatory": "M8.3 3.8a2.2 2.2 0 1 0 4.4 0a2.2 2.2 0 1 0 -4.4 0zM9 6.2L12 6.6L11 13.5L8.6 13L9 6.2ZM8.6 13L11 13L9.5 21L7 21ZM10.4 13L12.6 13L13.6 21L11.2 21ZM11.2 7.2L14 8L14.6 9.6L11.9 8.9ZM14.4 6.8L15.9 6.8L16.4 21L14.8 21Z",
|
|
1044
|
+
// Hearing: a bold ear silhouette (assistive listening).
|
|
1045
|
+
hearing: "M15.5 3.5C9 2.2 5.5 6 5.5 11.5C5.5 16 8 19.5 10.5 21C13.2 22.6 16.4 20.8 15.4 18C14.8 16.4 12.9 16.1 13 14C13.1 11.9 15.8 11.4 15.8 8.5C15.8 5.4 13 4 15.5 3.5Z",
|
|
1046
|
+
// CART captions: a rounded caption bubble with two bold caption bars cut out.
|
|
1047
|
+
cart: "M5.5 6L18.5 6a2.5 2.5 0 0 1 2.5 2.5L21 15.5a2.5 2.5 0 0 1 -2.5 2.5L11 18L7 20.5L7.5 18L5.5 18a2.5 2.5 0 0 1 -2.5 -2.5L3 8.5a2.5 2.5 0 0 1 2.5 -2.5zM6.5 11L17.5 11L17.5 12.6L6.5 12.6zM6.5 14L17.5 14L17.5 15.6L6.5 15.6z",
|
|
1048
|
+
// Sign language: a raised open hand (palm with four fingers and a thumb).
|
|
1049
|
+
"sign-language": "M7 11L17 11L17 18a2 2 0 0 1 -2 2L9 20a2 2 0 0 1 -2 -2zM7.6 5L9.4 5L9.4 12L7.6 12zM9.9 3.5L11.7 3.5L11.7 12L9.9 12zM12.3 3.5L14.1 3.5L14.1 12L12.3 12zM14.6 5L16.4 5L16.4 12L14.6 12zM7.2 12.5L5 10.2L6.4 8.9L8.6 11.2Z",
|
|
1050
|
+
// Plus-size: a broad-shouldered wide figure.
|
|
1051
|
+
"plus-size": "M9.4 4.3a2.6 2.6 0 1 0 5.2 0a2.6 2.6 0 1 0 -5.2 0zM5 20L4 13C4 10.5 7 9.5 12 9.5C17 9.5 20 10.5 20 13L19 20Z",
|
|
1052
|
+
// Lift-up armrest: a chair side-profile with an up arrow over the armrest.
|
|
1053
|
+
"lift-armrest": "M5 6L8 6L8 19L5 19zM5 16L18 16L18 19L5 19zM8 12L17 12L17 14.5L8 14.5zM14 7L16 7L16 12L14 12zM12 7L18 7L15 3Z"
|
|
1054
|
+
};
|
|
1055
|
+
var ACCESS_GLYPH_PATH = ACCESS_TYPE_GLYPH_PATHS.wheelchair;
|
|
1056
|
+
function accessGlyphPath(accessibility) {
|
|
1057
|
+
if (!accessibility?.length) return null;
|
|
1058
|
+
const primary = accessibility.includes("wheelchair") ? "wheelchair" : accessibility[0];
|
|
1059
|
+
return ACCESS_TYPE_GLYPH_PATHS[primary] ?? null;
|
|
1060
|
+
}
|
|
1038
1061
|
function bookableMarkerLabel(publicLabel) {
|
|
1039
1062
|
return /-(\d{1,5})$/.exec(publicLabel)?.[1] ?? publicLabel;
|
|
1040
1063
|
}
|
|
@@ -1075,6 +1098,15 @@ function stateAwareBookableLabelInk(fill, preferred) {
|
|
|
1075
1098
|
if (darkContrast === 0 && lightContrast === 0) return preferred;
|
|
1076
1099
|
return darkContrast >= lightContrast ? DARK_BOOKABLE_LABEL_INK : LIGHT_BOOKABLE_LABEL_INK;
|
|
1077
1100
|
}
|
|
1101
|
+
var GLYPH_CONTRAST = 3;
|
|
1102
|
+
function accessGlyphInk(fill) {
|
|
1103
|
+
const white = renderedTextContrast("#ffffff", fill);
|
|
1104
|
+
if (white != null && white >= GLYPH_CONTRAST) return "#ffffff";
|
|
1105
|
+
const darkContrast = renderedTextContrast(DARK_BOOKABLE_LABEL_INK, fill) ?? 0;
|
|
1106
|
+
const lightContrast = renderedTextContrast(LIGHT_BOOKABLE_LABEL_INK, fill) ?? 0;
|
|
1107
|
+
if (darkContrast === 0 && lightContrast === 0) return "#ffffff";
|
|
1108
|
+
return darkContrast >= lightContrast ? DARK_BOOKABLE_LABEL_INK : LIGHT_BOOKABLE_LABEL_INK;
|
|
1109
|
+
}
|
|
1078
1110
|
|
|
1079
1111
|
// src/core/renderedQuality.ts
|
|
1080
1112
|
var RENDERED_QUALITY_REPORT_VERSION = 3;
|
|
@@ -1601,6 +1633,12 @@ var VENUE_ICONS = [
|
|
|
1601
1633
|
group: "facilities",
|
|
1602
1634
|
path: "M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14 M16 16l5 5 M9 8.5a2 2 0 1 1 3 1.7c-.8.5-1 .8-1 1.8 M11 15h.01"
|
|
1603
1635
|
},
|
|
1636
|
+
{
|
|
1637
|
+
key: "restrooms",
|
|
1638
|
+
label: "Restrooms",
|
|
1639
|
+
group: "facilities",
|
|
1640
|
+
path: "M6 3h12a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Z M12 8a2 2 0 1 0 0 4 2 2 0 0 0 0-4 M9 18v-3.5a3 3 0 0 1 6 0V18"
|
|
1641
|
+
},
|
|
1604
1642
|
{
|
|
1605
1643
|
key: "charging",
|
|
1606
1644
|
label: "Charging point",
|
|
@@ -1650,6 +1688,18 @@ var VENUE_ICONS = [
|
|
|
1650
1688
|
group: "food-drink",
|
|
1651
1689
|
path: "M6 8h12l-1 12H7L6 8Z M9 8V6a3 3 0 0 1 6 0v2"
|
|
1652
1690
|
},
|
|
1691
|
+
{
|
|
1692
|
+
key: "screen",
|
|
1693
|
+
label: "Screen",
|
|
1694
|
+
group: "facilities",
|
|
1695
|
+
path: "M3 4h18v12H3V4Z M9 20h6 M12 16v4 M10 8l4 2-4 2V8Z"
|
|
1696
|
+
},
|
|
1697
|
+
{
|
|
1698
|
+
key: "sound-booth",
|
|
1699
|
+
label: "Sound booth",
|
|
1700
|
+
group: "facilities",
|
|
1701
|
+
path: "M6 4v16 M6 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4 M12 4v16 M12 8a2 2 0 1 0 0 4 2 2 0 0 0 0-4 M18 4v16 M18 12a2 2 0 1 0 0 4 2 2 0 0 0 0-4"
|
|
1702
|
+
},
|
|
1653
1703
|
// ---- Getting around ----------------------------------------------------
|
|
1654
1704
|
{
|
|
1655
1705
|
key: "entrance",
|
|
@@ -4308,7 +4358,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
4308
4358
|
this.accessRingById.set(seat.id, ring);
|
|
4309
4359
|
target.add(ring);
|
|
4310
4360
|
}
|
|
4311
|
-
if (seat.accessibility
|
|
4361
|
+
if (accessGlyphPath(seat.accessibility ?? [])) {
|
|
4312
4362
|
const glyph = this.buildAccessGlyph(seat, typeof c.fill() === "string" ? c.fill() : "");
|
|
4313
4363
|
this.accessGlyphById.set(seat.id, glyph);
|
|
4314
4364
|
target.add(glyph);
|
|
@@ -4382,12 +4432,14 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
4382
4432
|
return new Path({
|
|
4383
4433
|
x: seat.x,
|
|
4384
4434
|
y: seat.y,
|
|
4385
|
-
|
|
4435
|
+
// Non-null: buildAccessGlyph is only called for seats the gate confirmed
|
|
4436
|
+
// resolve to a primary-accommodation glyph.
|
|
4437
|
+
data: accessGlyphPath(seat.accessibility ?? []) ?? "",
|
|
4386
4438
|
offsetX: ACCESS_GLYPH_VIEWBOX / 2,
|
|
4387
4439
|
offsetY: ACCESS_GLYPH_VIEWBOX / 2,
|
|
4388
4440
|
scaleX: k,
|
|
4389
4441
|
scaleY: k,
|
|
4390
|
-
fill:
|
|
4442
|
+
fill: accessGlyphInk(seatFill),
|
|
4391
4443
|
listening: false,
|
|
4392
4444
|
visible: false,
|
|
4393
4445
|
perfectDrawEnabled: false,
|
|
@@ -6515,7 +6567,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
6515
6567
|
if (shouldCache && !this.cached) {
|
|
6516
6568
|
this.cacheSeatLayer();
|
|
6517
6569
|
} else if (!shouldCache && (this.cached || !this.seatLayer.listening())) {
|
|
6518
|
-
if (this.cached) this.
|
|
6570
|
+
if (this.cached) this.releaseSeatLayerBitmap();
|
|
6519
6571
|
this.seatLayer.listening(true);
|
|
6520
6572
|
this.cached = false;
|
|
6521
6573
|
this.seatLayer.batchDraw();
|
|
@@ -6535,6 +6587,28 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
6535
6587
|
this.rebuildSeatCache();
|
|
6536
6588
|
this.seatLayer.batchDraw();
|
|
6537
6589
|
}
|
|
6590
|
+
/**
|
|
6591
|
+
* Drop the seat-layer overview bitmap while PRESERVING every descendant's
|
|
6592
|
+
* cached local transform + clientRect.
|
|
6593
|
+
*
|
|
6594
|
+
* Konva's public `Layer.clearCache()` releases the bitmap and then runs a deep
|
|
6595
|
+
* `_clearSelfAndDescendantCache()` that clears those caches on all 14k seat
|
|
6596
|
+
* nodes. Recomputing them on the single frame the melt first reveals a section's
|
|
6597
|
+
* live seats is the ~480ms first-drill stall (OV-80). A camera glide only marks
|
|
6598
|
+
* each seat's ABSOLUTE_TRANSFORM dirty (recomputed lazily at ordinary pan cost)
|
|
6599
|
+
* and never moves a seat's LOCAL transform, so the local caches stay valid —
|
|
6600
|
+
* keeping them lets the first melt paint at pan cost, matching the ~17ms of
|
|
6601
|
+
* every subsequent glide on the same section. Any edit that actually moves a
|
|
6602
|
+
* seat invalidates its own transform cache through the attr setter, so only
|
|
6603
|
+
* still-valid caches survive here.
|
|
6604
|
+
*/
|
|
6605
|
+
releaseSeatLayerBitmap() {
|
|
6606
|
+
const layer = this.seatLayer;
|
|
6607
|
+
const entry = layer._cache.get("canvas");
|
|
6608
|
+
if (!entry) return;
|
|
6609
|
+
Konva.Util.releaseCanvas(entry.scene._canvas, entry.filter._canvas, entry.hit._canvas);
|
|
6610
|
+
layer._cache.delete("canvas");
|
|
6611
|
+
}
|
|
6538
6612
|
/**
|
|
6539
6613
|
* SYNCHRONOUS repaint that bypasses requestAnimationFrame — see the
|
|
6540
6614
|
* ISeatmapRenderer.forceDraw() contract. Chrome pauses rAF (and therefore
|
|
@@ -6553,7 +6627,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
6553
6627
|
if (this.effScale() < CACHE_THRESHOLD) {
|
|
6554
6628
|
this.rebuildSeatCache();
|
|
6555
6629
|
} else if (this.cached) {
|
|
6556
|
-
this.
|
|
6630
|
+
this.releaseSeatLayerBitmap();
|
|
6557
6631
|
this.seatLayer.listening(true);
|
|
6558
6632
|
this.cached = false;
|
|
6559
6633
|
}
|
|
@@ -7074,6 +7148,36 @@ var PickerController = class {
|
|
|
7074
7148
|
const group = this.groupedTableBySeatId.get(seatIdOrLabel) ?? this.groupedTablesByLabel.get(seatIdOrLabel);
|
|
7075
7149
|
return group ? this.toTableSeat(group) : null;
|
|
7076
7150
|
}
|
|
7151
|
+
/**
|
|
7152
|
+
* Buyer-facing name + type word for a checkout line item, resolved from the
|
|
7153
|
+
* SAME author overrides the tray/tooltip already render. `label` stays the
|
|
7154
|
+
* booking identity; a host builds its own order summary from `displayLabel`/
|
|
7155
|
+
* `displayType` so the buyer sees the designer's copy, not the internal label.
|
|
7156
|
+
* Absent fields = no override (host falls back to `label`).
|
|
7157
|
+
*/
|
|
7158
|
+
lineItemDisplay(item) {
|
|
7159
|
+
if (item.objectType === "ga") {
|
|
7160
|
+
const doc = this.visibleDoc();
|
|
7161
|
+
const area = gaAreasOf(doc).find((candidate) => candidate.id === item.objectId);
|
|
7162
|
+
return {
|
|
7163
|
+
...area?.displayLabel ? { displayLabel: area.displayLabel } : {},
|
|
7164
|
+
...area?.displayType ? { displayType: area.displayType } : {}
|
|
7165
|
+
};
|
|
7166
|
+
}
|
|
7167
|
+
if (item.objectType === "table") {
|
|
7168
|
+
const group = this.groupedTablesByLabel.get(item.label);
|
|
7169
|
+
return {
|
|
7170
|
+
...group?.displayLabel && group.displayLabel !== group.label ? { displayLabel: group.displayLabel } : {},
|
|
7171
|
+
...group?.displayType ? { displayType: group.displayType } : {}
|
|
7172
|
+
};
|
|
7173
|
+
}
|
|
7174
|
+
const seat = this.labelToSeat.get(item.label);
|
|
7175
|
+
const context = seat ? this.seatContext.get(seat.id) : void 0;
|
|
7176
|
+
return {
|
|
7177
|
+
...seat?.displayLabel ? { displayLabel: seat.displayLabel } : {},
|
|
7178
|
+
...context?.displayType ? { displayType: context.displayType } : {}
|
|
7179
|
+
};
|
|
7180
|
+
}
|
|
7077
7181
|
/** Fetch chart, build label maps, mount the renderer, seed statuses, go live. */
|
|
7078
7182
|
async render(host) {
|
|
7079
7183
|
if (this.renderer) return null;
|