universal-ad-loader 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/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +208 -2
- package/astro/AdSlot.astro +23 -0
- package/astro/UalBundled.astro +34 -0
- package/astro/UalLoader.astro +40 -0
- package/dist/global.d.ts +13 -0
- package/dist/index.cjs +1288 -0
- package/dist/index.d.ts +281 -0
- package/dist/index.mjs +1266 -0
- package/dist/next.cjs +35 -0
- package/dist/next.d.ts +8 -0
- package/dist/next.mjs +16 -0
- package/dist/react.cjs +122 -0
- package/dist/react.d.ts +36 -0
- package/dist/react.mjs +103 -0
- package/dist/ual.js +1277 -0
- package/dist/ual.min.js +12 -0
- package/dist/vue.cjs +128 -0
- package/dist/vue.d.ts +21 -0
- package/dist/vue.mjs +108 -0
- package/docs/ad-server-esistenti.md +78 -0
- package/docs/cdn.md +58 -0
- package/docs/esempio.md +156 -0
- package/docs/libreria.md +142 -0
- package/docs/pubblicazione-npm.md +114 -0
- package/package.json +119 -4
- package/schema/ual-config.schema.json +191 -0
package/dist/next.cjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/next.js
|
|
21
|
+
var next_exports = {};
|
|
22
|
+
__export(next_exports, {
|
|
23
|
+
AdSlot: () => import_react3.AdSlot,
|
|
24
|
+
UalProvider: () => UalProvider,
|
|
25
|
+
useUal: () => import_react3.useUal
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(next_exports);
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
var import_navigation = require("next/navigation");
|
|
30
|
+
var import_react2 = require("./react.cjs");
|
|
31
|
+
var import_react3 = require("./react.cjs");
|
|
32
|
+
function UalProvider(props) {
|
|
33
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
34
|
+
return (0, import_react.createElement)(import_react2.UalProvider, { ...props, pageKey: props.pageKey !== void 0 ? props.pageKey : pathname });
|
|
35
|
+
}
|
package/dist/next.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FunctionComponent } from 'react';
|
|
2
|
+
import type { UalProviderProps } from './react';
|
|
3
|
+
|
|
4
|
+
export type { AdSlotProps } from './react';
|
|
5
|
+
export { AdSlot, useUal } from './react';
|
|
6
|
+
|
|
7
|
+
/** Come il UalProvider React, ma `pageKey` è il percorso (usePathname) e il cambio pagina è automatico. */
|
|
8
|
+
export const UalProvider: FunctionComponent<UalProviderProps>;
|
package/dist/next.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
// src/next.js
|
|
4
|
+
import { createElement } from "react";
|
|
5
|
+
import { usePathname } from "next/navigation";
|
|
6
|
+
import { UalProvider as ReactProvider } from "./react.mjs";
|
|
7
|
+
import { AdSlot, useUal } from "./react.mjs";
|
|
8
|
+
function UalProvider(props) {
|
|
9
|
+
const pathname = usePathname();
|
|
10
|
+
return createElement(ReactProvider, { ...props, pageKey: props.pageKey !== void 0 ? props.pageKey : pathname });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
AdSlot,
|
|
14
|
+
UalProvider,
|
|
15
|
+
useUal
|
|
16
|
+
};
|
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/react.js
|
|
21
|
+
var react_exports = {};
|
|
22
|
+
__export(react_exports, {
|
|
23
|
+
AdSlot: () => AdSlot,
|
|
24
|
+
UalProvider: () => UalProvider,
|
|
25
|
+
useUal: () => useUal
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(react_exports);
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
|
|
30
|
+
// src/wrappers/start.js
|
|
31
|
+
var import_lib = require("./index.cjs");
|
|
32
|
+
var loading = /* @__PURE__ */ new Map();
|
|
33
|
+
function loadFromCdn(src) {
|
|
34
|
+
if (window.ual && window.ual.version) return Promise.resolve(window.ual);
|
|
35
|
+
if (!loading.has(src)) {
|
|
36
|
+
loading.set(src, new Promise((resolve, reject) => {
|
|
37
|
+
const s = document.createElement("script");
|
|
38
|
+
s.async = true;
|
|
39
|
+
s.src = src;
|
|
40
|
+
s.onload = () => {
|
|
41
|
+
if (window.ual && window.ual.version) resolve(window.ual);
|
|
42
|
+
else reject(new Error("il loader caricato da " + src + " non ha esposto window.ual"));
|
|
43
|
+
};
|
|
44
|
+
s.onerror = () => {
|
|
45
|
+
loading.delete(src);
|
|
46
|
+
reject(new Error("impossibile caricare il loader da " + src));
|
|
47
|
+
};
|
|
48
|
+
document.head.appendChild(s);
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
return loading.get(src);
|
|
52
|
+
}
|
|
53
|
+
async function startUal({ config, src, beforeInit }) {
|
|
54
|
+
const ual = src ? await loadFromCdn(src) : (0, import_lib.getUal)();
|
|
55
|
+
if (beforeInit) beforeInit(ual);
|
|
56
|
+
const started = typeof ual.isInitialized === "function" && ual.isInitialized();
|
|
57
|
+
if (started) {
|
|
58
|
+
const p = typeof ual.whenReady === "function" ? ual.whenReady() : null;
|
|
59
|
+
if (p) await p;
|
|
60
|
+
} else {
|
|
61
|
+
await ual.init(config);
|
|
62
|
+
}
|
|
63
|
+
return ual;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/react.js
|
|
67
|
+
var Ctx = (0, import_react.createContext)({ ual: null, ready: false });
|
|
68
|
+
function useUal() {
|
|
69
|
+
return (0, import_react.useContext)(Ctx);
|
|
70
|
+
}
|
|
71
|
+
function UalProvider({ config, src, pageKey, targeting, onEvent, children }) {
|
|
72
|
+
const [state, setState] = (0, import_react.useState)({ ual: null, ready: false });
|
|
73
|
+
const configRef = (0, import_react.useRef)(config);
|
|
74
|
+
const onEventRef = (0, import_react.useRef)(onEvent);
|
|
75
|
+
onEventRef.current = onEvent;
|
|
76
|
+
const targetingRef = (0, import_react.useRef)(targeting);
|
|
77
|
+
targetingRef.current = targeting;
|
|
78
|
+
(0, import_react.useEffect)(() => {
|
|
79
|
+
let alive = true;
|
|
80
|
+
let off = null;
|
|
81
|
+
startUal({
|
|
82
|
+
config: configRef.current,
|
|
83
|
+
src,
|
|
84
|
+
beforeInit: (ual) => {
|
|
85
|
+
if (!alive) return;
|
|
86
|
+
if (targetingRef.current) ual.setTargeting(targetingRef.current);
|
|
87
|
+
off = ual.on("*", (data, evt) => {
|
|
88
|
+
if (onEventRef.current) onEventRef.current(evt, data);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}).then((ual) => {
|
|
92
|
+
if (alive) setState({ ual, ready: true });
|
|
93
|
+
}).catch((e) => console.warn("[UAL]", e && e.message ? e.message : e));
|
|
94
|
+
return () => {
|
|
95
|
+
alive = false;
|
|
96
|
+
if (off) off();
|
|
97
|
+
};
|
|
98
|
+
}, []);
|
|
99
|
+
const first = (0, import_react.useRef)(true);
|
|
100
|
+
(0, import_react.useEffect)(() => {
|
|
101
|
+
if (first.current) {
|
|
102
|
+
first.current = false;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (state.ual) state.ual.pageView();
|
|
106
|
+
}, [pageKey]);
|
|
107
|
+
const targetingKey = JSON.stringify(targeting || {});
|
|
108
|
+
(0, import_react.useEffect)(() => {
|
|
109
|
+
if (state.ual && targetingRef.current) state.ual.setTargeting(targetingRef.current);
|
|
110
|
+
}, [state.ual, targetingKey]);
|
|
111
|
+
return (0, import_react.createElement)(Ctx.Provider, { value: state }, children);
|
|
112
|
+
}
|
|
113
|
+
function AdSlot({ name, params, minHeight, className, style, id }) {
|
|
114
|
+
return (0, import_react.createElement)("div", {
|
|
115
|
+
id,
|
|
116
|
+
className,
|
|
117
|
+
"data-ad-slot": name,
|
|
118
|
+
"data-ad-params": params ? JSON.stringify(params) : void 0,
|
|
119
|
+
// riserva lo spazio già nell'HTML del server: nessun salto di layout quando arriva il banner
|
|
120
|
+
style: minHeight ? { minHeight, ...style } : style
|
|
121
|
+
});
|
|
122
|
+
}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CSSProperties, FunctionComponent, ReactNode } from 'react';
|
|
2
|
+
import type { Ual, UalConfig, Targeting, UalEventMap } from './index';
|
|
3
|
+
|
|
4
|
+
export interface UalProviderProps {
|
|
5
|
+
/** Configurazione (oggetto, meglio con `defineConfig`) o URL del JSON. Letta solo all'avvio. */
|
|
6
|
+
config: UalConfig | string;
|
|
7
|
+
/** URL del loader su CDN (`ual.min.js`). Senza, UAL è incluso nel bundle del sito. */
|
|
8
|
+
src?: string;
|
|
9
|
+
/** Quando cambia, UAL ricalcola regole per pagina e slot (es. il percorso). */
|
|
10
|
+
pageKey?: string | number;
|
|
11
|
+
targeting?: Targeting;
|
|
12
|
+
/** Eventi di UAL (slotRendered, slotEmpty, consent, error…). */
|
|
13
|
+
onEvent?: <K extends keyof UalEventMap>(event: K, data: UalEventMap[K]) => void;
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Avvia UAL dopo l'idratazione, una volta per pagina. Nessun DOM proprio. */
|
|
18
|
+
export const UalProvider: FunctionComponent<UalProviderProps>;
|
|
19
|
+
|
|
20
|
+
export interface AdSlotProps {
|
|
21
|
+
/** Nome dello slot in configurazione (data-ad-slot). */
|
|
22
|
+
name: string;
|
|
23
|
+
/** Sovrascrive i `params` del provider per questa istanza. */
|
|
24
|
+
params?: Record<string, unknown>;
|
|
25
|
+
/** Riserva lo spazio già nell'HTML del server (evita salti di layout). */
|
|
26
|
+
minHeight?: number;
|
|
27
|
+
className?: string;
|
|
28
|
+
style?: CSSProperties;
|
|
29
|
+
id?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Una posizione pubblicitaria: un div vuoto che UAL riempie. */
|
|
33
|
+
export const AdSlot: FunctionComponent<AdSlotProps>;
|
|
34
|
+
|
|
35
|
+
/** `ual` è null finché UAL non è avviato (sempre null sul server). */
|
|
36
|
+
export function useUal(): { ual: Ual | null; ready: boolean };
|
package/dist/react.mjs
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
// src/react.js
|
|
4
|
+
import { createContext, createElement, useContext, useEffect, useRef, useState } from "react";
|
|
5
|
+
|
|
6
|
+
// src/wrappers/start.js
|
|
7
|
+
import { getUal } from "./index.mjs";
|
|
8
|
+
var loading = /* @__PURE__ */ new Map();
|
|
9
|
+
function loadFromCdn(src) {
|
|
10
|
+
if (window.ual && window.ual.version) return Promise.resolve(window.ual);
|
|
11
|
+
if (!loading.has(src)) {
|
|
12
|
+
loading.set(src, new Promise((resolve, reject) => {
|
|
13
|
+
const s = document.createElement("script");
|
|
14
|
+
s.async = true;
|
|
15
|
+
s.src = src;
|
|
16
|
+
s.onload = () => {
|
|
17
|
+
if (window.ual && window.ual.version) resolve(window.ual);
|
|
18
|
+
else reject(new Error("il loader caricato da " + src + " non ha esposto window.ual"));
|
|
19
|
+
};
|
|
20
|
+
s.onerror = () => {
|
|
21
|
+
loading.delete(src);
|
|
22
|
+
reject(new Error("impossibile caricare il loader da " + src));
|
|
23
|
+
};
|
|
24
|
+
document.head.appendChild(s);
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
return loading.get(src);
|
|
28
|
+
}
|
|
29
|
+
async function startUal({ config, src, beforeInit }) {
|
|
30
|
+
const ual = src ? await loadFromCdn(src) : getUal();
|
|
31
|
+
if (beforeInit) beforeInit(ual);
|
|
32
|
+
const started = typeof ual.isInitialized === "function" && ual.isInitialized();
|
|
33
|
+
if (started) {
|
|
34
|
+
const p = typeof ual.whenReady === "function" ? ual.whenReady() : null;
|
|
35
|
+
if (p) await p;
|
|
36
|
+
} else {
|
|
37
|
+
await ual.init(config);
|
|
38
|
+
}
|
|
39
|
+
return ual;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/react.js
|
|
43
|
+
var Ctx = createContext({ ual: null, ready: false });
|
|
44
|
+
function useUal() {
|
|
45
|
+
return useContext(Ctx);
|
|
46
|
+
}
|
|
47
|
+
function UalProvider({ config, src, pageKey, targeting, onEvent, children }) {
|
|
48
|
+
const [state, setState] = useState({ ual: null, ready: false });
|
|
49
|
+
const configRef = useRef(config);
|
|
50
|
+
const onEventRef = useRef(onEvent);
|
|
51
|
+
onEventRef.current = onEvent;
|
|
52
|
+
const targetingRef = useRef(targeting);
|
|
53
|
+
targetingRef.current = targeting;
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
let alive = true;
|
|
56
|
+
let off = null;
|
|
57
|
+
startUal({
|
|
58
|
+
config: configRef.current,
|
|
59
|
+
src,
|
|
60
|
+
beforeInit: (ual) => {
|
|
61
|
+
if (!alive) return;
|
|
62
|
+
if (targetingRef.current) ual.setTargeting(targetingRef.current);
|
|
63
|
+
off = ual.on("*", (data, evt) => {
|
|
64
|
+
if (onEventRef.current) onEventRef.current(evt, data);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}).then((ual) => {
|
|
68
|
+
if (alive) setState({ ual, ready: true });
|
|
69
|
+
}).catch((e) => console.warn("[UAL]", e && e.message ? e.message : e));
|
|
70
|
+
return () => {
|
|
71
|
+
alive = false;
|
|
72
|
+
if (off) off();
|
|
73
|
+
};
|
|
74
|
+
}, []);
|
|
75
|
+
const first = useRef(true);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (first.current) {
|
|
78
|
+
first.current = false;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (state.ual) state.ual.pageView();
|
|
82
|
+
}, [pageKey]);
|
|
83
|
+
const targetingKey = JSON.stringify(targeting || {});
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (state.ual && targetingRef.current) state.ual.setTargeting(targetingRef.current);
|
|
86
|
+
}, [state.ual, targetingKey]);
|
|
87
|
+
return createElement(Ctx.Provider, { value: state }, children);
|
|
88
|
+
}
|
|
89
|
+
function AdSlot({ name, params, minHeight, className, style, id }) {
|
|
90
|
+
return createElement("div", {
|
|
91
|
+
id,
|
|
92
|
+
className,
|
|
93
|
+
"data-ad-slot": name,
|
|
94
|
+
"data-ad-params": params ? JSON.stringify(params) : void 0,
|
|
95
|
+
// riserva lo spazio già nell'HTML del server: nessun salto di layout quando arriva il banner
|
|
96
|
+
style: minHeight ? { minHeight, ...style } : style
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export {
|
|
100
|
+
AdSlot,
|
|
101
|
+
UalProvider,
|
|
102
|
+
useUal
|
|
103
|
+
};
|