@bluewhaleops/browser 1.0.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.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var f=Object.defineProperty,b=Object.defineProperties,E=Object.getOwnPropertyDescriptor,B=Object.getOwnPropertyDescriptors,k=Object.getOwnPropertyNames,v=Object.getOwnPropertySymbols;var y=Object.prototype.hasOwnProperty,S=Object.prototype.propertyIsEnumerable;var w=(r,e,t)=>e in r?f(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,u=(r,e)=>{for(var t in e||(e={}))y.call(e,t)&&w(r,t,e[t]);if(v)for(var t of v(e))S.call(e,t)&&w(r,t,e[t]);return r},h=(r,e)=>b(r,B(e));var x=(r,e)=>{for(var t in e)f(r,t,{get:e[t],enumerable:!0})},q=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of k(e))!y.call(r,i)&&i!==t&&f(r,i,{get:()=>e[i],enumerable:!(n=E(e,i))||n.enumerable});return r};var C=r=>q(f({},"__esModule",{value:!0}),r);var U={};x(U,{BlueWhaleClient:()=>d,addBreadcrumb:()=>P,captureError:()=>_,init:()=>W,setUser:()=>R});module.exports=C(U);var l=class{constructor(e=50){this.buffer=[];this.max=e}add(e){this.buffer.push(e),this.buffer.length>this.max&&this.buffer.shift()}flush(){return[...this.buffer]}instrument(){if(typeof window=="undefined")return;let e=history.pushState.bind(history);history.pushState=(...n)=>{var i;return this.add({type:"navigation",message:`\u2192 ${(i=n[2])!=null?i:""}`,timestamp:Date.now()}),e(...n)},["log","warn","error","info"].forEach(n=>{let i=console[n].bind(console);console[n]=(...o)=>{let a=n==="log"?"info":n;this.add({type:"console",category:n,message:o.map(String).join(" ").slice(0,300),level:a,timestamp:Date.now()}),i(...o)}});let t=window.fetch.bind(window);window.fetch=async(n,i)=>{var g;let o=typeof n=="string"?n:n instanceof URL?n.href:n.url,a=(g=i==null?void 0:i.method)!=null?g:"GET",m=Date.now();try{let c=await t(n,i);return this.add({type:"fetch",category:"http",message:`${a} ${o}`,level:c.ok?"info":"warn",timestamp:m,data:{status:c.status,duration_ms:Date.now()-m}}),c}catch(c){throw this.add({type:"fetch",category:"http",message:`${a} ${o} failed`,level:"error",timestamp:m,data:{error:String(c)}}),c}},document.addEventListener("click",n=>{var a;let i=n.target;if(!i)return;let o=i.getAttribute("aria-label")||((a=i.innerText)==null?void 0:a.slice(0,60))||i.tagName;this.add({type:"click",message:o,timestamp:Date.now()})},{passive:!0,capture:!0})}};var D="1.0.0",p=class{constructor(e,t){this.queue=[];this.flushing=!1;this.endpoint=e,this.apiKey=t}enqueue(e){this.queue.length>=20&&this.queue.shift(),this.queue.push(h(u({},e),{sdk_version:D})),this.flush()}async flush(){if(this.flushing||this.queue.length===0)return;this.flushing=!0;let e=this.queue.shift();try{await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(e),keepalive:!0})}catch(t){}finally{this.flushing=!1,this.queue.length>0&&this.flush()}}};var T="https://bluewhaleops.com/api/ingest/error",d=class{constructor(e){this.initialized=!1;this.config=u({endpoint:T,environment:"production",release:"",maxBreadcrumbs:50,silent:!1,ventureId:""},e),this.crumbs=new l(this.config.maxBreadcrumbs),this.transport=new p(this.config.endpoint,this.config.apiKey)}init(){this.initialized||typeof window=="undefined"||(this.initialized=!0,this.crumbs.instrument(),window.addEventListener("error",e=>{var t,n,i;this.capture({error_type:(n=(t=e.error)==null?void 0:t.name)!=null?n:"Error",message:e.message||"Unknown error",stack:(i=e.error)==null?void 0:i.stack,url:window.location.href,source:"browser"})}),window.addEventListener("unhandledrejection",e=>{var n,i;let t=e.reason;this.capture({error_type:(n=t==null?void 0:t.name)!=null?n:"UnhandledRejection",message:(i=t==null?void 0:t.message)!=null?i:String(t),stack:t==null?void 0:t.stack,url:window.location.href,source:"browser"})}))}capture(e){let t=h(u({error_type:"Error"},e),{user_agent:typeof navigator!="undefined"?navigator.userAgent:void 0,environment:this.config.environment,release:this.config.release||void 0,venture_id:this.config.ventureId||void 0,breadcrumbs:this.crumbs.flush()});if(this.config.beforeSend){let n=this.config.beforeSend(t);if(n===!1)return;t=n}this.transport.enqueue(t)}setUser(e){this._userId=e}addBreadcrumb(e,t){this.crumbs.add({type:"custom",message:e,timestamp:Date.now(),data:t})}};var s=null;function W(r){s=new d(r),s.init()}function _(r,e){if(!s)return;let t=r instanceof Error?r:new Error(String(r));s.capture(u({error_type:t.name,message:t.message,stack:t.stack,source:"browser"},e))}function P(r,e){s==null||s.addBreadcrumb(r,e)}function R(r){s==null||s.setUser(r)}0&&(module.exports={BlueWhaleClient,addBreadcrumb,captureError,init,setUser});
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/breadcrumbs.ts","../src/transport.ts","../src/core.ts"],"sourcesContent":["import { BlueWhaleClient } from './core';\nimport type { BlueWhaleConfig, ErrorEvent, Breadcrumb } from './types';\n\nexport type { BlueWhaleConfig, ErrorEvent, Breadcrumb };\n\nlet _client: BlueWhaleClient | null = null;\n\n/**\n * Initialize BLUEWHALE error capture.\n * Call once — typically in your app's entry point or _app.tsx.\n *\n * @example\n * import { init } from '@bluewhaleops/browser';\n * init({ apiKey: 'bw_agent_xxx', ventureId: 'your-venture-uuid' });\n */\nexport function init(config: BlueWhaleConfig): void {\n _client = new BlueWhaleClient(config);\n _client.init();\n}\n\n/**\n * Manually capture an error or exception.\n */\nexport function captureError(err: unknown, extra?: Partial<ErrorEvent>): void {\n if (!_client) return;\n const e = err instanceof Error ? err : new Error(String(err));\n _client.capture({\n error_type: e.name,\n message: e.message,\n stack: e.stack,\n source: 'browser',\n ...extra,\n });\n}\n\n/**\n * Add a manual breadcrumb.\n */\nexport function addBreadcrumb(message: string, data?: Record<string, unknown>): void {\n _client?.addBreadcrumb(message, data);\n}\n\n/**\n * Tag the current user for error reports.\n */\nexport function setUser(userId: string): void {\n _client?.setUser(userId);\n}\n\nexport { BlueWhaleClient };\n","import type { Breadcrumb } from './types';\n\nexport class BreadcrumbBuffer {\n private buffer: Breadcrumb[] = [];\n private max: number;\n\n constructor(max = 50) {\n this.max = max;\n }\n\n add(crumb: Breadcrumb): void {\n this.buffer.push(crumb);\n if (this.buffer.length > this.max) this.buffer.shift();\n }\n\n flush(): Breadcrumb[] {\n return [...this.buffer];\n }\n\n instrument(): void {\n if (typeof window === 'undefined') return;\n\n // Navigation breadcrumbs\n const origPushState = history.pushState.bind(history);\n history.pushState = (...args) => {\n this.add({ type: 'navigation', message: `→ ${args[2] ?? ''}`, timestamp: Date.now() });\n return origPushState(...args);\n };\n\n // Console breadcrumbs\n (['log', 'warn', 'error', 'info'] as const).forEach((method) => {\n const orig = console[method].bind(console);\n console[method] = (...args: unknown[]) => {\n const level = method === 'log' ? 'info' : method as 'warn' | 'error' | 'info';\n this.add({\n type: 'console',\n category: method,\n message: args.map(String).join(' ').slice(0, 300),\n level,\n timestamp: Date.now(),\n });\n orig(...args);\n };\n });\n\n // Fetch breadcrumbs\n const origFetch = window.fetch.bind(window);\n window.fetch = async (input, init) => {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;\n const method = init?.method ?? 'GET';\n const start = Date.now();\n try {\n const res = await origFetch(input, init);\n this.add({\n type: 'fetch',\n category: 'http',\n message: `${method} ${url}`,\n level: res.ok ? 'info' : 'warn',\n timestamp: start,\n data: { status: res.status, duration_ms: Date.now() - start },\n });\n return res;\n } catch (err) {\n this.add({\n type: 'fetch',\n category: 'http',\n message: `${method} ${url} failed`,\n level: 'error',\n timestamp: start,\n data: { error: String(err) },\n });\n throw err;\n }\n };\n\n // Click breadcrumbs (top-level only, lightweight)\n document.addEventListener('click', (e) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const label = target.getAttribute('aria-label') || target.innerText?.slice(0, 60) || target.tagName;\n this.add({ type: 'click', message: label, timestamp: Date.now() });\n }, { passive: true, capture: true });\n }\n}\n","import type { ErrorEvent } from './types';\n\nconst SDK_VERSION = '1.0.0';\n\nexport class Transport {\n private endpoint: string;\n private apiKey: string;\n private queue: ErrorEvent[] = [];\n private flushing = false;\n\n constructor(endpoint: string, apiKey: string) {\n this.endpoint = endpoint;\n this.apiKey = apiKey;\n }\n\n enqueue(event: ErrorEvent): void {\n // Cap queue at 20 to avoid memory bloat\n if (this.queue.length >= 20) this.queue.shift();\n this.queue.push({ ...event, sdk_version: SDK_VERSION });\n this.flush();\n }\n\n private async flush(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n const event = this.queue.shift()!;\n try {\n await fetch(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(event),\n keepalive: true, // survives page unload\n });\n } catch {\n // Silent fail — don't error-loop\n } finally {\n this.flushing = false;\n if (this.queue.length > 0) this.flush();\n }\n }\n}\n","import type { BlueWhaleConfig, ErrorEvent, ErrorSource } from './types';\nimport { BreadcrumbBuffer } from './breadcrumbs';\nimport { Transport } from './transport';\n\nconst DEFAULT_ENDPOINT = 'https://bluewhaleops.com/api/ingest/error';\n\nexport class BlueWhaleClient {\n private config: Required<Omit<BlueWhaleConfig, 'beforeSend'>> & Pick<BlueWhaleConfig, 'beforeSend'>;\n private crumbs: BreadcrumbBuffer;\n private transport: Transport;\n private initialized = false;\n\n constructor(config: BlueWhaleConfig) {\n this.config = {\n endpoint: DEFAULT_ENDPOINT,\n environment: 'production',\n release: '',\n maxBreadcrumbs: 50,\n silent: false,\n ventureId: '',\n ...config,\n };\n this.crumbs = new BreadcrumbBuffer(this.config.maxBreadcrumbs);\n this.transport = new Transport(this.config.endpoint, this.config.apiKey);\n }\n\n init(): void {\n if (this.initialized || typeof window === 'undefined') return;\n this.initialized = true;\n\n this.crumbs.instrument();\n\n // Global JS errors\n window.addEventListener('error', (e) => {\n this.capture({\n error_type: e.error?.name ?? 'Error',\n message: e.message || 'Unknown error',\n stack: e.error?.stack,\n url: window.location.href,\n source: 'browser',\n });\n });\n\n // Unhandled promise rejections\n window.addEventListener('unhandledrejection', (e) => {\n const err = e.reason;\n this.capture({\n error_type: err?.name ?? 'UnhandledRejection',\n message: err?.message ?? String(err),\n stack: err?.stack,\n url: window.location.href,\n source: 'browser',\n });\n });\n }\n\n capture(partial: Partial<ErrorEvent> & { message: string; source: ErrorSource }): void {\n let event: ErrorEvent = {\n error_type: 'Error',\n ...partial,\n user_agent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,\n environment: this.config.environment,\n release: this.config.release || undefined,\n venture_id: this.config.ventureId || undefined,\n breadcrumbs: this.crumbs.flush(),\n };\n\n if (this.config.beforeSend) {\n const result = this.config.beforeSend(event);\n if (result === false) return;\n event = result;\n }\n\n this.transport.enqueue(event);\n }\n\n setUser(userId: string): void {\n // Store for next capture — patch via a tag\n (this as unknown as Record<string, unknown>)._userId = userId;\n }\n\n addBreadcrumb(message: string, data?: Record<string, unknown>): void {\n this.crumbs.add({ type: 'custom', message, timestamp: Date.now(), data });\n }\n}\n"],"mappings":"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","names":["src_exports","__export","BlueWhaleClient","addBreadcrumb","captureError","init","setUser","__toCommonJS","BreadcrumbBuffer","max","crumb","origPushState","args","_a","method","orig","level","origFetch","input","init","url","start","res","err","e","target","label","SDK_VERSION","Transport","endpoint","apiKey","event","__spreadProps","__spreadValues","e","DEFAULT_ENDPOINT","BlueWhaleClient","config","__spreadValues","BreadcrumbBuffer","Transport","_a","_b","_c","err","partial","event","__spreadProps","result","userId","message","data","_client","init","config","BlueWhaleClient","captureError","err","extra","e","__spreadValues","addBreadcrumb","message","data","setUser","userId"]}
@@ -0,0 +1,83 @@
1
+ type BreadcrumbType = 'console' | 'navigation' | 'fetch' | 'click' | 'custom';
2
+ type BreadcrumbLevel = 'info' | 'warn' | 'error' | 'debug';
3
+ type ErrorSource = 'browser' | 'node' | 'edge';
4
+ interface Breadcrumb {
5
+ type: BreadcrumbType;
6
+ category?: string;
7
+ message: string;
8
+ level?: BreadcrumbLevel;
9
+ timestamp: number;
10
+ data?: Record<string, unknown>;
11
+ }
12
+ interface ErrorEvent {
13
+ error_type: string;
14
+ message: string;
15
+ stack?: string;
16
+ url?: string;
17
+ user_agent?: string;
18
+ source: ErrorSource;
19
+ sdk_version?: string;
20
+ environment?: string;
21
+ venture_id?: string;
22
+ breadcrumbs?: Breadcrumb[];
23
+ release?: string;
24
+ user_id?: string;
25
+ tags?: Record<string, string>;
26
+ }
27
+ interface BlueWhaleConfig {
28
+ /** API key from bluewhaleops.com → Admin → API Keys */
29
+ apiKey: string;
30
+ /** Your venture UUID from BLUEWHALE dashboard */
31
+ ventureId?: string;
32
+ /** Ingest endpoint — defaults to https://bluewhaleops.com/api/ingest/error */
33
+ endpoint?: string;
34
+ /** environment tag — defaults to 'production' */
35
+ environment?: string;
36
+ /** release/version tag e.g. '1.2.3' */
37
+ release?: string;
38
+ /** Max breadcrumbs to keep in buffer — defaults to 50 */
39
+ maxBreadcrumbs?: number;
40
+ /** Suppress all console output from the SDK itself */
41
+ silent?: boolean;
42
+ /** Called before sending — return false to drop the event */
43
+ beforeSend?: (event: ErrorEvent) => ErrorEvent | false;
44
+ }
45
+
46
+ declare class BlueWhaleClient {
47
+ private config;
48
+ private crumbs;
49
+ private transport;
50
+ private initialized;
51
+ constructor(config: BlueWhaleConfig);
52
+ init(): void;
53
+ capture(partial: Partial<ErrorEvent> & {
54
+ message: string;
55
+ source: ErrorSource;
56
+ }): void;
57
+ setUser(userId: string): void;
58
+ addBreadcrumb(message: string, data?: Record<string, unknown>): void;
59
+ }
60
+
61
+ /**
62
+ * Initialize BLUEWHALE error capture.
63
+ * Call once — typically in your app's entry point or _app.tsx.
64
+ *
65
+ * @example
66
+ * import { init } from '@bluewhaleops/browser';
67
+ * init({ apiKey: 'bw_agent_xxx', ventureId: 'your-venture-uuid' });
68
+ */
69
+ declare function init(config: BlueWhaleConfig): void;
70
+ /**
71
+ * Manually capture an error or exception.
72
+ */
73
+ declare function captureError(err: unknown, extra?: Partial<ErrorEvent>): void;
74
+ /**
75
+ * Add a manual breadcrumb.
76
+ */
77
+ declare function addBreadcrumb(message: string, data?: Record<string, unknown>): void;
78
+ /**
79
+ * Tag the current user for error reports.
80
+ */
81
+ declare function setUser(userId: string): void;
82
+
83
+ export { BlueWhaleClient, type BlueWhaleConfig, type Breadcrumb, type ErrorEvent, addBreadcrumb, captureError, init, setUser };
@@ -0,0 +1,83 @@
1
+ type BreadcrumbType = 'console' | 'navigation' | 'fetch' | 'click' | 'custom';
2
+ type BreadcrumbLevel = 'info' | 'warn' | 'error' | 'debug';
3
+ type ErrorSource = 'browser' | 'node' | 'edge';
4
+ interface Breadcrumb {
5
+ type: BreadcrumbType;
6
+ category?: string;
7
+ message: string;
8
+ level?: BreadcrumbLevel;
9
+ timestamp: number;
10
+ data?: Record<string, unknown>;
11
+ }
12
+ interface ErrorEvent {
13
+ error_type: string;
14
+ message: string;
15
+ stack?: string;
16
+ url?: string;
17
+ user_agent?: string;
18
+ source: ErrorSource;
19
+ sdk_version?: string;
20
+ environment?: string;
21
+ venture_id?: string;
22
+ breadcrumbs?: Breadcrumb[];
23
+ release?: string;
24
+ user_id?: string;
25
+ tags?: Record<string, string>;
26
+ }
27
+ interface BlueWhaleConfig {
28
+ /** API key from bluewhaleops.com → Admin → API Keys */
29
+ apiKey: string;
30
+ /** Your venture UUID from BLUEWHALE dashboard */
31
+ ventureId?: string;
32
+ /** Ingest endpoint — defaults to https://bluewhaleops.com/api/ingest/error */
33
+ endpoint?: string;
34
+ /** environment tag — defaults to 'production' */
35
+ environment?: string;
36
+ /** release/version tag e.g. '1.2.3' */
37
+ release?: string;
38
+ /** Max breadcrumbs to keep in buffer — defaults to 50 */
39
+ maxBreadcrumbs?: number;
40
+ /** Suppress all console output from the SDK itself */
41
+ silent?: boolean;
42
+ /** Called before sending — return false to drop the event */
43
+ beforeSend?: (event: ErrorEvent) => ErrorEvent | false;
44
+ }
45
+
46
+ declare class BlueWhaleClient {
47
+ private config;
48
+ private crumbs;
49
+ private transport;
50
+ private initialized;
51
+ constructor(config: BlueWhaleConfig);
52
+ init(): void;
53
+ capture(partial: Partial<ErrorEvent> & {
54
+ message: string;
55
+ source: ErrorSource;
56
+ }): void;
57
+ setUser(userId: string): void;
58
+ addBreadcrumb(message: string, data?: Record<string, unknown>): void;
59
+ }
60
+
61
+ /**
62
+ * Initialize BLUEWHALE error capture.
63
+ * Call once — typically in your app's entry point or _app.tsx.
64
+ *
65
+ * @example
66
+ * import { init } from '@bluewhaleops/browser';
67
+ * init({ apiKey: 'bw_agent_xxx', ventureId: 'your-venture-uuid' });
68
+ */
69
+ declare function init(config: BlueWhaleConfig): void;
70
+ /**
71
+ * Manually capture an error or exception.
72
+ */
73
+ declare function captureError(err: unknown, extra?: Partial<ErrorEvent>): void;
74
+ /**
75
+ * Add a manual breadcrumb.
76
+ */
77
+ declare function addBreadcrumb(message: string, data?: Record<string, unknown>): void;
78
+ /**
79
+ * Tag the current user for error reports.
80
+ */
81
+ declare function setUser(userId: string): void;
82
+
83
+ export { BlueWhaleClient, type BlueWhaleConfig, type Breadcrumb, type ErrorEvent, addBreadcrumb, captureError, init, setUser };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ var w=Object.defineProperty,y=Object.defineProperties;var b=Object.getOwnPropertyDescriptors;var g=Object.getOwnPropertySymbols;var E=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var v=(n,e,t)=>e in n?w(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,u=(n,e)=>{for(var t in e||(e={}))E.call(e,t)&&v(n,t,e[t]);if(g)for(var t of g(e))B.call(e,t)&&v(n,t,e[t]);return n},d=(n,e)=>y(n,b(e));var f=class{constructor(e=50){this.buffer=[];this.max=e}add(e){this.buffer.push(e),this.buffer.length>this.max&&this.buffer.shift()}flush(){return[...this.buffer]}instrument(){if(typeof window=="undefined")return;let e=history.pushState.bind(history);history.pushState=(...r)=>{var i;return this.add({type:"navigation",message:`\u2192 ${(i=r[2])!=null?i:""}`,timestamp:Date.now()}),e(...r)},["log","warn","error","info"].forEach(r=>{let i=console[r].bind(console);console[r]=(...o)=>{let a=r==="log"?"info":r;this.add({type:"console",category:r,message:o.map(String).join(" ").slice(0,300),level:a,timestamp:Date.now()}),i(...o)}});let t=window.fetch.bind(window);window.fetch=async(r,i)=>{var m;let o=typeof r=="string"?r:r instanceof URL?r.href:r.url,a=(m=i==null?void 0:i.method)!=null?m:"GET",p=Date.now();try{let c=await t(r,i);return this.add({type:"fetch",category:"http",message:`${a} ${o}`,level:c.ok?"info":"warn",timestamp:p,data:{status:c.status,duration_ms:Date.now()-p}}),c}catch(c){throw this.add({type:"fetch",category:"http",message:`${a} ${o} failed`,level:"error",timestamp:p,data:{error:String(c)}}),c}},document.addEventListener("click",r=>{var a;let i=r.target;if(!i)return;let o=i.getAttribute("aria-label")||((a=i.innerText)==null?void 0:a.slice(0,60))||i.tagName;this.add({type:"click",message:o,timestamp:Date.now()})},{passive:!0,capture:!0})}};var k="1.0.0",h=class{constructor(e,t){this.queue=[];this.flushing=!1;this.endpoint=e,this.apiKey=t}enqueue(e){this.queue.length>=20&&this.queue.shift(),this.queue.push(d(u({},e),{sdk_version:k})),this.flush()}async flush(){if(this.flushing||this.queue.length===0)return;this.flushing=!0;let e=this.queue.shift();try{await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(e),keepalive:!0})}catch(t){}finally{this.flushing=!1,this.queue.length>0&&this.flush()}}};var S="https://bluewhaleops.com/api/ingest/error",l=class{constructor(e){this.initialized=!1;this.config=u({endpoint:S,environment:"production",release:"",maxBreadcrumbs:50,silent:!1,ventureId:""},e),this.crumbs=new f(this.config.maxBreadcrumbs),this.transport=new h(this.config.endpoint,this.config.apiKey)}init(){this.initialized||typeof window=="undefined"||(this.initialized=!0,this.crumbs.instrument(),window.addEventListener("error",e=>{var t,r,i;this.capture({error_type:(r=(t=e.error)==null?void 0:t.name)!=null?r:"Error",message:e.message||"Unknown error",stack:(i=e.error)==null?void 0:i.stack,url:window.location.href,source:"browser"})}),window.addEventListener("unhandledrejection",e=>{var r,i;let t=e.reason;this.capture({error_type:(r=t==null?void 0:t.name)!=null?r:"UnhandledRejection",message:(i=t==null?void 0:t.message)!=null?i:String(t),stack:t==null?void 0:t.stack,url:window.location.href,source:"browser"})}))}capture(e){let t=d(u({error_type:"Error"},e),{user_agent:typeof navigator!="undefined"?navigator.userAgent:void 0,environment:this.config.environment,release:this.config.release||void 0,venture_id:this.config.ventureId||void 0,breadcrumbs:this.crumbs.flush()});if(this.config.beforeSend){let r=this.config.beforeSend(t);if(r===!1)return;t=r}this.transport.enqueue(t)}setUser(e){this._userId=e}addBreadcrumb(e,t){this.crumbs.add({type:"custom",message:e,timestamp:Date.now(),data:t})}};var s=null;function U(n){s=new l(n),s.init()}function L(n,e){if(!s)return;let t=n instanceof Error?n:new Error(String(n));s.capture(u({error_type:t.name,message:t.message,stack:t.stack,source:"browser"},e))}function $(n,e){s==null||s.addBreadcrumb(n,e)}function I(n){s==null||s.setUser(n)}export{l as BlueWhaleClient,$ as addBreadcrumb,L as captureError,U as init,I as setUser};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/breadcrumbs.ts","../src/transport.ts","../src/core.ts","../src/index.ts"],"sourcesContent":["import type { Breadcrumb } from './types';\n\nexport class BreadcrumbBuffer {\n private buffer: Breadcrumb[] = [];\n private max: number;\n\n constructor(max = 50) {\n this.max = max;\n }\n\n add(crumb: Breadcrumb): void {\n this.buffer.push(crumb);\n if (this.buffer.length > this.max) this.buffer.shift();\n }\n\n flush(): Breadcrumb[] {\n return [...this.buffer];\n }\n\n instrument(): void {\n if (typeof window === 'undefined') return;\n\n // Navigation breadcrumbs\n const origPushState = history.pushState.bind(history);\n history.pushState = (...args) => {\n this.add({ type: 'navigation', message: `→ ${args[2] ?? ''}`, timestamp: Date.now() });\n return origPushState(...args);\n };\n\n // Console breadcrumbs\n (['log', 'warn', 'error', 'info'] as const).forEach((method) => {\n const orig = console[method].bind(console);\n console[method] = (...args: unknown[]) => {\n const level = method === 'log' ? 'info' : method as 'warn' | 'error' | 'info';\n this.add({\n type: 'console',\n category: method,\n message: args.map(String).join(' ').slice(0, 300),\n level,\n timestamp: Date.now(),\n });\n orig(...args);\n };\n });\n\n // Fetch breadcrumbs\n const origFetch = window.fetch.bind(window);\n window.fetch = async (input, init) => {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;\n const method = init?.method ?? 'GET';\n const start = Date.now();\n try {\n const res = await origFetch(input, init);\n this.add({\n type: 'fetch',\n category: 'http',\n message: `${method} ${url}`,\n level: res.ok ? 'info' : 'warn',\n timestamp: start,\n data: { status: res.status, duration_ms: Date.now() - start },\n });\n return res;\n } catch (err) {\n this.add({\n type: 'fetch',\n category: 'http',\n message: `${method} ${url} failed`,\n level: 'error',\n timestamp: start,\n data: { error: String(err) },\n });\n throw err;\n }\n };\n\n // Click breadcrumbs (top-level only, lightweight)\n document.addEventListener('click', (e) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const label = target.getAttribute('aria-label') || target.innerText?.slice(0, 60) || target.tagName;\n this.add({ type: 'click', message: label, timestamp: Date.now() });\n }, { passive: true, capture: true });\n }\n}\n","import type { ErrorEvent } from './types';\n\nconst SDK_VERSION = '1.0.0';\n\nexport class Transport {\n private endpoint: string;\n private apiKey: string;\n private queue: ErrorEvent[] = [];\n private flushing = false;\n\n constructor(endpoint: string, apiKey: string) {\n this.endpoint = endpoint;\n this.apiKey = apiKey;\n }\n\n enqueue(event: ErrorEvent): void {\n // Cap queue at 20 to avoid memory bloat\n if (this.queue.length >= 20) this.queue.shift();\n this.queue.push({ ...event, sdk_version: SDK_VERSION });\n this.flush();\n }\n\n private async flush(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n const event = this.queue.shift()!;\n try {\n await fetch(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(event),\n keepalive: true, // survives page unload\n });\n } catch {\n // Silent fail — don't error-loop\n } finally {\n this.flushing = false;\n if (this.queue.length > 0) this.flush();\n }\n }\n}\n","import type { BlueWhaleConfig, ErrorEvent, ErrorSource } from './types';\nimport { BreadcrumbBuffer } from './breadcrumbs';\nimport { Transport } from './transport';\n\nconst DEFAULT_ENDPOINT = 'https://bluewhaleops.com/api/ingest/error';\n\nexport class BlueWhaleClient {\n private config: Required<Omit<BlueWhaleConfig, 'beforeSend'>> & Pick<BlueWhaleConfig, 'beforeSend'>;\n private crumbs: BreadcrumbBuffer;\n private transport: Transport;\n private initialized = false;\n\n constructor(config: BlueWhaleConfig) {\n this.config = {\n endpoint: DEFAULT_ENDPOINT,\n environment: 'production',\n release: '',\n maxBreadcrumbs: 50,\n silent: false,\n ventureId: '',\n ...config,\n };\n this.crumbs = new BreadcrumbBuffer(this.config.maxBreadcrumbs);\n this.transport = new Transport(this.config.endpoint, this.config.apiKey);\n }\n\n init(): void {\n if (this.initialized || typeof window === 'undefined') return;\n this.initialized = true;\n\n this.crumbs.instrument();\n\n // Global JS errors\n window.addEventListener('error', (e) => {\n this.capture({\n error_type: e.error?.name ?? 'Error',\n message: e.message || 'Unknown error',\n stack: e.error?.stack,\n url: window.location.href,\n source: 'browser',\n });\n });\n\n // Unhandled promise rejections\n window.addEventListener('unhandledrejection', (e) => {\n const err = e.reason;\n this.capture({\n error_type: err?.name ?? 'UnhandledRejection',\n message: err?.message ?? String(err),\n stack: err?.stack,\n url: window.location.href,\n source: 'browser',\n });\n });\n }\n\n capture(partial: Partial<ErrorEvent> & { message: string; source: ErrorSource }): void {\n let event: ErrorEvent = {\n error_type: 'Error',\n ...partial,\n user_agent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,\n environment: this.config.environment,\n release: this.config.release || undefined,\n venture_id: this.config.ventureId || undefined,\n breadcrumbs: this.crumbs.flush(),\n };\n\n if (this.config.beforeSend) {\n const result = this.config.beforeSend(event);\n if (result === false) return;\n event = result;\n }\n\n this.transport.enqueue(event);\n }\n\n setUser(userId: string): void {\n // Store for next capture — patch via a tag\n (this as unknown as Record<string, unknown>)._userId = userId;\n }\n\n addBreadcrumb(message: string, data?: Record<string, unknown>): void {\n this.crumbs.add({ type: 'custom', message, timestamp: Date.now(), data });\n }\n}\n","import { BlueWhaleClient } from './core';\nimport type { BlueWhaleConfig, ErrorEvent, Breadcrumb } from './types';\n\nexport type { BlueWhaleConfig, ErrorEvent, Breadcrumb };\n\nlet _client: BlueWhaleClient | null = null;\n\n/**\n * Initialize BLUEWHALE error capture.\n * Call once — typically in your app's entry point or _app.tsx.\n *\n * @example\n * import { init } from '@bluewhaleops/browser';\n * init({ apiKey: 'bw_agent_xxx', ventureId: 'your-venture-uuid' });\n */\nexport function init(config: BlueWhaleConfig): void {\n _client = new BlueWhaleClient(config);\n _client.init();\n}\n\n/**\n * Manually capture an error or exception.\n */\nexport function captureError(err: unknown, extra?: Partial<ErrorEvent>): void {\n if (!_client) return;\n const e = err instanceof Error ? err : new Error(String(err));\n _client.capture({\n error_type: e.name,\n message: e.message,\n stack: e.stack,\n source: 'browser',\n ...extra,\n });\n}\n\n/**\n * Add a manual breadcrumb.\n */\nexport function addBreadcrumb(message: string, data?: Record<string, unknown>): void {\n _client?.addBreadcrumb(message, data);\n}\n\n/**\n * Tag the current user for error reports.\n */\nexport function setUser(userId: string): void {\n _client?.setUser(userId);\n}\n\nexport { BlueWhaleClient };\n"],"mappings":"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","names":["BreadcrumbBuffer","max","crumb","origPushState","args","_a","method","orig","level","origFetch","input","init","url","start","res","err","e","target","label","SDK_VERSION","Transport","endpoint","apiKey","event","__spreadProps","__spreadValues","e","DEFAULT_ENDPOINT","BlueWhaleClient","config","__spreadValues","BreadcrumbBuffer","Transport","_a","_b","_c","err","partial","event","__spreadProps","result","userId","message","data","_client","init","config","BlueWhaleClient","captureError","err","extra","e","__spreadValues","addBreadcrumb","message","data","setUser","userId"]}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@bluewhaleops/browser",
3
+ "version": "1.0.0",
4
+ "description": "BLUEWHALE browser error capture SDK — drop-in Sentry replacement for web apps",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsup",
14
+ "dev": "tsup --watch",
15
+ "type-check": "tsc --noEmit"
16
+ },
17
+ "engines": {
18
+ "node": ">=18.0.0"
19
+ },
20
+ "license": "MIT",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/tavara-holdings/blue-whale.git",
24
+ "directory": "packages/browser-sdk"
25
+ },
26
+ "devDependencies": {
27
+ "tsup": "^8.5.1",
28
+ "typescript": "^5.9.3"
29
+ }
30
+ }