@trackunit/react-map-adapter-google 0.0.148-alpha-7afddbbe4cc.0 → 0.0.149-alpha-3bf54986a78.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.
@@ -7,9 +7,13 @@ var aggregationLayers = require('@deck.gl/aggregation-layers');
7
7
  *
8
8
  * Invoked from {@link DeckGlGoogleMapsLifecycle} after dynamic import.
9
9
  */
10
- const buildDeckGlHeatmapLayer = (config) => {
10
+ const buildDeckGlHeatmapLayer = ({ config, onError, }) => {
11
11
  return new aggregationLayers.HeatmapLayer({
12
12
  id: `heatmap-${config.id}`,
13
+ onError: (error) => {
14
+ onError(error);
15
+ return true;
16
+ },
13
17
  data: config.features.features,
14
18
  getPosition: feature => {
15
19
  if (feature.geometry?.type !== "Point")
@@ -5,9 +5,13 @@ import { HeatmapLayer } from '@deck.gl/aggregation-layers';
5
5
  *
6
6
  * Invoked from {@link DeckGlGoogleMapsLifecycle} after dynamic import.
7
7
  */
8
- const buildDeckGlHeatmapLayer = (config) => {
8
+ const buildDeckGlHeatmapLayer = ({ config, onError, }) => {
9
9
  return new HeatmapLayer({
10
10
  id: `heatmap-${config.id}`,
11
+ onError: (error) => {
12
+ onError(error);
13
+ return true;
14
+ },
11
15
  data: config.features.features,
12
16
  getPosition: feature => {
13
17
  if (feature.geometry?.type !== "Point")
@@ -8,12 +8,14 @@ var googleMaps = require('@deck.gl/google-maps');
8
8
  * See https://deck.gl/docs/api-reference/google-maps/google-maps-overlay
9
9
  */
10
10
  const createDeckGlGoogleMapsOverlayRuntime = () => ({
11
- createOverlay: map => {
11
+ createOverlay: ({ map, onLoad, onError }) => {
12
12
  const overlay = new googleMaps.GoogleMapsOverlay({
13
13
  layers: [],
14
14
  // deck.gl 9.4.0 races in interleaved mode on vector maps: when the positioning overlay is added
15
15
  // before Google's WebGL context, deck keeps its own 1×1 canvas and the heatmap never shows.
16
16
  interleaved: false,
17
+ onLoad,
18
+ onError,
17
19
  });
18
20
  overlay.setMap(map);
19
21
  return {
@@ -6,12 +6,14 @@ import { GoogleMapsOverlay } from '@deck.gl/google-maps';
6
6
  * See https://deck.gl/docs/api-reference/google-maps/google-maps-overlay
7
7
  */
8
8
  const createDeckGlGoogleMapsOverlayRuntime = () => ({
9
- createOverlay: map => {
9
+ createOverlay: ({ map, onLoad, onError }) => {
10
10
  const overlay = new GoogleMapsOverlay({
11
11
  layers: [],
12
12
  // deck.gl 9.4.0 races in interleaved mode on vector maps: when the positioning overlay is added
13
13
  // before Google's WebGL context, deck keeps its own 1×1 canvas and the heatmap never shows.
14
14
  interleaved: false,
15
+ onLoad,
16
+ onError,
15
17
  });
16
18
  overlay.setMap(map);
17
19
  return {
package/index.cjs.js CHANGED
@@ -84,6 +84,7 @@ class DeckGlGoogleMapsOverlayCoordinator {
84
84
  this.runtime = null;
85
85
  this.loading = null;
86
86
  this.overlayCreation = null;
87
+ this.statusHandlers = null;
87
88
  }
88
89
  /** Associates the coordinator with a map and applies any pending layers. */
89
90
  connect(map) {
@@ -94,6 +95,10 @@ class DeckGlGoogleMapsOverlayCoordinator {
94
95
  }
95
96
  void this.syncOverlay();
96
97
  }
98
+ /** Receives async overlay readiness and failures, which callers cannot observe themselves. */
99
+ setStatusHandlers(handlers) {
100
+ this.statusHandlers = handlers;
101
+ }
97
102
  /** Starts loading the deck.gl overlay runtime without creating an overlay. */
98
103
  prepare() {
99
104
  return this.loadRuntime().then(() => undefined);
@@ -133,14 +138,32 @@ class DeckGlGoogleMapsOverlayCoordinator {
133
138
  .then(runtime => {
134
139
  if (this.map === null || this.pendingLayers.length === 0)
135
140
  return;
136
- this.overlay = runtime.createOverlay(this.map);
137
- this.overlay.setLayers(this.pendingLayers);
141
+ const overlay = runtime.createOverlay({
142
+ map: this.map,
143
+ onLoad: () => {
144
+ if (this.overlay === overlay)
145
+ this.statusHandlers?.onReady();
146
+ },
147
+ onError: cause => this.handleOverlayError(overlay, cause),
148
+ });
149
+ this.overlay = overlay;
150
+ overlay.setLayers(this.pendingLayers);
151
+ })
152
+ .catch((cause) => {
153
+ this.statusHandlers?.onError(cause);
138
154
  })
139
- .catch(() => undefined)
140
155
  .finally(() => {
141
156
  this.overlayCreation = null;
142
157
  });
143
158
  }
159
+ handleOverlayError(overlay, cause) {
160
+ if (this.overlay !== overlay)
161
+ return;
162
+ // deck.gl can raise this mid render frame (e.g. picking); finalizing there tears down a running Deck.
163
+ queueMicrotask(() => overlay.finalize());
164
+ this.overlay = null;
165
+ this.statusHandlers?.onError(cause);
166
+ }
144
167
  loadRuntime() {
145
168
  if (this.runtime !== null)
146
169
  return Promise.resolve(this.runtime);
@@ -174,10 +197,16 @@ class DeckGlGoogleMapsLifecycle {
174
197
  this.heatmapLayers = new Map();
175
198
  this.heatmapLayerBuilderModule = null;
176
199
  this.syncing = null;
200
+ /** Load failures retry on every snapshot; each heatmap is reported once until the module loads. */
201
+ this.reportedLoadFailureIds = new Set();
177
202
  }
178
203
  /** Binds to the map and syncs if snapshot state is already held. */
179
204
  connect(map) {
180
205
  this.map = map;
206
+ this.overlayCoordinator.setStatusHandlers({
207
+ onReady: () => this.reportedLoadFailureIds.clear(),
208
+ onError: cause => this.handleOverlayError(cause),
209
+ });
181
210
  this.overlayCoordinator.connect(map);
182
211
  void this.sync();
183
212
  }
@@ -196,7 +225,9 @@ class DeckGlGoogleMapsLifecycle {
196
225
  this.map = null;
197
226
  this.heatmapConfigs = [];
198
227
  this.heatmapLayers.clear();
228
+ this.reportedLoadFailureIds.clear();
199
229
  this.syncing = null;
230
+ this.overlayCoordinator.setStatusHandlers(null);
200
231
  this.overlayCoordinator.destroy();
201
232
  }
202
233
  sync() {
@@ -217,25 +248,26 @@ class DeckGlGoogleMapsLifecycle {
217
248
  .then(([module]) => {
218
249
  this.heatmapLayerBuilderModule = module;
219
250
  this.syncing = null;
251
+ this.reportedLoadFailureIds.clear();
220
252
  if (this.map === null)
221
253
  return;
222
254
  this.applyCurrentLayers(module);
223
255
  })
224
- .catch(() => {
256
+ .catch((cause) => {
225
257
  this.syncing = null;
258
+ if (this.map === null)
259
+ return;
260
+ this.reportLoadFailure(cause);
226
261
  });
227
262
  }
228
263
  applyCurrentLayers(module) {
229
264
  const currentIds = new Set(this.heatmapConfigs.map(config => config.id));
230
- const layers = this.heatmapConfigs.map(config => {
231
- const tracked = this.heatmapLayers.get(config.id);
232
- if (tracked !== undefined && esToolkit.isEqual(tracked.config, config)) {
233
- return tracked.layer;
234
- }
235
- const layer = module.buildDeckGlHeatmapLayer(config);
236
- this.heatmapLayers.set(config.id, { config, layer });
237
- return layer;
238
- });
265
+ const layers = [];
266
+ for (const config of this.heatmapConfigs) {
267
+ const layer = this.resolveLayer(module, config);
268
+ if (layer !== null)
269
+ layers.push(layer);
270
+ }
239
271
  for (const id of this.heatmapLayers.keys()) {
240
272
  if (!currentIds.has(id)) {
241
273
  this.heatmapLayers.delete(id);
@@ -243,6 +275,61 @@ class DeckGlGoogleMapsLifecycle {
243
275
  }
244
276
  this.overlayCoordinator.setLayers(layers);
245
277
  }
278
+ resolveLayer(module, config) {
279
+ const tracked = this.heatmapLayers.get(config.id);
280
+ if (tracked !== undefined && esToolkit.isEqual(tracked.config, config)) {
281
+ return tracked.layer;
282
+ }
283
+ try {
284
+ const layer = module.buildDeckGlHeatmapLayer({
285
+ config,
286
+ onError: cause => this.handleLayerError({ module, config, layer, cause }),
287
+ });
288
+ this.heatmapLayers.set(config.id, { config, layer });
289
+ return layer;
290
+ }
291
+ catch (cause) {
292
+ this.heatmapLayers.set(config.id, { config, layer: null });
293
+ this.reportError([config], "renderer-update-failed", cause);
294
+ return null;
295
+ }
296
+ }
297
+ handleLayerError({ module, config, layer, cause, }) {
298
+ if (this.heatmapLayers.get(config.id)?.layer !== layer)
299
+ return;
300
+ const failed = { config, layer: null };
301
+ this.heatmapLayers.set(config.id, failed);
302
+ this.reportError([config], "renderer-update-failed", cause);
303
+ // deck.gl raises layer errors mid update/draw; finalizing the overlay there tears down a running Deck.
304
+ queueMicrotask(() => {
305
+ if (this.heatmapLayers.get(config.id) !== failed)
306
+ return;
307
+ this.applyCurrentLayers(module);
308
+ });
309
+ }
310
+ /** deck.gl cannot reuse layers of a finalized overlay; failed builds stay tracked so they are not re-reported. */
311
+ handleOverlayError(cause) {
312
+ for (const [id, tracked] of this.heatmapLayers) {
313
+ if (tracked.layer !== null)
314
+ this.heatmapLayers.delete(id);
315
+ }
316
+ this.reportLoadFailure(cause);
317
+ }
318
+ reportLoadFailure(cause) {
319
+ this.reportOnce(this.reportedLoadFailureIds, this.heatmapConfigs, "renderer-load-failed", cause);
320
+ }
321
+ reportOnce(reportedIds, configs, code, cause) {
322
+ const unreported = configs.filter(config => !reportedIds.has(config.id));
323
+ for (const config of unreported) {
324
+ reportedIds.add(config.id);
325
+ }
326
+ this.reportError(unreported, code, cause);
327
+ }
328
+ reportError(configs, code, cause) {
329
+ for (const config of configs) {
330
+ config.onError?.({ layerId: config.id, code, cause });
331
+ }
332
+ }
246
333
  }
247
334
 
248
335
  /**
package/index.esm.js CHANGED
@@ -83,6 +83,7 @@ class DeckGlGoogleMapsOverlayCoordinator {
83
83
  this.runtime = null;
84
84
  this.loading = null;
85
85
  this.overlayCreation = null;
86
+ this.statusHandlers = null;
86
87
  }
87
88
  /** Associates the coordinator with a map and applies any pending layers. */
88
89
  connect(map) {
@@ -93,6 +94,10 @@ class DeckGlGoogleMapsOverlayCoordinator {
93
94
  }
94
95
  void this.syncOverlay();
95
96
  }
97
+ /** Receives async overlay readiness and failures, which callers cannot observe themselves. */
98
+ setStatusHandlers(handlers) {
99
+ this.statusHandlers = handlers;
100
+ }
96
101
  /** Starts loading the deck.gl overlay runtime without creating an overlay. */
97
102
  prepare() {
98
103
  return this.loadRuntime().then(() => undefined);
@@ -132,14 +137,32 @@ class DeckGlGoogleMapsOverlayCoordinator {
132
137
  .then(runtime => {
133
138
  if (this.map === null || this.pendingLayers.length === 0)
134
139
  return;
135
- this.overlay = runtime.createOverlay(this.map);
136
- this.overlay.setLayers(this.pendingLayers);
140
+ const overlay = runtime.createOverlay({
141
+ map: this.map,
142
+ onLoad: () => {
143
+ if (this.overlay === overlay)
144
+ this.statusHandlers?.onReady();
145
+ },
146
+ onError: cause => this.handleOverlayError(overlay, cause),
147
+ });
148
+ this.overlay = overlay;
149
+ overlay.setLayers(this.pendingLayers);
150
+ })
151
+ .catch((cause) => {
152
+ this.statusHandlers?.onError(cause);
137
153
  })
138
- .catch(() => undefined)
139
154
  .finally(() => {
140
155
  this.overlayCreation = null;
141
156
  });
142
157
  }
158
+ handleOverlayError(overlay, cause) {
159
+ if (this.overlay !== overlay)
160
+ return;
161
+ // deck.gl can raise this mid render frame (e.g. picking); finalizing there tears down a running Deck.
162
+ queueMicrotask(() => overlay.finalize());
163
+ this.overlay = null;
164
+ this.statusHandlers?.onError(cause);
165
+ }
143
166
  loadRuntime() {
144
167
  if (this.runtime !== null)
145
168
  return Promise.resolve(this.runtime);
@@ -173,10 +196,16 @@ class DeckGlGoogleMapsLifecycle {
173
196
  this.heatmapLayers = new Map();
174
197
  this.heatmapLayerBuilderModule = null;
175
198
  this.syncing = null;
199
+ /** Load failures retry on every snapshot; each heatmap is reported once until the module loads. */
200
+ this.reportedLoadFailureIds = new Set();
176
201
  }
177
202
  /** Binds to the map and syncs if snapshot state is already held. */
178
203
  connect(map) {
179
204
  this.map = map;
205
+ this.overlayCoordinator.setStatusHandlers({
206
+ onReady: () => this.reportedLoadFailureIds.clear(),
207
+ onError: cause => this.handleOverlayError(cause),
208
+ });
180
209
  this.overlayCoordinator.connect(map);
181
210
  void this.sync();
182
211
  }
@@ -195,7 +224,9 @@ class DeckGlGoogleMapsLifecycle {
195
224
  this.map = null;
196
225
  this.heatmapConfigs = [];
197
226
  this.heatmapLayers.clear();
227
+ this.reportedLoadFailureIds.clear();
198
228
  this.syncing = null;
229
+ this.overlayCoordinator.setStatusHandlers(null);
199
230
  this.overlayCoordinator.destroy();
200
231
  }
201
232
  sync() {
@@ -216,25 +247,26 @@ class DeckGlGoogleMapsLifecycle {
216
247
  .then(([module]) => {
217
248
  this.heatmapLayerBuilderModule = module;
218
249
  this.syncing = null;
250
+ this.reportedLoadFailureIds.clear();
219
251
  if (this.map === null)
220
252
  return;
221
253
  this.applyCurrentLayers(module);
222
254
  })
223
- .catch(() => {
255
+ .catch((cause) => {
224
256
  this.syncing = null;
257
+ if (this.map === null)
258
+ return;
259
+ this.reportLoadFailure(cause);
225
260
  });
226
261
  }
227
262
  applyCurrentLayers(module) {
228
263
  const currentIds = new Set(this.heatmapConfigs.map(config => config.id));
229
- const layers = this.heatmapConfigs.map(config => {
230
- const tracked = this.heatmapLayers.get(config.id);
231
- if (tracked !== undefined && isEqual(tracked.config, config)) {
232
- return tracked.layer;
233
- }
234
- const layer = module.buildDeckGlHeatmapLayer(config);
235
- this.heatmapLayers.set(config.id, { config, layer });
236
- return layer;
237
- });
264
+ const layers = [];
265
+ for (const config of this.heatmapConfigs) {
266
+ const layer = this.resolveLayer(module, config);
267
+ if (layer !== null)
268
+ layers.push(layer);
269
+ }
238
270
  for (const id of this.heatmapLayers.keys()) {
239
271
  if (!currentIds.has(id)) {
240
272
  this.heatmapLayers.delete(id);
@@ -242,6 +274,61 @@ class DeckGlGoogleMapsLifecycle {
242
274
  }
243
275
  this.overlayCoordinator.setLayers(layers);
244
276
  }
277
+ resolveLayer(module, config) {
278
+ const tracked = this.heatmapLayers.get(config.id);
279
+ if (tracked !== undefined && isEqual(tracked.config, config)) {
280
+ return tracked.layer;
281
+ }
282
+ try {
283
+ const layer = module.buildDeckGlHeatmapLayer({
284
+ config,
285
+ onError: cause => this.handleLayerError({ module, config, layer, cause }),
286
+ });
287
+ this.heatmapLayers.set(config.id, { config, layer });
288
+ return layer;
289
+ }
290
+ catch (cause) {
291
+ this.heatmapLayers.set(config.id, { config, layer: null });
292
+ this.reportError([config], "renderer-update-failed", cause);
293
+ return null;
294
+ }
295
+ }
296
+ handleLayerError({ module, config, layer, cause, }) {
297
+ if (this.heatmapLayers.get(config.id)?.layer !== layer)
298
+ return;
299
+ const failed = { config, layer: null };
300
+ this.heatmapLayers.set(config.id, failed);
301
+ this.reportError([config], "renderer-update-failed", cause);
302
+ // deck.gl raises layer errors mid update/draw; finalizing the overlay there tears down a running Deck.
303
+ queueMicrotask(() => {
304
+ if (this.heatmapLayers.get(config.id) !== failed)
305
+ return;
306
+ this.applyCurrentLayers(module);
307
+ });
308
+ }
309
+ /** deck.gl cannot reuse layers of a finalized overlay; failed builds stay tracked so they are not re-reported. */
310
+ handleOverlayError(cause) {
311
+ for (const [id, tracked] of this.heatmapLayers) {
312
+ if (tracked.layer !== null)
313
+ this.heatmapLayers.delete(id);
314
+ }
315
+ this.reportLoadFailure(cause);
316
+ }
317
+ reportLoadFailure(cause) {
318
+ this.reportOnce(this.reportedLoadFailureIds, this.heatmapConfigs, "renderer-load-failed", cause);
319
+ }
320
+ reportOnce(reportedIds, configs, code, cause) {
321
+ const unreported = configs.filter(config => !reportedIds.has(config.id));
322
+ for (const config of unreported) {
323
+ reportedIds.add(config.id);
324
+ }
325
+ this.reportError(unreported, code, cause);
326
+ }
327
+ reportError(configs, code, cause) {
328
+ for (const config of configs) {
329
+ config.onError?.({ layerId: config.id, code, cause });
330
+ }
331
+ }
245
332
  }
246
333
 
247
334
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-map-adapter-google",
3
- "version": "0.0.148-alpha-7afddbbe4cc.0",
3
+ "version": "0.0.149-alpha-3bf54986a78.0",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -14,9 +14,9 @@
14
14
  "@loaders.gl/core": "~4.5.2",
15
15
  "@luma.gl/core": "^9.4.1",
16
16
  "@luma.gl/engine": "^9.4.1",
17
- "@trackunit/react-map-adapter-shared": "0.0.158-alpha-7afddbbe4cc.0",
18
- "@trackunit/react-map-color-utils": "0.0.133-alpha-7afddbbe4cc.0",
19
- "@trackunit/geo-json-utils": "1.18.7-alpha-7afddbbe4cc.0",
17
+ "@trackunit/react-map-adapter-shared": "0.0.159-alpha-3bf54986a78.0",
18
+ "@trackunit/react-map-color-utils": "0.0.133-alpha-3bf54986a78.0",
19
+ "@trackunit/geo-json-utils": "1.18.7-alpha-3bf54986a78.0",
20
20
  "@googlemaps/markerclusterer": "^2.6.2",
21
21
  "@vis.gl/react-google-maps": "^1.7.1",
22
22
  "es-toolkit": "^1.52.0",
@@ -1,8 +1,9 @@
1
1
  import type { Layer } from "@deck.gl/core";
2
- import type { HeatmapSourceConfig, LayerSnapshot } from "@trackunit/react-map-adapter-shared";
2
+ import type { LayerSnapshot } from "@trackunit/react-map-adapter-shared";
3
+ import type { BuildDeckGlHeatmapLayerOptions } from "../heatmap/buildDeckGlHeatmapLayer";
3
4
  import { DeckGlGoogleMapsOverlayCoordinator } from "./DeckGlGoogleMapsOverlayCoordinator";
4
5
  type HeatmapLayerBuilderModule = Readonly<{
5
- buildDeckGlHeatmapLayer: (config: HeatmapSourceConfig) => Layer;
6
+ buildDeckGlHeatmapLayer: (options: BuildDeckGlHeatmapLayerOptions) => Layer;
6
7
  }>;
7
8
  type LoadHeatmapLayerBuilder = () => Promise<HeatmapLayerBuilderModule>;
8
9
  /**
@@ -20,6 +21,8 @@ export declare class DeckGlGoogleMapsLifecycle {
20
21
  private readonly heatmapLayers;
21
22
  private heatmapLayerBuilderModule;
22
23
  private syncing;
24
+ /** Load failures retry on every snapshot; each heatmap is reported once until the module loads. */
25
+ private readonly reportedLoadFailureIds;
23
26
  constructor(overlayCoordinator?: DeckGlGoogleMapsOverlayCoordinator, loadHeatmapLayerBuilder?: LoadHeatmapLayerBuilder);
24
27
  /** Binds to the map and syncs if snapshot state is already held. */
25
28
  connect(map: google.maps.Map): void;
@@ -34,5 +37,12 @@ export declare class DeckGlGoogleMapsLifecycle {
34
37
  destroy(): void;
35
38
  private sync;
36
39
  private applyCurrentLayers;
40
+ private resolveLayer;
41
+ private handleLayerError;
42
+ /** deck.gl cannot reuse layers of a finalized overlay; failed builds stay tracked so they are not re-reported. */
43
+ private handleOverlayError;
44
+ private reportLoadFailure;
45
+ private reportOnce;
46
+ private reportError;
37
47
  }
38
48
  export {};
@@ -1,6 +1,12 @@
1
1
  import type { Layer } from "@deck.gl/core";
2
2
  import type { DeckGlGoogleMapsOverlayRuntime } from "./createDeckGlGoogleMapsOverlayRuntime";
3
3
  export type LoadDeckGlGoogleMapsOverlayRuntime = () => Promise<DeckGlGoogleMapsOverlayRuntime>;
4
+ export type DeckGlGoogleMapsOverlayStatusHandlers = Readonly<{
5
+ /** The overlay's WebGL device is ready. */
6
+ onReady: () => void;
7
+ /** Overlay creation failed, or deck.gl reported an overlay error (the overlay is then discarded). */
8
+ onError: (cause: unknown) => void;
9
+ }>;
4
10
  /**
5
11
  * Owns a single deck.gl `GoogleMapsOverlay` on a Google map.
6
12
  *
@@ -15,9 +21,12 @@ export declare class DeckGlGoogleMapsOverlayCoordinator {
15
21
  private runtime;
16
22
  private loading;
17
23
  private overlayCreation;
24
+ private statusHandlers;
18
25
  constructor(loadOverlayRuntime?: LoadDeckGlGoogleMapsOverlayRuntime);
19
26
  /** Associates the coordinator with a map and applies any pending layers. */
20
27
  connect(map: google.maps.Map): void;
28
+ /** Receives async overlay readiness and failures, which callers cannot observe themselves. */
29
+ setStatusHandlers(handlers: DeckGlGoogleMapsOverlayStatusHandlers | null): void;
21
30
  /** Starts loading the deck.gl overlay runtime without creating an overlay. */
22
31
  prepare(): Promise<void>;
23
32
  /**
@@ -29,5 +38,6 @@ export declare class DeckGlGoogleMapsOverlayCoordinator {
29
38
  /** Finalizes the overlay and clears coordinator state. */
30
39
  destroy(): void;
31
40
  private syncOverlay;
41
+ private handleOverlayError;
32
42
  private loadRuntime;
33
43
  }
@@ -5,9 +5,16 @@ export type DeckGlGoogleMapsOverlayHandle = Readonly<{
5
5
  setLayers: (layers: ReadonlyArray<Layer>) => void;
6
6
  finalize: () => void;
7
7
  }>;
8
+ export type CreateDeckGlGoogleMapsOverlayOptions = Readonly<{
9
+ map: google.maps.Map;
10
+ /** Called once deck.gl's WebGL device is ready. */
11
+ onLoad: () => void;
12
+ /** Receives deck.gl's async overlay errors, such as WebGL device creation failure or context loss. */
13
+ onError: (cause: unknown) => void;
14
+ }>;
8
15
  /** Factory after lazy-loading `@deck.gl/google-maps`. */
9
16
  export type DeckGlGoogleMapsOverlayRuntime = Readonly<{
10
- createOverlay: (map: google.maps.Map) => DeckGlGoogleMapsOverlayHandle;
17
+ createOverlay: (options: CreateDeckGlGoogleMapsOverlayOptions) => DeckGlGoogleMapsOverlayHandle;
11
18
  }>;
12
19
  /**
13
20
  * Creates one `GoogleMapsOverlay` per map.
@@ -1,8 +1,13 @@
1
1
  import { HeatmapLayer } from "@deck.gl/aggregation-layers";
2
2
  import type { GeoJsonFeature, HeatmapSourceConfig } from "@trackunit/react-map-adapter-shared";
3
+ export type BuildDeckGlHeatmapLayerOptions = Readonly<{
4
+ config: HeatmapSourceConfig;
5
+ /** Receives deck.gl's async layer errors (setup and draw); draw errors repeat every frame. */
6
+ onError: (cause: unknown) => void;
7
+ }>;
3
8
  /**
4
9
  * Maps {@link HeatmapSourceConfig} → deck.gl `HeatmapLayer` on Google Maps.
5
10
  *
6
11
  * Invoked from {@link DeckGlGoogleMapsLifecycle} after dynamic import.
7
12
  */
8
- export declare const buildDeckGlHeatmapLayer: (config: HeatmapSourceConfig) => HeatmapLayer<GeoJsonFeature>;
13
+ export declare const buildDeckGlHeatmapLayer: ({ config, onError, }: BuildDeckGlHeatmapLayerOptions) => HeatmapLayer<GeoJsonFeature>;