@cookieyes/core 0.1.0 → 0.2.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 CHANGED
@@ -19,7 +19,76 @@ type ConsentChecker = (category: ConsentCategory) => boolean;
19
19
  declare function installNetworkBlocker(config: NetworkBlockerConfig, hasConsent: ConsentChecker): () => void;
20
20
  declare function uninstallNetworkBlocker(): void;
21
21
 
22
- type ConsentCategory = "necessary" | "functional" | "analytics" | "performance" | "advertisement";
22
+ /**
23
+ * A tool that can be stopped (and optionally resumed) at runtime when consent
24
+ * for its category changes — no page reload needed. `stop()` is called when the
25
+ * category is revoked; `resume()` (if provided) when it's re-granted.
26
+ *
27
+ * If `stop()` throws, that tool is treated as "couldn't be stopped cleanly" and
28
+ * falls back to the reload notice for that one tool — it never breaks the page.
29
+ */
30
+ type StopHandler = {
31
+ id: string;
32
+ category: ConsentCategory;
33
+ stop: () => void;
34
+ resume?: (() => void) | undefined;
35
+ };
36
+ /**
37
+ * A tool with no known clean runtime stop — revoking its category can only be
38
+ * fully applied by reloading the page. Registering one means "if this category
39
+ * is revoked, show the visitor the reload notice."
40
+ */
41
+ type ReloadOnlyHandler = {
42
+ id: string;
43
+ category: ConsentCategory;
44
+ needsReload: true;
45
+ };
46
+ type AnyStopHandler = StopHandler | ReloadOnlyHandler;
47
+ /**
48
+ * Built-in, first-party integrations. Each maps to either a clean stop-handler
49
+ * or a reload-only marker (see the audit in the README).
50
+ *
51
+ * Note: Google Analytics 4 and Google Tag Manager are **not** listed here.
52
+ * They're governed by Google Consent Mode v2, which the SDK broadcasts
53
+ * automatically whenever a `dataLayer` is present (see google-consent-mode.ts)
54
+ * — on load and on every consent change, derived from each category's `gcm`
55
+ * mapping. So you don't register them as integrations; just add the standard
56
+ * Consent Mode default snippet and the SDK owns the updates.
57
+ *
58
+ * VERIFIED clean-stop vendors (documented, stable runtime opt-out):
59
+ * - `meta` — `fbq('consent','revoke'|'grant')`, Meta's official consent API.
60
+ *
61
+ * The rest have no confident, documented runtime stop, so they're modelled as
62
+ * reload-only (Story 1's honest answer). Upgrading any of them to a clean-stop
63
+ * later is a one-line change here once a real API is confirmed.
64
+ */
65
+ type BuiltInIntegration = {
66
+ vendor: "meta";
67
+ category?: ConsentCategory | undefined;
68
+ } | {
69
+ vendor: "tiktok";
70
+ category?: ConsentCategory | undefined;
71
+ } | {
72
+ vendor: "linkedin";
73
+ category?: ConsentCategory | undefined;
74
+ } | {
75
+ vendor: "hotjar";
76
+ category?: ConsentCategory | undefined;
77
+ } | {
78
+ vendor: "segment";
79
+ category?: ConsentCategory | undefined;
80
+ };
81
+ declare function resolveBuiltInIntegration(cfg: BuiltInIntegration): AnyStopHandler;
82
+ declare function registerStopHandler(handler: AnyStopHandler): void;
83
+ /** Test-only: reset registry + transition state between cases. */
84
+ declare function _clearStopHandlers(): void;
85
+
86
+ /**
87
+ * A consent category id. The five built-in ids are offered for autocomplete,
88
+ * but any string is valid — customers can define their own taxonomy via
89
+ * `categories` (see {@link CategoryDef}).
90
+ */
91
+ type ConsentCategory = "necessary" | "functional" | "analytics" | "performance" | "advertisement" | (string & {});
23
92
  type Regulation = "GDPR" | "CCPA" | "DEFAULT";
24
93
  type TranslationMap = {
25
94
  bannerTitle: string;
@@ -63,6 +132,11 @@ type TranslationMap = {
63
132
  successText: string;
64
133
  successCountdown: string;
65
134
  };
135
+ reloadNotice: {
136
+ message: string;
137
+ reloadButton: string;
138
+ dismissButton: string;
139
+ };
66
140
  };
67
141
  type ThemeConfig = {
68
142
  primaryColor?: string | undefined;
@@ -92,20 +166,63 @@ type ConsentConfig = {
92
166
  apiKey?: string | undefined;
93
167
  backend?: ConsentBackend | undefined;
94
168
  regulation?: Regulation | undefined;
169
+ /**
170
+ * Define your own category taxonomy. Omit to get the built-in five
171
+ * (necessary, functional, analytics, performance, advertisement) unchanged.
172
+ * At least one category must be `{ required: true }`. Invalid configs fall
173
+ * back to the built-in five with a console warning. See {@link CategoryDef}.
174
+ */
175
+ categories?: CategoryDef[] | undefined;
95
176
  theme?: ThemeConfig | undefined;
96
- colorScheme?: "light" | "dark" | "system" | undefined;
177
+ colorScheme?: ColorScheme | undefined;
97
178
  reloadOnRevoke?: boolean | undefined;
179
+ /**
180
+ * Built-in, first-party integrations to stop cleanly (no reload) when their
181
+ * category is revoked — e.g. `{ vendor: "meta" }`. (Google Analytics/Tag
182
+ * Manager are handled automatically via the Consent Mode broadcast — no entry
183
+ * needed.) Integrations with no clean runtime stop fall back to the reload notice.
184
+ */
185
+ integrations?: BuiltInIntegration[] | undefined;
186
+ /**
187
+ * Your own scripts' stop instructions, for anything without a built-in
188
+ * integration. A handler that can stop cleanly provides `stop()`; one that
189
+ * can't should be registered as a reload-only handler instead so revoking it
190
+ * shows the reload notice rather than silently continuing to track.
191
+ */
192
+ customStopHandlers?: StopHandler[] | undefined;
98
193
  onConsentReady?: ((state: ConsentSnapshot) => void) | undefined;
99
194
  onConsentUpdate?: ((state: ConsentSnapshot) => void) | undefined;
100
195
  };
196
+ /**
197
+ * Surfaced when a revoked tool has no clean runtime stop and can only be fully
198
+ * applied by reloading. `required` is false once dismissed; `reasons` lists the
199
+ * handler ids that triggered it (e.g. `["hotjar"]`).
200
+ */
201
+ type ReloadNoticeState = {
202
+ required: boolean;
203
+ reasons: string[];
204
+ };
101
205
  type ConsentSnapshot = {
102
206
  consentId: string;
103
207
  hasActed: boolean;
104
- categories: Record<ConsentCategory, boolean>;
208
+ /** Category id → granted. Keys are the configured taxonomy's ids. */
209
+ categories: Record<string, boolean>;
105
210
  regulation: Regulation;
106
211
  lastRenewed?: number | undefined;
212
+ /**
213
+ * Signature of the category taxonomy in effect when this consent was
214
+ * recorded. Lets us (and the customer) tell what a returning visitor
215
+ * actually agreed to, and drives re-request when the taxonomy changes.
216
+ */
217
+ taxonomyHash?: string | undefined;
107
218
  };
108
219
  type ConsentManager = ConsentSnapshot & {
220
+ /**
221
+ * Consent in effect — changes only on a real decision (accept / reject / save
222
+ * / reset), never on a dialog toggle. Gate scripts/embeds on this. (`categories`
223
+ * is the live value that drives the dialog checkboxes.)
224
+ */
225
+ committedCategories: Record<string, boolean>;
109
226
  acceptAll: () => void;
110
227
  rejectAll: () => void;
111
228
  acceptSelected: (categories: ConsentCategory[]) => void;
@@ -117,9 +234,13 @@ type ConsentManager = ConsentSnapshot & {
117
234
  isPreferencesOpen: boolean;
118
235
  subscribe: (listener: (state: ConsentSnapshot) => void) => () => void;
119
236
  registerScript: (entry: ScriptEntry) => void;
237
+ /** Current reload-notice state (see {@link ReloadNoticeState}). */
238
+ reloadNotice: ReloadNoticeState;
239
+ /** Dismiss the reload notice; it won't reappear until a new revoke needs one. */
240
+ dismissReloadNotice: () => void;
120
241
  };
121
242
  /**
122
- * Shape of the JSON body POSTed to the customer's `backendURL`
243
+ * Shape of the JSON body POSTed to the customer's `apiUrl`
123
244
  * on every consent decision (Accept All / Reject All / Save Preferences).
124
245
  *
125
246
  * Customers building a TypeScript backend can import this type to get
@@ -127,7 +248,7 @@ type ConsentManager = ConsentSnapshot & {
127
248
  */
128
249
  type ConsentPayload = {
129
250
  consentId: string;
130
- categories: Record<ConsentCategory, boolean>;
251
+ categories: Record<string, boolean>;
131
252
  regulation: Regulation;
132
253
  domain: string;
133
254
  };
@@ -135,7 +256,7 @@ type ConsentPayload = {
135
256
  * Customer-implemented adapter that decides how a consent decision
136
257
  * reaches their backend. Provide this when `mode: "self-hosted"` and you
137
258
  * need full control over the request shape, headers, auth, transport,
138
- * batching, retries, etc. — anything you can't express with `backendURL`.
259
+ * batching, retries, etc. — anything you can't express with `apiUrl`.
139
260
  *
140
261
  * The SDK hands you a standardised `ConsentPayload`; you transform and
141
262
  * dispatch it however your backend expects.
@@ -143,24 +264,107 @@ type ConsentPayload = {
143
264
  interface ConsentBackend {
144
265
  persist(payload: ConsentPayload): Promise<void> | void;
145
266
  }
146
- type ConsentRuntimeMode = "self-hosted" | "offline";
147
- type ConsentRuntimeOptions = {
148
- mode: ConsentRuntimeMode;
149
- backendURL?: string | undefined;
150
- apiKey?: string | undefined;
151
- backend?: ConsentBackend | undefined;
152
- consentCategories?: ConsentCategory[] | undefined;
153
- overrides?: {
154
- regulation?: Regulation | undefined;
155
- } | undefined;
156
- i18n?: I18nConfig | undefined;
157
- colorScheme?: "light" | "dark" | "system" | undefined;
267
+ /**
268
+ * @deprecated Use `"cookie-only"` instead — identical behavior, clearer name.
269
+ * `"offline"` still works but will be removed in a future release.
270
+ */
271
+ type DeprecatedOfflineMode = "offline";
272
+ type ConsentRuntimeMode = "self-hosted" | "cookie-only" | DeprecatedOfflineMode;
273
+ type ColorScheme = "light" | "dark" | "system";
274
+ /**
275
+ * Fields shared by every {@link CookieYesConfig} regardless of `mode`.
276
+ * This is the one canonical config surface — both `@cookieyes/core` and
277
+ * `@cookieyes/react` consume the exact same object, so a config is
278
+ * copy-pasteable between them with zero edits.
279
+ */
280
+ type CookieYesConfigCommon = {
281
+ /**
282
+ * Which privacy regulation applies. Top-level and identical across every
283
+ * package (replaces the builder's `.regulation()` and core's former
284
+ * nested `overrides.regulation`).
285
+ */
286
+ regulation?: Regulation | undefined;
287
+ colorScheme?: ColorScheme | undefined;
158
288
  theme?: ThemeConfig | undefined;
289
+ i18n?: I18nConfig | undefined;
290
+ consentCategories?: ConsentCategory[] | undefined;
291
+ /**
292
+ * Define your own category taxonomy. Omit to get the built-in five
293
+ * (necessary, functional, analytics, performance, advertisement) unchanged.
294
+ * At least one category must be `{ required: true }`. Invalid configs fall
295
+ * back to the built-in five with a console warning. See {@link CategoryDef}.
296
+ */
297
+ categories?: CategoryDef[] | undefined;
159
298
  networkBlocker?: NetworkBlockerConfig | undefined;
160
299
  reloadOnRevoke?: boolean | undefined;
300
+ /**
301
+ * Built-in, first-party integrations to stop cleanly (no reload) when their
302
+ * category is revoked — e.g. `{ vendor: "meta" }`. (Google Analytics/Tag
303
+ * Manager are handled automatically via the Consent Mode broadcast — no entry
304
+ * needed.) Integrations with no clean runtime stop fall back to the reload notice.
305
+ */
306
+ integrations?: BuiltInIntegration[] | undefined;
307
+ /**
308
+ * Your own scripts' stop instructions, for anything without a built-in
309
+ * integration. A handler that can stop cleanly provides `stop()`; one that
310
+ * can't should be registered as a reload-only handler instead so revoking it
311
+ * shows the reload notice rather than silently continuing to track.
312
+ */
313
+ customStopHandlers?: StopHandler[] | undefined;
314
+ /** Low-level: fires once, after the runtime's initial state is known (e.g. to conditionally load analytics on first load). For ongoing updates, use `consentStore.subscribeToConsentChanges` instead. */
161
315
  onConsentReady?: ((state: ConsentSnapshot) => void) | undefined;
316
+ /** Low-level: fires on every saved consent change, for the lifetime of this config. If you need to subscribe/unsubscribe dynamically after mount, use `consentStore.getState().subscribeToConsentChanges` instead. */
162
317
  onConsentUpdate?: ((state: ConsentSnapshot) => void) | undefined;
318
+ /**
319
+ * @deprecated Set `regulation` at the top level instead. This nested form
320
+ * still works and maps to the top-level field; if both are given, the
321
+ * top-level `regulation` wins. Retained for back-compat and removed after
322
+ * three release cycles, per the SDK deprecation policy.
323
+ */
324
+ overrides?: {
325
+ regulation?: Regulation | undefined;
326
+ } | undefined;
327
+ };
328
+ /**
329
+ * Cookie-only mode — consent is stored client-side only; no backend keys are
330
+ * permitted (they fail at the type level). `mode: "cookie-only"` is the
331
+ * canonical value; `mode: "offline"` is a deprecated alias with identical
332
+ * behavior that emits a one-time-per-page-load deprecation warning.
333
+ */
334
+ type CookieYesOfflineConfig = CookieYesConfigCommon & {
335
+ mode: "cookie-only" | DeprecatedOfflineMode;
163
336
  };
337
+ /** Self-hosted mode — consent decisions are persisted to your own backend. */
338
+ type CookieYesSelfHostedConfig = CookieYesConfigCommon & {
339
+ mode: "self-hosted";
340
+ /** Endpoint the {@link ConsentPayload} is POSTed to. Canonical key. */
341
+ apiUrl?: string | undefined;
342
+ apiKey?: string | undefined;
343
+ /** Custom persistence adapter — full control over transport/headers/retries. */
344
+ backend?: ConsentBackend | undefined;
345
+ /**
346
+ * @deprecated Renamed to `apiUrl`. This alias still works and maps to
347
+ * `apiUrl`; if both are given, `apiUrl` wins. Retained for back-compat and
348
+ * removed after three release cycles, per the SDK deprecation policy.
349
+ */
350
+ backendURL?: string | undefined;
351
+ };
352
+ /**
353
+ * The canonical configuration object for the CookieYes SDK, discriminated on
354
+ * `mode`. Passed identically to `initCookieYes()` /
355
+ * `getOrCreateConsentRuntime()` in `@cookieyes/core` and `initCookieYes()` in
356
+ * `@cookieyes/react`.
357
+ *
358
+ * The discriminated union guarantees invalid combinations fail at compile time
359
+ * — e.g. supplying `apiUrl`/`backend` under `mode: "cookie-only"` is a type error.
360
+ */
361
+ type CookieYesConfig = CookieYesOfflineConfig | CookieYesSelfHostedConfig;
362
+ /**
363
+ * @deprecated Renamed to {@link CookieYesConfig}. Retained as a type alias for
364
+ * back-compat and removed after three release cycles, per the SDK deprecation
365
+ * policy.
366
+ */
367
+ type ConsentRuntimeOptions = CookieYesConfig;
164
368
  type ConsentChangePayload = {
165
369
  allowedCategories: ConsentCategory[];
166
370
  deniedCategories: ConsentCategory[];
@@ -168,12 +372,26 @@ type ConsentChangePayload = {
168
372
  type ActiveUI = "banner" | "dialog" | null;
169
373
  type ConsentStoreState = ConsentSnapshot & {
170
374
  activeUI: ActiveUI;
171
- consents: Record<ConsentCategory, boolean>;
375
+ /** Live/working values — reflect in-progress dialog toggles. Drive checkboxes. */
376
+ consents: Record<string, boolean>;
377
+ /**
378
+ * Consent in effect — changes only on a saved decision, not a toggle. Gate
379
+ * scripts/embeds on this (or {@link ConsentStoreState.has}).
380
+ */
381
+ committedConsents: Record<string, boolean>;
382
+ /** True when `category` is committed-granted (a saved decision), not just toggled. */
172
383
  has: (category: ConsentCategory) => boolean;
173
384
  saveConsents: (target: "all" | "necessary" | ConsentCategory[]) => Promise<void>;
174
385
  setConsent: (category: ConsentCategory, value: boolean) => void;
386
+ /** Low-level: fires only on *saved* preference changes, not transient UI toggles — see `ConsentStore.subscribe` for the recommended, general-purpose subscription. */
175
387
  subscribeToConsentChanges: (listener: (payload: ConsentChangePayload) => void) => () => void;
176
388
  };
389
+ /**
390
+ * The recommended way to read consent state outside React. `subscribe` fires
391
+ * on every state change (including transient UI toggles, e.g. a checkbox
392
+ * flip before saving); for saved-changes-only, see
393
+ * `ConsentStoreState.subscribeToConsentChanges`.
394
+ */
177
395
  type ConsentStore = {
178
396
  subscribe: (listener: (state: ConsentStoreState) => void) => () => void;
179
397
  getState: () => ConsentStoreState;
@@ -183,28 +401,159 @@ type ConsentRuntime = {
183
401
  consentStore: ConsentStore;
184
402
  };
185
403
 
404
+ /**
405
+ * Google Consent Mode v2 storage/signal types. A category can declare which of
406
+ * these it represents via {@link CategoryDef.gcm}; the SDK then broadcasts them
407
+ * (see google-consent-mode.ts). `security_storage` is always granted and is
408
+ * handled by the broadcast itself, so it never needs to be mapped.
409
+ */
410
+ type GoogleConsentSignal = "ad_storage" | "ad_user_data" | "ad_personalization" | "analytics_storage" | "functionality_storage" | "personalization_storage" | "security_storage";
411
+ /**
412
+ * A single consent category. `id` is the stable key stored in the cookie and
413
+ * used everywhere (banner, preferences, read APIs, integrations). Exactly one
414
+ * category should be marked `required` — the always-on, non-optional one (like
415
+ * the default "necessary") — flagged explicitly here, never inferred from a
416
+ * name, so it survives full renaming.
417
+ */
418
+ type CategoryDef = {
419
+ id: ConsentCategory;
420
+ /** The always-on, non-optional category. At least one is required. */
421
+ required?: boolean | undefined;
422
+ /** Display label. Falls back to the translation for built-in ids. */
423
+ label?: string | undefined;
424
+ /** Display description. Falls back to the translation for built-in ids. */
425
+ description?: string | undefined;
426
+ /** Google Consent Mode signals this category governs (see {@link GoogleConsentSignal}). */
427
+ gcm?: GoogleConsentSignal[] | undefined;
428
+ };
429
+ /**
430
+ * The built-in five, used verbatim when a customer configures nothing. GCM
431
+ * mapping mirrors production's `_ckySetGoogleConsentMode` (analytics →
432
+ * analytics_storage, advertisement → the ad_* signals, functional →
433
+ * functionality/personalization; performance maps to nothing; security_storage
434
+ * is always granted by the broadcast).
435
+ */
436
+ declare const DEFAULT_CATEGORIES: CategoryDef[];
437
+ type ResolvedCategories = {
438
+ /** Ordered category definitions actually in effect. */
439
+ list: CategoryDef[];
440
+ /** Ordered ids (fast access). */
441
+ ids: ConsentCategory[];
442
+ /** Ids marked `required` (always granted, never toggleable). */
443
+ requiredIds: Set<ConsentCategory>;
444
+ /** Stable signature of this taxonomy; a change here re-requests consent. */
445
+ taxonomyHash: string;
446
+ /** True when the built-in five are in effect (configured or fallback). */
447
+ isDefault: boolean;
448
+ };
449
+ /**
450
+ * Resolve the category list from config. Returns the built-in five when nothing
451
+ * is configured. On an invalid custom config (empty, duplicate/reserved ids, or
452
+ * no `required` category) it warns and falls back to the built-in five, rather
453
+ * than leaving the visitor a broken/empty or unprotected setup.
454
+ */
455
+ declare function resolveCategories(defs?: CategoryDef[]): ResolvedCategories;
456
+
457
+ /**
458
+ * The canonical config with every deprecated alias already collapsed into its
459
+ * top-level key. Both `@cookieyes/core` and `@cookieyes/react` consume the
460
+ * output of {@link _normalizeConfig}, so alias resolution lives in exactly one
461
+ * place and the two packages can never drift.
462
+ *
463
+ * @internal
464
+ */
465
+ type _NormalizedConfig = {
466
+ mode: ConsentRuntimeMode;
467
+ regulation?: Regulation | undefined;
468
+ colorScheme?: ColorScheme | undefined;
469
+ theme?: ThemeConfig | undefined;
470
+ i18n?: I18nConfig | undefined;
471
+ consentCategories?: ConsentCategory[] | undefined;
472
+ categories?: CategoryDef[] | undefined;
473
+ networkBlocker?: NetworkBlockerConfig | undefined;
474
+ reloadOnRevoke?: boolean | undefined;
475
+ integrations?: BuiltInIntegration[] | undefined;
476
+ customStopHandlers?: StopHandler[] | undefined;
477
+ onConsentReady?: ((state: ConsentSnapshot) => void) | undefined;
478
+ onConsentUpdate?: ((state: ConsentSnapshot) => void) | undefined;
479
+ apiUrl?: string | undefined;
480
+ apiKey?: string | undefined;
481
+ backend?: ConsentBackend | undefined;
482
+ };
483
+ /**
484
+ * Resolve a public {@link CookieYesConfig} into its canonical internal form.
485
+ *
486
+ * Deprecated aliases map silently to their canonical key when used alone; when
487
+ * an alias and its canonical key are both present, the canonical key wins and
488
+ * exactly one warning is logged for that collision.
489
+ *
490
+ * - `overrides.regulation` → `regulation`
491
+ * - `backendURL` → `apiUrl`
492
+ *
493
+ * @internal
494
+ */
495
+ declare function _normalizeConfig(config: CookieYesConfig): _NormalizedConfig;
496
+
186
497
  type RawCookieFields = {
187
498
  consentid?: string;
188
499
  consent?: string;
189
500
  action?: string;
190
- necessary?: string;
191
- functional?: string;
192
- analytics?: string;
193
- performance?: string;
194
- advertisement?: string;
501
+ /** Taxonomy signature stored with the consent (see ResolvedCategories.taxonomyHash). */
502
+ tax?: string;
195
503
  lastRenewedDate?: string;
504
+ /** Every non-meta pair: category id → "yes" | "no". */
505
+ categories: Record<string, string>;
196
506
  };
197
507
  declare function parseCookie(raw: string): RawCookieFields;
198
508
  declare function serializeCookie(snapshot: ConsentSnapshot): string;
199
509
  declare function generateConsentId(): string;
200
510
 
511
+ /**
512
+ * One-time-per-page-load console warning for `mode: "offline"`.
513
+ * Both @cookieyes/core and @cookieyes/react call this so the wording and the
514
+ * "once" behavior stay identical no matter which package reads the setting.
515
+ */
516
+ declare function _warnOfflineModeDeprecated(): void;
517
+ /** @internal test-only — resets the one-time warning guard between test cases. */
518
+ declare function _resetOfflineModeWarning(): void;
519
+
520
+ type GcmValue = "granted" | "denied";
521
+ /**
522
+ * Compute the granted/denied value for every GCM signal from the current
523
+ * category consent, using each category's `gcm` mapping.
524
+ *
525
+ * - A signal is `granted` if *any* granted category maps to it.
526
+ * - `security_storage` is always `granted` (it's strictly necessary and not
527
+ * consentable — this mirrors production's behaviour).
528
+ * - A signal that no category maps to defaults to `denied`.
529
+ */
530
+ declare function computeGoogleConsent(resolved: ResolvedCategories, categories: Record<string, boolean>): Record<GoogleConsentSignal, GcmValue>;
531
+ /**
532
+ * Push a Consent Mode `update` for all seven signals onto the dataLayer, if one
533
+ * is present. Safe to call on load and on every consent change; a no-op when no
534
+ * Google service is on the page.
535
+ *
536
+ * The customer is responsible for the Consent Mode *default* (the gtag snippet
537
+ * that must run before their Google tags, typically denying everything). This
538
+ * function owns the *update* that reflects the visitor's actual choice.
539
+ */
540
+ declare function broadcastGoogleConsent(resolved: ResolvedCategories, categories: Record<string, boolean>): void;
541
+
201
542
  declare const en: TranslationMap;
202
543
 
203
544
  declare function resolveTranslations(i18n?: I18nConfig): TranslationMap;
204
545
 
205
546
  declare function createConsentManager(config: ConsentConfig): ConsentManager;
206
547
 
207
- declare function getOrCreateConsentRuntime(options: ConsentRuntimeOptions): ConsentRuntime;
548
+ declare function getOrCreateConsentRuntime(config: CookieYesConfig): ConsentRuntime;
549
+ /**
550
+ * Canonical setup entry point. Alias of {@link getOrCreateConsentRuntime} that
551
+ * accepts the same {@link CookieYesConfig} and returns the same process-wide
552
+ * singleton — provided so documentation can use one setup name (`initCookieYes`)
553
+ * across every package.
554
+ */
555
+ declare function initCookieYes(config: CookieYesConfig): ConsentRuntime;
208
556
  declare function resetConsentRuntime(): void;
209
557
 
210
- export { type ActiveUI, type BlockedRequestInfo, type ConsentBackend, type ConsentCategory, type ConsentChangePayload, type ConsentConfig, type ConsentManager, type ConsentPayload, type ConsentRuntime, type ConsentRuntimeMode, type ConsentRuntimeOptions, type ConsentSnapshot, type ConsentStore, type ConsentStoreState, type I18nConfig, type NetworkBlockerConfig, type NetworkBlockerRule, type Regulation, type ScriptEntry, type ThemeConfig, type TranslationMap, createConsentManager, en as defaultTranslations, generateConsentId, getOrCreateConsentRuntime, installNetworkBlocker, parseCookie, resetConsentRuntime, resolveTranslations, serializeCookie, uninstallNetworkBlocker };
558
+ export { DEFAULT_CATEGORIES, _clearStopHandlers, _normalizeConfig, _resetOfflineModeWarning, _warnOfflineModeDeprecated, broadcastGoogleConsent, computeGoogleConsent, createConsentManager, en as defaultTranslations, generateConsentId, getOrCreateConsentRuntime, initCookieYes, installNetworkBlocker, parseCookie, registerStopHandler, resetConsentRuntime, resolveBuiltInIntegration, resolveCategories, resolveTranslations, serializeCookie, uninstallNetworkBlocker };
559
+ export type { ActiveUI, AnyStopHandler, BlockedRequestInfo, BuiltInIntegration, CategoryDef, ColorScheme, ConsentBackend, ConsentCategory, ConsentChangePayload, ConsentConfig, ConsentManager, ConsentPayload, ConsentRuntime, ConsentRuntimeMode, ConsentRuntimeOptions, ConsentSnapshot, ConsentStore, ConsentStoreState, CookieYesConfig, CookieYesOfflineConfig, CookieYesSelfHostedConfig, GoogleConsentSignal, I18nConfig, NetworkBlockerConfig, NetworkBlockerRule, Regulation, ReloadNoticeState, ReloadOnlyHandler, ResolvedCategories, ScriptEntry, StopHandler, ThemeConfig, TranslationMap, _NormalizedConfig };