@coframe/sdk 1.1.24 → 1.1.26

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/README.md CHANGED
@@ -51,6 +51,7 @@ await init({
51
51
  projectId: 'your-project-id',
52
52
  projectUrl: 'https://cdn.example.com/coframe/project.json',
53
53
  ingestUrl: 'https://www.example.com/ingest/v2',
54
+ replayScriptUrl: 'https://www.example.com/replay/latest.js',
54
55
  enableDebug: false,
55
56
  },
56
57
  })
@@ -65,11 +66,14 @@ only has to forward `<ingestUrl>/*` to `https://ingest.app.coframe.com/ingest/v2
65
66
  with the path unchanged. Both overrides are optional and retain the compiled
66
67
  Coframe endpoints when omitted.
67
68
 
69
+ `replayScriptUrl` replaces the session replay recorder script URL. A proxy must
70
+ forward it to `<edge>/replay/latest.js` unchanged.
71
+
68
72
  Configuring either `projectUrl` or `ingestUrl` makes CMAB experiments use
69
73
  deterministic local assignment without calling the Edge assignment API.
70
- Configure both overrides when the browser must avoid the SDK-compiled Coframe
71
- project and ingest endpoints entirely. Debug tools remain controlled by
72
- `enableDebug`.
74
+ Configure all three overrides when the browser must avoid the SDK-compiled
75
+ Coframe project, ingest and replay script endpoints entirely. Debug tools
76
+ remain controlled by `enableDebug`.
73
77
 
74
78
  ### URL controls
75
79
 
@@ -2835,7 +2835,7 @@ function keepRolledOutExperiments(frames) {
2835
2835
  function buildSessionContext(isInitialApply) {
2836
2836
  const context = {};
2837
2837
  const viewport = getScreenSize();
2838
- if (isReportedSize(viewport.width) && isReportedSize(viewport.height)) {
2838
+ if (isReportedSize$1(viewport.width) && isReportedSize$1(viewport.height)) {
2839
2839
  context.viewport_width = viewport.width;
2840
2840
  context.viewport_height = viewport.height;
2841
2841
  }
@@ -2858,7 +2858,7 @@ function buildSessionContext(isInitialApply) {
2858
2858
  }
2859
2859
  return context;
2860
2860
  }
2861
- function isReportedSize(size) {
2861
+ function isReportedSize$1(size) {
2862
2862
  return (typeof size === 'number' && size > 0 && size !== Number.POSITIVE_INFINITY);
2863
2863
  }
2864
2864
  function getNavigationType(isInitialApply) {
@@ -3231,6 +3231,20 @@ function observeUrlChanges(baseUrlMatch, onUrlChange) {
3231
3231
  patchHistoryMethod('replaceState');
3232
3232
  }
3233
3233
 
3234
+ const callbacks = [];
3235
+ function onEventsFlushed(callback) {
3236
+ callbacks.push(callback);
3237
+ }
3238
+ function notifyEventsFlushed() {
3239
+ const pendingCallbacks = callbacks.splice(0);
3240
+ for (const callback of pendingCallbacks) {
3241
+ try {
3242
+ callback();
3243
+ }
3244
+ catch (_a) { }
3245
+ }
3246
+ }
3247
+
3234
3248
  function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders, sessionContext, pageUrl = getCurrentPageUrl()) {
3235
3249
  const sessionPayload = [
3236
3250
  Coframe,
@@ -3505,6 +3519,7 @@ function setupListeners(Coframe, executionStartTime) {
3505
3519
  personalizationHeaders: Coframe.personalizationHeaders,
3506
3520
  });
3507
3521
  flushQueuedEvents(Coframe.projectId);
3522
+ notifyEventsFlushed();
3508
3523
  }, 1);
3509
3524
  window.addEventListener('beforeunload', () => handleEventFlush('before_unload'));
3510
3525
  window.addEventListener('pagehide', () => handleEventFlush('page_hide'));
@@ -3778,7 +3793,131 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
3778
3793
  setupFlushInterval(Coframe);
3779
3794
  }
3780
3795
 
3796
+ let startRequested = false;
3797
+ let replayScriptUrl;
3798
+ const COMPILED_REPLAY_SCRIPT_URL = `${"https://edge.cofra.me"}/replay/latest.js`;
3799
+ function configureReplayScriptUrl(url) {
3800
+ replayScriptUrl = (url === null || url === void 0 ? void 0 : url.trim()) || undefined;
3801
+ }
3802
+ function createMonitoringPayload(coframe, monitoringType, metadata) {
3803
+ return {
3804
+ event_id: generateUUID(),
3805
+ monitoring_type: monitoringType,
3806
+ local_time: new Date().toISOString(),
3807
+ project_id: coframe.projectId,
3808
+ session_id: coframe.sessionId,
3809
+ url: location.href,
3810
+ org_id: coframe.orgId,
3811
+ metadata,
3812
+ };
3813
+ }
3814
+ function reportStartFailure(coframe, reason) {
3815
+ try {
3816
+ queueMonitoringEvent(coframe, createMonitoringPayload(coframe, 'replay_start_failed', { reason }));
3817
+ }
3818
+ catch (_a) { }
3819
+ }
3820
+ function createStartContext(coframe, settings, forceSample) {
3821
+ return {
3822
+ projectId: coframe.projectId,
3823
+ ingestUrl: resolveIngestUrl("https://ingest.app.coframe.com/ingest/v2"),
3824
+ settings,
3825
+ forceSample,
3826
+ getPageViewId: () => coframe.sessionId,
3827
+ getUserToken: () => coframe.userToken,
3828
+ getVariantIds: () => { var _a; return ((_a = coframe.experimentInfo) !== null && _a !== void 0 ? _a : []).map((experiment) => experiment.variant_id); },
3829
+ canSend: shouldSendEvents,
3830
+ onEventsFlushed: (callback) => {
3831
+ if (queuedEvents.length === 0 && queuedSessions.length === 0) {
3832
+ callback();
3833
+ }
3834
+ else {
3835
+ onEventsFlushed(callback);
3836
+ }
3837
+ },
3838
+ report: (type, metadata) => queueMonitoringEvent(coframe, createMonitoringPayload(coframe, type, metadata)),
3839
+ };
3840
+ }
3841
+ function startReplayIfEnabled(coframe, project, nonce) {
3842
+ var _a;
3843
+ try {
3844
+ const settings = (_a = project.settings) === null || _a === void 0 ? void 0 : _a.session_replay;
3845
+ if ((settings === null || settings === void 0 ? void 0 : settings.enabled) !== true ||
3846
+ typeof CompressionStream !== 'function' ||
3847
+ !shouldSendEvents() ||
3848
+ startRequested) {
3849
+ return;
3850
+ }
3851
+ let forceSample = false;
3852
+ try {
3853
+ forceSample = localStorage.getItem('coframe.enableRecording') === 'true';
3854
+ }
3855
+ catch (_b) { }
3856
+ const script = document.createElement('script');
3857
+ script.id = 'coframe-replay-script';
3858
+ script.async = true;
3859
+ script.src = replayScriptUrl !== null && replayScriptUrl !== void 0 ? replayScriptUrl : COMPILED_REPLAY_SCRIPT_URL;
3860
+ if (nonce)
3861
+ script.nonce = nonce;
3862
+ script.onload = () => {
3863
+ try {
3864
+ const replay = window.CoframeReplay;
3865
+ if ((replay === null || replay === void 0 ? void 0 : replay.protocolVersion) === 1) {
3866
+ replay.start(createStartContext(coframe, settings, forceSample));
3867
+ }
3868
+ else {
3869
+ reportStartFailure(coframe, 'incompatible_protocol');
3870
+ }
3871
+ }
3872
+ catch (error) {
3873
+ reportStartFailure(coframe, error instanceof Error ? error.message : String(error));
3874
+ }
3875
+ };
3876
+ script.onerror = () => {
3877
+ reportStartFailure(coframe, 'script_load_failed');
3878
+ };
3879
+ startRequested = true;
3880
+ document.head.appendChild(script);
3881
+ }
3882
+ catch (error) {
3883
+ reportStartFailure(coframe, error instanceof Error ? error.message : String(error));
3884
+ }
3885
+ }
3886
+
3781
3887
  const TIMEOUT_MAX_MS = 5000;
3888
+ const MAX_NOT_RENDERED_REASON_CHARS = 200;
3889
+ function isReportedSize(size) {
3890
+ return (typeof size === 'number' && size > 0 && size !== Number.POSITIVE_INFINITY);
3891
+ }
3892
+ function describeEnvironment(initTime) {
3893
+ const metadata = {};
3894
+ if (typeof window !== 'undefined') {
3895
+ if (isReportedSize(window.innerWidth)) {
3896
+ metadata.viewport_width = window.innerWidth;
3897
+ }
3898
+ if (isReportedSize(window.innerHeight)) {
3899
+ metadata.viewport_height = window.innerHeight;
3900
+ }
3901
+ const screen = window.screen;
3902
+ if (screen && isReportedSize(screen.width)) {
3903
+ metadata.screen_width = screen.width;
3904
+ }
3905
+ if (screen && isReportedSize(screen.height)) {
3906
+ metadata.screen_height = screen.height;
3907
+ }
3908
+ if (isReportedSize(window.devicePixelRatio)) {
3909
+ metadata.device_pixel_ratio = window.devicePixelRatio;
3910
+ }
3911
+ if (typeof navigator.userAgent === 'string') {
3912
+ metadata.user_agent = navigator.userAgent;
3913
+ }
3914
+ if (typeof document.readyState === 'string') {
3915
+ metadata.document_ready_state = document.readyState;
3916
+ }
3917
+ }
3918
+ metadata.ms_since_init = Math.max(0, Date.now() - initTime);
3919
+ return metadata;
3920
+ }
3782
3921
  function getFeatureFlagValue(cmd) {
3783
3922
  if (cmd.featureFlagSet !== undefined)
3784
3923
  return cmd.featureFlagSet;
@@ -3812,6 +3951,7 @@ async function resolveConfig(Coframe, revealPage) {
3812
3951
  const executionStartTime = new Date();
3813
3952
  Coframe.batchSize = config.batchSize || 32;
3814
3953
  configureIngestUrl(config.ingestUrl);
3954
+ configureReplayScriptUrl(config.replayScriptUrl);
3815
3955
  const gracefulExit = (msg) => {
3816
3956
  console.warn(`[Coframe] ${msg}`);
3817
3957
  revealPage();
@@ -3832,6 +3972,15 @@ async function resolveConfig(Coframe, revealPage) {
3832
3972
  logger.warn('Failed to wait for variant rendered command', 'missing_variant_rendered');
3833
3973
  }
3834
3974
  };
3975
+ const warnVariantNotRendered = (reason) => {
3976
+ if (!applyVariantChangesStarted)
3977
+ return;
3978
+ const metadata = describeEnvironment(executionStartTime.getTime());
3979
+ if (typeof reason === 'string') {
3980
+ metadata.reason = reason.slice(0, MAX_NOT_RENDERED_REASON_CHARS);
3981
+ }
3982
+ logger.warn('Variant not rendered', 'variant_not_rendered', metadata);
3983
+ };
3835
3984
  waitForCmd((cmd) => cmd.variantRendered === true || cmd.emit === 'variantRendered', Coframe, timeoutMs)
3836
3985
  .then((cmd) => {
3837
3986
  if (!cmd) {
@@ -3841,6 +3990,13 @@ async function resolveConfig(Coframe, revealPage) {
3841
3990
  .finally(() => {
3842
3991
  revealPage();
3843
3992
  });
3993
+ const loggedReasons = [];
3994
+ listenForCmd((cmd) => cmd.emit === 'variantNotRendered', (cmd) => {
3995
+ if (loggedReasons.indexOf(cmd.reason) !== -1)
3996
+ return;
3997
+ loggedReasons.push(cmd.reason);
3998
+ warnVariantNotRendered(cmd.reason);
3999
+ });
3844
4000
  if (!projectId) {
3845
4001
  logger.error('No project ID', 'no_project_id', {
3846
4002
  description: 'No Coframe Page ID',
@@ -4106,6 +4262,12 @@ async function init(options) {
4106
4262
  return;
4107
4263
  const analytics = setupTracking(Coframe, projectResult, configResult.previewVariantId, configResult.executionStartTime, configResult.config.nonce, configResult.config.waitForCookiesEnabled, identity.onConsentChange);
4108
4264
  await modifyPage(Coframe, configResult, projectResult, analytics);
4265
+ try {
4266
+ startReplayIfEnabled(Coframe, projectResult.project, configResult.config.nonce);
4267
+ }
4268
+ catch (error) {
4269
+ console.warn('[Coframe] Failed to start session replay', error);
4270
+ }
4109
4271
  }
4110
4272
  Coframe.debug = {
4111
4273
  getSelector,
@@ -2833,7 +2833,7 @@ function keepRolledOutExperiments(frames) {
2833
2833
  function buildSessionContext(isInitialApply) {
2834
2834
  const context = {};
2835
2835
  const viewport = getScreenSize();
2836
- if (isReportedSize(viewport.width) && isReportedSize(viewport.height)) {
2836
+ if (isReportedSize$1(viewport.width) && isReportedSize$1(viewport.height)) {
2837
2837
  context.viewport_width = viewport.width;
2838
2838
  context.viewport_height = viewport.height;
2839
2839
  }
@@ -2856,7 +2856,7 @@ function buildSessionContext(isInitialApply) {
2856
2856
  }
2857
2857
  return context;
2858
2858
  }
2859
- function isReportedSize(size) {
2859
+ function isReportedSize$1(size) {
2860
2860
  return (typeof size === 'number' && size > 0 && size !== Number.POSITIVE_INFINITY);
2861
2861
  }
2862
2862
  function getNavigationType(isInitialApply) {
@@ -3229,6 +3229,20 @@ function observeUrlChanges(baseUrlMatch, onUrlChange) {
3229
3229
  patchHistoryMethod('replaceState');
3230
3230
  }
3231
3231
 
3232
+ const callbacks = [];
3233
+ function onEventsFlushed(callback) {
3234
+ callbacks.push(callback);
3235
+ }
3236
+ function notifyEventsFlushed() {
3237
+ const pendingCallbacks = callbacks.splice(0);
3238
+ for (const callback of pendingCallbacks) {
3239
+ try {
3240
+ callback();
3241
+ }
3242
+ catch (_a) { }
3243
+ }
3244
+ }
3245
+
3232
3246
  function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders, sessionContext, pageUrl = getCurrentPageUrl()) {
3233
3247
  const sessionPayload = [
3234
3248
  Coframe,
@@ -3503,6 +3517,7 @@ function setupListeners(Coframe, executionStartTime) {
3503
3517
  personalizationHeaders: Coframe.personalizationHeaders,
3504
3518
  });
3505
3519
  flushQueuedEvents(Coframe.projectId);
3520
+ notifyEventsFlushed();
3506
3521
  }, 1);
3507
3522
  window.addEventListener('beforeunload', () => handleEventFlush('before_unload'));
3508
3523
  window.addEventListener('pagehide', () => handleEventFlush('page_hide'));
@@ -3776,7 +3791,131 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
3776
3791
  setupFlushInterval(Coframe);
3777
3792
  }
3778
3793
 
3794
+ let startRequested = false;
3795
+ let replayScriptUrl;
3796
+ const COMPILED_REPLAY_SCRIPT_URL = `${"https://edge.cofra.me"}/replay/latest.js`;
3797
+ function configureReplayScriptUrl(url) {
3798
+ replayScriptUrl = (url === null || url === void 0 ? void 0 : url.trim()) || undefined;
3799
+ }
3800
+ function createMonitoringPayload(coframe, monitoringType, metadata) {
3801
+ return {
3802
+ event_id: generateUUID(),
3803
+ monitoring_type: monitoringType,
3804
+ local_time: new Date().toISOString(),
3805
+ project_id: coframe.projectId,
3806
+ session_id: coframe.sessionId,
3807
+ url: location.href,
3808
+ org_id: coframe.orgId,
3809
+ metadata,
3810
+ };
3811
+ }
3812
+ function reportStartFailure(coframe, reason) {
3813
+ try {
3814
+ queueMonitoringEvent(coframe, createMonitoringPayload(coframe, 'replay_start_failed', { reason }));
3815
+ }
3816
+ catch (_a) { }
3817
+ }
3818
+ function createStartContext(coframe, settings, forceSample) {
3819
+ return {
3820
+ projectId: coframe.projectId,
3821
+ ingestUrl: resolveIngestUrl("https://ingest.app.coframe.com/ingest/v2"),
3822
+ settings,
3823
+ forceSample,
3824
+ getPageViewId: () => coframe.sessionId,
3825
+ getUserToken: () => coframe.userToken,
3826
+ getVariantIds: () => { var _a; return ((_a = coframe.experimentInfo) !== null && _a !== void 0 ? _a : []).map((experiment) => experiment.variant_id); },
3827
+ canSend: shouldSendEvents,
3828
+ onEventsFlushed: (callback) => {
3829
+ if (queuedEvents.length === 0 && queuedSessions.length === 0) {
3830
+ callback();
3831
+ }
3832
+ else {
3833
+ onEventsFlushed(callback);
3834
+ }
3835
+ },
3836
+ report: (type, metadata) => queueMonitoringEvent(coframe, createMonitoringPayload(coframe, type, metadata)),
3837
+ };
3838
+ }
3839
+ function startReplayIfEnabled(coframe, project, nonce) {
3840
+ var _a;
3841
+ try {
3842
+ const settings = (_a = project.settings) === null || _a === void 0 ? void 0 : _a.session_replay;
3843
+ if ((settings === null || settings === void 0 ? void 0 : settings.enabled) !== true ||
3844
+ typeof CompressionStream !== 'function' ||
3845
+ !shouldSendEvents() ||
3846
+ startRequested) {
3847
+ return;
3848
+ }
3849
+ let forceSample = false;
3850
+ try {
3851
+ forceSample = localStorage.getItem('coframe.enableRecording') === 'true';
3852
+ }
3853
+ catch (_b) { }
3854
+ const script = document.createElement('script');
3855
+ script.id = 'coframe-replay-script';
3856
+ script.async = true;
3857
+ script.src = replayScriptUrl !== null && replayScriptUrl !== void 0 ? replayScriptUrl : COMPILED_REPLAY_SCRIPT_URL;
3858
+ if (nonce)
3859
+ script.nonce = nonce;
3860
+ script.onload = () => {
3861
+ try {
3862
+ const replay = window.CoframeReplay;
3863
+ if ((replay === null || replay === void 0 ? void 0 : replay.protocolVersion) === 1) {
3864
+ replay.start(createStartContext(coframe, settings, forceSample));
3865
+ }
3866
+ else {
3867
+ reportStartFailure(coframe, 'incompatible_protocol');
3868
+ }
3869
+ }
3870
+ catch (error) {
3871
+ reportStartFailure(coframe, error instanceof Error ? error.message : String(error));
3872
+ }
3873
+ };
3874
+ script.onerror = () => {
3875
+ reportStartFailure(coframe, 'script_load_failed');
3876
+ };
3877
+ startRequested = true;
3878
+ document.head.appendChild(script);
3879
+ }
3880
+ catch (error) {
3881
+ reportStartFailure(coframe, error instanceof Error ? error.message : String(error));
3882
+ }
3883
+ }
3884
+
3779
3885
  const TIMEOUT_MAX_MS = 5000;
3886
+ const MAX_NOT_RENDERED_REASON_CHARS = 200;
3887
+ function isReportedSize(size) {
3888
+ return (typeof size === 'number' && size > 0 && size !== Number.POSITIVE_INFINITY);
3889
+ }
3890
+ function describeEnvironment(initTime) {
3891
+ const metadata = {};
3892
+ if (typeof window !== 'undefined') {
3893
+ if (isReportedSize(window.innerWidth)) {
3894
+ metadata.viewport_width = window.innerWidth;
3895
+ }
3896
+ if (isReportedSize(window.innerHeight)) {
3897
+ metadata.viewport_height = window.innerHeight;
3898
+ }
3899
+ const screen = window.screen;
3900
+ if (screen && isReportedSize(screen.width)) {
3901
+ metadata.screen_width = screen.width;
3902
+ }
3903
+ if (screen && isReportedSize(screen.height)) {
3904
+ metadata.screen_height = screen.height;
3905
+ }
3906
+ if (isReportedSize(window.devicePixelRatio)) {
3907
+ metadata.device_pixel_ratio = window.devicePixelRatio;
3908
+ }
3909
+ if (typeof navigator.userAgent === 'string') {
3910
+ metadata.user_agent = navigator.userAgent;
3911
+ }
3912
+ if (typeof document.readyState === 'string') {
3913
+ metadata.document_ready_state = document.readyState;
3914
+ }
3915
+ }
3916
+ metadata.ms_since_init = Math.max(0, Date.now() - initTime);
3917
+ return metadata;
3918
+ }
3780
3919
  function getFeatureFlagValue(cmd) {
3781
3920
  if (cmd.featureFlagSet !== undefined)
3782
3921
  return cmd.featureFlagSet;
@@ -3810,6 +3949,7 @@ async function resolveConfig(Coframe, revealPage) {
3810
3949
  const executionStartTime = new Date();
3811
3950
  Coframe.batchSize = config.batchSize || 32;
3812
3951
  configureIngestUrl(config.ingestUrl);
3952
+ configureReplayScriptUrl(config.replayScriptUrl);
3813
3953
  const gracefulExit = (msg) => {
3814
3954
  console.warn(`[Coframe] ${msg}`);
3815
3955
  revealPage();
@@ -3830,6 +3970,15 @@ async function resolveConfig(Coframe, revealPage) {
3830
3970
  logger.warn('Failed to wait for variant rendered command', 'missing_variant_rendered');
3831
3971
  }
3832
3972
  };
3973
+ const warnVariantNotRendered = (reason) => {
3974
+ if (!applyVariantChangesStarted)
3975
+ return;
3976
+ const metadata = describeEnvironment(executionStartTime.getTime());
3977
+ if (typeof reason === 'string') {
3978
+ metadata.reason = reason.slice(0, MAX_NOT_RENDERED_REASON_CHARS);
3979
+ }
3980
+ logger.warn('Variant not rendered', 'variant_not_rendered', metadata);
3981
+ };
3833
3982
  waitForCmd((cmd) => cmd.variantRendered === true || cmd.emit === 'variantRendered', Coframe, timeoutMs)
3834
3983
  .then((cmd) => {
3835
3984
  if (!cmd) {
@@ -3839,6 +3988,13 @@ async function resolveConfig(Coframe, revealPage) {
3839
3988
  .finally(() => {
3840
3989
  revealPage();
3841
3990
  });
3991
+ const loggedReasons = [];
3992
+ listenForCmd((cmd) => cmd.emit === 'variantNotRendered', (cmd) => {
3993
+ if (loggedReasons.indexOf(cmd.reason) !== -1)
3994
+ return;
3995
+ loggedReasons.push(cmd.reason);
3996
+ warnVariantNotRendered(cmd.reason);
3997
+ });
3842
3998
  if (!projectId) {
3843
3999
  logger.error('No project ID', 'no_project_id', {
3844
4000
  description: 'No Coframe Page ID',
@@ -4104,6 +4260,12 @@ async function init(options) {
4104
4260
  return;
4105
4261
  const analytics = setupTracking(Coframe, projectResult, configResult.previewVariantId, configResult.executionStartTime, configResult.config.nonce, configResult.config.waitForCookiesEnabled, identity.onConsentChange);
4106
4262
  await modifyPage(Coframe, configResult, projectResult, analytics);
4263
+ try {
4264
+ startReplayIfEnabled(Coframe, projectResult.project, configResult.config.nonce);
4265
+ }
4266
+ catch (error) {
4267
+ console.warn('[Coframe] Failed to start session replay', error);
4268
+ }
4107
4269
  }
4108
4270
  Coframe.debug = {
4109
4271
  getSelector,
@@ -74,6 +74,15 @@ type ModalTrigger = 'exit' | 'scroll' | 'enter' | 'timer';
74
74
  interface AnalyticsCallback {
75
75
  callback: string;
76
76
  }
77
+ interface SessionReplaySettings {
78
+ enabled: boolean;
79
+ sample_rate: number;
80
+ mask_text_selector: string;
81
+ block_selector: string;
82
+ url_deny_patterns: string[];
83
+ max_session_minutes: number;
84
+ max_session_bytes: number;
85
+ }
77
86
  interface TreatmentData {
78
87
  impressionId: string;
79
88
  userToken: string;
@@ -141,6 +150,7 @@ interface ProjectSettings {
141
150
  bot_cloaking_enabled?: boolean;
142
151
  bot_score_threshold?: number;
143
152
  analytics_callback?: AnalyticsCallback;
153
+ session_replay?: SessionReplaySettings | null;
144
154
  }
145
155
  interface Project {
146
156
  org_id: string;
@@ -252,6 +262,7 @@ type CoframeConfig = {
252
262
  currentUrl?: string;
253
263
  projectUrl?: string;
254
264
  ingestUrl?: string;
265
+ replayScriptUrl?: string;
255
266
  referrer?: string;
256
267
  userContext?: Record<string, unknown>;
257
268
  nonce?: string;
@@ -93,6 +93,15 @@ type ModalTrigger = 'exit' | 'scroll' | 'enter' | 'timer';
93
93
  interface AnalyticsCallback {
94
94
  callback: string;
95
95
  }
96
+ interface SessionReplaySettings {
97
+ enabled: boolean;
98
+ sample_rate: number;
99
+ mask_text_selector: string;
100
+ block_selector: string;
101
+ url_deny_patterns: string[];
102
+ max_session_minutes: number;
103
+ max_session_bytes: number;
104
+ }
96
105
  interface TreatmentData {
97
106
  impressionId: string;
98
107
  userToken: string;
@@ -160,6 +169,7 @@ interface ProjectSettings {
160
169
  bot_cloaking_enabled?: boolean;
161
170
  bot_score_threshold?: number;
162
171
  analytics_callback?: AnalyticsCallback;
172
+ session_replay?: SessionReplaySettings | null;
163
173
  }
164
174
  interface Project {
165
175
  org_id: string;
@@ -271,6 +281,7 @@ type CoframeConfig = {
271
281
  currentUrl?: string;
272
282
  projectUrl?: string;
273
283
  ingestUrl?: string;
284
+ replayScriptUrl?: string;
274
285
  referrer?: string;
275
286
  userContext?: Record<string, unknown>;
276
287
  nonce?: string;
@@ -74,6 +74,15 @@ type ModalTrigger = 'exit' | 'scroll' | 'enter' | 'timer';
74
74
  interface AnalyticsCallback {
75
75
  callback: string;
76
76
  }
77
+ interface SessionReplaySettings {
78
+ enabled: boolean;
79
+ sample_rate: number;
80
+ mask_text_selector: string;
81
+ block_selector: string;
82
+ url_deny_patterns: string[];
83
+ max_session_minutes: number;
84
+ max_session_bytes: number;
85
+ }
77
86
  interface Audience {
78
87
  selector: ActivationCondition;
79
88
  }
@@ -107,6 +116,7 @@ interface ProjectSettings {
107
116
  bot_cloaking_enabled?: boolean;
108
117
  bot_score_threshold?: number;
109
118
  analytics_callback?: AnalyticsCallback;
119
+ session_replay?: SessionReplaySettings | null;
110
120
  }
111
121
  interface Project {
112
122
  org_id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coframe/sdk",
3
- "version": "1.1.24",
3
+ "version": "1.1.26",
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",
@@ -98,6 +98,8 @@
98
98
  }
99
99
  },
100
100
  "dependencies": {
101
+ "@rrweb/record": "2.1.0",
102
+ "fflate": "0.8.3",
101
103
  "typescript": "^6.0.2"
102
104
  },
103
105
  "devDependencies": {
@@ -136,4 +138,4 @@
136
138
  "ua-parser-js": "^2.0.10"
137
139
  },
138
140
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
139
- }
141
+ }