@inspira-npm/events-react 0.0.0-stage → 0.1.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 +44 -0
- package/dist/index.js +102 -0
- package/package.json +39 -4
- package/README.md +0 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
import { AdClickProps, AdClickProps as AdClickProps$1, BrowserEventName, CLICK_ID_PARAM, CONSENT_CHANGE_EVENT, ConsentState, DEFAULT_CONSENT_COOKIE, EventName, EventProps, EventProps as EventProps$1, ImpressionEventName, ImpressionEventName as ImpressionEventName$1, ImpressionOptions, ImpressionOptions as ImpressionOptions$1, Tracker, Tracker as Tracker$1, TrackerConfig, cookieConsent, createNoopTracker, createTracker, isClickId, parseConsentValue, readClickIdFromUrl, withClickId } 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
|
+
export { type AdClickEvent, type AdClickHandlers, type AdClickProps, type BrowserEventName, CLICK_ID_PARAM, CONSENT_CHANGE_EVENT, type ConsentState, DEFAULT_CONSENT_COOKIE, type EventName, type EventProps, type EventsProviderProps, type ImpressionEventName, type ImpressionOptions, type Tracker, type TrackerConfig, cookieConsent, createNoopTracker, createTracker, isClickId, parseConsentValue, readClickIdFromUrl, withClickId };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
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 } 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/use-ad-click.ts
|
|
37
|
+
/**
|
|
38
|
+
* Props para el `<a>` de un ad: `<a {...useAdClick(props, url)}>`. Al hacer click registra
|
|
39
|
+
* `ad_click` y cambia el `href` del ancla a la URL con `?ipc=` antes de que el navegador navegue.
|
|
40
|
+
*/
|
|
41
|
+
function useAdClick(props, url) {
|
|
42
|
+
const tracker = useTracker();
|
|
43
|
+
const propsKey = JSON.stringify(props);
|
|
44
|
+
const onClick = useCallback((event) => {
|
|
45
|
+
const href = tracker.trackAdClick(JSON.parse(propsKey), url);
|
|
46
|
+
const target = event.currentTarget;
|
|
47
|
+
if (typeof HTMLAnchorElement !== "undefined" && target instanceof HTMLAnchorElement) target.href = href;
|
|
48
|
+
}, [
|
|
49
|
+
tracker,
|
|
50
|
+
propsKey,
|
|
51
|
+
url
|
|
52
|
+
]);
|
|
53
|
+
const onAuxClick = useCallback((event) => {
|
|
54
|
+
if (event.button !== void 0 && event.button !== 1) return;
|
|
55
|
+
onClick(event);
|
|
56
|
+
}, [onClick]);
|
|
57
|
+
return useMemo(() => ({
|
|
58
|
+
href: url,
|
|
59
|
+
onClick,
|
|
60
|
+
onAuxClick
|
|
61
|
+
}), [
|
|
62
|
+
url,
|
|
63
|
+
onClick,
|
|
64
|
+
onAuxClick
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
// src/use-click-id-capture.ts
|
|
68
|
+
/**
|
|
69
|
+
* En el sitio destino de un ad: guarda el `?ipc=` de la URL para atribuir la conversión.
|
|
70
|
+
* Va en un efecto porque lee `location` y el storage, que no existen en el servidor.
|
|
71
|
+
*/
|
|
72
|
+
function useClickIdCapture() {
|
|
73
|
+
const tracker = useTracker();
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
tracker.captureClickId();
|
|
76
|
+
}, [tracker]);
|
|
77
|
+
}
|
|
78
|
+
// src/use-impression.ts
|
|
79
|
+
/**
|
|
80
|
+
* Mide la impresión visible del elemento al que se asigna el ref devuelto:
|
|
81
|
+
* `<div ref={useImpression("ad_impression", props)}>`.
|
|
82
|
+
*
|
|
83
|
+
* `props` y `options` pueden ser literales nuevos en cada render: se comparan por valor.
|
|
84
|
+
*/
|
|
85
|
+
function useImpression(name, props, options) {
|
|
86
|
+
const tracker = useTracker();
|
|
87
|
+
const propsKey = JSON.stringify(props);
|
|
88
|
+
const optionsKey = options ? JSON.stringify(options) : "";
|
|
89
|
+
const cleanupRef = useRef(null);
|
|
90
|
+
return useCallback((el) => {
|
|
91
|
+
cleanupRef.current?.();
|
|
92
|
+
cleanupRef.current = null;
|
|
93
|
+
if (!el) return;
|
|
94
|
+
cleanupRef.current = tracker.observeImpression(el, name, JSON.parse(propsKey), optionsKey ? JSON.parse(optionsKey) : void 0);
|
|
95
|
+
}, [
|
|
96
|
+
tracker,
|
|
97
|
+
name,
|
|
98
|
+
propsKey,
|
|
99
|
+
optionsKey
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
export { CLICK_ID_PARAM, CONSENT_CHANGE_EVENT, DEFAULT_CONSENT_COOKIE, EventsProvider, cookieConsent, createNoopTracker, createTracker, isClickId, parseConsentValue, readClickIdFromUrl, useAdClick, useClickIdCapture, useImpression, useTrack, useTracker, withClickId };
|
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.1.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.1.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