@inspira-npm/events-react 0.0.0-stage → 0.3.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.d.ts +54 -0
- package/dist/index.js +124 -0
- package/package.json +39 -4
- package/README.md +0 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
import { AdClickProps, AdClickProps as AdClickProps$1, BrowserEventName, CLICK_ID_PARAM, CONSENT_CHANGE_EVENT, ClickRecordOptions, ConsentState, DEFAULT_CONSENT_COOKIE, EventName, EventProps, EventProps as EventProps$1, ImpressionEventName, ImpressionEventName as ImpressionEventName$1, ImpressionOptions, ImpressionOptions as ImpressionOptions$1, OutboundClickProps, OutboundClickProps as OutboundClickProps$1, Tracker, Tracker as Tracker$1, TrackerConfig, cookieConsent, createNoopTracker, createTracker, isClickId, parseConsentValue, readClickIdFromUrl, withClickId, withTrackingParams } from "@inspira-npm/events";
|
|
3
|
+
import { ReactElement, ReactNode } from "react";
|
|
4
|
+
interface EventsProviderProps {
|
|
5
|
+
/** Tracker creado con `createTracker` (a nivel de módulo, para que no cambie entre renders). */
|
|
6
|
+
tracker: Tracker$1;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/** Hace disponible `tracker` a los hooks de este paquete. */
|
|
10
|
+
export declare function EventsProvider({ tracker, children }: EventsProviderProps): ReactElement;
|
|
11
|
+
/** Tracker del `<EventsProvider>` más cercano. Sin provider devuelve un no-op (no rompe la página). */
|
|
12
|
+
export declare function useTracker(): Tracker$1;
|
|
13
|
+
/** `tracker.track` con identidad estable mientras el tracker no cambie (apto para deps). */
|
|
14
|
+
export declare function useTrack(): Tracker$1["track"];
|
|
15
|
+
/** Lo mínimo que se usa del evento: lo cumplen el `MouseEvent` de React y el del DOM. */
|
|
16
|
+
interface AdClickEvent {
|
|
17
|
+
currentTarget: EventTarget | null;
|
|
18
|
+
button?: number;
|
|
19
|
+
}
|
|
20
|
+
interface AdClickHandlers {
|
|
21
|
+
/** La `url` tal cual: igual en servidor y cliente, así la hidratación no difiere. */
|
|
22
|
+
href: string;
|
|
23
|
+
onClick: (event: AdClickEvent) => void;
|
|
24
|
+
/** Click medio (abrir en otra pestaña) también cuenta como click. */
|
|
25
|
+
onAuxClick: (event: AdClickEvent) => void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Props para el `<a>` de un ad: `<a {...useAdClick(props, url)}>`. Al hacer click registra
|
|
29
|
+
* `ad_click` y cambia el `href` del ancla a la URL con `?ipc=` antes de que el navegador navegue.
|
|
30
|
+
*/
|
|
31
|
+
export declare function useAdClick(props: AdClickProps$1, url: string): AdClickHandlers;
|
|
32
|
+
/**
|
|
33
|
+
* En el sitio destino de un ad: guarda el `?ipc=` de la URL para atribuir la conversión.
|
|
34
|
+
* Va en un efecto porque lee `location` y el storage, que no existen en el servidor.
|
|
35
|
+
*/
|
|
36
|
+
export declare function useClickIdCapture(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Mide la impresión visible del elemento al que se asigna el ref devuelto:
|
|
39
|
+
* `<div ref={useImpression("ad_impression", props)}>`.
|
|
40
|
+
*
|
|
41
|
+
* `props` y `options` pueden ser literales nuevos en cada render: se comparan por valor.
|
|
42
|
+
*/
|
|
43
|
+
export declare function useImpression<N extends ImpressionEventName$1>(name: N, props: EventProps$1<N>, options?: ImpressionOptions$1): (el: Element | null) => void;
|
|
44
|
+
/** Mismo contrato que en `useAdClick`. */
|
|
45
|
+
type OutboundClickEvent = AdClickEvent;
|
|
46
|
+
type OutboundClickHandlers = AdClickHandlers;
|
|
47
|
+
/**
|
|
48
|
+
* Props para el `<a>` de un link o CTA medido hacia otro sitio o página (p. ej. el CTA de una
|
|
49
|
+
* landing que lleva al sitio principal): `<a {...useOutboundClick(props, url)}>`. Igual que
|
|
50
|
+
* `useAdClick`: el `href` del render es la URL tal cual y al hacer click registra
|
|
51
|
+
* `outbound_click` y reescribe el `href` con `?ipc=` antes de que el navegador navegue.
|
|
52
|
+
*/
|
|
53
|
+
export declare function useOutboundClick(props: OutboundClickProps$1, url: string): OutboundClickHandlers;
|
|
54
|
+
export { type AdClickEvent, type AdClickHandlers, type AdClickProps, type BrowserEventName, CLICK_ID_PARAM, CONSENT_CHANGE_EVENT, type ClickRecordOptions, type ConsentState, DEFAULT_CONSENT_COOKIE, type EventName, type EventProps, type EventsProviderProps, type ImpressionEventName, type ImpressionOptions, type OutboundClickEvent, type OutboundClickHandlers, type OutboundClickProps, type Tracker, type TrackerConfig, cookieConsent, createNoopTracker, createTracker, isClickId, parseConsentValue, readClickIdFromUrl, withClickId, withTrackingParams };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { CLICK_ID_PARAM, CONSENT_CHANGE_EVENT, DEFAULT_CONSENT_COOKIE, cookieConsent, createNoopTracker, createNoopTracker as createNoopTracker$1, createTracker, isClickId, parseConsentValue, readClickIdFromUrl, withClickId, withTrackingParams } from "@inspira-npm/events";
|
|
3
|
+
import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useRef } from "react";
|
|
4
|
+
// src/provider.ts
|
|
5
|
+
const TrackerContext = createContext(null);
|
|
6
|
+
/** Hace disponible `tracker` a los hooks de este paquete. */
|
|
7
|
+
function EventsProvider({ tracker, children }) {
|
|
8
|
+
return createElement(TrackerContext.Provider, { value: tracker }, children);
|
|
9
|
+
}
|
|
10
|
+
function isProduction() {
|
|
11
|
+
try {
|
|
12
|
+
return process.env.NODE_ENV === "production";
|
|
13
|
+
} catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
let fallback = null;
|
|
18
|
+
let warned = false;
|
|
19
|
+
function missingProviderTracker() {
|
|
20
|
+
if (!warned && !isProduction()) {
|
|
21
|
+
warned = true;
|
|
22
|
+
console.warn("[inspira-events] Falta <EventsProvider>: los eventos de este árbol no se envían (tracker no-op).");
|
|
23
|
+
}
|
|
24
|
+
fallback ?? (fallback = createNoopTracker$1());
|
|
25
|
+
return fallback;
|
|
26
|
+
}
|
|
27
|
+
/** Tracker del `<EventsProvider>` más cercano. Sin provider devuelve un no-op (no rompe la página). */
|
|
28
|
+
function useTracker() {
|
|
29
|
+
return useContext(TrackerContext) ?? missingProviderTracker();
|
|
30
|
+
}
|
|
31
|
+
/** `tracker.track` con identidad estable mientras el tracker no cambie (apto para deps). */
|
|
32
|
+
function useTrack() {
|
|
33
|
+
const tracker = useTracker();
|
|
34
|
+
return useCallback((name, props) => tracker.track(name, props), [tracker]);
|
|
35
|
+
}
|
|
36
|
+
// src/tracked-link.ts
|
|
37
|
+
/**
|
|
38
|
+
* Base de `useAdClick` y `useOutboundClick`: en cada click llama a `trackClick` (que registra el
|
|
39
|
+
* evento y devuelve la URL con `?ipc=`) y reescribe el `href` del `<a>` antes de que el navegador
|
|
40
|
+
* navegue. `trackClick` debe ser estable (una función de módulo).
|
|
41
|
+
*/
|
|
42
|
+
function useTrackedLink(props, url, trackClick) {
|
|
43
|
+
const tracker = useTracker();
|
|
44
|
+
const propsKey = JSON.stringify(props);
|
|
45
|
+
const onClick = useCallback((event) => {
|
|
46
|
+
const href = trackClick(tracker, JSON.parse(propsKey), url);
|
|
47
|
+
const target = event.currentTarget;
|
|
48
|
+
if (typeof HTMLAnchorElement !== "undefined" && target instanceof HTMLAnchorElement) target.href = href;
|
|
49
|
+
}, [
|
|
50
|
+
tracker,
|
|
51
|
+
propsKey,
|
|
52
|
+
url,
|
|
53
|
+
trackClick
|
|
54
|
+
]);
|
|
55
|
+
const onAuxClick = useCallback((event) => {
|
|
56
|
+
if (event.button !== void 0 && event.button !== 1) return;
|
|
57
|
+
onClick(event);
|
|
58
|
+
}, [onClick]);
|
|
59
|
+
return useMemo(() => ({
|
|
60
|
+
href: url,
|
|
61
|
+
onClick,
|
|
62
|
+
onAuxClick
|
|
63
|
+
}), [
|
|
64
|
+
url,
|
|
65
|
+
onClick,
|
|
66
|
+
onAuxClick
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
// src/use-ad-click.ts
|
|
70
|
+
const trackAdClick = (tracker, props, url) => tracker.trackAdClick(props, url);
|
|
71
|
+
/**
|
|
72
|
+
* Props para el `<a>` de un ad: `<a {...useAdClick(props, url)}>`. Al hacer click registra
|
|
73
|
+
* `ad_click` y cambia el `href` del ancla a la URL con `?ipc=` antes de que el navegador navegue.
|
|
74
|
+
*/
|
|
75
|
+
function useAdClick(props, url) {
|
|
76
|
+
return useTrackedLink(props, url, trackAdClick);
|
|
77
|
+
}
|
|
78
|
+
// src/use-click-id-capture.ts
|
|
79
|
+
/**
|
|
80
|
+
* En el sitio destino de un ad: guarda el `?ipc=` de la URL para atribuir la conversión.
|
|
81
|
+
* Va en un efecto porque lee `location` y el storage, que no existen en el servidor.
|
|
82
|
+
*/
|
|
83
|
+
function useClickIdCapture() {
|
|
84
|
+
const tracker = useTracker();
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
tracker.captureClickId();
|
|
87
|
+
}, [tracker]);
|
|
88
|
+
}
|
|
89
|
+
// src/use-impression.ts
|
|
90
|
+
/**
|
|
91
|
+
* Mide la impresión visible del elemento al que se asigna el ref devuelto:
|
|
92
|
+
* `<div ref={useImpression("ad_impression", props)}>`.
|
|
93
|
+
*
|
|
94
|
+
* `props` y `options` pueden ser literales nuevos en cada render: se comparan por valor.
|
|
95
|
+
*/
|
|
96
|
+
function useImpression(name, props, options) {
|
|
97
|
+
const tracker = useTracker();
|
|
98
|
+
const propsKey = JSON.stringify(props);
|
|
99
|
+
const optionsKey = options ? JSON.stringify(options) : "";
|
|
100
|
+
const cleanupRef = useRef(null);
|
|
101
|
+
return useCallback((el) => {
|
|
102
|
+
cleanupRef.current?.();
|
|
103
|
+
cleanupRef.current = null;
|
|
104
|
+
if (!el) return;
|
|
105
|
+
cleanupRef.current = tracker.observeImpression(el, name, JSON.parse(propsKey), optionsKey ? JSON.parse(optionsKey) : void 0);
|
|
106
|
+
}, [
|
|
107
|
+
tracker,
|
|
108
|
+
name,
|
|
109
|
+
propsKey,
|
|
110
|
+
optionsKey
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
// src/use-outbound-click.ts
|
|
114
|
+
const trackOutboundClick = (tracker, props, url) => tracker.trackOutboundClick(props, url);
|
|
115
|
+
/**
|
|
116
|
+
* Props para el `<a>` de un link o CTA medido hacia otro sitio o página (p. ej. el CTA de una
|
|
117
|
+
* landing que lleva al sitio principal): `<a {...useOutboundClick(props, url)}>`. Igual que
|
|
118
|
+
* `useAdClick`: el `href` del render es la URL tal cual y al hacer click registra
|
|
119
|
+
* `outbound_click` y reescribe el `href` con `?ipc=` antes de que el navegador navegue.
|
|
120
|
+
*/
|
|
121
|
+
function useOutboundClick(props, url) {
|
|
122
|
+
return useTrackedLink(props, url, trackOutboundClick);
|
|
123
|
+
}
|
|
124
|
+
export { CLICK_ID_PARAM, CONSENT_CHANGE_EVENT, DEFAULT_CONSENT_COOKIE, EventsProvider, cookieConsent, createNoopTracker, createTracker, isClickId, parseConsentValue, readClickIdFromUrl, useAdClick, useClickIdCapture, useImpression, useOutboundClick, useTrack, useTracker, withClickId, withTrackingParams };
|
package/package.json
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inspira-npm/events-react",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Provider y hooks de React para @inspira-npm/events.",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"!dist/**/*.map"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsdown",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
24
|
+
"prepublishOnly": "npm run typecheck && npm run test && npm run build"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@inspira-npm/events": "^0.3.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/react": "19.3.0",
|
|
34
|
+
"@types/react-dom": "19.3.0",
|
|
35
|
+
"react": "19.2.4",
|
|
36
|
+
"react-dom": "19.2.4"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/README.md
DELETED