@nuxt/scripts 2.0.0-beta.6 → 2.0.0-beta.8

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 (67) hide show
  1. package/dist/devtools-client/200.html +1 -1
  2. package/dist/devtools-client/404.html +1 -1
  3. package/dist/devtools-client/_nuxt/{Bagqfgzu.js → BBRrg_AT.js} +3 -3
  4. package/dist/devtools-client/_nuxt/{CP6K2Qm6.js → BI6wdYky.js} +1 -1
  5. package/dist/devtools-client/_nuxt/{CWci3Eb_.js → BckE5qrE.js} +1 -1
  6. package/dist/devtools-client/_nuxt/{D_hceTm9.js → Cs0md1ml.js} +1 -1
  7. package/dist/devtools-client/_nuxt/{DZ6h2v9A.js → DN3hUMR_.js} +1 -1
  8. package/dist/devtools-client/_nuxt/{DXDqMNFL.js → DXEYGql4.js} +1 -1
  9. package/dist/devtools-client/_nuxt/{utTTwIIR.js → Divy0_cA.js} +3 -3
  10. package/dist/devtools-client/_nuxt/builds/latest.json +1 -1
  11. package/dist/devtools-client/_nuxt/builds/meta/afe20d38-a0b8-4d9f-be82-37b90ecac717.json +1 -0
  12. package/dist/devtools-client/_nuxt/error-404.BJ1JSMYb.css +1 -0
  13. package/dist/devtools-client/_nuxt/error-500.BBf0uW5X.css +1 -0
  14. package/dist/devtools-client/docs/index.html +1 -1
  15. package/dist/devtools-client/first-party/index.html +1 -1
  16. package/dist/devtools-client/index.html +1 -1
  17. package/dist/devtools-client/registry/index.html +1 -1
  18. package/dist/module.d.mts +1 -0
  19. package/dist/module.d.ts +1 -0
  20. package/dist/module.json +1 -1
  21. package/dist/module.mjs +4 -1
  22. package/dist/registry.mjs +24 -1
  23. package/dist/runtime/components/Leaflet/ScriptLeafletMap.d.vue.ts +5 -5
  24. package/dist/runtime/components/Leaflet/ScriptLeafletMap.vue.d.ts +5 -5
  25. package/dist/runtime/components/MapLibre/ScriptMapLibreAttributionControl.d.vue.ts +7 -0
  26. package/dist/runtime/components/MapLibre/ScriptMapLibreAttributionControl.vue +42 -0
  27. package/dist/runtime/components/MapLibre/ScriptMapLibreAttributionControl.vue.d.ts +7 -0
  28. package/dist/runtime/components/MapLibre/ScriptMapLibreFullscreenControl.d.vue.ts +13 -0
  29. package/dist/runtime/components/MapLibre/ScriptMapLibreFullscreenControl.vue +27 -0
  30. package/dist/runtime/components/MapLibre/ScriptMapLibreFullscreenControl.vue.d.ts +13 -0
  31. package/dist/runtime/components/MapLibre/ScriptMapLibreGeoJson.d.vue.ts +26 -35
  32. package/dist/runtime/components/MapLibre/ScriptMapLibreGeoJson.vue +233 -15
  33. package/dist/runtime/components/MapLibre/ScriptMapLibreGeoJson.vue.d.ts +26 -35
  34. package/dist/runtime/components/MapLibre/ScriptMapLibreGeolocateControl.d.vue.ts +25 -0
  35. package/dist/runtime/components/MapLibre/ScriptMapLibreGeolocateControl.vue +49 -0
  36. package/dist/runtime/components/MapLibre/ScriptMapLibreGeolocateControl.vue.d.ts +25 -0
  37. package/dist/runtime/components/MapLibre/ScriptMapLibreMap.d.vue.ts +22 -86
  38. package/dist/runtime/components/MapLibre/ScriptMapLibreMap.vue +23 -2
  39. package/dist/runtime/components/MapLibre/ScriptMapLibreMap.vue.d.ts +22 -86
  40. package/dist/runtime/components/MapLibre/ScriptMapLibreMarker.d.vue.ts +3 -12
  41. package/dist/runtime/components/MapLibre/ScriptMapLibreMarker.vue.d.ts +3 -12
  42. package/dist/runtime/components/MapLibre/ScriptMapLibreNavigationControl.d.vue.ts +3 -8
  43. package/dist/runtime/components/MapLibre/ScriptMapLibreNavigationControl.vue +1 -4
  44. package/dist/runtime/components/MapLibre/ScriptMapLibreNavigationControl.vue.d.ts +3 -8
  45. package/dist/runtime/components/MapLibre/ScriptMapLibrePopup.d.vue.ts +3 -10
  46. package/dist/runtime/components/MapLibre/ScriptMapLibrePopup.vue.d.ts +3 -10
  47. package/dist/runtime/components/MapLibre/ScriptMapLibreScaleControl.d.vue.ts +7 -0
  48. package/dist/runtime/components/MapLibre/ScriptMapLibreScaleControl.vue +25 -0
  49. package/dist/runtime/components/MapLibre/ScriptMapLibreScaleControl.vue.d.ts +7 -0
  50. package/dist/runtime/components/MapLibre/types.d.ts +275 -0
  51. package/dist/runtime/components/MapLibre/types.js +0 -0
  52. package/dist/runtime/components/MapLibre/useMapLibreResource.d.ts +8 -1
  53. package/dist/runtime/components/MapLibre/useMapLibreResource.js +9 -2
  54. package/dist/runtime/registry/pulse-analytics.d.ts +32 -0
  55. package/dist/runtime/registry/pulse-analytics.js +80 -0
  56. package/dist/runtime/registry/schemas.d.ts +42 -0
  57. package/dist/runtime/registry/schemas.js +42 -0
  58. package/dist/runtime/registry/tawk-to.d.ts +126 -0
  59. package/dist/runtime/registry/tawk-to.js +147 -0
  60. package/dist/runtime/types.d.ts +6 -1
  61. package/dist/stats.mjs +81 -0
  62. package/dist/types-source.mjs +312 -4
  63. package/dist/types.d.mts +2 -0
  64. package/package.json +10 -10
  65. package/dist/devtools-client/_nuxt/builds/meta/8bf6d5ed-9af4-4b18-be50-90e3f19066d5.json +0 -1
  66. package/dist/devtools-client/_nuxt/error-404.Bn3cR6N7.css +0 -1
  67. package/dist/devtools-client/_nuxt/error-500.ClHmgt9z.css +0 -1
@@ -0,0 +1,275 @@
1
+ import type { GeoJSON } from 'geojson';
2
+ import type * as MapLibre from 'maplibre-gl';
3
+ import type { HTMLAttributes, ReservedProps, ShallowRef } from 'vue';
4
+ import type { ElementScriptTrigger } from '../../types.js';
5
+ /**
6
+ * Public types for the MapLibre components. They are re-exported from
7
+ * `@nuxt/scripts` so a consumer can type refs, layer arrays and event payloads
8
+ * without a deep import.
9
+ */
10
+ export interface ScriptMapLibreMapProps {
11
+ /**
12
+ * Defines when the MapLibre script loads.
13
+ * @default 'visible'
14
+ */
15
+ trigger?: ElementScriptTrigger;
16
+ /** MapLibre style URL or inline style specification. */
17
+ mapStyle: string | MapLibre.StyleSpecification;
18
+ /** Initial and reactively controlled map center. */
19
+ center: MapLibre.LngLatLike;
20
+ /** Initial and reactively controlled zoom level. @default 12 */
21
+ zoom?: number;
22
+ /** Initial and reactively controlled bearing in degrees. @default 0 */
23
+ bearing?: number;
24
+ /** Initial and reactively controlled pitch in degrees. @default 0 */
25
+ pitch?: number;
26
+ /** Options passed to `new maplibregl.Map()`. Dedicated props take precedence. */
27
+ options?: Omit<MapLibre.MapOptions, 'container'>;
28
+ /** Inject MapLibre's stylesheet when the script begins loading. @default true */
29
+ injectStyles?: boolean;
30
+ /** Custom MapLibre stylesheet URL. */
31
+ stylesheetUrl?: string;
32
+ /** Worker URL passed to `maplibregl.setWorkerUrl()`. */
33
+ workerUrl?: string;
34
+ /** Width reserved before the map loads. @default 640 */
35
+ width?: number | string;
36
+ /** Height reserved before the map loads. @default 400 */
37
+ height?: number | string;
38
+ /** Accessible name for an interactive map. @default 'Interactive map' */
39
+ ariaLabel?: string;
40
+ /** Disable map input and remove it from the accessibility tree when decorative. @default true */
41
+ interactive?: boolean;
42
+ /** Attributes applied to the outer layout container. */
43
+ rootAttrs?: HTMLAttributes & ReservedProps & Record<string, unknown>;
44
+ }
45
+ export interface ScriptMapLibreMapExpose {
46
+ maplibre: ShallowRef<typeof MapLibre | undefined>;
47
+ map: ShallowRef<MapLibre.Map | undefined>;
48
+ load: () => Promise<unknown> | unknown;
49
+ /** Moves the camera so the bounds fit the viewport. Does nothing before the map exists. */
50
+ fitBounds: (bounds: MapLibre.LngLatBoundsLike, options?: MapLibre.FitBoundsOptions) => void;
51
+ /** Animates the camera along a straight path. Does nothing before the map exists. */
52
+ easeTo: (options: MapLibre.EaseToOptions) => void;
53
+ /** Animates the camera along a curved flight path. Does nothing before the map exists. */
54
+ flyTo: (options: MapLibre.FlyToOptions) => void;
55
+ }
56
+ export interface ScriptMapLibreMapEmits {
57
+ 'ready': [payload: ScriptMapLibreMapExpose];
58
+ 'error': [error: Error];
59
+ /** The map finished its first complete render. Sources and layers are safe to add. */
60
+ 'load': [event: MapLibre.MapEventType['load']];
61
+ /** The style finished loading. MapLibre drops every source and layer before this fires. */
62
+ 'styleload': [event: MapLibre.MapEventType['style.load']];
63
+ 'click': [event: MapLibre.MapEventType['click']];
64
+ 'move': [event: MapLibre.MapEventType['move']];
65
+ 'moveend': [event: MapLibre.MapEventType['moveend']];
66
+ 'zoom': [event: MapLibre.MapEventType['zoom']];
67
+ 'zoomend': [event: MapLibre.MapEventType['zoomend']];
68
+ 'rotate': [event: MapLibre.MapEventType['rotate']];
69
+ 'rotateend': [event: MapLibre.MapEventType['rotateend']];
70
+ 'pitch': [event: MapLibre.MapEventType['pitch']];
71
+ 'pitchend': [event: MapLibre.MapEventType['pitchend']];
72
+ 'update:center': [center: MapLibre.LngLat];
73
+ 'update:zoom': [zoom: number];
74
+ 'update:bearing': [bearing: number];
75
+ 'update:pitch': [pitch: number];
76
+ }
77
+ export interface ScriptMapLibreMapSlots {
78
+ default?: () => any;
79
+ loading?: () => any;
80
+ awaitingLoad?: () => any;
81
+ error?: (props: {
82
+ error: Error;
83
+ }) => any;
84
+ placeholder?: () => any;
85
+ /** Text or links that expose the canvas map's essential information to assistive technology. */
86
+ description?: () => any;
87
+ }
88
+ /**
89
+ * Layer kinds a GeoJSON source can render. MapLibre's own style validation
90
+ * rejects the rest: `hillshade` and `color-relief` need a `raster-dem` source,
91
+ * `raster` needs raster tiles, and `background` takes no source at all.
92
+ */
93
+ type GeoJsonLayerType = 'circle' | 'fill' | 'fill-extrusion' | 'heatmap' | 'line' | 'symbol';
94
+ /**
95
+ * A style layer for this component's source.
96
+ *
97
+ * `LayerSpecification` is a union and a plain `Omit` is not distributive, so it
98
+ * collapses the union to its common keys and drops `filter`. MapLibre's own
99
+ * `DistributiveOmit` keeps each member, so `type` narrows `filter`, `paint` and
100
+ * `layout` for that layer kind.
101
+ *
102
+ * Only a GeoJSON-compatible layer may leave `source` out. A `raster`,
103
+ * `hillshade` or `color-relief` layer must name its own source.
104
+ */
105
+ export type ScriptMapLibreGeoJsonLayer = (MapLibre.DistributiveOmit<Extract<MapLibre.LayerSpecification, {
106
+ type: GeoJsonLayerType;
107
+ }>, 'source'> & {
108
+ /** Override the component's source ID for this layer. */
109
+ source?: string;
110
+ }) | Extract<MapLibre.LayerSpecification, {
111
+ type: 'color-relief' | 'hillshade' | 'raster';
112
+ }>;
113
+ export interface ScriptMapLibreGeoJsonProps {
114
+ /** MapLibre source ID. Changing it rebuilds the owned source and layers. */
115
+ sourceId: string;
116
+ /** Inline GeoJSON data or a URL returning GeoJSON. */
117
+ data: GeoJSON | string;
118
+ /** GeoJSON source options. `type` and `data` are supplied by the component. */
119
+ sourceOptions?: Omit<MapLibre.GeoJSONSourceSpecification, 'type' | 'data'>;
120
+ /**
121
+ * Style layers backed by this source.
122
+ * A paint, layout or filter change updates the layers in place.
123
+ * Any other change rebuilds the source and the layers.
124
+ */
125
+ layers: ScriptMapLibreGeoJsonLayer[];
126
+ /** Existing layer ID before which the layers are inserted. */
127
+ beforeId?: string;
128
+ /** CSS cursor applied while the pointer is over one of these layers. */
129
+ cursor?: string;
130
+ }
131
+ export interface ScriptMapLibreGeoJsonEmits {
132
+ /**
133
+ * The component could not apply a source or layer, or MapLibre reported an error for one.
134
+ * MapLibre reports an invalid paint, layout or filter value this way. It does not throw.
135
+ * A failed rebuild removes the component's own source and layers.
136
+ * A failed paint, layout or filter update leaves them on the map.
137
+ */
138
+ error: [error: Error];
139
+ /** The pointer clicked one of this component's layers. */
140
+ click: [event: MapLibre.MapLayerMouseEvent];
141
+ /**
142
+ * The pointer double-clicked one of this component's layers.
143
+ * Call `event.preventDefault()` to stop MapLibre's double-click zoom.
144
+ */
145
+ dblclick: [event: MapLibre.MapLayerMouseEvent];
146
+ /**
147
+ * The pointer entered this component's layers as a group.
148
+ * It does not fire again when the pointer moves between touching features.
149
+ */
150
+ mouseenter: [event: MapLibre.MapLayerMouseEvent];
151
+ /**
152
+ * The pointer moved over a feature in one of this component's layers.
153
+ * `event.features` lists the features under the pointer, topmost first.
154
+ */
155
+ mousemove: [event: MapLibre.MapLayerMouseEvent];
156
+ /** The pointer left every feature in this component's layers. */
157
+ mouseleave: [event: MapLibre.MapLayerMouseEvent];
158
+ /**
159
+ * The source and layers exist on the map.
160
+ * Fires after the first add and after every re-add, such as after a style swap.
161
+ * A re-add clears feature state, so restore it here.
162
+ */
163
+ sourceready: [payload: {
164
+ map: MapLibre.Map;
165
+ sourceId: string;
166
+ }];
167
+ }
168
+ export interface ScriptMapLibreGeoJsonResource {
169
+ map: MapLibre.Map;
170
+ onLoad: () => void;
171
+ onStyleLoad: () => void;
172
+ onStyleDataLoading: () => void;
173
+ onIdle: () => void;
174
+ onError: (event: {
175
+ error: Error | {
176
+ message: string;
177
+ };
178
+ }) => void;
179
+ }
180
+ export interface ScriptMapLibreMarkerProps {
181
+ /** Reactive marker position in `[longitude, latitude]` order. */
182
+ position: MapLibre.LngLatLike;
183
+ /** Accessible name for the marker element. */
184
+ ariaLabel?: string;
185
+ /** Tooltip text for the marker element. */
186
+ title?: string;
187
+ /** Options passed to `new maplibregl.Marker()`. Options with public setters also update reactively. */
188
+ options?: MapLibre.MarkerOptions;
189
+ }
190
+ export interface ScriptMapLibreMarkerEmits {
191
+ click: [event: MouseEvent];
192
+ dragstart: [event: MapLibre.Event];
193
+ drag: [event: MapLibre.Event];
194
+ dragend: [event: MapLibre.Event];
195
+ }
196
+ export interface ScriptMapLibrePopupProps {
197
+ /** Position for a standalone popup. Omit when nested inside a marker. */
198
+ position?: MapLibre.LngLatLike;
199
+ /** Whether the popup is open. @default false */
200
+ open?: boolean;
201
+ /** Options passed to `new maplibregl.Popup()`. Options with public setters also update reactively. */
202
+ options?: MapLibre.PopupOptions;
203
+ }
204
+ export interface ScriptMapLibrePopupEmits {
205
+ open: [event: MapLibre.Event];
206
+ close: [event: MapLibre.Event];
207
+ }
208
+ export interface ScriptMapLibreNavigationControlProps {
209
+ /** Position of the navigation control. */
210
+ position?: MapLibre.ControlPosition;
211
+ /** Options passed to `new maplibregl.NavigationControl()`. */
212
+ options?: MapLibre.NavigationControlOptions;
213
+ }
214
+ export interface ScriptMapLibreScaleControlProps {
215
+ /** Position of the scale control. MapLibre places it bottom-left by default. */
216
+ position?: MapLibre.ControlPosition;
217
+ /**
218
+ * Options passed to `new maplibregl.ScaleControl()`.
219
+ * `unit` also updates reactively through `setUnit()`.
220
+ */
221
+ options?: MapLibre.ScaleControlOptions;
222
+ }
223
+ export interface ScriptMapLibreGeolocateControlProps {
224
+ /** Position of the geolocate control. */
225
+ position?: MapLibre.ControlPosition;
226
+ /** Options passed to `new maplibregl.GeolocateControl()`. */
227
+ options?: MapLibre.GeolocateControlOptions;
228
+ }
229
+ export interface ScriptMapLibreGeolocateControlEmits {
230
+ /** The Geolocation API returned a position. */
231
+ geolocate: [event: MapLibre.GeolocateControlEventType['geolocate']];
232
+ /**
233
+ * The Geolocation API returned an error.
234
+ * `code` 1 means the user denied permission. MapLibre then disables the button.
235
+ */
236
+ error: [event: MapLibre.GeolocateControlEventType['error']];
237
+ /** The position is outside the map's `maxBounds`. */
238
+ outofmaxbounds: [event: MapLibre.GeolocateControlEventType['outofmaxbounds']];
239
+ /** The control entered the active lock state. Needs `trackUserLocation`. */
240
+ trackuserlocationstart: [event: MapLibre.GeolocateControlEventType['trackuserlocationstart']];
241
+ /** The control left the active lock state. Needs `trackUserLocation`. */
242
+ trackuserlocationend: [event: MapLibre.GeolocateControlEventType['trackuserlocationend']];
243
+ /** The user clicked the button in the active lock state. */
244
+ userlocationfocus: [event: MapLibre.GeolocateControlEventType['userlocationfocus']];
245
+ /** The user moved the map in the active lock state. */
246
+ userlocationlostfocus: [event: MapLibre.GeolocateControlEventType['userlocationlostfocus']];
247
+ /**
248
+ * Geolocation cannot work in this browser.
249
+ * `permission-denied` means the user blocked it before the control loaded.
250
+ * MapLibre disables the button and fires no `error` event in both cases.
251
+ */
252
+ unavailable: [reason: 'unsupported' | 'permission-denied'];
253
+ }
254
+ export interface ScriptMapLibreFullscreenControlProps {
255
+ /** Position of the fullscreen control. */
256
+ position?: MapLibre.ControlPosition;
257
+ /** Options passed to `new maplibregl.FullscreenControl()`. */
258
+ options?: MapLibre.FullscreenControlOptions;
259
+ }
260
+ export interface ScriptMapLibreFullscreenControlEmits {
261
+ /** The map entered fullscreen mode. */
262
+ fullscreenstart: [event: MapLibre.FullscreenControlEventType['fullscreenstart']];
263
+ /** The map left fullscreen mode. */
264
+ fullscreenend: [event: MapLibre.FullscreenControlEventType['fullscreenend']];
265
+ }
266
+ export interface ScriptMapLibreAttributionControlProps {
267
+ /** Position of the attribution control. MapLibre places it bottom-right by default. */
268
+ position?: MapLibre.ControlPosition;
269
+ /**
270
+ * Options passed to `new maplibregl.AttributionControl()`.
271
+ * Source attribution from the style and tiles always shows. `customAttribution` only adds text.
272
+ */
273
+ options?: MapLibre.AttributionControlOptions;
274
+ }
275
+ export {};
File without changes
@@ -12,12 +12,19 @@ export interface MapLibreResourceContext {
12
12
  map: MapLibre.Map;
13
13
  maplibre: typeof MapLibre;
14
14
  }
15
+ /**
16
+ * Logs a MapLibre resource failure and hands it to the owning component, so the
17
+ * consumer can surface it instead of only seeing a console message.
18
+ */
19
+ export declare function reportMapLibreResourceError(error: unknown, onError?: (error: Error) => void): Error;
15
20
  /**
16
21
  * Creates a MapLibre resource after its parent map and any component-specific
17
22
  * DOM refs are ready, then removes it synchronously during unmount.
18
23
  */
19
- export declare function useMapLibreResource<T>({ ready, create, cleanup, }: {
24
+ export declare function useMapLibreResource<T>({ ready, create, cleanup, onError, }: {
20
25
  ready?: () => boolean;
21
26
  create: (context: MapLibreResourceContext) => T;
22
27
  cleanup: (resource: T, context: MapLibreResourceContext) => void;
28
+ /** Called when `create` throws, after the failure is logged. */
29
+ onError?: (error: Error) => void;
23
30
  }): ShallowRef<T | undefined>;
@@ -1,10 +1,17 @@
1
1
  import { inject, onUnmounted, shallowRef, watch } from "vue";
2
2
  export const MAPLIBRE_MAP_INJECTION_KEY = Symbol("maplibre-map");
3
3
  export const MAPLIBRE_MARKER_INJECTION_KEY = Symbol("maplibre-marker");
4
+ export function reportMapLibreResourceError(error, onError) {
5
+ const failure = error instanceof Error ? error : new Error("MapLibre resource creation failed", { cause: error });
6
+ console.error("[nuxt-scripts] MapLibre resource creation failed:", error);
7
+ onError?.(failure);
8
+ return failure;
9
+ }
4
10
  export function useMapLibreResource({
5
11
  ready,
6
12
  create,
7
- cleanup
13
+ cleanup,
14
+ onError
8
15
  }) {
9
16
  const mapContext = inject(MAPLIBRE_MAP_INJECTION_KEY, void 0);
10
17
  const resource = shallowRef();
@@ -23,7 +30,7 @@ export function useMapLibreResource({
23
30
  resourceContext = { map, maplibre };
24
31
  resource.value = create(resourceContext);
25
32
  } catch (error) {
26
- console.error("[nuxt-scripts] MapLibre resource creation failed:", error);
33
+ reportMapLibreResourceError(error, onError);
27
34
  } finally {
28
35
  creating = false;
29
36
  }
@@ -0,0 +1,32 @@
1
+ import type { RegistryScriptInput } from '#nuxt-scripts/types';
2
+ import { PulseAnalyticsOptions } from './schemas.js';
3
+ export { PulseAnalyticsOptions };
4
+ export type PulseAnalyticsInput = RegistryScriptInput<typeof PulseAnalyticsOptions, false>;
5
+ export interface PulseAnalyticsApi {
6
+ /**
7
+ * Records a custom event.
8
+ * @param name Event name: letters, numbers and underscores, up to 64 characters.
9
+ * Trimmed and lowercased before storage.
10
+ * @param props Optional properties. Values must be strings; a number or boolean
11
+ * rejects the whole event.
12
+ * @param revenue Optional monetary value, zero or greater.
13
+ * @see https://docs.ciphera.net/pulse/custom-events
14
+ */
15
+ track: (name: string, props?: Record<string, string>, revenue?: number) => void;
16
+ /**
17
+ * The current pathname as Pulse records it: trailing slash stripped, root kept
18
+ * as `/`. Returns `null` until the tracker has loaded.
19
+ */
20
+ cleanPath: () => string | null;
21
+ }
22
+ declare global {
23
+ interface Window {
24
+ pulse: PulseAnalyticsApi;
25
+ /**
26
+ * Set by the tracker before its opt-out checks run. Present without
27
+ * `pulse.track` means the tracker ran and declined to record.
28
+ */
29
+ __pulseInstalled?: boolean;
30
+ }
31
+ }
32
+ export declare function useScriptPulseAnalytics<T extends PulseAnalyticsApi>(_options?: PulseAnalyticsInput): import("#nuxt-scripts/types").UseScriptContext<T>;
@@ -0,0 +1,80 @@
1
+ import { useRegistryScript } from "../utils.js";
2
+ import { PulseAnalyticsOptions } from "./schemas.js";
3
+ export { PulseAnalyticsOptions };
4
+ const PULSE_QUEUE_KEY = Symbol.for("nuxt-scripts.pulse-queue");
5
+ const MAX_QUEUED_EVENTS = 100;
6
+ function getPulseState() {
7
+ if (typeof window === "undefined")
8
+ return;
9
+ const g = globalThis;
10
+ if (!g[PULSE_QUEUE_KEY]) {
11
+ g[PULSE_QUEUE_KEY] = { queue: [], flushed: false, declined: false };
12
+ }
13
+ return g[PULSE_QUEUE_KEY];
14
+ }
15
+ function isPulseReady() {
16
+ return typeof window !== "undefined" && typeof window.pulse?.track === "function";
17
+ }
18
+ function hasPulseDeclined() {
19
+ return typeof window !== "undefined" && window.__pulseInstalled === true && !isPulseReady();
20
+ }
21
+ export function useScriptPulseAnalytics(_options) {
22
+ const flushQueue = () => {
23
+ const state = getPulseState();
24
+ if (!state || state.flushed || state.declined)
25
+ return;
26
+ if (hasPulseDeclined()) {
27
+ state.declined = true;
28
+ state.queue.length = 0;
29
+ return;
30
+ }
31
+ if (!isPulseReady())
32
+ return;
33
+ state.flushed = true;
34
+ while (state.queue.length > 0) {
35
+ const args = state.queue.shift();
36
+ try {
37
+ window.pulse.track(...args);
38
+ } catch {
39
+ }
40
+ }
41
+ };
42
+ const track = (name, props, revenue) => {
43
+ if (isPulseReady()) {
44
+ window.pulse.track(name, props, revenue);
45
+ return;
46
+ }
47
+ const state = getPulseState();
48
+ if (!state || state.declined)
49
+ return;
50
+ if (hasPulseDeclined()) {
51
+ state.declined = true;
52
+ state.queue.length = 0;
53
+ return;
54
+ }
55
+ if (state.queue.length < MAX_QUEUED_EVENTS)
56
+ state.queue.push([name, props, revenue]);
57
+ };
58
+ return useRegistryScript("pulseAnalytics", (options) => ({
59
+ scriptInput: {
60
+ "src": "https://js.ciphera.net/script.js",
61
+ "data-domain": options.domain,
62
+ "data-api": options.apiUrl || void 0,
63
+ // Presence flags: the tracker reads them with hasAttribute(), so a
64
+ // rendered `data-no-scroll="false"` would still switch scroll tracking off.
65
+ "data-no-scroll": options.trackScroll === false ? "" : void 0,
66
+ "data-no-outbound": options.trackOutbound === false ? "" : void 0,
67
+ "data-no-downloads": options.trackDownloads === false ? "" : void 0
68
+ },
69
+ schema: import.meta.dev ? PulseAnalyticsOptions : void 0,
70
+ scriptOptions: {
71
+ use() {
72
+ flushQueue();
73
+ return {
74
+ track,
75
+ cleanPath: () => window.pulse?.cleanPath?.() ?? null
76
+ };
77
+ }
78
+ }
79
+ }), _options);
80
+ }
@@ -791,6 +791,34 @@ export declare const RedditPixelOptions: import("valibot").ObjectSchema<{
791
791
  */
792
792
  readonly id: import("valibot").StringSchema<undefined>;
793
793
  }, undefined>;
794
+ export declare const PulseAnalyticsOptions: import("valibot").ObjectSchema<{
795
+ /**
796
+ * The site domain as registered in Pulse.
797
+ * @see https://docs.ciphera.net/pulse/script-installation
798
+ */
799
+ readonly domain: import("valibot").StringSchema<undefined>;
800
+ /**
801
+ * The API origin the tracker posts events to. Only needed for a self-hosted
802
+ * or reverse-proxied Pulse API.
803
+ * @default 'https://pulse-api.ciphera.net'
804
+ */
805
+ readonly apiUrl: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
806
+ /**
807
+ * Record scroll depth.
808
+ * @default true
809
+ */
810
+ readonly trackScroll: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
811
+ /**
812
+ * Record outbound link clicks as `outbound_link` events.
813
+ * @default true
814
+ */
815
+ readonly trackOutbound: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
816
+ /**
817
+ * Record file download clicks as `file_download` events.
818
+ * @default true
819
+ */
820
+ readonly trackDownloads: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
821
+ }, undefined>;
794
822
  export declare const RybbitAnalyticsOptions: import("valibot").ObjectSchema<{
795
823
  /**
796
824
  * Your Rybbit site ID.
@@ -1188,6 +1216,20 @@ export declare const StripeOptions: import("valibot").ObjectSchema<{
1188
1216
  */
1189
1217
  readonly version: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"v3", undefined>, import("valibot").LiteralSchema<"acacia", undefined>, import("valibot").LiteralSchema<"basil", undefined>, import("valibot").LiteralSchema<"clover", undefined>, import("valibot").LiteralSchema<"dahlia", undefined>, import("valibot").StringSchema<undefined>], undefined>, undefined>;
1190
1218
  }, undefined>;
1219
+ export declare const TawkToOptions: import("valibot").ObjectSchema<{
1220
+ /**
1221
+ * Your Tawk.to property ID: the first path segment of the widget embed URL
1222
+ * `https://embed.tawk.to/<propertyId>/<widgetId>`.
1223
+ * @see https://dashboard.tawk.to/
1224
+ */
1225
+ readonly propertyId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>]>;
1226
+ /**
1227
+ * Your Tawk.to widget ID: the second path segment of the widget embed URL
1228
+ * `https://embed.tawk.to/<propertyId>/<widgetId>`.
1229
+ * @see https://dashboard.tawk.to/
1230
+ */
1231
+ readonly widgetId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>]>;
1232
+ }, undefined>;
1191
1233
  export declare const TikTokPixelOptions: import("valibot").ObjectSchema<{
1192
1234
  /**
1193
1235
  * Your TikTok Pixel ID.
@@ -753,6 +753,34 @@ export const RedditPixelOptions = object({
753
753
  */
754
754
  id: string()
755
755
  });
756
+ export const PulseAnalyticsOptions = object({
757
+ /**
758
+ * The site domain as registered in Pulse.
759
+ * @see https://docs.ciphera.net/pulse/script-installation
760
+ */
761
+ domain: string(),
762
+ /**
763
+ * The API origin the tracker posts events to. Only needed for a self-hosted
764
+ * or reverse-proxied Pulse API.
765
+ * @default 'https://pulse-api.ciphera.net'
766
+ */
767
+ apiUrl: optional(string()),
768
+ /**
769
+ * Record scroll depth.
770
+ * @default true
771
+ */
772
+ trackScroll: optional(boolean()),
773
+ /**
774
+ * Record outbound link clicks as `outbound_link` events.
775
+ * @default true
776
+ */
777
+ trackOutbound: optional(boolean()),
778
+ /**
779
+ * Record file download clicks as `file_download` events.
780
+ * @default true
781
+ */
782
+ trackDownloads: optional(boolean())
783
+ });
756
784
  export const RybbitAnalyticsOptions = object({
757
785
  /**
758
786
  * Your Rybbit site ID.
@@ -1107,6 +1135,20 @@ export const StripeOptions = object({
1107
1135
  */
1108
1136
  version: optional(union([literal("v3"), literal("acacia"), literal("basil"), literal("clover"), literal("dahlia"), string()]))
1109
1137
  });
1138
+ export const TawkToOptions = object({
1139
+ /**
1140
+ * Your Tawk.to property ID: the first path segment of the widget embed URL
1141
+ * `https://embed.tawk.to/<propertyId>/<widgetId>`.
1142
+ * @see https://dashboard.tawk.to/
1143
+ */
1144
+ propertyId: pipe(string(), minLength(1)),
1145
+ /**
1146
+ * Your Tawk.to widget ID: the second path segment of the widget embed URL
1147
+ * `https://embed.tawk.to/<propertyId>/<widgetId>`.
1148
+ * @see https://dashboard.tawk.to/
1149
+ */
1150
+ widgetId: pipe(string(), minLength(1))
1151
+ });
1110
1152
  export const TikTokPixelOptions = object({
1111
1153
  /**
1112
1154
  * Your TikTok Pixel ID.