@tileflow/svelte 0.1.0-alpha.16 → 0.1.0-alpha.17
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/package.json +2 -2
- package/src/TileflowMap.svelte +69 -114
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tileflow/svelte",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.17",
|
|
4
4
|
"description": "Svelte component for rendering Tileflow maps with MapLibre.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@tileflow/core": "0.1.0-alpha.
|
|
45
|
+
"@tileflow/core": ">=0.1.0-alpha.17 <0.1.0-beta.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"maplibre-gl": ">=5",
|
package/src/TileflowMap.svelte
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
type LngLatLike,
|
|
4
4
|
type Map as MapLibreMap,
|
|
5
5
|
type MapOptions as MapLibreMapOptions,
|
|
6
|
-
type RequestParameters,
|
|
7
|
-
type RequestTransformFunction,
|
|
8
6
|
type StyleSpecification,
|
|
9
7
|
} from 'maplibre-gl';
|
|
10
8
|
import {createEventDispatcher, onMount, tick} from 'svelte';
|
|
@@ -15,13 +13,11 @@
|
|
|
15
13
|
mergeTileflowAnalytics,
|
|
16
14
|
normalizeTileflowCaptureId,
|
|
17
15
|
normalizeTileflowStaticImageSize,
|
|
18
|
-
resolveTileflowAnalyticsRequestUrl,
|
|
19
16
|
resolveTileflowManifestMap,
|
|
20
17
|
resolveTileflowMapMode,
|
|
21
18
|
resolveTileflowRuntimeStyle,
|
|
22
19
|
resolveTileflowStaticImageUrl,
|
|
23
20
|
shouldLoadTileflowManifest,
|
|
24
|
-
startTileflowSession,
|
|
25
21
|
type MapLibreStyle,
|
|
26
22
|
type TileflowAnalytics,
|
|
27
23
|
type TileflowConfig,
|
|
@@ -29,6 +25,13 @@
|
|
|
29
25
|
type TileflowProjectThemes,
|
|
30
26
|
type TileflowRuntimeManifestMap,
|
|
31
27
|
} from '@tileflow/core';
|
|
28
|
+
import {
|
|
29
|
+
attachTileflowMapLifecycle,
|
|
30
|
+
createTileflowMarkerController,
|
|
31
|
+
createTileflowSessionStarter,
|
|
32
|
+
createTileflowTransformRequest,
|
|
33
|
+
type TileflowMapLifecycleAttachment,
|
|
34
|
+
} from '@tileflow/core/browser';
|
|
32
35
|
|
|
33
36
|
export let alt = '';
|
|
34
37
|
export let analytics: TileflowAnalytics | undefined = undefined;
|
|
@@ -63,7 +66,7 @@
|
|
|
63
66
|
let imageSize: {height: number; width: number} | null = null;
|
|
64
67
|
let imageResizeObserver: ResizeObserver | null = null;
|
|
65
68
|
let mapInstance: MapLibreMap | null = null;
|
|
66
|
-
let
|
|
69
|
+
let mapLifecycleAttachment: TileflowMapLifecycleAttachment | null = null;
|
|
67
70
|
let mapResizeObserver: ResizeObserver | null = null;
|
|
68
71
|
let manifestMap: TileflowRuntimeManifestMap | null = null;
|
|
69
72
|
let manifestLoadId = 0;
|
|
@@ -73,7 +76,22 @@
|
|
|
73
76
|
|
|
74
77
|
const dispatch = createEventDispatcher<{load: MapLibreMap}>();
|
|
75
78
|
const sessionId = createTileflowSessionId();
|
|
76
|
-
const
|
|
79
|
+
const sessionStarter = createTileflowSessionStarter({sessionId, source: 'svelte'});
|
|
80
|
+
const markerController = createTileflowMarkerController<
|
|
81
|
+
MapLibreMap,
|
|
82
|
+
TileflowMapMarker,
|
|
83
|
+
maplibregl.Marker
|
|
84
|
+
>({
|
|
85
|
+
attach(markerInstance, targetMap, definition) {
|
|
86
|
+
markerInstance.setLngLat(definition.coordinates).addTo(targetMap);
|
|
87
|
+
markerInstance.getElement().title = definition.label ?? definition.id;
|
|
88
|
+
},
|
|
89
|
+
create: (definition) =>
|
|
90
|
+
new maplibregl.Marker({
|
|
91
|
+
color: definition.color ?? '#C6A15B',
|
|
92
|
+
}),
|
|
93
|
+
remove: (markerInstance) => markerInstance.remove(),
|
|
94
|
+
});
|
|
77
95
|
|
|
78
96
|
$: resolvedMode = resolveTileflowMapMode({imageUrl, mode, preferLocalDev});
|
|
79
97
|
$: resolvedCaptureId = normalizeTileflowCaptureId(captureId);
|
|
@@ -225,11 +243,22 @@
|
|
|
225
243
|
|
|
226
244
|
function destroyMap() {
|
|
227
245
|
readinessRunId += 1;
|
|
246
|
+
const lifecycleAttachment = mapLifecycleAttachment;
|
|
247
|
+
const currentMap = mapInstance;
|
|
248
|
+
mapLifecycleAttachment = null;
|
|
249
|
+
mapInstance = null;
|
|
228
250
|
mapResizeObserver?.disconnect();
|
|
229
251
|
mapResizeObserver = null;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
lifecycleAttachment?.dispose();
|
|
255
|
+
} finally {
|
|
256
|
+
try {
|
|
257
|
+
markerController.dispose();
|
|
258
|
+
} finally {
|
|
259
|
+
currentMap?.remove();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
233
262
|
}
|
|
234
263
|
|
|
235
264
|
function recreateMap() {
|
|
@@ -248,11 +277,13 @@
|
|
|
248
277
|
container,
|
|
249
278
|
interactive: resolvedInteractive,
|
|
250
279
|
style: runtime.style as StyleSpecification | string,
|
|
251
|
-
transformRequest:
|
|
252
|
-
|
|
280
|
+
transformRequest: createTileflowTransformRequest({
|
|
281
|
+
always: true,
|
|
282
|
+
asyncAnalyticsTiming: 'request',
|
|
283
|
+
getAnalytics: () => resolvedAnalytics,
|
|
253
284
|
sessionId,
|
|
254
|
-
mapOptions?.transformRequest,
|
|
255
|
-
),
|
|
285
|
+
transformRequest: mapOptions?.transformRequest ?? undefined,
|
|
286
|
+
}),
|
|
256
287
|
zoom: resolvedZoom,
|
|
257
288
|
});
|
|
258
289
|
|
|
@@ -267,47 +298,29 @@
|
|
|
267
298
|
});
|
|
268
299
|
mapResizeObserver.observe(container);
|
|
269
300
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
});
|
|
294
|
-
maplibreMap.on('styledataloading', () => {
|
|
295
|
-
readinessRunId += 1;
|
|
296
|
-
captureState = 'loading';
|
|
297
|
-
});
|
|
298
|
-
maplibreMap.on('idle', () => {
|
|
299
|
-
const runId = ++readinessRunId;
|
|
300
|
-
requestAnimationFrame(() => {
|
|
301
|
-
requestAnimationFrame(() => {
|
|
302
|
-
if (runId === readinessRunId && mapInstance === maplibreMap) {
|
|
303
|
-
captureState = 'idle';
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
maplibreMap.on('error', () => {
|
|
309
|
-
readinessRunId += 1;
|
|
310
|
-
captureState = 'error';
|
|
301
|
+
mapLifecycleAttachment = attachTileflowMapLifecycle<MapLibreMap, number>({
|
|
302
|
+
getSession: () => {
|
|
303
|
+
const analyticsForLoad = resolvedAnalytics;
|
|
304
|
+
return {
|
|
305
|
+
analytics: analyticsForLoad,
|
|
306
|
+
styleId:
|
|
307
|
+
analyticsForLoad?.styleId ?? (typeof runtime.style === 'string' ? runtime.style : map),
|
|
308
|
+
};
|
|
309
|
+
},
|
|
310
|
+
map: maplibreMap,
|
|
311
|
+
onLoad: () => dispatch('load', maplibreMap),
|
|
312
|
+
scheduler: {
|
|
313
|
+
cancelFrame: (frame) => cancelAnimationFrame(frame),
|
|
314
|
+
requestFrame: (callback) => requestAnimationFrame(callback),
|
|
315
|
+
},
|
|
316
|
+
sessionStarter,
|
|
317
|
+
setState: (state) => {
|
|
318
|
+
captureState = state;
|
|
319
|
+
},
|
|
320
|
+
subscribe: (targetMap, event, listener) => {
|
|
321
|
+
const subscription = targetMap.on(event, listener);
|
|
322
|
+
return () => subscription.unsubscribe();
|
|
323
|
+
},
|
|
311
324
|
});
|
|
312
325
|
|
|
313
326
|
syncMarkers();
|
|
@@ -321,30 +334,12 @@
|
|
|
321
334
|
}
|
|
322
335
|
|
|
323
336
|
function syncMarkers() {
|
|
324
|
-
clearMarkers();
|
|
325
|
-
|
|
326
337
|
if (!mapInstance) {
|
|
338
|
+
markerController.clear();
|
|
327
339
|
return;
|
|
328
340
|
}
|
|
329
341
|
|
|
330
|
-
|
|
331
|
-
const markerInstance = new maplibregl.Marker({
|
|
332
|
-
color: marker.color ?? '#C6A15B',
|
|
333
|
-
})
|
|
334
|
-
.setLngLat(marker.coordinates)
|
|
335
|
-
.addTo(mapInstance!);
|
|
336
|
-
|
|
337
|
-
markerInstance.getElement().title = marker.label ?? marker.id;
|
|
338
|
-
return markerInstance;
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
function clearMarkers() {
|
|
343
|
-
for (const marker of markerInstances) {
|
|
344
|
-
marker.remove();
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
markerInstances = [];
|
|
342
|
+
markerController.replace(mapInstance, markers);
|
|
348
343
|
}
|
|
349
344
|
|
|
350
345
|
async function handleImageLoad(event: Event) {
|
|
@@ -383,46 +378,6 @@
|
|
|
383
378
|
captureState = 'error';
|
|
384
379
|
}
|
|
385
380
|
|
|
386
|
-
function createTransformRequest(
|
|
387
|
-
getAnalytics: () => TileflowAnalytics | undefined,
|
|
388
|
-
session: string,
|
|
389
|
-
userTransformRequest?: TileflowMapOptions['transformRequest'],
|
|
390
|
-
): RequestTransformFunction | undefined {
|
|
391
|
-
return (url, resourceType) => {
|
|
392
|
-
const request = userTransformRequest?.(url, resourceType);
|
|
393
|
-
const analyticsInput = getAnalytics();
|
|
394
|
-
|
|
395
|
-
if (isPromiseLike(request)) {
|
|
396
|
-
return request.then((resolvedRequest) =>
|
|
397
|
-
applyTileflowAnalyticsRequest(url, resolvedRequest, analyticsInput, session) ??
|
|
398
|
-
resolvedRequest,
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
return applyTileflowAnalyticsRequest(url, request, analyticsInput, session);
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
function applyTileflowAnalyticsRequest(
|
|
407
|
-
url: string,
|
|
408
|
-
request: RequestParameters | undefined,
|
|
409
|
-
analyticsInput: TileflowAnalytics | undefined,
|
|
410
|
-
session: string,
|
|
411
|
-
): RequestParameters | undefined {
|
|
412
|
-
const requestUrl = request?.url ?? url;
|
|
413
|
-
const nextUrl = resolveTileflowAnalyticsRequestUrl(requestUrl, analyticsInput, session);
|
|
414
|
-
|
|
415
|
-
if (!nextUrl) {
|
|
416
|
-
return request;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return request ? {...request, url: nextUrl} : {url: nextUrl};
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
function isPromiseLike<T>(value: T | Promise<T> | undefined): value is Promise<T> {
|
|
423
|
-
return Boolean(value && typeof (value as Promise<T>).then === 'function');
|
|
424
|
-
}
|
|
425
|
-
|
|
426
381
|
function formatHeight(value: number | string): string {
|
|
427
382
|
return typeof value === 'number' ? `${value}px` : value;
|
|
428
383
|
}
|