blocfeed 0.19.0 → 0.21.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.
@@ -28,6 +28,17 @@ interface BehavioralEvent {
28
28
  element_text: string | null;
29
29
  event_data: Record<string, unknown> | null;
30
30
  created_at: string;
31
+ /**
32
+ * A render-stable identifier for the element associated with the event.
33
+ * Built from `data-blocfeed-component`, then a `data-testid`-family
34
+ * attribute, then the element id (walking up to a few ancestors). When
35
+ * none of those are available the field is `null`. Used by the backend
36
+ * to dedupe events for the "same logical element" across re-renders, even
37
+ * when the CSS selector changes.
38
+ *
39
+ * See `buildStableElementKey` in `src/shared/dom.ts`.
40
+ */
41
+ stable_key: string | null;
31
42
  }
32
43
  interface RageClickConfig {
33
44
  enabled?: boolean;
@@ -506,4 +517,4 @@ interface BlocFeedController {
506
517
  }
507
518
  declare function createBlocFeedController(config: BlocFeedConfig): BlocFeedController;
508
519
 
509
- export { type TransportResult as A, type BlocFeedConfig as B, type CaptureConfig as C, type DiagnosticsConfig as D, type ElementDescriptor as E, type FeedbackCategory as F, type TriggerStyle as G, type VideoIntent as H, type ImageAsset as I, type VideoMime as J, type VoiceConfig as K, type ClickEvent as L, type MaybePromise as M, type NetworkEntry as N, type HoverListener as O, type PickerConfig as P, type StateListener as Q, type RecordingConfig as R, type SubmitResult as S, type ThemeConfig as T, createBlocFeedController as U, type VideoAsset as V, type WidgetPosition as W, type BlocFeedHandle as a, type BlocFeedState as b, type BlocFeedController as c, type BehavioralEvent as d, type BehavioralConfig as e, type BehavioralEventType as f, type BlocFeedError as g, type BlocFeedStrings as h, type BlocFeedUser as i, type CaptureDiagnostics as j, type CaptureResult as k, type ConsoleEntry as l, type FeedbackApiResponse as m, type FeedbackPayload as n, type MetadataConfig as o, type MetadataContext as p, type Rect as q, type ScreenshotAdapter as r, type ScreenshotAdapterOptions as s, type ScreenshotIntent as t, type ScreenshotMime as u, type SecurityConfig as v, type SecurityFinding as w, type SecuritySnapshot as x, type SessionPhase as y, type TransportConfig as z };
520
+ export { type VideoMime as A, type BlocFeedUser as B, type CaptureConfig as C, type DiagnosticsConfig as D, type ElementDescriptor as E, type FeedbackPayload as F, createBlocFeedController as G, type HoverListener as H, type ImageAsset as I, type BehavioralConfig as J, type BehavioralEvent as K, type BehavioralEventType as L, type MetadataConfig as M, type NetworkEntry as N, type CaptureDiagnostics as O, type MaybePromise as P, type PickerConfig as Q, type RecordingConfig as R, type ScreenshotAdapter as S, type ThemeConfig as T, type TransportResult as U, type VideoAsset as V, type WidgetPosition as W, type CaptureResult as a, type ClickEvent as b, type VoiceConfig as c, type MetadataContext as d, type SecuritySnapshot as e, type SecurityConfig as f, type BlocFeedConfig as g, type BlocFeedController as h, type BlocFeedError as i, type BlocFeedHandle as j, type BlocFeedState as k, type BlocFeedStrings as l, type ConsoleEntry as m, type FeedbackApiResponse as n, type FeedbackCategory as o, type Rect as p, type ScreenshotAdapterOptions as q, type ScreenshotIntent as r, type ScreenshotMime as s, type SecurityFinding as t, type SessionPhase as u, type StateListener as v, type SubmitResult as w, type TransportConfig as x, type TriggerStyle as y, type VideoIntent as z };
@@ -28,6 +28,17 @@ interface BehavioralEvent {
28
28
  element_text: string | null;
29
29
  event_data: Record<string, unknown> | null;
30
30
  created_at: string;
31
+ /**
32
+ * A render-stable identifier for the element associated with the event.
33
+ * Built from `data-blocfeed-component`, then a `data-testid`-family
34
+ * attribute, then the element id (walking up to a few ancestors). When
35
+ * none of those are available the field is `null`. Used by the backend
36
+ * to dedupe events for the "same logical element" across re-renders, even
37
+ * when the CSS selector changes.
38
+ *
39
+ * See `buildStableElementKey` in `src/shared/dom.ts`.
40
+ */
41
+ stable_key: string | null;
31
42
  }
32
43
  interface RageClickConfig {
33
44
  enabled?: boolean;
@@ -506,4 +517,4 @@ interface BlocFeedController {
506
517
  }
507
518
  declare function createBlocFeedController(config: BlocFeedConfig): BlocFeedController;
508
519
 
509
- export { type TransportResult as A, type BlocFeedConfig as B, type CaptureConfig as C, type DiagnosticsConfig as D, type ElementDescriptor as E, type FeedbackCategory as F, type TriggerStyle as G, type VideoIntent as H, type ImageAsset as I, type VideoMime as J, type VoiceConfig as K, type ClickEvent as L, type MaybePromise as M, type NetworkEntry as N, type HoverListener as O, type PickerConfig as P, type StateListener as Q, type RecordingConfig as R, type SubmitResult as S, type ThemeConfig as T, createBlocFeedController as U, type VideoAsset as V, type WidgetPosition as W, type BlocFeedHandle as a, type BlocFeedState as b, type BlocFeedController as c, type BehavioralEvent as d, type BehavioralConfig as e, type BehavioralEventType as f, type BlocFeedError as g, type BlocFeedStrings as h, type BlocFeedUser as i, type CaptureDiagnostics as j, type CaptureResult as k, type ConsoleEntry as l, type FeedbackApiResponse as m, type FeedbackPayload as n, type MetadataConfig as o, type MetadataContext as p, type Rect as q, type ScreenshotAdapter as r, type ScreenshotAdapterOptions as s, type ScreenshotIntent as t, type ScreenshotMime as u, type SecurityConfig as v, type SecurityFinding as w, type SecuritySnapshot as x, type SessionPhase as y, type TransportConfig as z };
520
+ export { type VideoMime as A, type BlocFeedUser as B, type CaptureConfig as C, type DiagnosticsConfig as D, type ElementDescriptor as E, type FeedbackPayload as F, createBlocFeedController as G, type HoverListener as H, type ImageAsset as I, type BehavioralConfig as J, type BehavioralEvent as K, type BehavioralEventType as L, type MetadataConfig as M, type NetworkEntry as N, type CaptureDiagnostics as O, type MaybePromise as P, type PickerConfig as Q, type RecordingConfig as R, type ScreenshotAdapter as S, type ThemeConfig as T, type TransportResult as U, type VideoAsset as V, type WidgetPosition as W, type CaptureResult as a, type ClickEvent as b, type VoiceConfig as c, type MetadataContext as d, type SecuritySnapshot as e, type SecurityConfig as f, type BlocFeedConfig as g, type BlocFeedController as h, type BlocFeedError as i, type BlocFeedHandle as j, type BlocFeedState as k, type BlocFeedStrings as l, type ConsoleEntry as m, type FeedbackApiResponse as n, type FeedbackCategory as o, type Rect as p, type ScreenshotAdapterOptions as q, type ScreenshotIntent as r, type ScreenshotMime as s, type SecurityFinding as t, type SessionPhase as u, type StateListener as v, type SubmitResult as w, type TransportConfig as x, type TriggerStyle as y, type VideoIntent as z };
package/dist/engine.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkZQDABCPT_cjs=require('./chunk-ZQDABCPT.cjs');function s(o){if(o?.aborted)throw new Error("Aborted")}async function v(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function l(o,t){let{width:e,height:r}=await v(o);return {dataUrl:o,mime:t,width:e,height:r}}function U(o){return {async captureElement(t,e){if(!chunkZQDABCPT_cjs.a())throw new Error("captureElement can only run in the browser");s(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return s(e.signal),await l(n,e.mime)},async captureFullPage(t){if(!chunkZQDABCPT_cjs.a())throw new Error("captureFullPage can only run in the browser");s(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),i=Math.min(1,t.maxDimension/Math.max(r,n)),c={width:Math.max(1,Math.round(r*i)),height:Math.max(1,Math.round(n*i)),scale:t.pixelRatio},a=t.mime==="image/jpeg"?await o.domToJpeg(e,{...c,quality:t.quality??.92}):await o.domToPng(e,c);return s(t.signal),await l(a,t.mime)}}}function O(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(e),c=new Uint8Array(i.length);for(let a=0;a<i.length;a+=1)c[a]=i.charCodeAt(a);return new Blob([c],{type:n})}Object.defineProperty(exports,"clearClickEvents",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.j}});Object.defineProperty(exports,"clearDiagnostics",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.y}});Object.defineProperty(exports,"clearQueue",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.g}});Object.defineProperty(exports,"clearSecurityFindings",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.B}});Object.defineProperty(exports,"collectMetadata",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.d}});Object.defineProperty(exports,"createBlocFeedController",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.t}});Object.defineProperty(exports,"createHtmlToImageAdapter",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.b}});Object.defineProperty(exports,"dequeueAll",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.f}});Object.defineProperty(exports,"drainClickEvents",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.i}});Object.defineProperty(exports,"drainDiagnostics",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.x}});Object.defineProperty(exports,"enqueue",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.e}});Object.defineProperty(exports,"getMyFeedbackUrl",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.p}});Object.defineProperty(exports,"getQueueSize",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.h}});Object.defineProperty(exports,"getSecurityFindings",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.A}});Object.defineProperty(exports,"getViewerToken",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.o}});Object.defineProperty(exports,"installDiagnostics",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.v}});Object.defineProperty(exports,"isRecordingSupported",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.k}});Object.defineProperty(exports,"isVoiceSupported",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.m}});Object.defineProperty(exports,"runCapture",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.c}});Object.defineProperty(exports,"runSecretScan",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.z}});Object.defineProperty(exports,"startRecording",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.l}});Object.defineProperty(exports,"startVoiceRecording",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.n}});Object.defineProperty(exports,"transcribeAudio",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.q}});Object.defineProperty(exports,"uninstallDiagnostics",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.w}});exports.createModernScreenshotAdapter=U;exports.dataUrlToBlob=O;
1
+ 'use strict';var chunkE3YSP5LQ_cjs=require('./chunk-E3YSP5LQ.cjs');function s(o){if(o?.aborted)throw new Error("Aborted")}async function v(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function l(o,t){let{width:e,height:r}=await v(o);return {dataUrl:o,mime:t,width:e,height:r}}function U(o){return {async captureElement(t,e){if(!chunkE3YSP5LQ_cjs.a())throw new Error("captureElement can only run in the browser");s(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return s(e.signal),await l(n,e.mime)},async captureFullPage(t){if(!chunkE3YSP5LQ_cjs.a())throw new Error("captureFullPage can only run in the browser");s(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),i=Math.min(1,t.maxDimension/Math.max(r,n)),c={width:Math.max(1,Math.round(r*i)),height:Math.max(1,Math.round(n*i)),scale:t.pixelRatio},a=t.mime==="image/jpeg"?await o.domToJpeg(e,{...c,quality:t.quality??.92}):await o.domToPng(e,c);return s(t.signal),await l(a,t.mime)}}}function O(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(e),c=new Uint8Array(i.length);for(let a=0;a<i.length;a+=1)c[a]=i.charCodeAt(a);return new Blob([c],{type:n})}Object.defineProperty(exports,"clearClickEvents",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.j}});Object.defineProperty(exports,"clearDiagnostics",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.z}});Object.defineProperty(exports,"clearQueue",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.g}});Object.defineProperty(exports,"clearSecurityFindings",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.C}});Object.defineProperty(exports,"collectMetadata",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.d}});Object.defineProperty(exports,"createBlocFeedController",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.u}});Object.defineProperty(exports,"createHtmlToImageAdapter",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.b}});Object.defineProperty(exports,"dequeueAll",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.f}});Object.defineProperty(exports,"drainClickEvents",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.i}});Object.defineProperty(exports,"drainDiagnostics",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.y}});Object.defineProperty(exports,"enqueue",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.e}});Object.defineProperty(exports,"getMyFeedbackUrl",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.p}});Object.defineProperty(exports,"getQueueSize",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.h}});Object.defineProperty(exports,"getSecurityFindings",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.B}});Object.defineProperty(exports,"getViewerToken",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.o}});Object.defineProperty(exports,"installDiagnostics",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.w}});Object.defineProperty(exports,"isRecordingSupported",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.k}});Object.defineProperty(exports,"isVoiceSupported",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.m}});Object.defineProperty(exports,"runCapture",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.c}});Object.defineProperty(exports,"runSecretScan",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.A}});Object.defineProperty(exports,"startRecording",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.l}});Object.defineProperty(exports,"startVoiceRecording",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.n}});Object.defineProperty(exports,"transcribeAudio",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.q}});Object.defineProperty(exports,"uninstallDiagnostics",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.x}});exports.createModernScreenshotAdapter=U;exports.dataUrlToBlob=O;
package/dist/engine.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { r as ScreenshotAdapter, C as CaptureConfig, k as CaptureResult, V as VideoAsset, R as RecordingConfig, L as ClickEvent, K as VoiceConfig, o as MetadataConfig, p as MetadataContext, i as BlocFeedUser, n as FeedbackPayload, x as SecuritySnapshot, v as SecurityConfig } from './controller-C5mxpGk4.cjs';
2
- export { B as BlocFeedConfig, c as BlocFeedController, g as BlocFeedError, a as BlocFeedHandle, b as BlocFeedState, h as BlocFeedStrings, l as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, m as FeedbackApiResponse, F as FeedbackCategory, O as HoverListener, I as ImageAsset, N as NetworkEntry, q as Rect, s as ScreenshotAdapterOptions, t as ScreenshotIntent, u as ScreenshotMime, w as SecurityFinding, y as SessionPhase, Q as StateListener, S as SubmitResult, T as ThemeConfig, z as TransportConfig, G as TriggerStyle, H as VideoIntent, J as VideoMime, W as WidgetPosition, U as createBlocFeedController } from './controller-C5mxpGk4.cjs';
1
+ import { S as ScreenshotAdapter, C as CaptureConfig, a as CaptureResult, V as VideoAsset, R as RecordingConfig, b as ClickEvent, c as VoiceConfig, M as MetadataConfig, d as MetadataContext, B as BlocFeedUser, F as FeedbackPayload, e as SecuritySnapshot, f as SecurityConfig } from './controller-BPGXlZKD.cjs';
2
+ export { g as BlocFeedConfig, h as BlocFeedController, i as BlocFeedError, j as BlocFeedHandle, k as BlocFeedState, l as BlocFeedStrings, m as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, n as FeedbackApiResponse, o as FeedbackCategory, H as HoverListener, I as ImageAsset, N as NetworkEntry, p as Rect, q as ScreenshotAdapterOptions, r as ScreenshotIntent, s as ScreenshotMime, t as SecurityFinding, u as SessionPhase, v as StateListener, w as SubmitResult, T as ThemeConfig, x as TransportConfig, y as TriggerStyle, z as VideoIntent, A as VideoMime, W as WidgetPosition, G as createBlocFeedController } from './controller-BPGXlZKD.cjs';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
package/dist/engine.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { r as ScreenshotAdapter, C as CaptureConfig, k as CaptureResult, V as VideoAsset, R as RecordingConfig, L as ClickEvent, K as VoiceConfig, o as MetadataConfig, p as MetadataContext, i as BlocFeedUser, n as FeedbackPayload, x as SecuritySnapshot, v as SecurityConfig } from './controller-C5mxpGk4.js';
2
- export { B as BlocFeedConfig, c as BlocFeedController, g as BlocFeedError, a as BlocFeedHandle, b as BlocFeedState, h as BlocFeedStrings, l as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, m as FeedbackApiResponse, F as FeedbackCategory, O as HoverListener, I as ImageAsset, N as NetworkEntry, q as Rect, s as ScreenshotAdapterOptions, t as ScreenshotIntent, u as ScreenshotMime, w as SecurityFinding, y as SessionPhase, Q as StateListener, S as SubmitResult, T as ThemeConfig, z as TransportConfig, G as TriggerStyle, H as VideoIntent, J as VideoMime, W as WidgetPosition, U as createBlocFeedController } from './controller-C5mxpGk4.js';
1
+ import { S as ScreenshotAdapter, C as CaptureConfig, a as CaptureResult, V as VideoAsset, R as RecordingConfig, b as ClickEvent, c as VoiceConfig, M as MetadataConfig, d as MetadataContext, B as BlocFeedUser, F as FeedbackPayload, e as SecuritySnapshot, f as SecurityConfig } from './controller-BPGXlZKD.js';
2
+ export { g as BlocFeedConfig, h as BlocFeedController, i as BlocFeedError, j as BlocFeedHandle, k as BlocFeedState, l as BlocFeedStrings, m as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, n as FeedbackApiResponse, o as FeedbackCategory, H as HoverListener, I as ImageAsset, N as NetworkEntry, p as Rect, q as ScreenshotAdapterOptions, r as ScreenshotIntent, s as ScreenshotMime, t as SecurityFinding, u as SessionPhase, v as StateListener, w as SubmitResult, T as ThemeConfig, x as TransportConfig, y as TriggerStyle, z as VideoIntent, A as VideoMime, W as WidgetPosition, G as createBlocFeedController } from './controller-BPGXlZKD.js';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
package/dist/engine.js CHANGED
@@ -1 +1 @@
1
- import {a}from'./chunk-XVMFV46F.js';export{j as clearClickEvents,y as clearDiagnostics,g as clearQueue,B as clearSecurityFindings,d as collectMetadata,t as createBlocFeedController,b as createHtmlToImageAdapter,f as dequeueAll,i as drainClickEvents,x as drainDiagnostics,e as enqueue,p as getMyFeedbackUrl,h as getQueueSize,A as getSecurityFindings,o as getViewerToken,v as installDiagnostics,k as isRecordingSupported,m as isVoiceSupported,c as runCapture,z as runSecretScan,l as startRecording,n as startVoiceRecording,q as transcribeAudio,w as uninstallDiagnostics}from'./chunk-XVMFV46F.js';function s(o){if(o?.aborted)throw new Error("Aborted")}async function v(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function l(o,t){let{width:e,height:r}=await v(o);return {dataUrl:o,mime:t,width:e,height:r}}function U(o){return {async captureElement(t,e){if(!a())throw new Error("captureElement can only run in the browser");s(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return s(e.signal),await l(n,e.mime)},async captureFullPage(t){if(!a())throw new Error("captureFullPage can only run in the browser");s(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),i=Math.min(1,t.maxDimension/Math.max(r,n)),c={width:Math.max(1,Math.round(r*i)),height:Math.max(1,Math.round(n*i)),scale:t.pixelRatio},a$1=t.mime==="image/jpeg"?await o.domToJpeg(e,{...c,quality:t.quality??.92}):await o.domToPng(e,c);return s(t.signal),await l(a$1,t.mime)}}}function O(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(e),c=new Uint8Array(i.length);for(let a=0;a<i.length;a+=1)c[a]=i.charCodeAt(a);return new Blob([c],{type:n})}export{U as createModernScreenshotAdapter,O as dataUrlToBlob};
1
+ import {a}from'./chunk-GJW5E4AF.js';export{j as clearClickEvents,z as clearDiagnostics,g as clearQueue,C as clearSecurityFindings,d as collectMetadata,u as createBlocFeedController,b as createHtmlToImageAdapter,f as dequeueAll,i as drainClickEvents,y as drainDiagnostics,e as enqueue,p as getMyFeedbackUrl,h as getQueueSize,B as getSecurityFindings,o as getViewerToken,w as installDiagnostics,k as isRecordingSupported,m as isVoiceSupported,c as runCapture,A as runSecretScan,l as startRecording,n as startVoiceRecording,q as transcribeAudio,x as uninstallDiagnostics}from'./chunk-GJW5E4AF.js';function s(o){if(o?.aborted)throw new Error("Aborted")}async function v(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function l(o,t){let{width:e,height:r}=await v(o);return {dataUrl:o,mime:t,width:e,height:r}}function U(o){return {async captureElement(t,e){if(!a())throw new Error("captureElement can only run in the browser");s(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return s(e.signal),await l(n,e.mime)},async captureFullPage(t){if(!a())throw new Error("captureFullPage can only run in the browser");s(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),i=Math.min(1,t.maxDimension/Math.max(r,n)),c={width:Math.max(1,Math.round(r*i)),height:Math.max(1,Math.round(n*i)),scale:t.pixelRatio},a$1=t.mime==="image/jpeg"?await o.domToJpeg(e,{...c,quality:t.quality??.92}):await o.domToPng(e,c);return s(t.signal),await l(a$1,t.mime)}}}function O(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(e),c=new Uint8Array(i.length);for(let a=0;a<i.length;a+=1)c[a]=i.charCodeAt(a);return new Blob([c],{type:n})}export{U as createModernScreenshotAdapter,O as dataUrlToBlob};
package/dist/main.cjs CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- 'use strict';var chunkZQDABCPT_cjs=require('./chunk-ZQDABCPT.cjs');Object.defineProperty(exports,"BehavioralTracker",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.s}});Object.defineProperty(exports,"BlocFeed",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.F}});Object.defineProperty(exports,"BlocFeedProvider",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.u}});Object.defineProperty(exports,"BlocFeedWidget",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.D}});Object.defineProperty(exports,"SDK_VERSION",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.E}});Object.defineProperty(exports,"track",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.r}});Object.defineProperty(exports,"useBlocFeed",{enumerable:true,get:function(){return chunkZQDABCPT_cjs.C}});
2
+ 'use strict';var chunkE3YSP5LQ_cjs=require('./chunk-E3YSP5LQ.cjs');Object.defineProperty(exports,"BehavioralTracker",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.t}});Object.defineProperty(exports,"BlocFeed",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.G}});Object.defineProperty(exports,"BlocFeedProvider",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.v}});Object.defineProperty(exports,"BlocFeedWidget",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.E}});Object.defineProperty(exports,"SDK_VERSION",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.F}});Object.defineProperty(exports,"track",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.s}});Object.defineProperty(exports,"useBlocFeed",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.D}});
package/dist/main.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BlocFeedConfig, a as BlocFeedHandle, b as BlocFeedState, c as BlocFeedController, C as CaptureConfig, F as FeedbackCategory, S as SubmitResult, d as BehavioralEvent, e as BehavioralConfig } from './controller-C5mxpGk4.cjs';
2
- export { f as BehavioralEventType, g as BlocFeedError, h as BlocFeedStrings, i as BlocFeedUser, j as CaptureDiagnostics, k as CaptureResult, l as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, m as FeedbackApiResponse, n as FeedbackPayload, I as ImageAsset, M as MaybePromise, o as MetadataConfig, p as MetadataContext, N as NetworkEntry, P as PickerConfig, R as RecordingConfig, q as Rect, r as ScreenshotAdapter, s as ScreenshotAdapterOptions, t as ScreenshotIntent, u as ScreenshotMime, v as SecurityConfig, w as SecurityFinding, x as SecuritySnapshot, y as SessionPhase, T as ThemeConfig, z as TransportConfig, A as TransportResult, G as TriggerStyle, V as VideoAsset, H as VideoIntent, J as VideoMime, K as VoiceConfig, W as WidgetPosition } from './controller-C5mxpGk4.cjs';
1
+ import { g as BlocFeedConfig, j as BlocFeedHandle, k as BlocFeedState, h as BlocFeedController, C as CaptureConfig, o as FeedbackCategory, w as SubmitResult, K as BehavioralEvent, J as BehavioralConfig } from './controller-BPGXlZKD.cjs';
2
+ export { L as BehavioralEventType, i as BlocFeedError, l as BlocFeedStrings, B as BlocFeedUser, O as CaptureDiagnostics, a as CaptureResult, m as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, n as FeedbackApiResponse, F as FeedbackPayload, I as ImageAsset, P as MaybePromise, M as MetadataConfig, d as MetadataContext, N as NetworkEntry, Q as PickerConfig, R as RecordingConfig, p as Rect, S as ScreenshotAdapter, q as ScreenshotAdapterOptions, r as ScreenshotIntent, s as ScreenshotMime, f as SecurityConfig, t as SecurityFinding, e as SecuritySnapshot, u as SessionPhase, T as ThemeConfig, x as TransportConfig, U as TransportResult, y as TriggerStyle, V as VideoAsset, z as VideoIntent, A as VideoMime, c as VoiceConfig, W as WidgetPosition } from './controller-BPGXlZKD.cjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
@@ -72,6 +72,13 @@ interface TrackerOpts {
72
72
  config?: BehavioralConfig;
73
73
  submitter?: Submitter;
74
74
  passiveSampler?: () => boolean;
75
+ /**
76
+ * Extra strings appended to the heartbeat `sdk_features` array. Used by
77
+ * non-React entry points (e.g. the IIFE script-tag bundle) to mark the
78
+ * install method on the dashboard side. Purely additive — does not alter
79
+ * detector or replay behaviour.
80
+ */
81
+ extraSdkFeatures?: string[];
75
82
  }
76
83
  declare class BehavioralTracker {
77
84
  private readonly opts;
@@ -103,7 +110,7 @@ declare function track(name: string, properties?: TrackProperties, options?: Tra
103
110
  * Pinned at publish time. Sent with the heartbeat so the dashboard can
104
111
  * surface SDK version drift to customers.
105
112
  */
106
- declare const SDK_VERSION = "0.19.0";
113
+ declare const SDK_VERSION = "0.21.0";
107
114
 
108
115
  /**
109
116
  * Non-React entry point. Mirrors the shape of the rest of the SDK exports;
package/dist/main.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BlocFeedConfig, a as BlocFeedHandle, b as BlocFeedState, c as BlocFeedController, C as CaptureConfig, F as FeedbackCategory, S as SubmitResult, d as BehavioralEvent, e as BehavioralConfig } from './controller-C5mxpGk4.js';
2
- export { f as BehavioralEventType, g as BlocFeedError, h as BlocFeedStrings, i as BlocFeedUser, j as CaptureDiagnostics, k as CaptureResult, l as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, m as FeedbackApiResponse, n as FeedbackPayload, I as ImageAsset, M as MaybePromise, o as MetadataConfig, p as MetadataContext, N as NetworkEntry, P as PickerConfig, R as RecordingConfig, q as Rect, r as ScreenshotAdapter, s as ScreenshotAdapterOptions, t as ScreenshotIntent, u as ScreenshotMime, v as SecurityConfig, w as SecurityFinding, x as SecuritySnapshot, y as SessionPhase, T as ThemeConfig, z as TransportConfig, A as TransportResult, G as TriggerStyle, V as VideoAsset, H as VideoIntent, J as VideoMime, K as VoiceConfig, W as WidgetPosition } from './controller-C5mxpGk4.js';
1
+ import { g as BlocFeedConfig, j as BlocFeedHandle, k as BlocFeedState, h as BlocFeedController, C as CaptureConfig, o as FeedbackCategory, w as SubmitResult, K as BehavioralEvent, J as BehavioralConfig } from './controller-BPGXlZKD.js';
2
+ export { L as BehavioralEventType, i as BlocFeedError, l as BlocFeedStrings, B as BlocFeedUser, O as CaptureDiagnostics, a as CaptureResult, m as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, n as FeedbackApiResponse, F as FeedbackPayload, I as ImageAsset, P as MaybePromise, M as MetadataConfig, d as MetadataContext, N as NetworkEntry, Q as PickerConfig, R as RecordingConfig, p as Rect, S as ScreenshotAdapter, q as ScreenshotAdapterOptions, r as ScreenshotIntent, s as ScreenshotMime, f as SecurityConfig, t as SecurityFinding, e as SecuritySnapshot, u as SessionPhase, T as ThemeConfig, x as TransportConfig, U as TransportResult, y as TriggerStyle, V as VideoAsset, z as VideoIntent, A as VideoMime, c as VoiceConfig, W as WidgetPosition } from './controller-BPGXlZKD.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
@@ -72,6 +72,13 @@ interface TrackerOpts {
72
72
  config?: BehavioralConfig;
73
73
  submitter?: Submitter;
74
74
  passiveSampler?: () => boolean;
75
+ /**
76
+ * Extra strings appended to the heartbeat `sdk_features` array. Used by
77
+ * non-React entry points (e.g. the IIFE script-tag bundle) to mark the
78
+ * install method on the dashboard side. Purely additive — does not alter
79
+ * detector or replay behaviour.
80
+ */
81
+ extraSdkFeatures?: string[];
75
82
  }
76
83
  declare class BehavioralTracker {
77
84
  private readonly opts;
@@ -103,7 +110,7 @@ declare function track(name: string, properties?: TrackProperties, options?: Tra
103
110
  * Pinned at publish time. Sent with the heartbeat so the dashboard can
104
111
  * surface SDK version drift to customers.
105
112
  */
106
- declare const SDK_VERSION = "0.19.0";
113
+ declare const SDK_VERSION = "0.21.0";
107
114
 
108
115
  /**
109
116
  * Non-React entry point. Mirrors the shape of the rest of the SDK exports;
package/dist/main.js CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- export{s as BehavioralTracker,F as BlocFeed,u as BlocFeedProvider,D as BlocFeedWidget,E as SDK_VERSION,r as track,C as useBlocFeed}from'./chunk-XVMFV46F.js';
2
+ export{t as BehavioralTracker,G as BlocFeed,v as BlocFeedProvider,E as BlocFeedWidget,F as SDK_VERSION,s as track,D as useBlocFeed}from'./chunk-GJW5E4AF.js';
@@ -0,0 +1 @@
1
+ 'use strict';var chunkE3YSP5LQ_cjs=require('./chunk-E3YSP5LQ.cjs'),react=require('react');function a(e){e.user?.id&&chunkE3YSP5LQ_cjs.r(e.user.id);let i=new chunkE3YSP5LQ_cjs.t({blocfeedId:e.blocfeed_id,...e.config!==void 0?{config:e.config}:{},...e.extraSdkFeatures!==void 0?{extraSdkFeatures:e.extraSdkFeatures}:{}});return i.install(),i}function u(e){return react.useEffect(()=>{let i=a({blocfeed_id:e.blocfeed_id,...e.user!==void 0?{user:e.user}:{},...e.config!==void 0?{config:e.config}:{}});return ()=>{i.uninstall();}},[e.blocfeed_id]),null}var r=null,g={init(e){r||(r=a(e));},identify(e,i){chunkE3YSP5LQ_cjs.r(e);},track(e,i){chunkE3YSP5LQ_cjs.s(e,i);},uninstall(){r&&(r.uninstall(),r=null);}};function v(){return r}function k(){r&&(r.uninstall(),r=null);}Object.defineProperty(exports,"SDK_VERSION",{enumerable:true,get:function(){return chunkE3YSP5LQ_cjs.F}});exports.BlocFeed=g;exports.BlocFeedPassive=u;exports.__getStandaloneTrackerForTesting=v;exports.__resetStandaloneTrackerForTesting=k;
@@ -0,0 +1,62 @@
1
+ import { TrackProperties, BehavioralTracker } from './main.cjs';
2
+ export { SDK_VERSION } from './main.cjs';
3
+ import { B as BlocFeedUser, J as BehavioralConfig } from './controller-BPGXlZKD.cjs';
4
+ export { K as BehavioralEvent } from './controller-BPGXlZKD.cjs';
5
+ import 'react/jsx-runtime';
6
+ import 'react';
7
+
8
+ /**
9
+ * blocfeed/passive — tracking-only entry point.
10
+ *
11
+ * Skips the entire React feedback panel (`BlocFeedWidget`, framer-motion,
12
+ * triggers, picker UI). Use this when you only want session replay +
13
+ * behavioral signals + custom events.
14
+ *
15
+ * Two ways to install:
16
+ *
17
+ * 1. React: <BlocFeedPassive blocfeed_id="bf_xxx" /> — returns null,
18
+ * installs a `BehavioralTracker` on mount, uninstalls on unmount.
19
+ *
20
+ * 2. Vanilla: BlocFeed.init({ blocfeed_id, user, config }) — same tracker
21
+ * with no React dependency. Singleton; calling init() twice is a no-op.
22
+ *
23
+ * IMPORTANT: this file deliberately does NOT import from react/BlocFeedWidget
24
+ * or react/triggers — that would defeat tree-shaking for customers who only
25
+ * import `blocfeed/passive`.
26
+ */
27
+
28
+ interface BlocFeedPassiveProps {
29
+ blocfeed_id: string;
30
+ user?: BlocFeedUser;
31
+ config?: BehavioralConfig;
32
+ }
33
+ declare function BlocFeedPassive(props: BlocFeedPassiveProps): null;
34
+ interface BlocFeedInitOpts {
35
+ blocfeed_id: string;
36
+ user?: BlocFeedUser;
37
+ config?: BehavioralConfig;
38
+ /** @internal */
39
+ extraSdkFeatures?: string[];
40
+ }
41
+ declare const BlocFeed: {
42
+ /**
43
+ * Install the tracker. Idempotent — subsequent calls are a no-op until
44
+ * `uninstall()` runs.
45
+ */
46
+ init(opts: BlocFeedInitOpts): void;
47
+ /**
48
+ * Attach a `user_id` to subsequent `track()` calls. Pass `undefined` to
49
+ * clear. `traits` is reserved for future use; currently ignored.
50
+ */
51
+ identify(userId: string, _traits?: Record<string, unknown>): void;
52
+ /** Send a custom event. See `track()` for validation rules. */
53
+ track(name: string, properties?: TrackProperties): void;
54
+ /** Tear down the standalone tracker. Safe to call when not installed. */
55
+ uninstall(): void;
56
+ };
57
+ /** @internal */
58
+ declare function __getStandaloneTrackerForTesting(): BehavioralTracker | null;
59
+ /** @internal */
60
+ declare function __resetStandaloneTrackerForTesting(): void;
61
+
62
+ export { BehavioralConfig, BlocFeed, type BlocFeedInitOpts, BlocFeedPassive, type BlocFeedPassiveProps, __getStandaloneTrackerForTesting, __resetStandaloneTrackerForTesting };
@@ -0,0 +1,62 @@
1
+ import { TrackProperties, BehavioralTracker } from './main.js';
2
+ export { SDK_VERSION } from './main.js';
3
+ import { B as BlocFeedUser, J as BehavioralConfig } from './controller-BPGXlZKD.js';
4
+ export { K as BehavioralEvent } from './controller-BPGXlZKD.js';
5
+ import 'react/jsx-runtime';
6
+ import 'react';
7
+
8
+ /**
9
+ * blocfeed/passive — tracking-only entry point.
10
+ *
11
+ * Skips the entire React feedback panel (`BlocFeedWidget`, framer-motion,
12
+ * triggers, picker UI). Use this when you only want session replay +
13
+ * behavioral signals + custom events.
14
+ *
15
+ * Two ways to install:
16
+ *
17
+ * 1. React: <BlocFeedPassive blocfeed_id="bf_xxx" /> — returns null,
18
+ * installs a `BehavioralTracker` on mount, uninstalls on unmount.
19
+ *
20
+ * 2. Vanilla: BlocFeed.init({ blocfeed_id, user, config }) — same tracker
21
+ * with no React dependency. Singleton; calling init() twice is a no-op.
22
+ *
23
+ * IMPORTANT: this file deliberately does NOT import from react/BlocFeedWidget
24
+ * or react/triggers — that would defeat tree-shaking for customers who only
25
+ * import `blocfeed/passive`.
26
+ */
27
+
28
+ interface BlocFeedPassiveProps {
29
+ blocfeed_id: string;
30
+ user?: BlocFeedUser;
31
+ config?: BehavioralConfig;
32
+ }
33
+ declare function BlocFeedPassive(props: BlocFeedPassiveProps): null;
34
+ interface BlocFeedInitOpts {
35
+ blocfeed_id: string;
36
+ user?: BlocFeedUser;
37
+ config?: BehavioralConfig;
38
+ /** @internal */
39
+ extraSdkFeatures?: string[];
40
+ }
41
+ declare const BlocFeed: {
42
+ /**
43
+ * Install the tracker. Idempotent — subsequent calls are a no-op until
44
+ * `uninstall()` runs.
45
+ */
46
+ init(opts: BlocFeedInitOpts): void;
47
+ /**
48
+ * Attach a `user_id` to subsequent `track()` calls. Pass `undefined` to
49
+ * clear. `traits` is reserved for future use; currently ignored.
50
+ */
51
+ identify(userId: string, _traits?: Record<string, unknown>): void;
52
+ /** Send a custom event. See `track()` for validation rules. */
53
+ track(name: string, properties?: TrackProperties): void;
54
+ /** Tear down the standalone tracker. Safe to call when not installed. */
55
+ uninstall(): void;
56
+ };
57
+ /** @internal */
58
+ declare function __getStandaloneTrackerForTesting(): BehavioralTracker | null;
59
+ /** @internal */
60
+ declare function __resetStandaloneTrackerForTesting(): void;
61
+
62
+ export { BehavioralConfig, BlocFeed, type BlocFeedInitOpts, BlocFeedPassive, type BlocFeedPassiveProps, __getStandaloneTrackerForTesting, __resetStandaloneTrackerForTesting };
@@ -0,0 +1 @@
1
+ import {s,r as r$1,t}from'./chunk-GJW5E4AF.js';export{F as SDK_VERSION}from'./chunk-GJW5E4AF.js';import {useEffect}from'react';function a(e){e.user?.id&&r$1(e.user.id);let i=new t({blocfeedId:e.blocfeed_id,...e.config!==void 0?{config:e.config}:{},...e.extraSdkFeatures!==void 0?{extraSdkFeatures:e.extraSdkFeatures}:{}});return i.install(),i}function u(e){return useEffect(()=>{let i=a({blocfeed_id:e.blocfeed_id,...e.user!==void 0?{user:e.user}:{},...e.config!==void 0?{config:e.config}:{}});return ()=>{i.uninstall();}},[e.blocfeed_id]),null}var r=null,g={init(e){r||(r=a(e));},identify(e,i){r$1(e);},track(e,i){s(e,i);},uninstall(){r&&(r.uninstall(),r=null);}};function v(){return r}function k(){r&&(r.uninstall(),r=null);}export{g as BlocFeed,u as BlocFeedPassive,v as __getStandaloneTrackerForTesting,k as __resetStandaloneTrackerForTesting};