@shopkit/observability 0.1.0 → 0.1.1
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 +8 -1
- package/dist/client/index.d.mts +3 -1
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/head-stub/index.js +1 -1
- package/dist/head-stub/index.mjs +1 -1
- package/dist/server/index.d.mts +9 -1
- package/dist/server/index.d.ts +9 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ initObservability({
|
|
|
19
19
|
|
|
20
20
|
About 4.6 KB gzip up front; `web-vitals` loads after page load. Never throws into the page. Each page view is its own trace; same-origin API calls join it. Next.js link prefetches are marked unsampled, so the server doesn't trace them.
|
|
21
21
|
|
|
22
|
-
Every signal carries `page.type` (from the optional `pageType(path)` callback) and, where the browser knows it, `network.effective_type`. Other options: `ignore.paths` / `ignore.cookies` (non-shopper traffic), `slowFetchMs` (default 2000), `sessionCap` (default 100 per page).
|
|
22
|
+
Every signal carries `page.type` (from the optional `pageType(path)` callback) and, where the browser knows it, `network.effective_type`. Other options: `ignore.paths` / `ignore.cookies` (non-shopper traffic), `slowFetchMs` (default 2000), `sessionCap` (default 100 per page), `apiOrigins` (URLs of your own APIs on other domains, e.g. the commerce backend: their 5xx and slow calls count as yours).
|
|
23
23
|
|
|
24
24
|
Business flows (checkout, add to cart):
|
|
25
25
|
|
|
@@ -82,8 +82,13 @@ registerOTel({
|
|
|
82
82
|
traceSampler: skipPathsSampler(/^\/(api\/obs$|_next\/)/), // never trace these paths
|
|
83
83
|
spanProcessors: [scrubSpanProcessor(), "auto"], // strip query strings, emails, phones
|
|
84
84
|
});
|
|
85
|
+
|
|
86
|
+
// Next's instrumentation hook: an error in a streamed page render is otherwise unrecorded.
|
|
87
|
+
export const onRequestError = (err: unknown) => recordServerError(err);
|
|
85
88
|
```
|
|
86
89
|
|
|
90
|
+
`recordServerError` puts the error in the request's trace with `error.digest`, the same digest the browser's `useReportError` report carries.
|
|
91
|
+
|
|
87
92
|
## Keeping source maps private: `shopkit-move-sourcemaps`
|
|
88
93
|
|
|
89
94
|
```sh
|
|
@@ -93,3 +98,5 @@ shopkit-move-sourcemaps .next/static .next/obs-sourcemaps
|
|
|
93
98
|
```
|
|
94
99
|
|
|
95
100
|
Moves every `*.map` out of the served folder. Fails (exit 1) if it can't, so maps are never shipped publicly.
|
|
101
|
+
|
|
102
|
+
With Sentry, set `sourcemaps: { deleteSourcemapsAfterUpload: false }` in `withSentryConfig`: by default Sentry deletes the maps at the end of the build, before this command runs, and browser stacks stay minified.
|
package/dist/client/index.d.mts
CHANGED
|
@@ -19,8 +19,10 @@ interface ObservabilityConfig {
|
|
|
19
19
|
};
|
|
20
20
|
/** Max spans per page load. */
|
|
21
21
|
sessionCap?: number;
|
|
22
|
-
/** Successful
|
|
22
|
+
/** Successful calls to our own APIs at least this slow are recorded. Default 2000. */
|
|
23
23
|
slowFetchMs?: number;
|
|
24
|
+
/** URLs of our own APIs on other origins (e.g. the commerce backend): their 5xx and slow calls count as ours. */
|
|
25
|
+
apiOrigins?: string[];
|
|
24
26
|
/** Names the kind of page from its path ("product", "collection"), for filtering. */
|
|
25
27
|
pageType?: (path: string) => string | undefined;
|
|
26
28
|
}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -19,8 +19,10 @@ interface ObservabilityConfig {
|
|
|
19
19
|
};
|
|
20
20
|
/** Max spans per page load. */
|
|
21
21
|
sessionCap?: number;
|
|
22
|
-
/** Successful
|
|
22
|
+
/** Successful calls to our own APIs at least this slow are recorded. Default 2000. */
|
|
23
23
|
slowFetchMs?: number;
|
|
24
|
+
/** URLs of our own APIs on other origins (e.g. the commerce backend): their 5xx and slow calls count as ours. */
|
|
25
|
+
apiOrigins?: string[];
|
|
24
26
|
/** Names the kind of page from its path ("product", "collection"), for filtering. */
|
|
25
27
|
pageType?: (path: string) => string | undefined;
|
|
26
28
|
}
|
package/dist/client/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var I={SERVICE_NAME:"service.name",SERVICE_VERSION:"service.version",DEPLOYMENT_ENVIRONMENT:"deployment.environment",APP:"app"},f={JS_ERROR:"browser.js_error",UNHANDLED_REJECTION:"browser.unhandled_rejection",RESOURCE_ERROR:"browser.resource_error",RENDER_ERROR:"browser.render_error",HYDRATION_ERROR:"browser.hydration_error",CHUNK_ERROR:"browser.chunk_error",FETCH:"browser.fetch",WEB_VITAL:"web_vital",RAGE_CLICK:"ui.rage_click",TELEMETRY_DROPPED:"telemetry.dropped",FLOW_PREFIX:"flow."};function R(){return performance.timeOrigin+performance.now()}function v(e){let t=crypto.getRandomValues(new Uint8Array(e)),r="";for(let o of t)r+=o.toString(16).padStart(2,"0");return /^0+$/.test(r)?v(e):r}var _=()=>v(16),y=()=>v(8);var L=1e3,j=8e3;function Y(e){return e instanceof Error?{"exception.type":e.name,"exception.message":e.message.slice(0,L),"exception.stacktrace":e.stack?.slice(0,j)}:{"exception.type":"Error","exception.message":String(e).slice(0,L)}}var X=new RegExp(["Loading (CSS )?chunk \\S+ failed","Failed to fetch dynamically imported module","Importing a module script failed","error loading dynamically imported module"].join("|"),"i");function J(e){return e instanceof Error?e.name==="ChunkLoadError"||X.test(e.message):false}var z=/Minified React error #(418|423|425)\b|Hydration failed|error while hydrating|did not match\. Server/i;function Q(e,t){return J(t)?f.CHUNK_ERROR:t instanceof Error&&z.test(t.message)?f.HYDRATION_ERROR:e}function A(e){function t(o,n,i={}){try{let s=R();e.emit({name:o,traceId:e.traceId,spanId:y(),parentSpanId:e.parentSpanId,startMs:s,endMs:s,...i,attributes:{"page.path":location.pathname,...n}});}catch{}}function r(o,n,i={},s={}){try{let c={name:"exception",timeMs:R(),attributes:Y(n)};t(Q(o,n),i,{...s,error:!0,events:[c]});}catch{}}return {record:t,recordException:r}}var C=e=>e.split(/[?#]/)[0];function Z(e){if(e instanceof HTMLImageElement||e instanceof HTMLScriptElement)return e.src;if(e instanceof HTMLLinkElement)return e.href}function U(e){let{record:t,recordException:r}=A(e),o=e.slowFetchMs??2e3;function n(d){if(d instanceof ErrorEvent){r(f.JS_ERROR,d.error??d.message);return}let p=Z(d.target);if(p===void 0)return;let u=d.target.tagName.toLowerCase(),a=u!=="img"&&new URL(p,location.href).origin!==location.origin;t(f.RESOURCE_ERROR,{"resource.tag":u,"resource.url":C(p),"resource.third_party":a||void 0},{error:!a});}function i(d){r(f.UNHANDLED_REJECTION,d.reason);}let s=new URL(e.relayUrl,location.href).href,c=window.fetch,m=c.bind(window);function g(d,p){try{let u=d instanceof Request?d:void 0,a=new URL(u?.url??String(d),location.href),l=C(a.href);return l===s?void 0:{method:(p?.method??u?.method??"GET").toUpperCase(),url:l,sameOrigin:a.origin===location.origin}}catch{return}}function h(d,p,u){try{let a=p?.headers??(d instanceof Request?d.headers:{}),l=new Headers(a);if(l.has("traceparent"))return p;let E=l.has("next-router-prefetch")?"00":"01";return l.set("traceparent",`00-${e.traceId}-${u}-${E}`),{...p,headers:l}}catch{return p}}async function S(d,p){let u=g(d,p);if(!u)return m(d,p);let a=`${f.FETCH} ${u.method}`,l={"http.method":u.method,"url.full":u.url},E=y(),w={kind:"client",startMs:R(),spanId:E};u.sameOrigin&&(p=h(d,p,E));try{let b=await m(d,p),x={...l,"http.status_code":b.status};return !b.ok&&b.type!=="opaque"?t(a,x,{...w,error:b.status>=500}):b.ok&&u.sameOrigin&&R()-w.startMs>=o&&t(a,x,{...w,error:!1}),b}catch(b){throw b instanceof DOMException&&b.name==="AbortError"||r(a,b,l,w),b}}return window.addEventListener("error",n,true),window.addEventListener("unhandledrejection",i),window.fetch=S,()=>{window.removeEventListener("error",n,true),window.removeEventListener("unhandledrejection",i),window.fetch===S&&(window.fetch=c);}}function ee(e){let t=e.events?.find(n=>n.name==="exception")?.attributes;if(!t)return;let{"exception.type":r,"exception.message":o}=t;return `${r}|${o}|${String(t["exception.stacktrace"]??"").slice(0,500)}`}function D(e=Date.now){let t=new Map;return function(o){let n=ee(o);if(n===void 0)return false;let i=e(),s=o.attributes?.["component.id"]!==void 0,c=t.get(n),m=c!==void 0&&i-c.at<1e3;return m&&(!s||c.boundary)?true:(t.size>=100&&t.clear(),t.set(n,{at:i,boundary:s||m&&c.boundary}),false)}}var T="__shopkitObsStub",V="__shopkitObsBooted";function P(){try{let e=window;e[V]=!0;let t=e[T];return delete e[T],t?.take()??[]}catch{return []}}function H(e,t){for(let r of t){let o={startMs:r.ts,endMs:r.ts};if(r.k==="r"){let n={"resource.tag":r.tag,"resource.url":r.url};e.record(f.RESOURCE_ERROR,n,{...o,error:true});}else {let n=new Error(r.message);n.name=r.type??"Error",n.stack=r.stack;let i=r.k==="u"?f.UNHANDLED_REJECTION:f.JS_ERROR;e.recordException(i,n,{},o);}}}var te=1e3,re=3,ne="input, textarea, select, [contenteditable]",oe="button, a, [role=button], summary, label";function ie(e){let t=[],r=e;for(let o=0;r&&r!==document.body&&o<3;o++){let n=r.tagName.toLowerCase();if(r.id){t.unshift(`${n}#${r.id}`);break}let i=Array.from(r.classList).slice(0,2);t.unshift(i.length?`${n}.${i.join(".")}`:n),r=r.parentElement;}return t.join(" > ").slice(0,200)}function F(e){let t=null,r=[],o=false;function n(i){try{let s=i.target instanceof Element?i.target:null;if(!s||s===document.body||s===document.documentElement||s.closest(ne))return;let c=s.closest(oe)??s,m=Date.now();c!==t&&(t=c,r=[]),r=r.filter(g=>m-g<te),r.push(m),r.length===1&&(o=!1),r.length>=re&&!o&&(o=!0,e(f.RAGE_CLICK,{"ui.target":ie(c)}));}catch{}}return document.addEventListener("click",n,true),()=>document.removeEventListener("click",n,true)}var B=Symbol.for("@shopkit/observability.reporter");function O(e){globalThis[B]=e;}function G(){return globalThis[B]}var se={internal:1,client:3},ae=0,ce=2;function N(e){let t=Math.floor(e),r=Math.round((e-t)*1e6);return r===1e6&&(t+=1,r=0),t===0?String(r):`${t}${String(r).padStart(6,"0")}`}function ue(e){if(typeof e=="string")return {stringValue:e};if(typeof e=="boolean")return {boolValue:e};if(Number.isFinite(e))return Number.isInteger(e)?{intValue:String(e)}:{doubleValue:e}}function M(e){let t=[];if(!e)return t;for(let r in e){let o=e[r],n=o===void 0?void 0:ue(o);n&&t.push({key:r,value:n});}return t}function de(e){return {traceId:e.traceId,spanId:e.spanId,...e.parentSpanId&&{parentSpanId:e.parentSpanId},name:e.name,kind:se[e.kind??"internal"],startTimeUnixNano:N(e.startMs),endTimeUnixNano:N(e.endMs),attributes:M(e.attributes),events:(e.events??[]).map(t=>({name:t.name,timeUnixNano:N(t.timeMs),attributes:M(t.attributes)})),status:{code:e.error?ce:ae}}}function K(e,t,r){return {resourceSpans:[{resource:{attributes:M(e)},scopeSpans:[{scope:t,spans:r.map(de)}]}]}}var pe=6e4,$="text/plain;charset=UTF-8";function q(e){let{url:t,resource:r,scope:o}=e,n=e.maxBatch??30,i=e.flushMs??5e3,s=e.sessionCap??100,c=[],m=0,g=0,h=0,S;function d(){if(g===h)return;let a=R(),l=g-h;return h=g,{name:f.TELEMETRY_DROPPED,traceId:e.traceId??_(),spanId:y(),startMs:a,endMs:a,attributes:{"telemetry.dropped_count":l,"page.path":location.pathname}}}function p(a,l){let E=JSON.stringify(K(r,o,a)),w=new Blob([E],{type:$});if(w.size>pe){if(a.length===1)return;let b=a.length>>1;p(a.slice(0,b),l),p(a.slice(b),l);return}l&&navigator.sendBeacon?.(t,w)||fetch(t,{method:"POST",body:E,headers:{"content-type":$},keepalive:l,credentials:"omit"}).catch(()=>{});}function u(a){clearTimeout(S),S=void 0;let l=a?d():void 0;if(l&&c.push(l),c.length===0)return;let E=c;c=[];try{p(E,a);}catch{}}return document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&u(true);}),window.addEventListener("pagehide",()=>u(true)),{add(a){if(m>=s){g++;return}m++,c.push(a),document.visibilityState==="hidden"?u(true):c.length>=n?u(false):S??(S=setTimeout(()=>u(false),i));}}}function W(e){let t=false;function r(n){if(t)return;let i=R();try{e.emit({name:f.WEB_VITAL,traceId:e.traceId,spanId:y(),parentSpanId:e.parentSpanId,startMs:i,endMs:i,attributes:{"page.path":location.pathname,"web_vital.name":n.name,"web_vital.value":n.value,"web_vital.rating":n.rating,"web_vital.navigation_type":n.navigationType}});}catch{}}function o(){import('web-vitals').then(({onCLS:n,onFCP:i,onINP:s,onLCP:c,onTTFB:m})=>{[n,i,s,c,m].forEach(g=>g(r));}).catch(()=>{});}return document.readyState==="complete"?o():window.addEventListener("load",o,{once:true}),()=>{t=true,window.removeEventListener("load",o);}}var k=Symbol.for("@shopkit/observability"),le=/^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/;function fe(e){let t=e?le.exec(e.trim()):null;if(!(!t||/^0+$/.test(t[1])||/^0+$/.test(t[2])))return {traceId:t[1],parentSpanId:t[2]}}function me(){return document.cookie.split(";").map(e=>e.split("=")[0].trim())}function ge(e){if(e?.paths?.some(o=>o.test(location.pathname)))return true;let t=new URLSearchParams(location.search);if(e?.params?.some(o=>t.has(o)))return true;let r=e?.cookies?.length?me():[];return e?.cookies?.some(o=>r.includes(o))??false}function be(e){return String(e.events?.[0]?.attributes?.["exception.message"]??"")}function Re(e){try{return Ee(e)}catch{return ()=>{}}}function Ee(e){let t=globalThis;if(typeof window>"u")return ()=>{};let r=P();if(t[k]||ge(e.ignore))return ()=>{};t[k]=true;let o=document.querySelector('meta[name="traceparent"]')?.getAttribute("content"),n=fe(o)?.traceId,i={traceId:_()},s=q({url:e.relayUrl,resource:{[I.SERVICE_NAME]:e.serviceName,[I.APP]:e.app,[I.SERVICE_VERSION]:e.release,[I.DEPLOYMENT_ENVIRONMENT]:e.environment},scope:{name:"@shopkit/observability",version:"0.1.0"},sessionCap:e.sessionCap,traceId:i.traceId}),c=e.ignore?.errors??[],m=D(),g=u=>{let a=be(u);a&&c.some(l=>l.test(a))||m(u)||(u.attributes={...u.attributes,"page.type":e.pageType?.(location.pathname),"page.render_trace_id":n,"network.effective_type":navigator.connection?.effectiveType},s.add(u));},h=U({emit:g,...i,relayUrl:e.relayUrl,slowFetchMs:e.slowFetchMs}),S=W({emit:g,...i}),d=A({emit:g,...i});O(d),H(d,r);let p=F(d.record);return ()=>{h(),S(),p(),O(void 0),t[k]=false;}}var Se=1e3;function ye(e,t){let r=R(),o=false;function n(i,s){if(!o){o=true;try{G()?.record(f.FLOW_PREFIX+e,{...t,...s,"flow.outcome":i},{startMs:r,error:i==="failure"});}catch{}}}return {success:i=>n("success",{...i}),fail:(i,s,c)=>n("failure",{...c,"flow.failure_reason":i,"flow.error_message":s===void 0?void 0:(s instanceof Error?s.message:String(s)).slice(0,Se)})}}exports.initObservability=Re;exports.startFlow=ye;
|
|
1
|
+
'use strict';var A={SERVICE_NAME:"service.name",SERVICE_VERSION:"service.version",DEPLOYMENT_ENVIRONMENT:"deployment.environment",APP:"app"},p={JS_ERROR:"browser.js_error",UNHANDLED_REJECTION:"browser.unhandled_rejection",RESOURCE_ERROR:"browser.resource_error",RENDER_ERROR:"browser.render_error",HYDRATION_ERROR:"browser.hydration_error",CHUNK_ERROR:"browser.chunk_error",FETCH:"browser.fetch",WEB_VITAL:"web_vital",RAGE_CLICK:"ui.rage_click",TELEMETRY_DROPPED:"telemetry.dropped",FLOW_PREFIX:"flow."};function R(){return performance.timeOrigin+performance.now()}function T(e){let t=crypto.getRandomValues(new Uint8Array(e)),r="";for(let o of t)r+=o.toString(16).padStart(2,"0");return /^0+$/.test(r)?T(e):r}var v=()=>T(16),h=()=>T(8);var P=1e3,z=8e3;function Q(e){return e instanceof Error?{"exception.type":e.name,"exception.message":e.message.slice(0,P),"exception.stacktrace":e.stack?.slice(0,z)}:{"exception.type":"Error","exception.message":String(e).slice(0,P)}}var Z=new RegExp(["Loading (CSS )?chunk \\S+ failed","Failed to fetch dynamically imported module","Importing a module script failed","error loading dynamically imported module"].join("|"),"i");function ee(e){return e instanceof Error?e.name==="ChunkLoadError"||Z.test(e.message):false}var te=/Minified React error #(418|423|425)\b|Hydration failed|error while hydrating|did not match\. Server/i;function re(e,t){return ee(t)?p.CHUNK_ERROR:t instanceof Error&&te.test(t.message)?p.HYDRATION_ERROR:e}function x(e){function t(o,n,i={}){try{let c=R();e.emit({name:o,traceId:e.traceId,spanId:h(),parentSpanId:e.parentSpanId,startMs:c,endMs:c,...i,attributes:{"page.path":location.pathname,...n}});}catch{}}function r(o,n,i={},c={}){try{let u={name:"exception",timeMs:R(),attributes:Q(n)};t(re(o,n),i,{...c,error:!0,events:[u]});}catch{}}return {record:t,recordException:r}}var V=e=>e.split(/[?#]/)[0];function ne(e){if(e instanceof HTMLImageElement||e instanceof HTMLScriptElement)return e.src;if(e instanceof HTMLLinkElement)return e.href}function M(e,t,r,o={}){let n=t!=="img"&&new URL(r,location.href).origin!==location.origin;e(p.RESOURCE_ERROR,{"resource.tag":t,"resource.url":V(r),"resource.third_party":n||void 0},{...o,error:!n});}function H(e){let{record:t,recordException:r}=x(e),o=e.slowFetchMs??2e3;function n(s){if(s instanceof ErrorEvent){r(p.JS_ERROR,s.error??s.message);return}let a=ne(s.target);a!==void 0&&M(t,s.target.tagName.toLowerCase(),a);}function i(s){r(p.UNHANDLED_REJECTION,s.reason);}let c=new URL(e.relayUrl,location.href).href,u=new Set(e.apiOrigins?.flatMap(s=>{try{return [new URL(s).origin]}catch{return []}})),l=new Set,f=window.fetch,S=f.bind(window);function w(s,a){try{let d=s instanceof Request?s:void 0,m=new URL(d?.url??String(s),location.href),g=V(m.href);if(g===c)return;let E=(a?.method??d?.method??"GET").toUpperCase(),_=m.origin===location.origin;return {method:E,url:g,sameOrigin:_,ours:_||u.has(m.origin)}}catch{return}}function I(s,a,d){try{let m=a?.headers??(s instanceof Request?s.headers:{}),g=new Headers(m);if(g.has("traceparent"))return a;let E=g.has("next-router-prefetch")?"00":"01";return g.set("traceparent",`00-${e.traceId}-${d}-${E}`),{...a,headers:g}}catch{return a}}async function y(s,a){let d=w(s,a);if(!d)return S(s,a);let m=`${p.FETCH} ${d.method}`,g={"http.method":d.method,"url.full":d.url},E=h(),_={kind:"client",startMs:R(),spanId:E};d.sameOrigin&&(a=I(s,a,E));try{let b=await S(s,a),O={...g,"http.status_code":b.status};if(!b.ok&&b.type!=="opaque"){let D=`${m} ${d.url} ${b.status}`;l.has(D)||(l.add(D),t(m,O,{..._,error:d.ours&&b.status>=500}));}else b.ok&&d.ours&&R()-_.startMs>=o&&t(m,O,{..._,error:!1});return b}catch(b){throw b instanceof DOMException&&b.name==="AbortError"||r(m,b,g,_),b}}return window.addEventListener("error",n,true),window.addEventListener("unhandledrejection",i),window.fetch=y,()=>{window.removeEventListener("error",n,true),window.removeEventListener("unhandledrejection",i),window.fetch===y&&(window.fetch=f);}}function oe(e){let t=e.events?.find(n=>n.name==="exception")?.attributes;if(!t)return;let{"exception.type":r,"exception.message":o}=t;return `${r}|${o}|${String(t["exception.stacktrace"]??"").slice(0,500)}`}function F(e=Date.now){let t=new Map;return function(o){let n=oe(o);if(n===void 0)return false;let i=e(),c=o.attributes?.["component.id"]!==void 0,u=t.get(n),l=u!==void 0&&i-u.at<1e3;return l&&(!c||u.boundary)?true:(t.size>=100&&t.clear(),t.set(n,{at:i,boundary:c||l&&u.boundary}),false)}}var N="__shopkitObsStub",B="__shopkitObsBooted";function $(){try{let e=window;e[B]=!0;let t=e[N];return delete e[N],t?.take()??[]}catch{return []}}function G(e,t){for(let r of t){let o={startMs:r.ts,endMs:r.ts};if(r.k==="r")M(e.record,r.tag??"",r.url??"",o);else {let n=new Error(r.message);n.name=r.type??"Error",n.stack=r.stack;let i=r.k==="u"?p.UNHANDLED_REJECTION:p.JS_ERROR;e.recordException(i,n,{},o);}}}var ie=1e3,se=3,ae="input, textarea, select, [contenteditable]",ce="button, a, [role=button], summary, label";function ue(e){let t=[],r=e;for(let o=0;r&&r!==document.body&&o<3;o++){let n=r.tagName.toLowerCase();if(r.id){t.unshift(`${n}#${r.id}`);break}let i=Array.from(r.classList).slice(0,2);t.unshift(i.length?`${n}.${i.join(".")}`:n),r=r.parentElement;}return t.join(" > ").slice(0,200)}function K(e){let t=null,r=[],o=false;function n(i){try{let c=i.target instanceof Element?i.target:null;if(!c||c===document.body||c===document.documentElement||c.closest(ae))return;let u=c.closest(ce)??c,l=Date.now();u!==t&&(t=u,r=[]),r=r.filter(f=>l-f<ie),r.push(l),r.length===1&&(o=!1),r.length>=se&&!o&&(o=!0,e(p.RAGE_CLICK,{"ui.target":ue(u)}));}catch{}}return document.addEventListener("click",n,true),()=>document.removeEventListener("click",n,true)}var q=Symbol.for("@shopkit/observability.reporter");function L(e){globalThis[q]=e;}function W(){return globalThis[q]}var de={internal:1,client:3},pe=0,le=2;function k(e){let t=Math.floor(e),r=Math.round((e-t)*1e6);return r===1e6&&(t+=1,r=0),t===0?String(r):`${t}${String(r).padStart(6,"0")}`}function fe(e){if(typeof e=="string")return {stringValue:e};if(typeof e=="boolean")return {boolValue:e};if(Number.isFinite(e))return Number.isInteger(e)?{intValue:String(e)}:{doubleValue:e}}function C(e){let t=[];if(!e)return t;for(let r in e){let o=e[r],n=o===void 0?void 0:fe(o);n&&t.push({key:r,value:n});}return t}function me(e){return {traceId:e.traceId,spanId:e.spanId,...e.parentSpanId&&{parentSpanId:e.parentSpanId},name:e.name,kind:de[e.kind??"internal"],startTimeUnixNano:k(e.startMs),endTimeUnixNano:k(e.endMs),attributes:C(e.attributes),events:(e.events??[]).map(t=>({name:t.name,timeUnixNano:k(t.timeMs),attributes:C(t.attributes)})),status:{code:e.error?le:pe}}}function j(e,t,r){return {resourceSpans:[{resource:{attributes:C(e)},scopeSpans:[{scope:t,spans:r.map(me)}]}]}}var ge=6e4,Y="text/plain;charset=UTF-8";function X(e){let{url:t,resource:r,scope:o}=e,n=e.maxBatch??30,i=e.flushMs??5e3,c=e.sessionCap??100,u=[],l=0,f=0,S=0,w;function I(){if(f===S)return;let a=R(),d=f-S;return S=f,{name:p.TELEMETRY_DROPPED,traceId:e.traceId??v(),spanId:h(),startMs:a,endMs:a,attributes:{"telemetry.dropped_count":d,"page.path":location.pathname}}}function y(a,d){let m=JSON.stringify(j(r,o,a)),g=new Blob([m],{type:Y});if(g.size>ge){if(a.length===1)return;let E=a.length>>1;y(a.slice(0,E),d),y(a.slice(E),d);return}d&&navigator.sendBeacon?.(t,g)||fetch(t,{method:"POST",body:m,headers:{"content-type":Y},keepalive:d,credentials:"omit"}).catch(()=>{});}function s(a){clearTimeout(w),w=void 0;let d=a?I():void 0;if(d&&u.push(d),u.length===0)return;let m=u;u=[];try{y(m,a);}catch{}}return document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&s(true);}),window.addEventListener("pagehide",()=>s(true)),{add(a){if(l>=c){f++;return}l++,u.push(a),document.visibilityState==="hidden"?s(true):u.length>=n?s(false):w??(w=setTimeout(()=>s(false),i));}}}function J(e){let t=false;function r(n){if(t)return;let i=R();try{e.emit({name:p.WEB_VITAL,traceId:e.traceId,spanId:h(),parentSpanId:e.parentSpanId,startMs:i,endMs:i,attributes:{"page.path":n.navigationURL?new URL(n.navigationURL).pathname:location.pathname,"web_vital.name":n.name,"web_vital.value":n.value,"web_vital.rating":n.rating,"web_vital.navigation_type":n.navigationType}});}catch{}}function o(){import('web-vitals').then(({onCLS:n,onFCP:i,onINP:c,onLCP:u,onTTFB:l})=>{[n,i,c,u,l].forEach(f=>f(r));}).catch(()=>{});}return document.readyState==="complete"?o():window.addEventListener("load",o,{once:true}),()=>{t=true,window.removeEventListener("load",o);}}var U=Symbol.for("@shopkit/observability"),be=/^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/;function Re(e){let t=e?be.exec(e.trim()):null;if(!(!t||/^0+$/.test(t[1])||/^0+$/.test(t[2])))return {traceId:t[1],parentSpanId:t[2]}}function Ee(){return document.cookie.split(";").map(e=>e.split("=")[0].trim())}function Se(e){if(e?.paths?.some(o=>o.test(location.pathname)))return true;let t=new URLSearchParams(location.search);if(e?.params?.some(o=>t.has(o)))return true;let r=e?.cookies?.length?Ee():[];return e?.cookies?.some(o=>r.includes(o))??false}function ye(e){return String(e.events?.[0]?.attributes?.["exception.message"]??"")}function he(e){try{return we(e)}catch{return ()=>{}}}function we(e){let t=globalThis;if(typeof window>"u")return ()=>{};let r=$();if(t[U]||Se(e.ignore))return ()=>{};t[U]=true;let o=document.querySelector('meta[name="traceparent"]')?.getAttribute("content"),n=Re(o)?.traceId,i={traceId:v()},c=X({url:e.relayUrl,resource:{[A.SERVICE_NAME]:e.serviceName,[A.APP]:e.app,[A.SERVICE_VERSION]:e.release,[A.DEPLOYMENT_ENVIRONMENT]:e.environment},scope:{name:"@shopkit/observability",version:"0.1.1"},sessionCap:e.sessionCap,traceId:i.traceId}),u=e.ignore?.errors??[],l=F(),f=s=>{let a=ye(s);a&&u.some(d=>d.test(a))||l(s)||(s.attributes={...s.attributes,"page.type":e.pageType?.(String(s.attributes?.["page.path"])),"page.render_trace_id":n,"network.effective_type":navigator.connection?.effectiveType},c.add(s));},S=H({emit:f,...i,relayUrl:e.relayUrl,slowFetchMs:e.slowFetchMs,apiOrigins:e.apiOrigins}),w=J({emit:f,...i}),I=x({emit:f,...i});L(I),G(I,r);let y=K(I.record);return ()=>{S(),w(),y(),L(void 0),t[U]=false;}}var Ie=1e3;function _e(e,t){let r=R(),o=false;function n(i,c){if(!o){o=true;try{W()?.record(p.FLOW_PREFIX+e,{...t,...c,"flow.outcome":i},{startMs:r,error:i==="failure"});}catch{}}}return {success:i=>n("success",{...i}),fail:(i,c,u)=>n("failure",{...u,"flow.failure_reason":i,"flow.error_message":c===void 0?void 0:(c instanceof Error?c.message:String(c)).slice(0,Ie)})}}exports.initObservability=he;exports.startFlow=_e;
|
package/dist/client/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {a,b}from'../chunk-YDBHIXG5.mjs';import {b as b$1,a as a$1}from'../chunk-6E7DD34Z.mjs';function R(){return performance.timeOrigin+performance.now()}function _(e){let t=crypto.getRandomValues(new Uint8Array(e)),r="";for(let o of t)r+=o.toString(16).padStart(2,"0");return /^0+$/.test(r)?_(e):r}var x=()=>_(16),y=()=>_(8);var C=1e3,j=8e3;function X(e){return e instanceof Error?{"exception.type":e.name,"exception.message":e.message.slice(0,C),"exception.stacktrace":e.stack?.slice(0,j)}:{"exception.type":"Error","exception.message":String(e).slice(0,C)}}var Y=new RegExp(["Loading (CSS )?chunk \\S+ failed","Failed to fetch dynamically imported module","Importing a module script failed","error loading dynamically imported module"].join("|"),"i");function J(e){return e instanceof Error?e.name==="ChunkLoadError"||Y.test(e.message):false}var z=/Minified React error #(418|423|425)\b|Hydration failed|error while hydrating|did not match\. Server/i;function Q(e,t){return J(t)?b.CHUNK_ERROR:t instanceof Error&&z.test(t.message)?b.HYDRATION_ERROR:e}function v(e){function t(o,n,i={}){try{let a=R();e.emit({name:o,traceId:e.traceId,spanId:y(),parentSpanId:e.parentSpanId,startMs:a,endMs:a,...i,attributes:{"page.path":location.pathname,...n}});}catch{}}function r(o,n,i={},a={}){try{let c={name:"exception",timeMs:R(),attributes:X(n)};t(Q(o,n),i,{...a,error:!0,events:[c]});}catch{}}return {record:t,recordException:r}}var U=e=>e.split(/[?#]/)[0];function Z(e){if(e instanceof HTMLImageElement||e instanceof HTMLScriptElement)return e.src;if(e instanceof HTMLLinkElement)return e.href}function V(e){let{record:t,recordException:r}=v(e),o=e.slowFetchMs??2e3;function n(d){if(d instanceof ErrorEvent){r(b.JS_ERROR,d.error??d.message);return}let p=Z(d.target);if(p===void 0)return;let u=d.target.tagName.toLowerCase(),s=u!=="img"&&new URL(p,location.href).origin!==location.origin;t(b.RESOURCE_ERROR,{"resource.tag":u,"resource.url":U(p),"resource.third_party":s||void 0},{error:!s});}function i(d){r(b.UNHANDLED_REJECTION,d.reason);}let a=new URL(e.relayUrl,location.href).href,c=window.fetch,m=c.bind(window);function g(d,p){try{let u=d instanceof Request?d:void 0,s=new URL(u?.url??String(d),location.href),l=U(s.href);return l===a?void 0:{method:(p?.method??u?.method??"GET").toUpperCase(),url:l,sameOrigin:s.origin===location.origin}}catch{return}}function h(d,p,u){try{let s=p?.headers??(d instanceof Request?d.headers:{}),l=new Headers(s);if(l.has("traceparent"))return p;let S=l.has("next-router-prefetch")?"00":"01";return l.set("traceparent",`00-${e.traceId}-${u}-${S}`),{...p,headers:l}}catch{return p}}async function E(d,p){let u=g(d,p);if(!u)return m(d,p);let s=`${b.FETCH} ${u.method}`,l={"http.method":u.method,"url.full":u.url},S=y(),w={kind:"client",startMs:R(),spanId:S};u.sameOrigin&&(p=h(d,p,S));try{let b=await m(d,p),A={...l,"http.status_code":b.status};return !b.ok&&b.type!=="opaque"?t(s,A,{...w,error:b.status>=500}):b.ok&&u.sameOrigin&&R()-w.startMs>=o&&t(s,A,{...w,error:!1}),b}catch(b){throw b instanceof DOMException&&b.name==="AbortError"||r(s,b,l,w),b}}return window.addEventListener("error",n,true),window.addEventListener("unhandledrejection",i),window.fetch=E,()=>{window.removeEventListener("error",n,true),window.removeEventListener("unhandledrejection",i),window.fetch===E&&(window.fetch=c);}}function ee(e){let t=e.events?.find(n=>n.name==="exception")?.attributes;if(!t)return;let{"exception.type":r,"exception.message":o}=t;return `${r}|${o}|${String(t["exception.stacktrace"]??"").slice(0,500)}`}function D(e=Date.now){let t=new Map;return function(o){let n=ee(o);if(n===void 0)return false;let i=e(),a=o.attributes?.["component.id"]!==void 0,c=t.get(n),m=c!==void 0&&i-c.at<1e3;return m&&(!a||c.boundary)?true:(t.size>=100&&t.clear(),t.set(n,{at:i,boundary:a||m&&c.boundary}),false)}}function P(){try{let e=window;e[b$1]=!0;let t=e[a$1];return delete e[a$1],t?.take()??[]}catch{return []}}function H(e,t){for(let r of t){let o={startMs:r.ts,endMs:r.ts};if(r.k==="r"){let n={"resource.tag":r.tag,"resource.url":r.url};e.record(b.RESOURCE_ERROR,n,{...o,error:true});}else {let n=new Error(r.message);n.name=r.type??"Error",n.stack=r.stack;let i=r.k==="u"?b.UNHANDLED_REJECTION:b.JS_ERROR;e.recordException(i,n,{},o);}}}var te=1e3,re=3,ne="input, textarea, select, [contenteditable]",oe="button, a, [role=button], summary, label";function ie(e){let t=[],r=e;for(let o=0;r&&r!==document.body&&o<3;o++){let n=r.tagName.toLowerCase();if(r.id){t.unshift(`${n}#${r.id}`);break}let i=Array.from(r.classList).slice(0,2);t.unshift(i.length?`${n}.${i.join(".")}`:n),r=r.parentElement;}return t.join(" > ").slice(0,200)}function F(e){let t=null,r=[],o=false;function n(i){try{let a=i.target instanceof Element?i.target:null;if(!a||a===document.body||a===document.documentElement||a.closest(ne))return;let c=a.closest(oe)??a,m=Date.now();c!==t&&(t=c,r=[]),r=r.filter(g=>m-g<te),r.push(m),r.length===1&&(o=!1),r.length>=re&&!o&&(o=!0,e(b.RAGE_CLICK,{"ui.target":ie(c)}));}catch{}}return document.addEventListener("click",n,true),()=>document.removeEventListener("click",n,true)}var $=Symbol.for("@shopkit/observability.reporter");function M(e){globalThis[$]=e;}function B(){return globalThis[$]}var ae={internal:1,client:3},se=0,ce=2;function O(e){let t=Math.floor(e),r=Math.round((e-t)*1e6);return r===1e6&&(t+=1,r=0),t===0?String(r):`${t}${String(r).padStart(6,"0")}`}function ue(e){if(typeof e=="string")return {stringValue:e};if(typeof e=="boolean")return {boolValue:e};if(Number.isFinite(e))return Number.isInteger(e)?{intValue:String(e)}:{doubleValue:e}}function N(e){let t=[];if(!e)return t;for(let r in e){let o=e[r],n=o===void 0?void 0:ue(o);n&&t.push({key:r,value:n});}return t}function de(e){return {traceId:e.traceId,spanId:e.spanId,...e.parentSpanId&&{parentSpanId:e.parentSpanId},name:e.name,kind:ae[e.kind??"internal"],startTimeUnixNano:O(e.startMs),endTimeUnixNano:O(e.endMs),attributes:N(e.attributes),events:(e.events??[]).map(t=>({name:t.name,timeUnixNano:O(t.timeMs),attributes:N(t.attributes)})),status:{code:e.error?ce:se}}}function K(e,t,r){return {resourceSpans:[{resource:{attributes:N(e)},scopeSpans:[{scope:t,spans:r.map(de)}]}]}}var pe=6e4,G="text/plain;charset=UTF-8";function q(e){let{url:t,resource:r,scope:o}=e,n=e.maxBatch??30,i=e.flushMs??5e3,a=e.sessionCap??100,c=[],m=0,g=0,h=0,E;function d(){if(g===h)return;let s=R(),l=g-h;return h=g,{name:b.TELEMETRY_DROPPED,traceId:e.traceId??x(),spanId:y(),startMs:s,endMs:s,attributes:{"telemetry.dropped_count":l,"page.path":location.pathname}}}function p(s,l){let S=JSON.stringify(K(r,o,s)),w=new Blob([S],{type:G});if(w.size>pe){if(s.length===1)return;let b=s.length>>1;p(s.slice(0,b),l),p(s.slice(b),l);return}l&&navigator.sendBeacon?.(t,w)||fetch(t,{method:"POST",body:S,headers:{"content-type":G},keepalive:l,credentials:"omit"}).catch(()=>{});}function u(s){clearTimeout(E),E=void 0;let l=s?d():void 0;if(l&&c.push(l),c.length===0)return;let S=c;c=[];try{p(S,s);}catch{}}return document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&u(true);}),window.addEventListener("pagehide",()=>u(true)),{add(s){if(m>=a){g++;return}m++,c.push(s),document.visibilityState==="hidden"?u(true):c.length>=n?u(false):E??(E=setTimeout(()=>u(false),i));}}}function W(e){let t=false;function r(n){if(t)return;let i=R();try{e.emit({name:b.WEB_VITAL,traceId:e.traceId,spanId:y(),parentSpanId:e.parentSpanId,startMs:i,endMs:i,attributes:{"page.path":location.pathname,"web_vital.name":n.name,"web_vital.value":n.value,"web_vital.rating":n.rating,"web_vital.navigation_type":n.navigationType}});}catch{}}function o(){import('web-vitals').then(({onCLS:n,onFCP:i,onINP:a,onLCP:c,onTTFB:m})=>{[n,i,a,c,m].forEach(g=>g(r));}).catch(()=>{});}return document.readyState==="complete"?o():window.addEventListener("load",o,{once:true}),()=>{t=true,window.removeEventListener("load",o);}}var k=Symbol.for("@shopkit/observability"),le=/^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/;function fe(e){let t=e?le.exec(e.trim()):null;if(!(!t||/^0+$/.test(t[1])||/^0+$/.test(t[2])))return {traceId:t[1],parentSpanId:t[2]}}function me(){return document.cookie.split(";").map(e=>e.split("=")[0].trim())}function ge(e){if(e?.paths?.some(o=>o.test(location.pathname)))return true;let t=new URLSearchParams(location.search);if(e?.params?.some(o=>t.has(o)))return true;let r=e?.cookies?.length?me():[];return e?.cookies?.some(o=>r.includes(o))??false}function be(e){return String(e.events?.[0]?.attributes?.["exception.message"]??"")}function Re(e){try{return Se(e)}catch{return ()=>{}}}function Se(e){let t=globalThis;if(typeof window>"u")return ()=>{};let r=P();if(t[k]||ge(e.ignore))return ()=>{};t[k]=true;let o=document.querySelector('meta[name="traceparent"]')?.getAttribute("content"),n=fe(o)?.traceId,i={traceId:x()},a$1=q({url:e.relayUrl,resource:{[a.SERVICE_NAME]:e.serviceName,[a.APP]:e.app,[a.SERVICE_VERSION]:e.release,[a.DEPLOYMENT_ENVIRONMENT]:e.environment},scope:{name:"@shopkit/observability",version:"0.1.0"},sessionCap:e.sessionCap,traceId:i.traceId}),c=e.ignore?.errors??[],m=D(),g=u=>{let s=be(u);s&&c.some(l=>l.test(s))||m(u)||(u.attributes={...u.attributes,"page.type":e.pageType?.(location.pathname),"page.render_trace_id":n,"network.effective_type":navigator.connection?.effectiveType},a$1.add(u));},h=V({emit:g,...i,relayUrl:e.relayUrl,slowFetchMs:e.slowFetchMs}),E=W({emit:g,...i}),d=v({emit:g,...i});M(d),H(d,r);let p=F(d.record);return ()=>{h(),E(),p(),M(void 0),t[k]=false;}}var Ee=1e3;function ye(e,t){let r=R(),o=false;function n(i,a){if(!o){o=true;try{B()?.record(b.FLOW_PREFIX+e,{...t,...a,"flow.outcome":i},{startMs:r,error:i==="failure"});}catch{}}}return {success:i=>n("success",{...i}),fail:(i,a,c)=>n("failure",{...c,"flow.failure_reason":i,"flow.error_message":a===void 0?void 0:(a instanceof Error?a.message:String(a)).slice(0,Ee)})}}export{Re as initObservability,ye as startFlow};
|
|
1
|
+
import {a,b}from'../chunk-YDBHIXG5.mjs';import {b as b$1,a as a$1}from'../chunk-6E7DD34Z.mjs';function R(){return performance.timeOrigin+performance.now()}function _(e){let t=crypto.getRandomValues(new Uint8Array(e)),r="";for(let o of t)r+=o.toString(16).padStart(2,"0");return /^0+$/.test(r)?_(e):r}var A=()=>_(16),E=()=>_(8);var D=1e3,z=8e3;function Q(e){return e instanceof Error?{"exception.type":e.name,"exception.message":e.message.slice(0,D),"exception.stacktrace":e.stack?.slice(0,z)}:{"exception.type":"Error","exception.message":String(e).slice(0,D)}}var Z=new RegExp(["Loading (CSS )?chunk \\S+ failed","Failed to fetch dynamically imported module","Importing a module script failed","error loading dynamically imported module"].join("|"),"i");function ee(e){return e instanceof Error?e.name==="ChunkLoadError"||Z.test(e.message):false}var te=/Minified React error #(418|423|425)\b|Hydration failed|error while hydrating|did not match\. Server/i;function re(e,t){return ee(t)?b.CHUNK_ERROR:t instanceof Error&&te.test(t.message)?b.HYDRATION_ERROR:e}function T(e){function t(o,n,i={}){try{let c=R();e.emit({name:o,traceId:e.traceId,spanId:E(),parentSpanId:e.parentSpanId,startMs:c,endMs:c,...i,attributes:{"page.path":location.pathname,...n}});}catch{}}function r(o,n,i={},c={}){try{let u={name:"exception",timeMs:R(),attributes:Q(n)};t(re(o,n),i,{...c,error:!0,events:[u]});}catch{}}return {record:t,recordException:r}}var H=e=>e.split(/[?#]/)[0];function ne(e){if(e instanceof HTMLImageElement||e instanceof HTMLScriptElement)return e.src;if(e instanceof HTMLLinkElement)return e.href}function N(e,t,r,o={}){let n=t!=="img"&&new URL(r,location.href).origin!==location.origin;e(b.RESOURCE_ERROR,{"resource.tag":t,"resource.url":H(r),"resource.third_party":n||void 0},{...o,error:!n});}function F(e){let{record:t,recordException:r}=T(e),o=e.slowFetchMs??2e3;function n(a){if(a instanceof ErrorEvent){r(b.JS_ERROR,a.error??a.message);return}let s=ne(a.target);s!==void 0&&N(t,a.target.tagName.toLowerCase(),s);}function i(a){r(b.UNHANDLED_REJECTION,a.reason);}let c=new URL(e.relayUrl,location.href).href,u=new Set(e.apiOrigins?.flatMap(a=>{try{return [new URL(a).origin]}catch{return []}})),l=new Set,f=window.fetch,y=f.bind(window);function w(a,s){try{let d=a instanceof Request?a:void 0,m=new URL(d?.url??String(a),location.href),g=H(m.href);if(g===c)return;let S=(s?.method??d?.method??"GET").toUpperCase(),v=m.origin===location.origin;return {method:S,url:g,sameOrigin:v,ours:v||u.has(m.origin)}}catch{return}}function I(a,s,d){try{let m=s?.headers??(a instanceof Request?a.headers:{}),g=new Headers(m);if(g.has("traceparent"))return s;let S=g.has("next-router-prefetch")?"00":"01";return g.set("traceparent",`00-${e.traceId}-${d}-${S}`),{...s,headers:g}}catch{return s}}async function h(a,s){let d=w(a,s);if(!d)return y(a,s);let m=`${b.FETCH} ${d.method}`,g={"http.method":d.method,"url.full":d.url},S=E(),v={kind:"client",startMs:R(),spanId:S};d.sameOrigin&&(s=I(a,s,S));try{let b=await y(a,s),O={...g,"http.status_code":b.status};if(!b.ok&&b.type!=="opaque"){let V=`${m} ${d.url} ${b.status}`;l.has(V)||(l.add(V),t(m,O,{...v,error:d.ours&&b.status>=500}));}else b.ok&&d.ours&&R()-v.startMs>=o&&t(m,O,{...v,error:!1});return b}catch(b){throw b instanceof DOMException&&b.name==="AbortError"||r(m,b,g,v),b}}return window.addEventListener("error",n,true),window.addEventListener("unhandledrejection",i),window.fetch=h,()=>{window.removeEventListener("error",n,true),window.removeEventListener("unhandledrejection",i),window.fetch===h&&(window.fetch=f);}}function oe(e){let t=e.events?.find(n=>n.name==="exception")?.attributes;if(!t)return;let{"exception.type":r,"exception.message":o}=t;return `${r}|${o}|${String(t["exception.stacktrace"]??"").slice(0,500)}`}function $(e=Date.now){let t=new Map;return function(o){let n=oe(o);if(n===void 0)return false;let i=e(),c=o.attributes?.["component.id"]!==void 0,u=t.get(n),l=u!==void 0&&i-u.at<1e3;return l&&(!c||u.boundary)?true:(t.size>=100&&t.clear(),t.set(n,{at:i,boundary:c||l&&u.boundary}),false)}}function B(){try{let e=window;e[b$1]=!0;let t=e[a$1];return delete e[a$1],t?.take()??[]}catch{return []}}function K(e,t){for(let r of t){let o={startMs:r.ts,endMs:r.ts};if(r.k==="r")N(e.record,r.tag??"",r.url??"",o);else {let n=new Error(r.message);n.name=r.type??"Error",n.stack=r.stack;let i=r.k==="u"?b.UNHANDLED_REJECTION:b.JS_ERROR;e.recordException(i,n,{},o);}}}var ie=1e3,ae=3,se="input, textarea, select, [contenteditable]",ce="button, a, [role=button], summary, label";function ue(e){let t=[],r=e;for(let o=0;r&&r!==document.body&&o<3;o++){let n=r.tagName.toLowerCase();if(r.id){t.unshift(`${n}#${r.id}`);break}let i=Array.from(r.classList).slice(0,2);t.unshift(i.length?`${n}.${i.join(".")}`:n),r=r.parentElement;}return t.join(" > ").slice(0,200)}function G(e){let t=null,r=[],o=false;function n(i){try{let c=i.target instanceof Element?i.target:null;if(!c||c===document.body||c===document.documentElement||c.closest(se))return;let u=c.closest(ce)??c,l=Date.now();u!==t&&(t=u,r=[]),r=r.filter(f=>l-f<ie),r.push(l),r.length===1&&(o=!1),r.length>=ae&&!o&&(o=!0,e(b.RAGE_CLICK,{"ui.target":ue(u)}));}catch{}}return document.addEventListener("click",n,true),()=>document.removeEventListener("click",n,true)}var q=Symbol.for("@shopkit/observability.reporter");function k(e){globalThis[q]=e;}function W(){return globalThis[q]}var de={internal:1,client:3},pe=0,le=2;function L(e){let t=Math.floor(e),r=Math.round((e-t)*1e6);return r===1e6&&(t+=1,r=0),t===0?String(r):`${t}${String(r).padStart(6,"0")}`}function fe(e){if(typeof e=="string")return {stringValue:e};if(typeof e=="boolean")return {boolValue:e};if(Number.isFinite(e))return Number.isInteger(e)?{intValue:String(e)}:{doubleValue:e}}function C(e){let t=[];if(!e)return t;for(let r in e){let o=e[r],n=o===void 0?void 0:fe(o);n&&t.push({key:r,value:n});}return t}function me(e){return {traceId:e.traceId,spanId:e.spanId,...e.parentSpanId&&{parentSpanId:e.parentSpanId},name:e.name,kind:de[e.kind??"internal"],startTimeUnixNano:L(e.startMs),endTimeUnixNano:L(e.endMs),attributes:C(e.attributes),events:(e.events??[]).map(t=>({name:t.name,timeUnixNano:L(t.timeMs),attributes:C(t.attributes)})),status:{code:e.error?le:pe}}}function j(e,t,r){return {resourceSpans:[{resource:{attributes:C(e)},scopeSpans:[{scope:t,spans:r.map(me)}]}]}}var ge=6e4,X="text/plain;charset=UTF-8";function Y(e){let{url:t,resource:r,scope:o}=e,n=e.maxBatch??30,i=e.flushMs??5e3,c=e.sessionCap??100,u=[],l=0,f=0,y=0,w;function I(){if(f===y)return;let s=R(),d=f-y;return y=f,{name:b.TELEMETRY_DROPPED,traceId:e.traceId??A(),spanId:E(),startMs:s,endMs:s,attributes:{"telemetry.dropped_count":d,"page.path":location.pathname}}}function h(s,d){let m=JSON.stringify(j(r,o,s)),g=new Blob([m],{type:X});if(g.size>ge){if(s.length===1)return;let S=s.length>>1;h(s.slice(0,S),d),h(s.slice(S),d);return}d&&navigator.sendBeacon?.(t,g)||fetch(t,{method:"POST",body:m,headers:{"content-type":X},keepalive:d,credentials:"omit"}).catch(()=>{});}function a(s){clearTimeout(w),w=void 0;let d=s?I():void 0;if(d&&u.push(d),u.length===0)return;let m=u;u=[];try{h(m,s);}catch{}}return document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&a(true);}),window.addEventListener("pagehide",()=>a(true)),{add(s){if(l>=c){f++;return}l++,u.push(s),document.visibilityState==="hidden"?a(true):u.length>=n?a(false):w??(w=setTimeout(()=>a(false),i));}}}function J(e){let t=false;function r(n){if(t)return;let i=R();try{e.emit({name:b.WEB_VITAL,traceId:e.traceId,spanId:E(),parentSpanId:e.parentSpanId,startMs:i,endMs:i,attributes:{"page.path":n.navigationURL?new URL(n.navigationURL).pathname:location.pathname,"web_vital.name":n.name,"web_vital.value":n.value,"web_vital.rating":n.rating,"web_vital.navigation_type":n.navigationType}});}catch{}}function o(){import('web-vitals').then(({onCLS:n,onFCP:i,onINP:c,onLCP:u,onTTFB:l})=>{[n,i,c,u,l].forEach(f=>f(r));}).catch(()=>{});}return document.readyState==="complete"?o():window.addEventListener("load",o,{once:true}),()=>{t=true,window.removeEventListener("load",o);}}var U=Symbol.for("@shopkit/observability"),be=/^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/;function Re(e){let t=e?be.exec(e.trim()):null;if(!(!t||/^0+$/.test(t[1])||/^0+$/.test(t[2])))return {traceId:t[1],parentSpanId:t[2]}}function Se(){return document.cookie.split(";").map(e=>e.split("=")[0].trim())}function ye(e){if(e?.paths?.some(o=>o.test(location.pathname)))return true;let t=new URLSearchParams(location.search);if(e?.params?.some(o=>t.has(o)))return true;let r=e?.cookies?.length?Se():[];return e?.cookies?.some(o=>r.includes(o))??false}function he(e){return String(e.events?.[0]?.attributes?.["exception.message"]??"")}function Ee(e){try{return we(e)}catch{return ()=>{}}}function we(e){let t=globalThis;if(typeof window>"u")return ()=>{};let r=B();if(t[U]||ye(e.ignore))return ()=>{};t[U]=true;let o=document.querySelector('meta[name="traceparent"]')?.getAttribute("content"),n=Re(o)?.traceId,i={traceId:A()},c=Y({url:e.relayUrl,resource:{[a.SERVICE_NAME]:e.serviceName,[a.APP]:e.app,[a.SERVICE_VERSION]:e.release,[a.DEPLOYMENT_ENVIRONMENT]:e.environment},scope:{name:"@shopkit/observability",version:"0.1.1"},sessionCap:e.sessionCap,traceId:i.traceId}),u=e.ignore?.errors??[],l=$(),f=a=>{let s=he(a);s&&u.some(d=>d.test(s))||l(a)||(a.attributes={...a.attributes,"page.type":e.pageType?.(String(a.attributes?.["page.path"])),"page.render_trace_id":n,"network.effective_type":navigator.connection?.effectiveType},c.add(a));},y=F({emit:f,...i,relayUrl:e.relayUrl,slowFetchMs:e.slowFetchMs,apiOrigins:e.apiOrigins}),w=J({emit:f,...i}),I=T({emit:f,...i});k(I),K(I,r);let h=G(I.record);return ()=>{y(),w(),h(),k(void 0),t[U]=false;}}var Ie=1e3;function ve(e,t){let r=R(),o=false;function n(i,c){if(!o){o=true;try{W()?.record(b.FLOW_PREFIX+e,{...t,...c,"flow.outcome":i},{startMs:r,error:i==="failure"});}catch{}}}return {success:i=>n("success",{...i}),fail:(i,c,u)=>n("failure",{...u,"flow.failure_reason":i,"flow.error_message":c===void 0?void 0:(c instanceof Error?c.message:String(c)).slice(0,Ie)})}}export{Ee as initObservability,ve as startFlow};
|
package/dist/head-stub/index.js
CHANGED
|
@@ -36,5 +36,5 @@ w.addEventListener("load",function(){T=setTimeout(F,C.g);w.addEventListener("pag
|
|
|
36
36
|
// initObservability calls take(): the app started, hand the queue over.
|
|
37
37
|
w.${r}={take:function(){b=true;X();return q}};
|
|
38
38
|
`,i=t=>t.split(`
|
|
39
|
-
`).map(e=>e.trim()).filter(e=>e&&!e.startsWith("//")).join(""),c=i(o);function d(t,e=3e3){let a={u:t.relayUrl,s:t.serviceName,a:t.app,g:e,v:"0.1.
|
|
39
|
+
`).map(e=>e.trim()).filter(e=>e&&!e.startsWith("//")).join(""),c=i(o);function d(t,e=3e3){let a={u:t.relayUrl,s:t.serviceName,a:t.app,g:e,v:"0.1.1"},s=JSON.stringify(a).replace(/</g,"\\u003c");return `(function(C){${c}})(${s});`}
|
|
40
40
|
exports.BOOTED_GLOBAL=n;exports.HEAD_STUB_GLOBAL=r;exports.headStubScript=d;
|
package/dist/head-stub/index.mjs
CHANGED
|
@@ -36,5 +36,5 @@ w.addEventListener("load",function(){T=setTimeout(F,C.g);w.addEventListener("pag
|
|
|
36
36
|
// initObservability calls take(): the app started, hand the queue over.
|
|
37
37
|
w.${a}={take:function(){b=true;X();return q}};
|
|
38
38
|
`,i=t=>t.split(`
|
|
39
|
-
`).map(e=>e.trim()).filter(e=>e&&!e.startsWith("//")).join(""),c=i(o);function u(t,e=3e3){let a={u:t.relayUrl,s:t.serviceName,a:t.app,g:e,v:"0.1.
|
|
39
|
+
`).map(e=>e.trim()).filter(e=>e&&!e.startsWith("//")).join(""),c=i(o);function u(t,e=3e3){let a={u:t.relayUrl,s:t.serviceName,a:t.app,g:e,v:"0.1.1"},s=JSON.stringify(a).replace(/</g,"\\u003c");return `(function(C){${c}})(${s});`}
|
|
40
40
|
export{u as headStubScript};
|
package/dist/server/index.d.mts
CHANGED
|
@@ -15,4 +15,12 @@ declare function skipPathsSampler(skip: RegExp): Sampler;
|
|
|
15
15
|
*/
|
|
16
16
|
declare function scrubSpanProcessor(): SpanProcessor;
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Records a server error in the request's trace, for hooks like Next's `onRequestError`.
|
|
20
|
+
* An error in a streamed page render doesn't fail the request (it's already a 200), so the
|
|
21
|
+
* framework records nothing; the browser gets only a generic message and the `digest`,
|
|
22
|
+
* kept here as `error.digest` to match the two.
|
|
23
|
+
*/
|
|
24
|
+
declare function recordServerError(err: unknown): void;
|
|
25
|
+
|
|
26
|
+
export { recordServerError, scrubSpanProcessor, skipPathsSampler };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -15,4 +15,12 @@ declare function skipPathsSampler(skip: RegExp): Sampler;
|
|
|
15
15
|
*/
|
|
16
16
|
declare function scrubSpanProcessor(): SpanProcessor;
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Records a server error in the request's trace, for hooks like Next's `onRequestError`.
|
|
20
|
+
* An error in a streamed page render doesn't fail the request (it's already a 200), so the
|
|
21
|
+
* framework records nothing; the browser gets only a generic message and the `digest`,
|
|
22
|
+
* kept here as `error.digest` to match the two.
|
|
23
|
+
*/
|
|
24
|
+
declare function recordServerError(err: unknown): void;
|
|
25
|
+
|
|
26
|
+
export { recordServerError, scrubSpanProcessor, skipPathsSampler };
|
package/dist/server/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var api=require('@opentelemetry/api');var
|
|
2
|
-
exports.scrubSpanProcessor=
|
|
1
|
+
'use strict';var api=require('@opentelemetry/api');var p=0,u=2;function d(e){let t=e["url.path"]??e["http.target"];return typeof t=="string"?t.split("?")[0]:void 0}function S(e){return {shouldSample(t,r,s,o,g){let i=d(g);if(i&&e.test(i))return {decision:p};let a=api.trace.getSpanContext(t);return a?{decision:(a.traceFlags&api.TraceFlags.SAMPLED)===api.TraceFlags.SAMPLED?u:p}:{decision:u}},toString:()=>`SkipPathsSampler(${e})`}}var b=/\?[^\s#)'"]*?(?=(?::\d+:\d+)?(?:[\s#)'"]|$))/g,E=/(?<![\w.+-])[\w.+-]+@[\w-]+(?:\.[\w-]+)+/g,R=/(?<!\w)(?:\+?91[\s-]?)?[6-9]\d{9}(?!\w)/g;function h(e){return e.replace(/\S+/g,t=>{let r=t.indexOf("#");if(r<0||!t.slice(0,r).includes("://"))return t;let s=t.slice(r).search(/[)'"]/);return t.slice(0,r)+(s<0?"":t.slice(r+s))})}function n(e){return h(e.replace(b,"")).replace(E,"[email]").replace(R,"[phone]")}function m(e){if(e)for(let[t,r]of Object.entries(e))typeof r=="string"&&(e[t]=n(r));}function P(){return {onStart(){},onEnd(e){e.name=n(e.name),m(e.attributes);for(let r of e.events)m(r.attributes);let t=e.status;t.message&&(t.message=n(t.message));},forceFlush:()=>Promise.resolve(),shutdown:()=>Promise.resolve()}}function v(e){let t=api.trace.getActiveSpan(),r=t?.isRecording()?t:api.trace.getTracer("@shopkit/observability").startSpan("server.error"),s=e instanceof Error?e.message:String(e),o=e?.digest;r.recordException(e instanceof Error?e:s),r.setStatus({code:api.SpanStatusCode.ERROR,message:s}),typeof o=="string"&&r.setAttribute("error.digest",o),r!==t&&r.end();}
|
|
2
|
+
exports.recordServerError=v;exports.scrubSpanProcessor=P;exports.skipPathsSampler=S;
|
package/dist/server/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {a}from'../chunk-ZNVBPNNQ.mjs';import {trace,TraceFlags}from'@opentelemetry/api';var
|
|
1
|
+
import {a}from'../chunk-ZNVBPNNQ.mjs';import {trace,TraceFlags,SpanStatusCode}from'@opentelemetry/api';var c=0,m=2;function g(e){let t=e["url.path"]??e["http.target"];return typeof t=="string"?t.split("?")[0]:void 0}function l(e){return {shouldSample(t,r,n,o,d){let i=g(d);if(i&&e.test(i))return {decision:c};let a=trace.getSpanContext(t);return a?{decision:(a.traceFlags&TraceFlags.SAMPLED)===TraceFlags.SAMPLED?m:c}:{decision:m}},toString:()=>`SkipPathsSampler(${e})`}}function u(e){if(e)for(let[t,r]of Object.entries(e))typeof r=="string"&&(e[t]=a(r));}function b(){return {onStart(){},onEnd(e){e.name=a(e.name),u(e.attributes);for(let r of e.events)u(r.attributes);let t=e.status;t.message&&(t.message=a(t.message));},forceFlush:()=>Promise.resolve(),shutdown:()=>Promise.resolve()}}function E(e){let t=trace.getActiveSpan(),r=t?.isRecording()?t:trace.getTracer("@shopkit/observability").startSpan("server.error"),n=e instanceof Error?e.message:String(e),o=e?.digest;r.recordException(e instanceof Error?e:n),r.setStatus({code:SpanStatusCode.ERROR,message:n}),typeof o=="string"&&r.setAttribute("error.digest",o),r!==t&&r.end();}export{E as recordServerError,b as scrubSpanProcessor,l as skipPathsSampler};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopkit/observability",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Frontend observability for storefronts and the editor: browser errors, failed requests, web vitals and flows, sent as OTLP traces",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|