@thg-agentic/hyper-personalisation-web 0.0.0-stage → 3.17.1
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/LICENSE +21 -0
- package/README.md +825 -2
- package/dist/hp.min.js +3 -0
- package/dist/snippet.min.js +1 -0
- package/package.json +83 -3
- package/src/assignment.js +75 -0
- package/src/auto/attributes.js +16 -0
- package/src/auto/exposures.js +45 -0
- package/src/auto/lists.js +136 -0
- package/src/auto/promotions.js +104 -0
- package/src/auto/rails.js +217 -0
- package/src/auto/viewability.js +150 -0
- package/src/auto.js +13 -0
- package/src/bootstrap.js +476 -0
- package/src/carry.js +74 -0
- package/src/conformance.js +530 -0
- package/src/consent-gate.js +324 -0
- package/src/consent.js +604 -0
- package/src/context.js +439 -0
- package/src/datalayer.js +411 -0
- package/src/decisions.js +90 -0
- package/src/device-storage.js +201 -0
- package/src/experiments.js +220 -0
- package/src/ga4.js +124 -0
- package/src/hash.js +138 -0
- package/src/hp.js +135 -0
- package/src/index.js +818 -0
- package/src/preview.js +44 -0
- package/src/recommendation-context.js +101 -0
- package/src/segment.js +375 -0
- package/src/session/category.js +40 -0
- package/src/session/record.js +163 -0
- package/src/session/rules.js +195 -0
- package/src/session/signals.js +146 -0
- package/src/session-id.js +62 -0
- package/src/session.js +28 -0
- package/src/settings.js +211 -0
- package/src/shape.js +111 -0
- package/src/social-proof.js +139 -0
- package/src/spec-version.js +4 -0
- package/src/storage-scope.js +159 -0
- package/src/transport.js +436 -0
- package/src/version.js +2 -0
- package/types/auto.d.ts +51 -0
- package/types/bootstrap.d.ts +154 -0
- package/types/consent.d.ts +126 -0
- package/types/datalayer.d.ts +76 -0
- package/types/events.d.ts +680 -0
- package/types/hp.d.ts +64 -0
- package/types/index.d.ts +610 -0
- package/types/segment.d.ts +68 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
export type ConsentPurpose =
|
|
2
|
+
| 'analytics'
|
|
3
|
+
| 'marketing'
|
|
4
|
+
| 'personalisation'
|
|
5
|
+
| 'ad_user_data'
|
|
6
|
+
| 'ad_personalization';
|
|
7
|
+
|
|
8
|
+
/** schemas/common/consent-state.json: true granted, false refused, null never asked. */
|
|
9
|
+
export type ConsentState = Record<ConsentPurpose, boolean | null>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* context.consent.basis (spec 1.5): who decided whether an event may be collected. `visitor` is the
|
|
13
|
+
* visitor's own answer, where null is unanswered; `host` is the site's own decision.
|
|
14
|
+
*/
|
|
15
|
+
export type ConsentBasis = 'visitor' | 'host';
|
|
16
|
+
|
|
17
|
+
export declare const CONSENT_BASIS: Readonly<{
|
|
18
|
+
visitor: 'visitor';
|
|
19
|
+
host: 'host';
|
|
20
|
+
}>;
|
|
21
|
+
|
|
22
|
+
/** context.consent when the SDK has no adapter: `{ basis: 'host' }`. */
|
|
23
|
+
export declare function hostConsent(): { basis: 'host' };
|
|
24
|
+
|
|
25
|
+
export interface ConsentAdapter {
|
|
26
|
+
/** Recorded as context.consent.source. */
|
|
27
|
+
name: string;
|
|
28
|
+
/**
|
|
29
|
+
* Recorded as context.consent.basis. Default `visitor`; `staticConsent` is `host`. Set `host` only
|
|
30
|
+
* for an adapter that reports the site's own decision rather than asking the visitor.
|
|
31
|
+
*/
|
|
32
|
+
readonly basis?: ConsentBasis;
|
|
33
|
+
/** Null while the CMP has not answered. */
|
|
34
|
+
read(): Partial<ConsentState> | null;
|
|
35
|
+
/** Called on every change the CMP reports; returns an unsubscribe. */
|
|
36
|
+
subscribe(onChange: (state: Partial<ConsentState>) => void): () => void;
|
|
37
|
+
/**
|
|
38
|
+
* True when `subscribe` reports every change by itself. Otherwise the SDK re-reads the adapter
|
|
39
|
+
* every 2s while the page is visible, so a withdrawal nothing announces is still honoured.
|
|
40
|
+
*/
|
|
41
|
+
readonly observesChanges?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export declare const CONSENT_PURPOSES: readonly ConsentPurpose[];
|
|
45
|
+
/** 'thg_hp_consent': the consent cookie's name unless the host configures another. */
|
|
46
|
+
export declare const DEFAULT_CONSENT_COOKIE: string;
|
|
47
|
+
|
|
48
|
+
export interface DidomiConsentOptions {
|
|
49
|
+
/** Didomi purpose ids per spec purpose. An id also matches `<id>-<suffix>`. */
|
|
50
|
+
purposes?: Partial<Record<ConsentPurpose, string[]>>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface OneTrustConsentOptions {
|
|
54
|
+
/** OneTrust group id per spec purpose. Defaults: analytics C0002, personalisation C0003, marketing C0004. */
|
|
55
|
+
groups?: Partial<Record<ConsentPurpose, string>>;
|
|
56
|
+
/** Accept OneTrust's groups before the banner is closed. Only for notice-only / opt-out regions. */
|
|
57
|
+
impliedConsent?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface CookieConsentOptions {
|
|
61
|
+
/** The cookie your banner writes. Required. */
|
|
62
|
+
name: string;
|
|
63
|
+
/** The cookie's category id per spec purpose. `analytics` is required. */
|
|
64
|
+
categories: Partial<Record<ConsentPurpose, string>> & { analytics: string };
|
|
65
|
+
/**
|
|
66
|
+
* Accepted category ids from the URL-decoded cookie value, or null when it cannot be read.
|
|
67
|
+
* Default: comma-separated ids; empty means unknown.
|
|
68
|
+
*/
|
|
69
|
+
parse?(raw: string): Set<string> | null;
|
|
70
|
+
/** A literal cookie value meaning "rejected everything". */
|
|
71
|
+
refusedValue?: string;
|
|
72
|
+
/** context.consent.source. Default 'native'. */
|
|
73
|
+
source?: string;
|
|
74
|
+
/** Window event the banner dispatches after writing the cookie. Default 'thg_hp_consent_change'. */
|
|
75
|
+
changeEvent?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export declare function didomiConsent(
|
|
79
|
+
options?: DidomiConsentOptions,
|
|
80
|
+
): ConsentAdapter;
|
|
81
|
+
export declare function oneTrustConsent(
|
|
82
|
+
options?: OneTrustConsentOptions,
|
|
83
|
+
): ConsentAdapter;
|
|
84
|
+
export declare function cookieConsent(
|
|
85
|
+
options: CookieConsentOptions,
|
|
86
|
+
): ConsentAdapter;
|
|
87
|
+
/**
|
|
88
|
+
* Reads the consent cookie the SDK writes on a page that runs the CMP, for pages on the same
|
|
89
|
+
* registrable domain that don't (a separate checkout app, a subdomain). No answer in it = not answered.
|
|
90
|
+
* `name` must match the writer's `storageNames.consent`; both default to 'thg_hp_consent'.
|
|
91
|
+
*/
|
|
92
|
+
export declare function forwardedConsent(options?: {
|
|
93
|
+
name?: string;
|
|
94
|
+
}): ConsentAdapter;
|
|
95
|
+
export declare function staticConsent(
|
|
96
|
+
state: Partial<ConsentState>,
|
|
97
|
+
): ConsentAdapter;
|
|
98
|
+
|
|
99
|
+
export declare function normaliseConsentState(
|
|
100
|
+
raw: unknown,
|
|
101
|
+
): ConsentState | null;
|
|
102
|
+
export declare function sameConsentState(
|
|
103
|
+
a: ConsentState | null,
|
|
104
|
+
b: ConsentState | null,
|
|
105
|
+
): boolean;
|
|
106
|
+
/** The `thg_hp_consent` cookie value, e.g. `a=1&m=0&p=1`. */
|
|
107
|
+
export declare function formatConsentCookie(
|
|
108
|
+
state: Partial<ConsentState> | null,
|
|
109
|
+
): string;
|
|
110
|
+
export declare function parseConsentCookie(
|
|
111
|
+
value: string | null | undefined,
|
|
112
|
+
): ConsentState;
|
|
113
|
+
/**
|
|
114
|
+
* The adapter reporting only the purposes the property asks for (its settings' `consent.purposes`);
|
|
115
|
+
* the rest read as unanswered. Analytics is always reported. bootstrap and cdpPlugins apply it.
|
|
116
|
+
*/
|
|
117
|
+
export declare function reportingPurposes(
|
|
118
|
+
adapter: ConsentAdapter,
|
|
119
|
+
purposes: Partial<Record<ConsentPurpose, boolean>> | null,
|
|
120
|
+
): ConsentAdapter;
|
|
121
|
+
/** 'hp-consent': the header that carries consent to the serving API. */
|
|
122
|
+
export declare const CONSENT_HEADER: 'hp-consent';
|
|
123
|
+
/** `{ 'hp-consent': formatConsentCookie(state) }`, for any request to the serving API. */
|
|
124
|
+
export declare function servingHeaders(state: Partial<ConsentState> | null): {
|
|
125
|
+
'hp-consent': string;
|
|
126
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { CdpProduct } from './events';
|
|
2
|
+
|
|
3
|
+
export interface DataLayerEvent {
|
|
4
|
+
event: string;
|
|
5
|
+
properties?: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface DataLayerHelpers {
|
|
9
|
+
name: string;
|
|
10
|
+
entry: Record<string, unknown>;
|
|
11
|
+
ecommerce: Record<string, unknown>;
|
|
12
|
+
items: Record<string, unknown>[];
|
|
13
|
+
/** False when the push had no item list at all (not the same as an empty one). */
|
|
14
|
+
itemsListed: boolean;
|
|
15
|
+
products: CdpProduct[];
|
|
16
|
+
currency: string | null;
|
|
17
|
+
value: number | null;
|
|
18
|
+
promotions: Array<{
|
|
19
|
+
promotion_id: string;
|
|
20
|
+
name: string | null;
|
|
21
|
+
creative: string | null;
|
|
22
|
+
/** GA4 creative_slot, as Segment's `position` (spec 1.2). */
|
|
23
|
+
position: string | null;
|
|
24
|
+
}>;
|
|
25
|
+
toProducts(items: unknown[]): CdpProduct[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type DataLayerMapping = (
|
|
29
|
+
payload: Record<string, unknown>,
|
|
30
|
+
helpers: DataLayerHelpers,
|
|
31
|
+
) => DataLayerEvent | DataLayerEvent[] | null | undefined;
|
|
32
|
+
|
|
33
|
+
/** Anything with a Segment-style track: this package's client or an analytics-next instance. */
|
|
34
|
+
export interface TrackingClient {
|
|
35
|
+
track(
|
|
36
|
+
event: string,
|
|
37
|
+
properties?: Record<string, unknown>,
|
|
38
|
+
options?: { context?: Record<string, unknown> },
|
|
39
|
+
): unknown;
|
|
40
|
+
signedOut?(options?: { context?: Record<string, unknown> }): unknown;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Resolves a GA4 item's parent product id. Default `item.item_group_id ?? item.item_id`. */
|
|
44
|
+
export type ProductIdResolver = (item: Record<string, unknown>) => unknown;
|
|
45
|
+
|
|
46
|
+
/** How one commerce platform uses the dataLayer. Spread into the options: `{ ...preset }`. */
|
|
47
|
+
export interface DataLayerPreset {
|
|
48
|
+
/** The GA4 event name of a push. Default `entry.event`. */
|
|
49
|
+
eventName?(entry: Record<string, unknown>): string | null | undefined;
|
|
50
|
+
/** Rewrite a push into the GA4 shape before anything reads it; return null to skip it. */
|
|
51
|
+
transform?(entry: unknown): unknown;
|
|
52
|
+
productId?: ProductIdResolver;
|
|
53
|
+
/** Add or override mappings, keyed by GA4 event name. */
|
|
54
|
+
map?: Record<string, DataLayerMapping>;
|
|
55
|
+
/** GA4 event names to skip. purchase and refund are always skipped. */
|
|
56
|
+
ignore?: string[];
|
|
57
|
+
/** Checkout step numbers. Defaults: shipping 2, payment 3. */
|
|
58
|
+
steps?: { shipping?: number; payment?: number };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface ConnectDataLayerOptions extends DataLayerPreset {
|
|
62
|
+
/** Defaults to window.dataLayer, created when absent. */
|
|
63
|
+
dataLayer?: unknown[];
|
|
64
|
+
/** Identical pushes within this window are emitted once. Default 1000. */
|
|
65
|
+
dedupeMs?: number;
|
|
66
|
+
onError?(error: unknown, entry: unknown): void;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Returns disconnect(). */
|
|
70
|
+
export declare function connectDataLayer(
|
|
71
|
+
analytics: TrackingClient,
|
|
72
|
+
options?: ConnectDataLayerOptions,
|
|
73
|
+
): () => void;
|
|
74
|
+
|
|
75
|
+
/** The first usable id among the candidates, as a string, or null. Blank strings are skipped. */
|
|
76
|
+
export declare function firstId(...candidates: unknown[]): string | null;
|