@coframe/sdk 1.1.41 → 1.1.43

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.
@@ -1105,6 +1105,9 @@ let waitingForCookies = false;
1105
1105
  const setWaitingForCookies = (value) => {
1106
1106
  waitingForCookies = value;
1107
1107
  };
1108
+ function isWaitingForCookies() {
1109
+ return waitingForCookies;
1110
+ }
1108
1111
  let frameActivated = false;
1109
1112
  const setFrameActivated = (value) => {
1110
1113
  frameActivated = value;
@@ -4185,23 +4188,124 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
4185
4188
  setupFlushInterval(Coframe);
4186
4189
  }
4187
4190
 
4191
+ function readClientCommand() {
4192
+ try {
4193
+ const cmd = findLastCmd((c) => typeof c.cookiesEnabled === 'boolean');
4194
+ if (!cmd)
4195
+ return undefined;
4196
+ return cmd.cookiesEnabled === true ? 'granted' : 'denied';
4197
+ }
4198
+ catch (_a) {
4199
+ return undefined;
4200
+ }
4201
+ }
4202
+ function readOneTrust() {
4203
+ var _a;
4204
+ try {
4205
+ const { OnetrustActiveGroups: groups, OneTrust } = window;
4206
+ if (typeof groups !== 'string' && OneTrust === undefined)
4207
+ return undefined;
4208
+ if (typeof groups === 'string' && groups.split(',').indexOf('C0002') !== -1)
4209
+ return 'granted';
4210
+ return ((_a = OneTrust === null || OneTrust === void 0 ? void 0 : OneTrust.IsAlertBoxClosed) === null || _a === void 0 ? void 0 : _a.call(OneTrust)) === true ? 'denied' : 'pending';
4211
+ }
4212
+ catch (_b) {
4213
+ return undefined;
4214
+ }
4215
+ }
4216
+ function readCookiebot() {
4217
+ var _a;
4218
+ try {
4219
+ const { Cookiebot } = window;
4220
+ if (Cookiebot === undefined)
4221
+ return undefined;
4222
+ if (((_a = Cookiebot.consent) === null || _a === void 0 ? void 0 : _a.statistics) === true)
4223
+ return 'granted';
4224
+ return Cookiebot.hasResponse === true ? 'denied' : 'pending';
4225
+ }
4226
+ catch (_b) {
4227
+ return undefined;
4228
+ }
4229
+ }
4230
+ function readConsentMode() {
4231
+ var _a;
4232
+ try {
4233
+ const { dataLayer } = window;
4234
+ if (!Array.isArray(dataLayer))
4235
+ return undefined;
4236
+ let update;
4237
+ let defaultGranted = false;
4238
+ let defaultDenied = false;
4239
+ for (let i = 0; i < dataLayer.length; i++) {
4240
+ const entry = dataLayer[i];
4241
+ if (entry === null ||
4242
+ typeof entry !== 'object' ||
4243
+ entry[0] !== 'consent' ||
4244
+ (entry[1] !== 'default' && entry[1] !== 'update')) {
4245
+ continue;
4246
+ }
4247
+ const storage = (_a = entry[2]) === null || _a === void 0 ? void 0 : _a.analytics_storage;
4248
+ if (storage !== 'granted' && storage !== 'denied')
4249
+ continue;
4250
+ if (entry[1] === 'update')
4251
+ update = storage;
4252
+ else if (storage === 'denied')
4253
+ defaultDenied = true;
4254
+ else
4255
+ defaultGranted = true;
4256
+ }
4257
+ if (update !== undefined)
4258
+ return update;
4259
+ if (defaultDenied)
4260
+ return 'pending';
4261
+ return defaultGranted ? 'granted' : undefined;
4262
+ }
4263
+ catch (_b) {
4264
+ return undefined;
4265
+ }
4266
+ }
4267
+
4188
4268
  let startRequested = false;
4189
4269
  let replayScriptUrl;
4190
4270
  const COMPILED_REPLAY_SCRIPT_URL = `${"https://edge.cofra.me"}/replay/latest.js`;
4191
4271
  const CONSENT_POLL_MS = 100;
4192
4272
  const CONSENT_WAIT_MS = 5000;
4273
+ const CONSENT_DETECT_WAIT_MS = 10000;
4274
+ const EXPLICIT_CONSENT_WAIT_MS = 60000;
4193
4275
  function configureReplayScriptUrl(url) {
4194
4276
  replayScriptUrl = (url === null || url === void 0 ? void 0 : url.trim()) || undefined;
4195
4277
  }
4196
- function readReplayConsent() {
4278
+ function readReplayConsent(settings) {
4197
4279
  try {
4198
4280
  if (navigator
4199
4281
  .globalPrivacyControl === true) {
4200
4282
  return { state: 'denied', reason: 'gpc' };
4201
4283
  }
4202
4284
  const shopify = window.Shopify;
4203
- if (shopify === undefined)
4204
- return { state: 'allowed', source: 'none' };
4285
+ if (shopify === undefined) {
4286
+ const readers = [
4287
+ [readClientCommand, 'client'],
4288
+ [readOneTrust, 'onetrust'],
4289
+ [readCookiebot, 'cookiebot'],
4290
+ [readConsentMode, 'consent_mode'],
4291
+ ];
4292
+ for (let i = 0; i < readers.length; i++) {
4293
+ const [read, source] = readers[i];
4294
+ const signal = read();
4295
+ if (signal === 'granted')
4296
+ return { state: 'allowed', source };
4297
+ if (signal === 'denied')
4298
+ return { state: 'denied', reason: 'consent_denied' };
4299
+ if (signal === 'pending') {
4300
+ if (settings.consent_required === false)
4301
+ continue;
4302
+ return { state: 'pending', detected: true };
4303
+ }
4304
+ }
4305
+ if (settings.consent_required === false)
4306
+ return { state: 'allowed', source: 'not_required' };
4307
+ return { state: 'pending', detected: isWaitingForCookies() };
4308
+ }
4205
4309
  const customerPrivacy = shopify.customerPrivacy;
4206
4310
  const analyticsProcessingAllowed = customerPrivacy === null || customerPrivacy === void 0 ? void 0 : customerPrivacy.analyticsProcessingAllowed;
4207
4311
  if (typeof analyticsProcessingAllowed === 'function') {
@@ -4249,7 +4353,9 @@ function createStartContext(coframe, settings, forceSample, consentSource) {
4249
4353
  getPageViewId: () => coframe.sessionId,
4250
4354
  getUserToken: () => coframe.userToken,
4251
4355
  getVariantIds: () => { var _a; return ((_a = coframe.experimentInfo) !== null && _a !== void 0 ? _a : []).map((experiment) => experiment.variant_id); },
4252
- canSend: () => shouldSendEvents() && readReplayConsent().state === 'allowed',
4356
+ canSend: () => shouldSendEvents({
4357
+ ignoreConsent: window.Shopify === undefined,
4358
+ }) && readReplayConsent(settings).state === 'allowed',
4253
4359
  onEventsFlushed: (callback) => {
4254
4360
  if (queuedEvents.length === 0 && queuedSessions.length === 0) {
4255
4361
  callback();
@@ -4303,22 +4409,30 @@ function startReplayIfEnabled(coframe, project, nonce) {
4303
4409
  const settings = (_a = project.settings) === null || _a === void 0 ? void 0 : _a.session_replay;
4304
4410
  if ((settings === null || settings === void 0 ? void 0 : settings.enabled) !== true ||
4305
4411
  typeof CompressionStream !== 'function' ||
4306
- !shouldSendEvents() ||
4412
+ !shouldSendEvents({
4413
+ ignoreConsent: window.Shopify === undefined,
4414
+ }) ||
4307
4415
  startRequested) {
4308
4416
  return;
4309
4417
  }
4310
4418
  startRequested = true;
4419
+ const isShopify = window.Shopify !== undefined;
4311
4420
  let waited = 0;
4312
4421
  const decide = () => {
4313
4422
  var _a;
4314
- const consent = readReplayConsent();
4423
+ const consent = readReplayConsent(settings);
4315
4424
  if (consent.state === 'allowed') {
4316
4425
  insertReplayScript(coframe, settings, consent.source, nonce);
4317
4426
  }
4318
4427
  else if (consent.state === 'denied') {
4319
4428
  reportReplaySkipped(coframe, consent.reason);
4320
4429
  }
4321
- else if (waited >= CONSENT_WAIT_MS) {
4430
+ else if (!isShopify &&
4431
+ consent.detected !== true &&
4432
+ waited >= CONSENT_DETECT_WAIT_MS) {
4433
+ reportReplaySkipped(coframe, 'consent_not_configured');
4434
+ }
4435
+ else if (waited >= (isShopify ? CONSENT_WAIT_MS : EXPLICIT_CONSENT_WAIT_MS)) {
4322
4436
  reportReplaySkipped(coframe, 'consent_unavailable');
4323
4437
  }
4324
4438
  else {
@@ -1103,6 +1103,9 @@ let waitingForCookies = false;
1103
1103
  const setWaitingForCookies = (value) => {
1104
1104
  waitingForCookies = value;
1105
1105
  };
1106
+ function isWaitingForCookies() {
1107
+ return waitingForCookies;
1108
+ }
1106
1109
  let frameActivated = false;
1107
1110
  const setFrameActivated = (value) => {
1108
1111
  frameActivated = value;
@@ -4183,23 +4186,124 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
4183
4186
  setupFlushInterval(Coframe);
4184
4187
  }
4185
4188
 
4189
+ function readClientCommand() {
4190
+ try {
4191
+ const cmd = findLastCmd((c) => typeof c.cookiesEnabled === 'boolean');
4192
+ if (!cmd)
4193
+ return undefined;
4194
+ return cmd.cookiesEnabled === true ? 'granted' : 'denied';
4195
+ }
4196
+ catch (_a) {
4197
+ return undefined;
4198
+ }
4199
+ }
4200
+ function readOneTrust() {
4201
+ var _a;
4202
+ try {
4203
+ const { OnetrustActiveGroups: groups, OneTrust } = window;
4204
+ if (typeof groups !== 'string' && OneTrust === undefined)
4205
+ return undefined;
4206
+ if (typeof groups === 'string' && groups.split(',').indexOf('C0002') !== -1)
4207
+ return 'granted';
4208
+ return ((_a = OneTrust === null || OneTrust === void 0 ? void 0 : OneTrust.IsAlertBoxClosed) === null || _a === void 0 ? void 0 : _a.call(OneTrust)) === true ? 'denied' : 'pending';
4209
+ }
4210
+ catch (_b) {
4211
+ return undefined;
4212
+ }
4213
+ }
4214
+ function readCookiebot() {
4215
+ var _a;
4216
+ try {
4217
+ const { Cookiebot } = window;
4218
+ if (Cookiebot === undefined)
4219
+ return undefined;
4220
+ if (((_a = Cookiebot.consent) === null || _a === void 0 ? void 0 : _a.statistics) === true)
4221
+ return 'granted';
4222
+ return Cookiebot.hasResponse === true ? 'denied' : 'pending';
4223
+ }
4224
+ catch (_b) {
4225
+ return undefined;
4226
+ }
4227
+ }
4228
+ function readConsentMode() {
4229
+ var _a;
4230
+ try {
4231
+ const { dataLayer } = window;
4232
+ if (!Array.isArray(dataLayer))
4233
+ return undefined;
4234
+ let update;
4235
+ let defaultGranted = false;
4236
+ let defaultDenied = false;
4237
+ for (let i = 0; i < dataLayer.length; i++) {
4238
+ const entry = dataLayer[i];
4239
+ if (entry === null ||
4240
+ typeof entry !== 'object' ||
4241
+ entry[0] !== 'consent' ||
4242
+ (entry[1] !== 'default' && entry[1] !== 'update')) {
4243
+ continue;
4244
+ }
4245
+ const storage = (_a = entry[2]) === null || _a === void 0 ? void 0 : _a.analytics_storage;
4246
+ if (storage !== 'granted' && storage !== 'denied')
4247
+ continue;
4248
+ if (entry[1] === 'update')
4249
+ update = storage;
4250
+ else if (storage === 'denied')
4251
+ defaultDenied = true;
4252
+ else
4253
+ defaultGranted = true;
4254
+ }
4255
+ if (update !== undefined)
4256
+ return update;
4257
+ if (defaultDenied)
4258
+ return 'pending';
4259
+ return defaultGranted ? 'granted' : undefined;
4260
+ }
4261
+ catch (_b) {
4262
+ return undefined;
4263
+ }
4264
+ }
4265
+
4186
4266
  let startRequested = false;
4187
4267
  let replayScriptUrl;
4188
4268
  const COMPILED_REPLAY_SCRIPT_URL = `${"https://edge.cofra.me"}/replay/latest.js`;
4189
4269
  const CONSENT_POLL_MS = 100;
4190
4270
  const CONSENT_WAIT_MS = 5000;
4271
+ const CONSENT_DETECT_WAIT_MS = 10000;
4272
+ const EXPLICIT_CONSENT_WAIT_MS = 60000;
4191
4273
  function configureReplayScriptUrl(url) {
4192
4274
  replayScriptUrl = (url === null || url === void 0 ? void 0 : url.trim()) || undefined;
4193
4275
  }
4194
- function readReplayConsent() {
4276
+ function readReplayConsent(settings) {
4195
4277
  try {
4196
4278
  if (navigator
4197
4279
  .globalPrivacyControl === true) {
4198
4280
  return { state: 'denied', reason: 'gpc' };
4199
4281
  }
4200
4282
  const shopify = window.Shopify;
4201
- if (shopify === undefined)
4202
- return { state: 'allowed', source: 'none' };
4283
+ if (shopify === undefined) {
4284
+ const readers = [
4285
+ [readClientCommand, 'client'],
4286
+ [readOneTrust, 'onetrust'],
4287
+ [readCookiebot, 'cookiebot'],
4288
+ [readConsentMode, 'consent_mode'],
4289
+ ];
4290
+ for (let i = 0; i < readers.length; i++) {
4291
+ const [read, source] = readers[i];
4292
+ const signal = read();
4293
+ if (signal === 'granted')
4294
+ return { state: 'allowed', source };
4295
+ if (signal === 'denied')
4296
+ return { state: 'denied', reason: 'consent_denied' };
4297
+ if (signal === 'pending') {
4298
+ if (settings.consent_required === false)
4299
+ continue;
4300
+ return { state: 'pending', detected: true };
4301
+ }
4302
+ }
4303
+ if (settings.consent_required === false)
4304
+ return { state: 'allowed', source: 'not_required' };
4305
+ return { state: 'pending', detected: isWaitingForCookies() };
4306
+ }
4203
4307
  const customerPrivacy = shopify.customerPrivacy;
4204
4308
  const analyticsProcessingAllowed = customerPrivacy === null || customerPrivacy === void 0 ? void 0 : customerPrivacy.analyticsProcessingAllowed;
4205
4309
  if (typeof analyticsProcessingAllowed === 'function') {
@@ -4247,7 +4351,9 @@ function createStartContext(coframe, settings, forceSample, consentSource) {
4247
4351
  getPageViewId: () => coframe.sessionId,
4248
4352
  getUserToken: () => coframe.userToken,
4249
4353
  getVariantIds: () => { var _a; return ((_a = coframe.experimentInfo) !== null && _a !== void 0 ? _a : []).map((experiment) => experiment.variant_id); },
4250
- canSend: () => shouldSendEvents() && readReplayConsent().state === 'allowed',
4354
+ canSend: () => shouldSendEvents({
4355
+ ignoreConsent: window.Shopify === undefined,
4356
+ }) && readReplayConsent(settings).state === 'allowed',
4251
4357
  onEventsFlushed: (callback) => {
4252
4358
  if (queuedEvents.length === 0 && queuedSessions.length === 0) {
4253
4359
  callback();
@@ -4301,22 +4407,30 @@ function startReplayIfEnabled(coframe, project, nonce) {
4301
4407
  const settings = (_a = project.settings) === null || _a === void 0 ? void 0 : _a.session_replay;
4302
4408
  if ((settings === null || settings === void 0 ? void 0 : settings.enabled) !== true ||
4303
4409
  typeof CompressionStream !== 'function' ||
4304
- !shouldSendEvents() ||
4410
+ !shouldSendEvents({
4411
+ ignoreConsent: window.Shopify === undefined,
4412
+ }) ||
4305
4413
  startRequested) {
4306
4414
  return;
4307
4415
  }
4308
4416
  startRequested = true;
4417
+ const isShopify = window.Shopify !== undefined;
4309
4418
  let waited = 0;
4310
4419
  const decide = () => {
4311
4420
  var _a;
4312
- const consent = readReplayConsent();
4421
+ const consent = readReplayConsent(settings);
4313
4422
  if (consent.state === 'allowed') {
4314
4423
  insertReplayScript(coframe, settings, consent.source, nonce);
4315
4424
  }
4316
4425
  else if (consent.state === 'denied') {
4317
4426
  reportReplaySkipped(coframe, consent.reason);
4318
4427
  }
4319
- else if (waited >= CONSENT_WAIT_MS) {
4428
+ else if (!isShopify &&
4429
+ consent.detected !== true &&
4430
+ waited >= CONSENT_DETECT_WAIT_MS) {
4431
+ reportReplaySkipped(coframe, 'consent_not_configured');
4432
+ }
4433
+ else if (waited >= (isShopify ? CONSENT_WAIT_MS : EXPLICIT_CONSENT_WAIT_MS)) {
4320
4434
  reportReplaySkipped(coframe, 'consent_unavailable');
4321
4435
  }
4322
4436
  else {
@@ -81,6 +81,7 @@ interface SessionReplaySettings {
81
81
  block_selector: string;
82
82
  url_deny_patterns: string[];
83
83
  url_allow_patterns?: string[];
84
+ consent_required?: boolean;
84
85
  max_session_minutes: number;
85
86
  max_session_bytes: number;
86
87
  }
@@ -101,6 +101,7 @@ interface SessionReplaySettings {
101
101
  block_selector: string;
102
102
  url_deny_patterns: string[];
103
103
  url_allow_patterns?: string[];
104
+ consent_required?: boolean;
104
105
  max_session_minutes: number;
105
106
  max_session_bytes: number;
106
107
  }
@@ -81,6 +81,7 @@ interface SessionReplaySettings {
81
81
  block_selector: string;
82
82
  url_deny_patterns: string[];
83
83
  url_allow_patterns?: string[];
84
+ consent_required?: boolean;
84
85
  max_session_minutes: number;
85
86
  max_session_bytes: number;
86
87
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coframe/sdk",
3
- "version": "1.1.41",
3
+ "version": "1.1.43",
4
4
  "description": "Coframe optimizes your website using generative AI to deliver maximum impact to your audience and allow your site to improve itself as you sleep. Learn more at coframe.com.",
5
5
  "main": "dist/pkg/cf.cjs.js",
6
6
  "module": "dist/pkg/cf.esm.mjs",