@nuxt/scripts 1.0.0-beta.25 → 1.0.0-beta.27

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.
Files changed (42) hide show
  1. package/dist/client/200.html +1 -1
  2. package/dist/client/404.html +1 -1
  3. package/dist/client/_nuxt/{DjhmCJlE.js → CwXQ1Eqw.js} +3 -3
  4. package/dist/client/_nuxt/{TJ5JFHov.js → JXDRhrZp.js} +1 -1
  5. package/dist/client/_nuxt/{C-7nRtzO.js → KCxg59bo.js} +1 -1
  6. package/dist/client/_nuxt/builds/latest.json +1 -1
  7. package/dist/client/_nuxt/builds/meta/d0d06e27-af53-4f1a-b7ae-18727423b3ed.json +1 -0
  8. package/dist/client/_nuxt/{D5k4eN9O.js → viP3Pc9X.js} +1 -1
  9. package/dist/client/index.html +1 -1
  10. package/dist/module.d.mts +1 -1
  11. package/dist/module.d.ts +1 -1
  12. package/dist/module.json +1 -1
  13. package/dist/module.mjs +38 -8
  14. package/dist/registry.mjs +2 -2
  15. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +2 -5
  16. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +14 -15
  17. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +2 -5
  18. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.d.vue.ts +1 -4
  19. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue +32 -41
  20. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue.d.ts +1 -4
  21. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue +19 -28
  22. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue +18 -22
  23. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue +30 -37
  24. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.d.vue.ts +1 -4
  25. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +31 -36
  26. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue.d.ts +1 -4
  27. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +17 -22
  28. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +19 -28
  29. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue +19 -28
  30. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue +19 -28
  31. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue +19 -28
  32. package/dist/runtime/components/GoogleMaps/injectionKeys.d.ts +11 -0
  33. package/dist/runtime/components/GoogleMaps/injectionKeys.js +3 -0
  34. package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.d.ts +26 -0
  35. package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.js +37 -0
  36. package/dist/runtime/server/gravatar-proxy.d.ts +1 -1
  37. package/dist/runtime/server/gravatar-proxy.js +0 -1
  38. package/dist/stats.d.mts +97 -9
  39. package/dist/stats.d.ts +97 -9
  40. package/dist/stats.mjs +1233 -292
  41. package/package.json +8 -6
  42. package/dist/client/_nuxt/builds/meta/2ec0342e-5e00-4781-82aa-c3c0f9154516.json +0 -1
@@ -1,9 +1,7 @@
1
1
  <script setup>
2
- import { whenever } from "@vueuse/core";
3
- import { inject, onUnmounted, useTemplateRef } from "vue";
4
- import { MAP_INJECTION_KEY } from "./ScriptGoogleMaps.vue";
5
- import { ADVANCED_MARKER_ELEMENT_INJECTION_KEY } from "./ScriptGoogleMapsAdvancedMarkerElement.vue";
6
- import { MARKER_INJECTION_KEY } from "./ScriptGoogleMapsMarker.vue";
2
+ import { inject, useTemplateRef, watch } from "vue";
3
+ import { ADVANCED_MARKER_ELEMENT_INJECTION_KEY, MARKER_INJECTION_KEY } from "./injectionKeys";
4
+ import { useGoogleMapsResource } from "./useGoogleMapsResource";
7
5
  const props = defineProps({
8
6
  options: { type: null, required: false }
9
7
  });
@@ -19,58 +17,53 @@ const infoWindowEvents = [
19
17
  "visible",
20
18
  "zindex_changed"
21
19
  ];
22
- const mapContext = inject(MAP_INJECTION_KEY, void 0);
23
20
  const markerContext = inject(MARKER_INJECTION_KEY, void 0);
24
21
  const advancedMarkerElementContext = inject(ADVANCED_MARKER_ELEMENT_INJECTION_KEY, void 0);
25
22
  const infoWindowContainer = useTemplateRef("info-window-container");
26
- let infoWindow;
27
- whenever(
28
- () => mapContext?.map.value && mapContext.mapsApi.value && infoWindowContainer.value,
29
- () => {
30
- infoWindow = new mapContext.mapsApi.value.InfoWindow({
23
+ let markerClickListener;
24
+ const infoWindow = useGoogleMapsResource({
25
+ ready: () => !!infoWindowContainer.value,
26
+ create({ mapsApi, map }) {
27
+ const iw = new mapsApi.InfoWindow({
31
28
  content: infoWindowContainer.value,
32
29
  ...props.options
33
30
  });
34
- setupInfoWindowEventListeners(infoWindow);
31
+ setupEventListeners(iw);
35
32
  if (markerContext?.marker.value) {
36
- markerContext.marker.value.addListener("click", () => {
37
- infoWindow.open({
33
+ markerClickListener = markerContext.marker.value.addListener("click", () => {
34
+ iw.open({
38
35
  anchor: markerContext.marker.value,
39
- map: mapContext.map.value
36
+ map
40
37
  });
41
38
  });
42
39
  } else if (advancedMarkerElementContext?.advancedMarkerElement.value) {
43
- advancedMarkerElementContext.advancedMarkerElement.value.addListener("click", () => {
44
- infoWindow.open({
40
+ markerClickListener = advancedMarkerElementContext.advancedMarkerElement.value.addListener("click", () => {
41
+ iw.open({
45
42
  anchor: advancedMarkerElementContext.advancedMarkerElement.value,
46
- map: mapContext.map.value
43
+ map
47
44
  });
48
45
  });
49
46
  } else {
50
- infoWindow.setPosition(props.options?.position);
51
- infoWindow.open(mapContext.map.value);
47
+ iw.setPosition(props.options?.position);
48
+ iw.open(map);
52
49
  }
53
- whenever(() => props.options, (options) => {
54
- infoWindow?.setOptions(options);
55
- }, {
56
- deep: true
57
- });
50
+ return iw;
58
51
  },
59
- {
60
- immediate: true,
61
- once: true
62
- }
63
- );
64
- onUnmounted(() => {
65
- if (!infoWindow || !mapContext?.mapsApi.value) {
66
- return;
52
+ cleanup(iw, { mapsApi }) {
53
+ markerClickListener?.remove();
54
+ markerClickListener = void 0;
55
+ mapsApi.event.clearInstanceListeners(iw);
56
+ iw.close();
67
57
  }
68
- mapContext.mapsApi.value.event.clearInstanceListeners(infoWindow);
69
- infoWindow.close();
70
58
  });
71
- function setupInfoWindowEventListeners(infoWindow2) {
59
+ watch(() => props.options, (options) => {
60
+ if (infoWindow.value && options) {
61
+ infoWindow.value.setOptions(options);
62
+ }
63
+ }, { deep: true });
64
+ function setupEventListeners(iw) {
72
65
  infoWindowEvents.forEach((event) => {
73
- infoWindow2.addListener(event, () => emit(event));
66
+ iw.addListener(event, () => emit(event));
74
67
  });
75
68
  }
76
69
  </script>
@@ -1,7 +1,4 @@
1
- import type { InjectionKey, ShallowRef } from 'vue';
2
- export declare const MARKER_INJECTION_KEY: InjectionKey<{
3
- marker: ShallowRef<google.maps.Marker | undefined>;
4
- }>;
1
+ export { MARKER_INJECTION_KEY } from './injectionKeys.js';
5
2
  declare const _default: typeof __VLS_export;
6
3
  export default _default;
7
4
  declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
@@ -1,9 +1,9 @@
1
1
  <script>
2
- import { whenever } from "@vueuse/core";
3
- import { inject, onUnmounted, provide, shallowRef } from "vue";
4
- import { MAP_INJECTION_KEY } from "./ScriptGoogleMaps.vue";
2
+ import { inject, provide, watch } from "vue";
3
+ import { MARKER_INJECTION_KEY } from "./injectionKeys";
5
4
  import { MARKER_CLUSTERER_INJECTION_KEY } from "./ScriptGoogleMapsMarkerClusterer.vue";
6
- export const MARKER_INJECTION_KEY = /* @__PURE__ */ Symbol("marker");
5
+ import { useGoogleMapsResource } from "./useGoogleMapsResource";
6
+ export { MARKER_INJECTION_KEY } from "./injectionKeys";
7
7
  </script>
8
8
 
9
9
  <script setup>
@@ -36,46 +36,41 @@ const eventsWithMapMouseEventPayload = [
36
36
  "mouseover",
37
37
  "mouseup"
38
38
  ];
39
- const mapContext = inject(MAP_INJECTION_KEY, void 0);
40
39
  const markerClustererContext = inject(MARKER_CLUSTERER_INJECTION_KEY, void 0);
41
- const marker = shallowRef(void 0);
42
- whenever(() => mapContext?.map.value && mapContext.mapsApi.value, () => {
43
- marker.value = new mapContext.mapsApi.value.Marker(props.options);
44
- setupMarkerEventListeners(marker.value);
45
- if (markerClustererContext?.markerClusterer.value) {
46
- markerClustererContext.markerClusterer.value.addMarker(marker.value, true);
47
- markerClustererContext.requestRerender();
48
- } else {
49
- marker.value.setMap(mapContext.map.value);
40
+ const marker = useGoogleMapsResource({
41
+ create({ mapsApi, map }) {
42
+ const m = new mapsApi.Marker(props.options);
43
+ setupEventListeners(m);
44
+ if (markerClustererContext?.markerClusterer.value) {
45
+ markerClustererContext.markerClusterer.value.addMarker(m, true);
46
+ markerClustererContext.requestRerender();
47
+ } else {
48
+ m.setMap(map);
49
+ }
50
+ return m;
51
+ },
52
+ cleanup(m, { mapsApi }) {
53
+ mapsApi.event.clearInstanceListeners(m);
54
+ if (markerClustererContext?.markerClusterer.value) {
55
+ markerClustererContext.markerClusterer.value.removeMarker(m, true);
56
+ markerClustererContext.requestRerender();
57
+ } else {
58
+ m.setMap(null);
59
+ }
50
60
  }
51
- whenever(() => props.options, (options) => {
52
- marker.value?.setOptions(options);
53
- }, {
54
- deep: true
55
- });
56
- }, {
57
- immediate: true,
58
- once: true
59
61
  });
60
- onUnmounted(() => {
61
- if (!marker.value || !mapContext?.mapsApi.value) {
62
- return;
63
- }
64
- mapContext.mapsApi.value.event.clearInstanceListeners(marker.value);
65
- if (markerClustererContext?.markerClusterer.value) {
66
- markerClustererContext.markerClusterer.value.removeMarker(marker.value, true);
67
- markerClustererContext.requestRerender();
68
- } else {
69
- marker.value.setMap(null);
62
+ watch(() => props.options, (options) => {
63
+ if (marker.value && options) {
64
+ marker.value.setOptions(options);
70
65
  }
71
- });
66
+ }, { deep: true });
72
67
  provide(MARKER_INJECTION_KEY, { marker });
73
- function setupMarkerEventListeners(marker2) {
68
+ function setupEventListeners(m) {
74
69
  eventsWithoutPayload.forEach((event) => {
75
- marker2.addListener(event, () => emit(event));
70
+ m.addListener(event, () => emit(event));
76
71
  });
77
72
  eventsWithMapMouseEventPayload.forEach((event) => {
78
- marker2.addListener(event, (payload) => emit(event, payload));
73
+ m.addListener(event, (payload) => emit(event, payload));
79
74
  });
80
75
  }
81
76
  </script>
@@ -1,7 +1,4 @@
1
- import type { InjectionKey, ShallowRef } from 'vue';
2
- export declare const MARKER_INJECTION_KEY: InjectionKey<{
3
- marker: ShallowRef<google.maps.Marker | undefined>;
4
- }>;
1
+ export { MARKER_INJECTION_KEY } from './injectionKeys.js';
5
2
  declare const _default: typeof __VLS_export;
6
3
  export default _default;
7
4
  declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import { whenever } from "@vueuse/core";
3
- import { inject, onUnmounted, provide, shallowRef } from "vue";
4
- import { MAP_INJECTION_KEY } from "./ScriptGoogleMaps.vue";
3
+ import { provide, shallowRef } from "vue";
4
+ import { useGoogleMapsResource } from "./useGoogleMapsResource";
5
5
  export const MARKER_CLUSTERER_INJECTION_KEY = /* @__PURE__ */ Symbol("marker-clusterer");
6
6
  </script>
7
7
 
@@ -15,18 +15,20 @@ const markerClustererEvents = [
15
15
  "clusteringbegin",
16
16
  "clusteringend"
17
17
  ];
18
- const mapContext = inject(MAP_INJECTION_KEY, void 0);
19
- const markerClusterer = shallowRef(void 0);
20
- whenever(() => mapContext?.map.value, async (map) => {
21
- const { MarkerClusterer } = await import("@googlemaps/markerclusterer");
22
- markerClusterer.value = new MarkerClusterer({
23
- map,
24
- ...props.options
25
- });
26
- setupMarkerClustererEventListeners(markerClusterer.value);
27
- }, {
28
- immediate: true,
29
- once: true
18
+ const markerClusterer = useGoogleMapsResource({
19
+ async create({ map }) {
20
+ const { MarkerClusterer } = await import("@googlemaps/markerclusterer");
21
+ const clusterer = new MarkerClusterer({
22
+ map,
23
+ ...props.options
24
+ });
25
+ setupEventListeners(clusterer);
26
+ return clusterer;
27
+ },
28
+ cleanup(clusterer, { mapsApi }) {
29
+ mapsApi.event.clearInstanceListeners(clusterer);
30
+ clusterer.setMap(null);
31
+ }
30
32
  });
31
33
  const markerClustererNeedsRerender = shallowRef(false);
32
34
  function requestRerender() {
@@ -36,13 +38,6 @@ whenever(() => markerClustererNeedsRerender.value && markerClusterer.value, () =
36
38
  markerClusterer.value.render();
37
39
  markerClustererNeedsRerender.value = false;
38
40
  });
39
- onUnmounted(() => {
40
- if (!markerClusterer.value || !mapContext?.mapsApi.value) {
41
- return;
42
- }
43
- mapContext.mapsApi.value.event.clearInstanceListeners(markerClusterer.value);
44
- markerClusterer.value.setMap(null);
45
- });
46
41
  provide(
47
42
  MARKER_CLUSTERER_INJECTION_KEY,
48
43
  {
@@ -50,7 +45,7 @@ provide(
50
45
  requestRerender
51
46
  }
52
47
  );
53
- function setupMarkerClustererEventListeners(clusterer) {
48
+ function setupEventListeners(clusterer) {
54
49
  markerClustererEvents.forEach((event) => {
55
50
  clusterer.addListener(event, () => emit(event, clusterer));
56
51
  });
@@ -1,41 +1,32 @@
1
1
  <script setup>
2
- import { whenever } from "@vueuse/core";
3
- import { inject, onUnmounted, shallowRef } from "vue";
4
- import { MAP_INJECTION_KEY } from "./ScriptGoogleMaps.vue";
5
- import { ADVANCED_MARKER_ELEMENT_INJECTION_KEY } from "./ScriptGoogleMapsAdvancedMarkerElement.vue";
2
+ import { inject, watch } from "vue";
3
+ import { ADVANCED_MARKER_ELEMENT_INJECTION_KEY } from "./injectionKeys";
4
+ import { useGoogleMapsResource } from "./useGoogleMapsResource";
6
5
  const props = defineProps({
7
6
  options: { type: Object, required: false }
8
7
  });
9
- const mapContext = inject(MAP_INJECTION_KEY, void 0);
10
8
  const advancedMarkerElementContext = inject(ADVANCED_MARKER_ELEMENT_INJECTION_KEY, void 0);
11
- const pinElement = shallowRef(void 0);
12
- whenever(
13
- () => mapContext?.map.value && mapContext.mapsApi.value && advancedMarkerElementContext?.advancedMarkerElement.value,
14
- async () => {
15
- await mapContext.mapsApi.value.importLibrary("marker");
16
- pinElement.value = new mapContext.mapsApi.value.marker.PinElement(props.options);
9
+ const pinElement = useGoogleMapsResource({
10
+ ready: () => !!advancedMarkerElementContext?.advancedMarkerElement.value,
11
+ async create({ mapsApi }) {
12
+ await mapsApi.importLibrary("marker");
13
+ const pin = new mapsApi.marker.PinElement(props.options);
17
14
  if (advancedMarkerElementContext?.advancedMarkerElement.value) {
18
- advancedMarkerElementContext.advancedMarkerElement.value.content = pinElement.value.element;
15
+ advancedMarkerElementContext.advancedMarkerElement.value.content = pin.element;
19
16
  }
20
- whenever(() => props.options, (options) => {
21
- if (pinElement.value && options) {
22
- Object.assign(pinElement.value, options);
23
- }
24
- }, {
25
- deep: true
26
- });
17
+ return pin;
27
18
  },
28
- {
29
- immediate: true,
30
- once: true
31
- }
32
- );
33
- onUnmounted(() => {
34
- if (advancedMarkerElementContext?.advancedMarkerElement.value && pinElement.value) {
35
- advancedMarkerElementContext.advancedMarkerElement.value.content = null;
19
+ cleanup() {
20
+ if (advancedMarkerElementContext?.advancedMarkerElement.value) {
21
+ advancedMarkerElementContext.advancedMarkerElement.value.content = null;
22
+ }
36
23
  }
37
- pinElement.value = void 0;
38
24
  });
25
+ watch(() => props.options, (options) => {
26
+ if (pinElement.value && options) {
27
+ Object.assign(pinElement.value, options);
28
+ }
29
+ }, { deep: true });
39
30
  </script>
40
31
 
41
32
  <template>
@@ -1,7 +1,6 @@
1
1
  <script setup>
2
- import { whenever } from "@vueuse/core";
3
- import { inject, onUnmounted } from "vue";
4
- import { MAP_INJECTION_KEY } from "./ScriptGoogleMaps.vue";
2
+ import { watch } from "vue";
3
+ import { useGoogleMapsResource } from "./useGoogleMapsResource";
5
4
  const props = defineProps({
6
5
  options: { type: Object, required: false }
7
6
  });
@@ -21,36 +20,28 @@ const eventsWithMapMouseEventPayload = [
21
20
  "dragend",
22
21
  "dragstart"
23
22
  ];
24
- const mapContext = inject(MAP_INJECTION_KEY, void 0);
25
- let polygon;
26
- whenever(() => mapContext?.map.value && mapContext.mapsApi.value, () => {
27
- polygon = new mapContext.mapsApi.value.Polygon({
28
- map: mapContext.map.value,
29
- ...props.options
30
- });
31
- setupPolygonEventListeners(polygon);
32
- whenever(() => props.options, (options) => {
33
- polygon?.setOptions(options);
34
- }, {
35
- deep: true
36
- });
37
- }, {
38
- immediate: true,
39
- once: true
40
- });
41
- onUnmounted(() => {
42
- if (!polygon || !mapContext?.mapsApi.value) {
43
- return;
23
+ const polygon = useGoogleMapsResource({
24
+ create({ mapsApi, map }) {
25
+ const p = new mapsApi.Polygon({ map, ...props.options });
26
+ setupEventListeners(p);
27
+ return p;
28
+ },
29
+ cleanup(p, { mapsApi }) {
30
+ mapsApi.event.clearInstanceListeners(p);
31
+ p.setMap(null);
44
32
  }
45
- mapContext.mapsApi.value.event.clearInstanceListeners(polygon);
46
- polygon.setMap(null);
47
33
  });
48
- function setupPolygonEventListeners(polygon2) {
34
+ watch(() => props.options, (options) => {
35
+ if (polygon.value && options) {
36
+ polygon.value.setOptions(options);
37
+ }
38
+ }, { deep: true });
39
+ function setupEventListeners(p) {
49
40
  eventsWithPolyMouseEventPayload.forEach((event) => {
50
- polygon2.addListener(event, (payload) => emit(event, payload));
41
+ p.addListener(event, (payload) => emit(event, payload));
51
42
  });
52
43
  eventsWithMapMouseEventPayload.forEach((event) => {
53
- polygon2.addListener(event, (payload) => emit(event, payload));
44
+ p.addListener(event, (payload) => emit(event, payload));
54
45
  });
55
46
  }
56
47
  </script>
@@ -1,7 +1,6 @@
1
1
  <script setup>
2
- import { whenever } from "@vueuse/core";
3
- import { inject, onUnmounted } from "vue";
4
- import { MAP_INJECTION_KEY } from "./ScriptGoogleMaps.vue";
2
+ import { watch } from "vue";
3
+ import { useGoogleMapsResource } from "./useGoogleMapsResource";
5
4
  const props = defineProps({
6
5
  options: { type: Object, required: false }
7
6
  });
@@ -21,36 +20,28 @@ const eventsWithMapMouseEventPayload = [
21
20
  "dragend",
22
21
  "dragstart"
23
22
  ];
24
- const mapContext = inject(MAP_INJECTION_KEY, void 0);
25
- let polyline;
26
- whenever(() => mapContext?.map.value && mapContext.mapsApi.value, () => {
27
- polyline = new mapContext.mapsApi.value.Polyline({
28
- map: mapContext.map.value,
29
- ...props.options
30
- });
31
- setupPolylineEventListeners(polyline);
32
- whenever(() => props.options, (options) => {
33
- polyline?.setOptions(options);
34
- }, {
35
- deep: true
36
- });
37
- }, {
38
- immediate: true,
39
- once: true
40
- });
41
- onUnmounted(() => {
42
- if (!polyline || !mapContext?.mapsApi.value) {
43
- return;
23
+ const polyline = useGoogleMapsResource({
24
+ create({ mapsApi, map }) {
25
+ const p = new mapsApi.Polyline({ map, ...props.options });
26
+ setupEventListeners(p);
27
+ return p;
28
+ },
29
+ cleanup(p, { mapsApi }) {
30
+ mapsApi.event.clearInstanceListeners(p);
31
+ p.setMap(null);
44
32
  }
45
- mapContext.mapsApi.value.event.clearInstanceListeners(polyline);
46
- polyline.setMap(null);
47
33
  });
48
- function setupPolylineEventListeners(polyline2) {
34
+ watch(() => props.options, (options) => {
35
+ if (polyline.value && options) {
36
+ polyline.value.setOptions(options);
37
+ }
38
+ }, { deep: true });
39
+ function setupEventListeners(p) {
49
40
  eventsWithPolyMouseEventPayload.forEach((event) => {
50
- polyline2.addListener(event, (payload) => emit(event, payload));
41
+ p.addListener(event, (payload) => emit(event, payload));
51
42
  });
52
43
  eventsWithMapMouseEventPayload.forEach((event) => {
53
- polyline2.addListener(event, (payload) => emit(event, payload));
44
+ p.addListener(event, (payload) => emit(event, payload));
54
45
  });
55
46
  }
56
47
  </script>
@@ -1,7 +1,6 @@
1
1
  <script setup>
2
- import { whenever } from "@vueuse/core";
3
- import { inject, onUnmounted } from "vue";
4
- import { MAP_INJECTION_KEY } from "./ScriptGoogleMaps.vue";
2
+ import { watch } from "vue";
3
+ import { useGoogleMapsResource } from "./useGoogleMapsResource";
5
4
  const props = defineProps({
6
5
  options: { type: Object, required: false }
7
6
  });
@@ -22,36 +21,28 @@ const eventsWithMapMouseEventPayload = [
22
21
  "mouseover",
23
22
  "mouseup"
24
23
  ];
25
- const mapContext = inject(MAP_INJECTION_KEY, void 0);
26
- let rectangle;
27
- whenever(() => mapContext?.map.value && mapContext.mapsApi.value, () => {
28
- rectangle = new mapContext.mapsApi.value.Rectangle({
29
- map: mapContext.map.value,
30
- ...props.options
31
- });
32
- setupRectangleEventListeners(rectangle);
33
- whenever(() => props.options, (options) => {
34
- rectangle?.setOptions(options);
35
- }, {
36
- deep: true
37
- });
38
- }, {
39
- immediate: true,
40
- once: true
41
- });
42
- onUnmounted(() => {
43
- if (!rectangle || !mapContext?.mapsApi.value) {
44
- return;
24
+ const rectangle = useGoogleMapsResource({
25
+ create({ mapsApi, map }) {
26
+ const r = new mapsApi.Rectangle({ map, ...props.options });
27
+ setupEventListeners(r);
28
+ return r;
29
+ },
30
+ cleanup(r, { mapsApi }) {
31
+ mapsApi.event.clearInstanceListeners(r);
32
+ r.setMap(null);
45
33
  }
46
- mapContext.mapsApi.value.event.clearInstanceListeners(rectangle);
47
- rectangle.setMap(null);
48
34
  });
49
- function setupRectangleEventListeners(rectangle2) {
35
+ watch(() => props.options, (options) => {
36
+ if (rectangle.value && options) {
37
+ rectangle.value.setOptions(options);
38
+ }
39
+ }, { deep: true });
40
+ function setupEventListeners(r) {
50
41
  eventsWithoutPayload.forEach((event) => {
51
- rectangle2.addListener(event, () => emit(event));
42
+ r.addListener(event, () => emit(event));
52
43
  });
53
44
  eventsWithMapMouseEventPayload.forEach((event) => {
54
- rectangle2.addListener(event, (payload) => emit(event, payload));
45
+ r.addListener(event, (payload) => emit(event, payload));
55
46
  });
56
47
  }
57
48
  </script>
@@ -0,0 +1,11 @@
1
+ import type { InjectionKey, Ref, ShallowRef } from 'vue';
2
+ export declare const MAP_INJECTION_KEY: InjectionKey<{
3
+ map: ShallowRef<google.maps.Map | undefined>;
4
+ mapsApi: Ref<typeof google.maps | undefined>;
5
+ }>;
6
+ export declare const ADVANCED_MARKER_ELEMENT_INJECTION_KEY: InjectionKey<{
7
+ advancedMarkerElement: ShallowRef<google.maps.marker.AdvancedMarkerElement | undefined>;
8
+ }>;
9
+ export declare const MARKER_INJECTION_KEY: InjectionKey<{
10
+ marker: ShallowRef<google.maps.Marker | undefined>;
11
+ }>;
@@ -0,0 +1,3 @@
1
+ export const MAP_INJECTION_KEY = Symbol("map");
2
+ export const ADVANCED_MARKER_ELEMENT_INJECTION_KEY = Symbol("marker");
3
+ export const MARKER_INJECTION_KEY = Symbol("marker");
@@ -0,0 +1,26 @@
1
+ import type { ShallowRef } from 'vue';
2
+ export interface GoogleMapsResourceContext {
3
+ map: google.maps.Map;
4
+ mapsApi: typeof google.maps;
5
+ }
6
+ /**
7
+ * Composable for safely managing Google Maps resource lifecycle.
8
+ *
9
+ * Handles the common pattern: wait for map readiness → async create → cleanup on unmount.
10
+ *
11
+ * Safety guarantees:
12
+ * - No watchers created after `await` (prevents orphaned watchers that leak memory)
13
+ * - Unmount guard prevents resource creation after component unmount
14
+ * - Resources created during the async gap are immediately cleaned up
15
+ * - Resource ref is always nulled on unmount to allow GC
16
+ */
17
+ export declare function useGoogleMapsResource<T>({ ready, create, cleanup, }: {
18
+ /** Additional readiness condition beyond map + mapsApi being available */
19
+ ready?: () => boolean;
20
+ /** Create the Google Maps resource. Receives map context snapshot. May be async. */
21
+ create: (ctx: GoogleMapsResourceContext) => Promise<T> | T;
22
+ /** Clean up the resource. Called on unmount, or immediately if resource was created after unmount. */
23
+ cleanup?: (resource: T, ctx: {
24
+ mapsApi: typeof google.maps;
25
+ }) => void;
26
+ }): ShallowRef<T | undefined>;
@@ -0,0 +1,37 @@
1
+ import { whenever } from "@vueuse/core";
2
+ import { inject, onUnmounted, ref, shallowRef } from "vue";
3
+ import { MAP_INJECTION_KEY } from "./injectionKeys.js";
4
+ export function useGoogleMapsResource({
5
+ ready,
6
+ create,
7
+ cleanup
8
+ }) {
9
+ const mapContext = inject(MAP_INJECTION_KEY, void 0);
10
+ const resource = shallowRef(void 0);
11
+ const isUnmounted = ref(false);
12
+ whenever(
13
+ () => mapContext?.map.value && mapContext.mapsApi.value && (!ready || ready()),
14
+ async () => {
15
+ const result = await create({
16
+ map: mapContext.map.value,
17
+ mapsApi: mapContext.mapsApi.value
18
+ });
19
+ if (isUnmounted.value) {
20
+ if (cleanup && mapContext?.mapsApi.value) {
21
+ cleanup(result, { mapsApi: mapContext.mapsApi.value });
22
+ }
23
+ return;
24
+ }
25
+ resource.value = result;
26
+ },
27
+ { immediate: true, once: true }
28
+ );
29
+ onUnmounted(() => {
30
+ isUnmounted.value = true;
31
+ if (resource.value && cleanup && mapContext?.mapsApi.value) {
32
+ cleanup(resource.value, { mapsApi: mapContext.mapsApi.value });
33
+ }
34
+ resource.value = void 0;
35
+ });
36
+ return resource;
37
+ }
@@ -1,2 +1,2 @@
1
- declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<ArrayBuffer | undefined>>;
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
2
2
  export default _default;
@@ -29,7 +29,6 @@ export default defineEventHandler(async (event) => {
29
29
  r: rating
30
30
  });
31
31
  const response = await $fetch.raw(gravatarUrl, {
32
- responseType: "arrayBuffer",
33
32
  headers: {
34
33
  "User-Agent": "Nuxt Scripts Gravatar Proxy"
35
34
  }