@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.
@@ -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.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
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
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.