@syntrologie/runtime-sdk 2.8.0-canary.183 → 2.8.0-canary.185
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/defaults/clickIds.d.ts +14 -0
- package/dist/defaults/identifyOnEmail.d.ts +23 -0
- package/dist/defaults/identifyOnUrlParam.d.ts +29 -0
- package/dist/defaults/index.d.ts +51 -0
- package/dist/defaults/initialProperties.d.ts +26 -0
- package/dist/defaults/jsonLd.d.ts +17 -0
- package/dist/index.js +729 -1
- package/dist/index.js.map +4 -4
- package/dist/smart-canvas.esm.js +100 -100
- package/dist/smart-canvas.esm.js.map +4 -4
- package/dist/smart-canvas.js +711 -2
- package/dist/smart-canvas.js.map +4 -4
- package/dist/smart-canvas.min.js +101 -101
- package/dist/smart-canvas.min.js.map +4 -4
- package/dist/telemetry/adapters/posthog.d.ts +26 -0
- package/dist/telemetry/consent/ConsentDetector.d.ts +26 -0
- package/dist/telemetry/{consent.d.ts → consent/ConsentGate.d.ts} +33 -1
- package/dist/telemetry/consent/adapters/gtmConsentMode.d.ts +18 -0
- package/dist/telemetry/consent/adapters/iabTcf.d.ts +21 -0
- package/dist/telemetry/consent/adapters/shopify.d.ts +17 -0
- package/dist/telemetry/consent/index.d.ts +17 -0
- package/dist/telemetry/consent/types.d.ts +47 -0
- package/dist/telemetry/types.d.ts +24 -0
- package/dist/version.d.ts +1 -1
- package/package.json +3 -5
- package/schema/canvas-config.schema.json +352 -1
- package/CAPABILITIES.md +0 -1450
|
@@ -73,6 +73,20 @@ export interface PostHogAdapterOptions {
|
|
|
73
73
|
* @default false
|
|
74
74
|
*/
|
|
75
75
|
requireExplicitConsent?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* PostHog cookieless tracking mode. Captures events with a privacy-
|
|
78
|
+
* preserving session-scoped hash instead of a persistent cookie.
|
|
79
|
+
*
|
|
80
|
+
* - 'always': never use cookies; always cookieless
|
|
81
|
+
* - 'on_reject': use cookies until consent is rejected, then cookieless
|
|
82
|
+
*
|
|
83
|
+
* Recommended pairing for the SDK consent layer: `'on_reject'` so
|
|
84
|
+
* baseline behavioral telemetry flows for all visitors regardless
|
|
85
|
+
* of consent state, with full identified tracking only after grant.
|
|
86
|
+
*
|
|
87
|
+
* @default undefined (cookies used unconditionally)
|
|
88
|
+
*/
|
|
89
|
+
cookieless_mode?: 'always' | 'on_reject';
|
|
76
90
|
/**
|
|
77
91
|
* Enable behavioral signal detection (hesitation, rage click, etc.)
|
|
78
92
|
* Pass `true` for defaults, or a partial DetectorConfig to customize thresholds.
|
|
@@ -128,6 +142,18 @@ export declare class PostHogAdapter implements TelemetryClient {
|
|
|
128
142
|
getSegmentFlags(): Record<string, boolean>;
|
|
129
143
|
identify(id: string, props?: Properties): void;
|
|
130
144
|
alias(id: string, aliasId: string): void;
|
|
145
|
+
/**
|
|
146
|
+
* Opt the current visitor INTO capturing. Drives the granted-state
|
|
147
|
+
* transition from the consent gate. When previously cookieless or
|
|
148
|
+
* opted-out, switches to full identified capture.
|
|
149
|
+
*/
|
|
150
|
+
optInCapturing(): void;
|
|
151
|
+
/**
|
|
152
|
+
* Opt the current visitor OUT of capturing. Drives the denied-state
|
|
153
|
+
* transition from the consent gate. Stops sending events; existing
|
|
154
|
+
* cookieless/anonymous events remain in the data warehouse.
|
|
155
|
+
*/
|
|
156
|
+
optOutCapturing(): void;
|
|
131
157
|
track(eventName: string, payload?: CanvasAnalyticsPayload): void;
|
|
132
158
|
trackCanvasOpened(surface: CanvasSurface): void;
|
|
133
159
|
trackCanvasClosed(surface: CanvasSurface): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConsentDetector — orchestrates ConsentAdapters.
|
|
3
|
+
*
|
|
4
|
+
* Probes adapters in priority order. First adapter whose `detect()`
|
|
5
|
+
* returns true wins; its state changes are pushed into the gate. If
|
|
6
|
+
* no adapter matches, applies the configured fallback.
|
|
7
|
+
*
|
|
8
|
+
* See docs/plans/current/2026-05-04-sdk-default-instrumentation-spec.md
|
|
9
|
+
* Section X.
|
|
10
|
+
*/
|
|
11
|
+
import type { ConsentGate } from './ConsentGate';
|
|
12
|
+
import type { DetectorOptions } from './types';
|
|
13
|
+
export declare class ConsentDetector {
|
|
14
|
+
private readonly options;
|
|
15
|
+
constructor(options: DetectorOptions);
|
|
16
|
+
/**
|
|
17
|
+
* Start the detector. Probes adapters in array order; first match wins.
|
|
18
|
+
* Returns a teardown function that unsubscribes the active adapter.
|
|
19
|
+
*
|
|
20
|
+
* Async because adapters may need async initialization. Bootstrap
|
|
21
|
+
* should NOT await this — feature flags and anonymous telemetry
|
|
22
|
+
* should keep flowing while the detector probes.
|
|
23
|
+
*/
|
|
24
|
+
start(gate: ConsentGate): Promise<() => void>;
|
|
25
|
+
private resolveFallback;
|
|
26
|
+
}
|
|
@@ -21,6 +21,16 @@ export interface ConsentConfig {
|
|
|
21
21
|
readFromGtmConsentMode?: boolean;
|
|
22
22
|
/** Called whenever consent status changes. */
|
|
23
23
|
onConsentChange?: (status: ConsentStatus) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Resolves what 'pending' should be treated as for users who have not
|
|
26
|
+
* explicitly granted/denied (no banner interaction yet).
|
|
27
|
+
*
|
|
28
|
+
* For ROW (rest of world): typically returns 'granted' (opt-out regimes).
|
|
29
|
+
* For EU/UK/CH: returns 'denied' (explicit-opt-in regimes).
|
|
30
|
+
*
|
|
31
|
+
* Called lazily by `resolvePending()`. If not provided, defaults to 'denied'.
|
|
32
|
+
*/
|
|
33
|
+
pendingResolver?: () => Promise<ConsentStatus>;
|
|
24
34
|
}
|
|
25
35
|
type ConsentListener = (status: ConsentStatus) => void;
|
|
26
36
|
export declare class ConsentGate {
|
|
@@ -29,6 +39,7 @@ export declare class ConsentGate {
|
|
|
29
39
|
private configCallback?;
|
|
30
40
|
private gtmEnabled;
|
|
31
41
|
private destroyed;
|
|
42
|
+
private pendingResolverFn?;
|
|
32
43
|
constructor(config?: ConsentConfig);
|
|
33
44
|
/**
|
|
34
45
|
* Grant consent — enables telemetry collection.
|
|
@@ -47,6 +58,27 @@ export declare class ConsentGate {
|
|
|
47
58
|
* Returns an unsubscribe function.
|
|
48
59
|
*/
|
|
49
60
|
subscribe(listener: ConsentListener): () => void;
|
|
61
|
+
/**
|
|
62
|
+
* Subscribe to the next definitive (granted | denied) status change,
|
|
63
|
+
* then auto-unsubscribe. If status is already definitive, fires
|
|
64
|
+
* synchronously (next microtask) with current status.
|
|
65
|
+
*
|
|
66
|
+
* Used by D-2 (URL-param identify) to defer the identify() call
|
|
67
|
+
* until consent is decided.
|
|
68
|
+
*/
|
|
69
|
+
subscribeOnce(listener: ConsentListener): () => void;
|
|
70
|
+
/**
|
|
71
|
+
* Resolve what the current 'pending' state should be treated as,
|
|
72
|
+
* via the configured pendingResolver. Returns the current status
|
|
73
|
+
* directly if it's already 'granted' or 'denied'.
|
|
74
|
+
*
|
|
75
|
+
* Defaults to 'denied' if no resolver is configured (conservative).
|
|
76
|
+
*/
|
|
77
|
+
resolvePending(): Promise<ConsentStatus>;
|
|
78
|
+
/**
|
|
79
|
+
* Public setter — used by ConsentDetector / adapters to push state changes.
|
|
80
|
+
*/
|
|
81
|
+
setStatus(newStatus: ConsentStatus): void;
|
|
50
82
|
/**
|
|
51
83
|
* Poll GTM's dataLayer for consent state.
|
|
52
84
|
* Scans for the most recent consent update event with analytics_storage.
|
|
@@ -56,7 +88,7 @@ export declare class ConsentGate {
|
|
|
56
88
|
* Clean up listeners and stop responding to changes.
|
|
57
89
|
*/
|
|
58
90
|
destroy(): void;
|
|
59
|
-
private
|
|
91
|
+
private applyStatus;
|
|
60
92
|
private notify;
|
|
61
93
|
}
|
|
62
94
|
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GTM Consent Mode v2 adapter.
|
|
3
|
+
*
|
|
4
|
+
* Reads `analytics_storage` from window.dataLayer consent events.
|
|
5
|
+
* Universal de facto standard — most CMPs (Cookiebot, OneTrust,
|
|
6
|
+
* Iubenda, Termly, etc.) push to dataLayer.
|
|
7
|
+
*
|
|
8
|
+
* See docs/plans/current/2026-05-04-sdk-default-instrumentation-spec.md
|
|
9
|
+
* Section Y.
|
|
10
|
+
*/
|
|
11
|
+
import type { ConsentStatus } from '../ConsentGate';
|
|
12
|
+
import type { ConsentAdapter } from '../types';
|
|
13
|
+
export declare class GtmConsentModeAdapter implements ConsentAdapter {
|
|
14
|
+
readonly name = "gtm-consent-mode-v2";
|
|
15
|
+
detect(): boolean;
|
|
16
|
+
initialize(callback: (status: ConsentStatus) => void): () => void;
|
|
17
|
+
private readCurrentState;
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IAB TCF v2 adapter.
|
|
3
|
+
*
|
|
4
|
+
* Reads consent state from window.__tcfapi — the IAB Transparency &
|
|
5
|
+
* Consent Framework standard. Used by all major EU-focused CMPs:
|
|
6
|
+
* OneTrust, Cookiebot, Iubenda, Didomi, Sourcepoint, etc.
|
|
7
|
+
*
|
|
8
|
+
* Maps Purpose 1 (storage access) + Purpose 8 (measure content
|
|
9
|
+
* performance, i.e. analytics) → granted/denied. Both must be granted
|
|
10
|
+
* for analytics tracking to be allowed under TCF.
|
|
11
|
+
*
|
|
12
|
+
* See docs/plans/current/2026-05-04-sdk-default-instrumentation-spec.md
|
|
13
|
+
* Section W.
|
|
14
|
+
*/
|
|
15
|
+
import type { ConsentStatus } from '../ConsentGate';
|
|
16
|
+
import type { ConsentAdapter } from '../types';
|
|
17
|
+
export declare class IabTcfAdapter implements ConsentAdapter {
|
|
18
|
+
readonly name = "iab-tcf-v2";
|
|
19
|
+
detect(): boolean;
|
|
20
|
+
initialize(callback: (status: ConsentStatus) => void): () => void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shopify Customer Privacy adapter.
|
|
3
|
+
*
|
|
4
|
+
* Authoritative on Shopify storefronts. Uses Shopify's built-in
|
|
5
|
+
* customer-privacy API which combines analytics/marketing/preferences/
|
|
6
|
+
* sale-of-data consents into a single boolean via userCanBeTracked().
|
|
7
|
+
*
|
|
8
|
+
* See docs/plans/current/2026-05-04-sdk-default-instrumentation-spec.md
|
|
9
|
+
* Section Z.
|
|
10
|
+
*/
|
|
11
|
+
import type { ConsentStatus } from '../ConsentGate';
|
|
12
|
+
import type { ConsentAdapter } from '../types';
|
|
13
|
+
export declare class ShopifyCustomerPrivacyAdapter implements ConsentAdapter {
|
|
14
|
+
readonly name = "shopify-customer-privacy";
|
|
15
|
+
detect(): boolean;
|
|
16
|
+
initialize(callback: (status: ConsentStatus) => void): () => void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consent management — public exports.
|
|
3
|
+
*
|
|
4
|
+
* See:
|
|
5
|
+
* - ConsentGate: the runtime state machine for granted/denied/pending
|
|
6
|
+
* - ConsentDetector: orchestrates adapters that detect CMPs on the page
|
|
7
|
+
* - ConsentAdapter: the interface adapters implement
|
|
8
|
+
*
|
|
9
|
+
* Architecture per docs/plans/current/2026-05-04-sdk-default-instrumentation-spec.md.
|
|
10
|
+
*/
|
|
11
|
+
export { GtmConsentModeAdapter } from './adapters/gtmConsentMode';
|
|
12
|
+
export { IabTcfAdapter } from './adapters/iabTcf';
|
|
13
|
+
export { ShopifyCustomerPrivacyAdapter } from './adapters/shopify';
|
|
14
|
+
export { ConsentDetector } from './ConsentDetector';
|
|
15
|
+
export type { ConsentConfig, ConsentStatus } from './ConsentGate';
|
|
16
|
+
export { ConsentGate } from './ConsentGate';
|
|
17
|
+
export type { ConsentAdapter, DetectorOptions } from './types';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for the consent detection framework.
|
|
3
|
+
*
|
|
4
|
+
* See docs/plans/current/2026-05-04-sdk-default-instrumentation-spec.md
|
|
5
|
+
* Section X for the design rationale.
|
|
6
|
+
*/
|
|
7
|
+
import type { ConsentStatus } from './ConsentGate';
|
|
8
|
+
export interface ConsentAdapter {
|
|
9
|
+
/** Stable identifier — used in telemetry / logs. */
|
|
10
|
+
readonly name: string;
|
|
11
|
+
/**
|
|
12
|
+
* Synchronous detection: is this CMP currently present on the page?
|
|
13
|
+
* Must be cheap and never throw. Just check for global presence
|
|
14
|
+
* (e.g. `typeof window.Shopify?.customerPrivacy !== 'undefined'`).
|
|
15
|
+
*/
|
|
16
|
+
detect(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Subscribe to consent state. Returns immediately with a teardown
|
|
19
|
+
* function. The callback fires:
|
|
20
|
+
* - Once with the current best-known state (could be 'pending' if
|
|
21
|
+
* adapter needs an async handshake).
|
|
22
|
+
* - Whenever the state changes (user accepts/rejects, etc).
|
|
23
|
+
*
|
|
24
|
+
* Adapters that need async initialization (e.g. Shopify's
|
|
25
|
+
* loadFeatures) should fire 'pending' synchronously and update via
|
|
26
|
+
* the callback when the async work finishes.
|
|
27
|
+
*/
|
|
28
|
+
initialize(callback: (status: ConsentStatus) => void): () => void;
|
|
29
|
+
}
|
|
30
|
+
export interface DetectorOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Adapters in priority order. First adapter whose `detect()` returns
|
|
33
|
+
* true wins.
|
|
34
|
+
*/
|
|
35
|
+
adapters: ConsentAdapter[];
|
|
36
|
+
/**
|
|
37
|
+
* Optional callback fired once when the detector picks a winning
|
|
38
|
+
* adapter (or determines no adapter matched). Use for telemetry.
|
|
39
|
+
*/
|
|
40
|
+
onAdapterSelected?: (name: string | null) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Status to apply when no adapter matches. Typically wired to a
|
|
43
|
+
* geo-aware function ("granted" outside EU, "denied" inside).
|
|
44
|
+
* Defaults to 'pending' if not provided.
|
|
45
|
+
*/
|
|
46
|
+
fallbackStatus?: () => ConsentStatus | Promise<ConsentStatus>;
|
|
47
|
+
}
|
|
@@ -75,4 +75,28 @@ export interface TelemetryClient {
|
|
|
75
75
|
* Used by audit events to send named events to PostHog.
|
|
76
76
|
*/
|
|
77
77
|
track?(eventName: string, properties?: Record<string, unknown>): void;
|
|
78
|
+
/**
|
|
79
|
+
* Identify the current visitor with a stable ID.
|
|
80
|
+
* Merges anonymous events into the new person record. Idempotent
|
|
81
|
+
* for the same id. See SDK defaults spec D-1 / D-2.
|
|
82
|
+
*/
|
|
83
|
+
identify?(distinctId: string, properties?: Record<string, unknown>): void;
|
|
84
|
+
/**
|
|
85
|
+
* Alias an existing identity to another id (treat as same person).
|
|
86
|
+
* Used when a previously-identified visitor reveals an additional id
|
|
87
|
+
* in the same session (e.g., logs in as bolshoifish then enters
|
|
88
|
+
* parker.lowrey at checkout). PostHog merges both ids into one
|
|
89
|
+
* person record.
|
|
90
|
+
*/
|
|
91
|
+
alias?(newDistinctId: string, oldDistinctId?: string): void;
|
|
92
|
+
/**
|
|
93
|
+
* Switch from cookieless / opted-out mode to full identified capture.
|
|
94
|
+
* Driven by the ConsentGate when status transitions to 'granted'.
|
|
95
|
+
*/
|
|
96
|
+
optInCapturing?(): void;
|
|
97
|
+
/**
|
|
98
|
+
* Switch off all capturing. Driven by the ConsentGate when status
|
|
99
|
+
* transitions to 'denied'.
|
|
100
|
+
*/
|
|
101
|
+
optOutCapturing?(): void;
|
|
78
102
|
}
|
package/dist/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syntrologie/runtime-sdk",
|
|
3
|
-
"version": "2.8.0-canary.
|
|
3
|
+
"version": "2.8.0-canary.185",
|
|
4
4
|
"description": "Syntrologie Runtime SDK for web experimentation and analytics",
|
|
5
5
|
"license": "Proprietary",
|
|
6
6
|
"private": false,
|
|
@@ -39,15 +39,13 @@
|
|
|
39
39
|
"files": [
|
|
40
40
|
"dist",
|
|
41
41
|
"schema",
|
|
42
|
-
"scripts/validate-config.mjs"
|
|
43
|
-
"CAPABILITIES.md"
|
|
42
|
+
"scripts/validate-config.mjs"
|
|
44
43
|
],
|
|
45
44
|
"scripts": {
|
|
46
45
|
"clean": "rm -rf dist",
|
|
47
|
-
"aggregate-capabilities": "node ./scripts/aggregate-capabilities.mjs",
|
|
48
46
|
"generate-schema": "node ./scripts/generate-unified-schema.mjs",
|
|
49
47
|
"generate-schema:check": "node ./scripts/generate-unified-schema.mjs --check",
|
|
50
|
-
"build": "npm run
|
|
48
|
+
"build": "npm run build:types && npm run build:lib && npm run generate-schema && npm run build:cdn && npm run build:adaptives",
|
|
51
49
|
"build:types": "tsc --project tsconfig.build.json",
|
|
52
50
|
"build:lib": "node ./scripts/build-lib.mjs",
|
|
53
51
|
"build:cdn": "node ./scripts/build-cdn.js",
|