@seatlayer/core 0.27.0 → 0.28.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 +100 -5
- 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 +100 -5
- 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
|
}
|
|
@@ -1601,6 +1624,12 @@ var VENUE_ICONS = [
|
|
|
1601
1624
|
group: "facilities",
|
|
1602
1625
|
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
1626
|
},
|
|
1627
|
+
{
|
|
1628
|
+
key: "restrooms",
|
|
1629
|
+
label: "Restrooms",
|
|
1630
|
+
group: "facilities",
|
|
1631
|
+
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"
|
|
1632
|
+
},
|
|
1604
1633
|
{
|
|
1605
1634
|
key: "charging",
|
|
1606
1635
|
label: "Charging point",
|
|
@@ -1650,6 +1679,18 @@ var VENUE_ICONS = [
|
|
|
1650
1679
|
group: "food-drink",
|
|
1651
1680
|
path: "M6 8h12l-1 12H7L6 8Z M9 8V6a3 3 0 0 1 6 0v2"
|
|
1652
1681
|
},
|
|
1682
|
+
{
|
|
1683
|
+
key: "screen",
|
|
1684
|
+
label: "Screen",
|
|
1685
|
+
group: "facilities",
|
|
1686
|
+
path: "M3 4h18v12H3V4Z M9 20h6 M12 16v4 M10 8l4 2-4 2V8Z"
|
|
1687
|
+
},
|
|
1688
|
+
{
|
|
1689
|
+
key: "sound-booth",
|
|
1690
|
+
label: "Sound booth",
|
|
1691
|
+
group: "facilities",
|
|
1692
|
+
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"
|
|
1693
|
+
},
|
|
1653
1694
|
// ---- Getting around ----------------------------------------------------
|
|
1654
1695
|
{
|
|
1655
1696
|
key: "entrance",
|
|
@@ -4308,7 +4349,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
4308
4349
|
this.accessRingById.set(seat.id, ring);
|
|
4309
4350
|
target.add(ring);
|
|
4310
4351
|
}
|
|
4311
|
-
if (seat.accessibility
|
|
4352
|
+
if (accessGlyphPath(seat.accessibility ?? [])) {
|
|
4312
4353
|
const glyph = this.buildAccessGlyph(seat, typeof c.fill() === "string" ? c.fill() : "");
|
|
4313
4354
|
this.accessGlyphById.set(seat.id, glyph);
|
|
4314
4355
|
target.add(glyph);
|
|
@@ -4382,7 +4423,9 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
4382
4423
|
return new Path({
|
|
4383
4424
|
x: seat.x,
|
|
4384
4425
|
y: seat.y,
|
|
4385
|
-
|
|
4426
|
+
// Non-null: buildAccessGlyph is only called for seats the gate confirmed
|
|
4427
|
+
// resolve to a primary-accommodation glyph.
|
|
4428
|
+
data: accessGlyphPath(seat.accessibility ?? []) ?? "",
|
|
4386
4429
|
offsetX: ACCESS_GLYPH_VIEWBOX / 2,
|
|
4387
4430
|
offsetY: ACCESS_GLYPH_VIEWBOX / 2,
|
|
4388
4431
|
scaleX: k,
|
|
@@ -6515,7 +6558,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
6515
6558
|
if (shouldCache && !this.cached) {
|
|
6516
6559
|
this.cacheSeatLayer();
|
|
6517
6560
|
} else if (!shouldCache && (this.cached || !this.seatLayer.listening())) {
|
|
6518
|
-
if (this.cached) this.
|
|
6561
|
+
if (this.cached) this.releaseSeatLayerBitmap();
|
|
6519
6562
|
this.seatLayer.listening(true);
|
|
6520
6563
|
this.cached = false;
|
|
6521
6564
|
this.seatLayer.batchDraw();
|
|
@@ -6535,6 +6578,28 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
6535
6578
|
this.rebuildSeatCache();
|
|
6536
6579
|
this.seatLayer.batchDraw();
|
|
6537
6580
|
}
|
|
6581
|
+
/**
|
|
6582
|
+
* Drop the seat-layer overview bitmap while PRESERVING every descendant's
|
|
6583
|
+
* cached local transform + clientRect.
|
|
6584
|
+
*
|
|
6585
|
+
* Konva's public `Layer.clearCache()` releases the bitmap and then runs a deep
|
|
6586
|
+
* `_clearSelfAndDescendantCache()` that clears those caches on all 14k seat
|
|
6587
|
+
* nodes. Recomputing them on the single frame the melt first reveals a section's
|
|
6588
|
+
* live seats is the ~480ms first-drill stall (OV-80). A camera glide only marks
|
|
6589
|
+
* each seat's ABSOLUTE_TRANSFORM dirty (recomputed lazily at ordinary pan cost)
|
|
6590
|
+
* and never moves a seat's LOCAL transform, so the local caches stay valid —
|
|
6591
|
+
* keeping them lets the first melt paint at pan cost, matching the ~17ms of
|
|
6592
|
+
* every subsequent glide on the same section. Any edit that actually moves a
|
|
6593
|
+
* seat invalidates its own transform cache through the attr setter, so only
|
|
6594
|
+
* still-valid caches survive here.
|
|
6595
|
+
*/
|
|
6596
|
+
releaseSeatLayerBitmap() {
|
|
6597
|
+
const layer = this.seatLayer;
|
|
6598
|
+
const entry = layer._cache.get("canvas");
|
|
6599
|
+
if (!entry) return;
|
|
6600
|
+
Konva.Util.releaseCanvas(entry.scene._canvas, entry.filter._canvas, entry.hit._canvas);
|
|
6601
|
+
layer._cache.delete("canvas");
|
|
6602
|
+
}
|
|
6538
6603
|
/**
|
|
6539
6604
|
* SYNCHRONOUS repaint that bypasses requestAnimationFrame — see the
|
|
6540
6605
|
* ISeatmapRenderer.forceDraw() contract. Chrome pauses rAF (and therefore
|
|
@@ -6553,7 +6618,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
6553
6618
|
if (this.effScale() < CACHE_THRESHOLD) {
|
|
6554
6619
|
this.rebuildSeatCache();
|
|
6555
6620
|
} else if (this.cached) {
|
|
6556
|
-
this.
|
|
6621
|
+
this.releaseSeatLayerBitmap();
|
|
6557
6622
|
this.seatLayer.listening(true);
|
|
6558
6623
|
this.cached = false;
|
|
6559
6624
|
}
|
|
@@ -7074,6 +7139,36 @@ var PickerController = class {
|
|
|
7074
7139
|
const group = this.groupedTableBySeatId.get(seatIdOrLabel) ?? this.groupedTablesByLabel.get(seatIdOrLabel);
|
|
7075
7140
|
return group ? this.toTableSeat(group) : null;
|
|
7076
7141
|
}
|
|
7142
|
+
/**
|
|
7143
|
+
* Buyer-facing name + type word for a checkout line item, resolved from the
|
|
7144
|
+
* SAME author overrides the tray/tooltip already render. `label` stays the
|
|
7145
|
+
* booking identity; a host builds its own order summary from `displayLabel`/
|
|
7146
|
+
* `displayType` so the buyer sees the designer's copy, not the internal label.
|
|
7147
|
+
* Absent fields = no override (host falls back to `label`).
|
|
7148
|
+
*/
|
|
7149
|
+
lineItemDisplay(item) {
|
|
7150
|
+
if (item.objectType === "ga") {
|
|
7151
|
+
const doc = this.visibleDoc();
|
|
7152
|
+
const area = gaAreasOf(doc).find((candidate) => candidate.id === item.objectId);
|
|
7153
|
+
return {
|
|
7154
|
+
...area?.displayLabel ? { displayLabel: area.displayLabel } : {},
|
|
7155
|
+
...area?.displayType ? { displayType: area.displayType } : {}
|
|
7156
|
+
};
|
|
7157
|
+
}
|
|
7158
|
+
if (item.objectType === "table") {
|
|
7159
|
+
const group = this.groupedTablesByLabel.get(item.label);
|
|
7160
|
+
return {
|
|
7161
|
+
...group?.displayLabel && group.displayLabel !== group.label ? { displayLabel: group.displayLabel } : {},
|
|
7162
|
+
...group?.displayType ? { displayType: group.displayType } : {}
|
|
7163
|
+
};
|
|
7164
|
+
}
|
|
7165
|
+
const seat = this.labelToSeat.get(item.label);
|
|
7166
|
+
const context = seat ? this.seatContext.get(seat.id) : void 0;
|
|
7167
|
+
return {
|
|
7168
|
+
...seat?.displayLabel ? { displayLabel: seat.displayLabel } : {},
|
|
7169
|
+
...context?.displayType ? { displayType: context.displayType } : {}
|
|
7170
|
+
};
|
|
7171
|
+
}
|
|
7077
7172
|
/** Fetch chart, build label maps, mount the renderer, seed statuses, go live. */
|
|
7078
7173
|
async render(host) {
|
|
7079
7174
|
if (this.renderer) return null;
|