@lensmcp/react-instrumentation 1.23.4 → 1.23.7
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/index.d.ts +2 -1
- package/index.js +1 -1
- package/lib/flow-fetch.d.ts +5 -0
- package/lib/flow-fetch.js +1 -1
- package/lib/publish.d.ts +52 -2
- package/lib/publish.js +1 -1
- package/lib/route-flows.d.ts +10 -0
- package/lib/route-flows.js +1 -0
- package/package.json +2 -2
package/index.d.ts
CHANGED
|
@@ -4,10 +4,11 @@ export { tracedUseEffect, tracedUseMemo, tracedUseCallback, } from './lib/traced
|
|
|
4
4
|
export { TraceSlot, type TraceSlotProps } from './lib/trace-slot.js';
|
|
5
5
|
export { withTraceComponent, type WithTraceOptions } from './lib/hoc.js';
|
|
6
6
|
export { installFlowFetch, type FlowFetchOptions } from './lib/flow-fetch.js';
|
|
7
|
+
export { installRouteFlows, routeNodeId, type RouteFlowEnvironment } from './lib/route-flows.js';
|
|
7
8
|
export { useComponentIdentity } from './lib/component-identity.js';
|
|
8
9
|
export type { ComponentIdentity } from './lib/component-identity.js';
|
|
9
10
|
export { installFiberRenderPublisher, resetFiberRenderPublisherForTests } from './lib/fiber-renders.js';
|
|
10
|
-
export { publish, publishLazy, setPublisher, drainQueue, queuedByteCount, runInFlow, currentFlow, activeFlow, extendFlowWindow, beginBackgroundFlow, withFlow, type PublishEnvelope, type PublishCategory, type FlowSpec, } from './lib/publish.js';
|
|
11
|
+
export { publish, publishLazy, setPublisher, drainQueue, queuedByteCount, runInFlow, currentFlow, activeFlow, extendFlowWindow, beginBackgroundFlow, flowForNewActivity, configureAmbientFlows, DEFAULT_AMBIENT_FLOW_MAX_MS, FLOW_ORIGIN_FINGERPRINT_PREFIX, withFlow, type AmbientFlowOptions, type BackgroundFlowOrigin, type PublishEnvelope, type PublishCategory, type FlowSpec, } from './lib/publish.js';
|
|
11
12
|
export { componentLogicalId, hookLogicalId, slotLogicalId, makeInstanceId, depsHash, resetIdentityState, } from './lib/identity.js';
|
|
12
13
|
export type { RenderRecord, EffectRecord, HookRecord, SlotChangeRecord, ComponentMountRecord, ReactPublishPayload, } from './lib/types.js';
|
|
13
14
|
export { default as lensmcpBabelPlugin, type LensmcpBabelOptions } from './lib/babel-plugin.js';
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export{LensmcpRoot}from"./lib/lensmcp-root.js";export{LensmcpContext,useLensmcpContext}from"./lib/context.js";export{tracedUseEffect,tracedUseMemo,tracedUseCallback}from"./lib/traced-hooks.js";export{TraceSlot}from"./lib/trace-slot.js";export{withTraceComponent}from"./lib/hoc.js";export{installFlowFetch}from"./lib/flow-fetch.js";export{useComponentIdentity}from"./lib/component-identity.js";export{installFiberRenderPublisher,resetFiberRenderPublisherForTests}from"./lib/fiber-renders.js";export{publish,publishLazy,setPublisher,drainQueue,queuedByteCount,runInFlow,currentFlow,activeFlow,extendFlowWindow,beginBackgroundFlow,withFlow}from"./lib/publish.js";export{componentLogicalId,hookLogicalId,slotLogicalId,makeInstanceId,depsHash,resetIdentityState}from"./lib/identity.js";export{default as lensmcpBabelPlugin}from"./lib/babel-plugin.js";
|
|
1
|
+
"use strict";export{LensmcpRoot}from"./lib/lensmcp-root.js";export{LensmcpContext,useLensmcpContext}from"./lib/context.js";export{tracedUseEffect,tracedUseMemo,tracedUseCallback}from"./lib/traced-hooks.js";export{TraceSlot}from"./lib/trace-slot.js";export{withTraceComponent}from"./lib/hoc.js";export{installFlowFetch}from"./lib/flow-fetch.js";export{installRouteFlows,routeNodeId}from"./lib/route-flows.js";export{useComponentIdentity}from"./lib/component-identity.js";export{installFiberRenderPublisher,resetFiberRenderPublisherForTests}from"./lib/fiber-renders.js";export{publish,publishLazy,setPublisher,drainQueue,queuedByteCount,runInFlow,currentFlow,activeFlow,extendFlowWindow,beginBackgroundFlow,flowForNewActivity,configureAmbientFlows,DEFAULT_AMBIENT_FLOW_MAX_MS,FLOW_ORIGIN_FINGERPRINT_PREFIX,withFlow}from"./lib/publish.js";export{componentLogicalId,hookLogicalId,slotLogicalId,makeInstanceId,depsHash,resetIdentityState}from"./lib/identity.js";export{default as lensmcpBabelPlugin}from"./lib/babel-plugin.js";
|
package/lib/flow-fetch.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ export interface FlowFetchOptions {
|
|
|
15
15
|
* (an array, or a comma-separated string) before the root module instead.
|
|
16
16
|
*/
|
|
17
17
|
propagateTo?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Start a flow for navigation that no interaction caused (back/forward, programmatic, redirects long
|
|
20
|
+
* after load). See `installRouteFlows`. Default `true`; pass `false` to keep route changes flowless.
|
|
21
|
+
*/
|
|
22
|
+
routeFlows?: boolean;
|
|
18
23
|
}
|
|
19
24
|
/**
|
|
20
25
|
* `x-lensmcp-origin-node-id` is a SOURCE PATH — `ui:src/features/billing/CardForm.tsx:118:click`.
|
package/lib/flow-fetch.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var v=Object.defineProperty;var
|
|
1
|
+
"use strict";var v=Object.defineProperty;var c=(t,e)=>v(t,"name",{value:e,configurable:!0});var N=Object.defineProperty,l=c((t,e)=>N(t,"name",{value:e,configurable:!0}),"f");import{beginBackgroundFlow as H,extendFlowWindow as b,flowForNewActivity as P,publish as p}from"./publish.js";import{installRouteFlows as R}from"./route-flows.js";export function mayPropagateTo(t,e=[]){const d=typeof location<"u"?location.href:void 0;let f;try{f=new URL(t,d)}catch{return!1}if(typeof location<"u"&&f.origin===location.origin||I(f.hostname))return!0;for(const n of e){let r;try{r=new URL(n).origin}catch{continue}if(r===f.origin)return!0}return!1}c(mayPropagateTo,"mayPropagateTo"),l(mayPropagateTo,"mayPropagateTo");const S=new Set(["localhost","[::1]","::1"]);function I(t){const e=t.toLowerCase();return S.has(e)||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(e)}c(I,"S"),l(I,"isLoopbackHost");function x(){const t=globalThis.__LENSMCP_FLOW_PROPAGATE__;return Array.isArray(t)?t.filter(e=>typeof e=="string"):typeof t=="string"?t.split(",").map(e=>e.trim()).filter(Boolean):[]}c(x,"N"),l(x,"globalPropagateList");function F(){return Date.now().toString(36)+Math.random().toString(36).slice(2,12)}c(F,"O"),l(F,"newRequestId");function w(t){return typeof t=="string"?t:t instanceof URL?t.href:t.url??String(t)}c(w,"$"),l(w,"urlOf");let L=!1;export function installFlowFetch(t={}){const e=globalThis;if(typeof e.fetch!="function")return()=>{};!L&&typeof location<"u"&&typeof document<"u"&&(L=!0,H({originType:"page-load",originNodeId:`page:${location.pathname}`}));const d=t.flowHeader??"x-lensmcp-flow-id",f=t.originHeader??"x-lensmcp-origin-node-id",n=t.requestHeader??"x-request-id",r=t.propagateTo??[],s=e.fetch.bind(globalThis);globalThis.__LENSMCP_FLOW_FETCH__=!0;const a=l(((i,o)=>{const g=P();if(!g?.flowId)return s(i,o);if(!mayPropagateTo(w(i),[...r,...x()])){const $=s(i,o);return y(g,i,o,$,void 0),$}const k=typeof i=="object"&&i!==null&&"headers"in i?i.headers:void 0,u=new Headers(o?.headers??k??void 0);u.has(d)||u.set(d,g.flowId),g.originNodeId&&!u.has(f)&&u.set(f,g.originNodeId);const m=u.get(n)??F();u.has(n)||u.set(n,m);const T=s(i,{...o,headers:u});return y(g,i,o,T,m),T}),"patched");e.fetch=a;const h=t.routeFlows===!1?()=>{}:R();return()=>{h(),e.fetch=s}}c(installFlowFetch,"installFlowFetch"),l(installFlowFetch,"installFlowFetch");function _(t){const e=typeof location<"u"?location.href:void 0;try{return new URL(t,e).href}catch{return}}c(_,"R"),l(_,"absoluteHref");function y(t,e,d,f,n){const r=w(e),s=_(r),a=d?.method??(typeof e=="object"&&e!==null&&"method"in e?e.method??"GET":"GET"),h=Date.now(),i={flowId:t.flowId,...t.originType?{originType:t.originType}:{},...t.originNodeId?{originNodeId:t.originNodeId}:{},...n?{requestId:n}:{}};p({source:"react",category:"network",severity:"info",title:`fetch ${a} ${r}`,fingerprint:`flow-fetch:${a}:${r}`,context:i,raw:{kind:"fetch-start",url:r,method:a,...s?{href:s}:{},...n?{requestId:n}:{}}}),f.then(o=>{b(t),p({source:"react",category:"network",severity:o.ok||o.status===304?"info":"error",title:`fetch ${a} ${r} \u2192 ${o.status}${o.statusText?` ${o.statusText}`:""}`,fingerprint:`flow-fetch:${a}:${r}:${o.status}`,context:i,raw:{kind:"fetch-done",url:r,...s?{href:s}:{},...n?{requestId:n}:{},method:a,status:o.status,statusText:o.statusText,ok:o.ok,startedAt:h,durationMs:Date.now()-h}})},o=>{b(t),p({source:"react",category:"network",severity:"error",title:`fetch ${a} ${r} failed`,message:o instanceof Error?o.message:String(o),fingerprint:`flow-fetch:${a}:${r}:error`,context:i,raw:{kind:"fetch-error",url:r,...s?{href:s}:{},...n?{requestId:n}:{},method:a,startedAt:h,durationMs:Date.now()-h}})})}c(y,"b"),l(y,"publishFetchLeg");
|
package/lib/publish.d.ts
CHANGED
|
@@ -30,6 +30,30 @@ declare global {
|
|
|
30
30
|
}
|
|
31
31
|
/** Test seam: what the queue is currently holding, in estimated bytes. */
|
|
32
32
|
export declare function queuedByteCount(): number;
|
|
33
|
+
/**
|
|
34
|
+
* AMBIENT flows are the ones nobody clicked: the page load, a route change, a rollover. They exist so
|
|
35
|
+
* the work that follows an event the page cannot attribute still has a trace to join — and the window
|
|
36
|
+
* above is what keeps them alive. Every fetch COMPLETION re-arms it, so a page that polls faster than
|
|
37
|
+
* the window (an interval under four seconds, a long-poll chain, an SSE reconnect loop) re-arms it
|
|
38
|
+
* forever: one flow, no end, every poll appended. A real workspace produced exactly that.
|
|
39
|
+
*
|
|
40
|
+
* So an ambient flow has a MAXIMUM AGE. Past it the window is no longer re-armed for that flow, and the
|
|
41
|
+
* NEXT piece of network activity starts a fresh one (`flowForNewActivity`) that records which flow it
|
|
42
|
+
* continues. A flow started by a user action is untouched: a click's flow stays whatever it has always
|
|
43
|
+
* been, because "what did my click cause" has no natural end the producer can judge.
|
|
44
|
+
*
|
|
45
|
+
* The age is a cap on a flow's length, not on its event count. A page load legitimately carries
|
|
46
|
+
* thousands of events in a few seconds with no causal seam to cut at; only time has one.
|
|
47
|
+
*/
|
|
48
|
+
export declare const DEFAULT_AMBIENT_FLOW_MAX_MS = 30000;
|
|
49
|
+
export interface AmbientFlowOptions {
|
|
50
|
+
/**
|
|
51
|
+
* Longest an ambient flow may live before the next network activity rolls it over to a new one.
|
|
52
|
+
* `0`, `Infinity` or `'off'` disables the cap (the pre-cap behaviour). Default 30 000 ms.
|
|
53
|
+
*/
|
|
54
|
+
maxLifetimeMs?: number | 'off';
|
|
55
|
+
}
|
|
56
|
+
export declare function configureAmbientFlows(options: AmbientFlowOptions): void;
|
|
33
57
|
export declare function extendFlowWindow(spec?: FlowSpec): void;
|
|
34
58
|
/** The flow that owns work happening NOW: sync stack first, else the window. */
|
|
35
59
|
export declare function activeFlow(): FlowSpec | undefined;
|
|
@@ -39,10 +63,30 @@ export declare function activeFlow(): FlowSpec | undefined;
|
|
|
39
63
|
* follows inherits the flow) and publishes the origin event that makes the
|
|
40
64
|
* flow exist in the reducer.
|
|
41
65
|
*/
|
|
42
|
-
export declare function beginBackgroundFlow(origin:
|
|
66
|
+
export declare function beginBackgroundFlow(origin: BackgroundFlowOrigin): FlowSpec;
|
|
67
|
+
/** What starts an ambient flow: the origin type and node, and — for a rollover — the flow it continues. */
|
|
68
|
+
export interface BackgroundFlowOrigin {
|
|
43
69
|
originType: string;
|
|
44
70
|
originNodeId?: string;
|
|
45
|
-
|
|
71
|
+
continuesFlowId?: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The flow that a piece of network activity issued RIGHT NOW belongs to — which is `activeFlow()`, except
|
|
75
|
+
* that an ambient flow past its age cap is rolled over first: a new background flow starts, with its own
|
|
76
|
+
* `flow-origin`, and the activity belongs to that.
|
|
77
|
+
*
|
|
78
|
+
* Only ambient flows roll over, and only when there is activity to attribute. A flow whose window simply
|
|
79
|
+
* lapsed (an idle page) is not resurrected, and a flow started by a user action is never rolled.
|
|
80
|
+
*/
|
|
81
|
+
export declare function flowForNewActivity(): FlowSpec | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* A flow's origin event is the one thing that makes it a flow rather than a fragment, so it must never
|
|
84
|
+
* be the event a flood guard throws away. Every guard on the path to the bus is a per-FINGERPRINT token
|
|
85
|
+
* bucket (burst 30, then 5/s) — and the origin used to share one fingerprint per origin NODE, so the
|
|
86
|
+
* 31st click on a button inside a few seconds lost its origin and its flow arrived headless. Unique per
|
|
87
|
+
* FLOW, the first event of a fingerprint is always admitted, whatever the buckets downstream are doing.
|
|
88
|
+
*/
|
|
89
|
+
export declare const FLOW_ORIGIN_FINGERPRINT_PREFIX = "flow-origin:";
|
|
46
90
|
export declare function setPublisher(fn: PublishFn | undefined): void;
|
|
47
91
|
/**
|
|
48
92
|
* Push a flow onto the module-level stack for the duration of `fn`. Any
|
|
@@ -85,6 +129,12 @@ export declare function publish(env: PublishEnvelope): void;
|
|
|
85
129
|
* clone or walk happens.
|
|
86
130
|
*/
|
|
87
131
|
export declare function publishLazy(fingerprint: string, build: () => PublishEnvelope): void;
|
|
132
|
+
/**
|
|
133
|
+
* Test hook: forget every flow, window and ambient record, and any configured cap. The flow state is module
|
|
134
|
+
* state by design (it must outlive a render), so a test that exercises window and rollover timing needs a
|
|
135
|
+
* clean slate that does not depend on running in a fresh module registry.
|
|
136
|
+
*/
|
|
137
|
+
export declare function resetFlowStateForTests(): void;
|
|
88
138
|
/** Test hook — only useful in unit tests / smokes. */
|
|
89
139
|
export declare function drainQueue(): PublishEnvelope[];
|
|
90
140
|
export {};
|
package/lib/publish.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var C=Object.defineProperty;var t=(e,o)=>C(e,"name",{value:o,configurable:!0});var O=Object.defineProperty,n=t((e,o)=>O(e,"name",{value:o,configurable:!0}),"t");import{createEventFloodGuard as W,estimateJsonBytes as U}from"@lensmcp/protocol-types";const u=[],$=200,v=(()=>{const e=typeof process<"u"?process.env?.LENSMCP_PUBLISH_QUEUE_BYTES:void 0,o=Number(e);return Number.isFinite(o)&&o>0?Math.floor(o):1024*1024})(),I=[];let s=0;function M(e){const o=U(e,v);for(u.push(e),I.push(o),s+=o;u.length>$||s>v&&u.length>1;)u.shift(),s-=I.shift()??0;u.length===0&&(s=0)}t(M,"W"),n(M,"enqueue");function S(){const e=u.shift();return s-=I.shift()??0,u.length===0&&(s=0),e}t(S,"k"),n(S,"dequeue");export function queuedByteCount(){return s}t(queuedByteCount,"queuedByteCount"),n(queuedByteCount,"queuedByteCount");const p=[],F=4e3;let c;export const DEFAULT_AMBIENT_FLOW_MAX_MS=3e4;let y;function N(e){if(e==="off"||e==="Infinity")return 1/0;const o=typeof e=="string"&&e.trim()!==""?Number(e):e;if(!(typeof o!="number"||Number.isNaN(o)||o<0))return o===0||o===1/0?1/0:o}t(N,"_"),n(N,"parseMaxLifetime");function L(){if(y!==void 0)return y;const e=N(globalThis.__LENSMCP_AMBIENT_FLOW_MAX_MS__);return e!==void 0?e:N(typeof process<"u"?process.env?.LENSMCP_AMBIENT_FLOW_MAX_MS:void 0)??DEFAULT_AMBIENT_FLOW_MAX_MS}t(L,"D"),n(L,"ambientMaxMs");export function configureAmbientFlows(e){y=e.maxLifetimeMs===void 0?void 0:N(e.maxLifetimeMs)}t(configureAmbientFlows,"configureAmbientFlows"),n(configureAmbientFlows,"configureAmbientFlows");const l=new Map,X=16;function E(e){for(l.set(e,{bornAt:Date.now()});l.size>X;)l.delete(l.keys().next().value)}t(E,"C"),n(E,"trackAmbient");function b(e){const o=l.get(e.flowId);if(!o)return!1;const i=L();return i!==1/0&&Date.now()-o.bornAt>=i}t(b,"x"),n(b,"ambientExhausted");export function extendFlowWindow(e){const o=e??currentFlow()??c?.spec;o&&(b(o)||(c={spec:o,until:Date.now()+F}))}t(extendFlowWindow,"extendFlowWindow"),n(extendFlowWindow,"extendFlowWindow");function a(){return c&&Date.now()<c.until?c.spec:void 0}t(a,"g"),n(a,"windowedFlow");export function activeFlow(){return currentFlow()??a()}t(activeFlow,"activeFlow"),n(activeFlow,"activeFlow");export function beginBackgroundFlow(e){const o={flowId:h(),originType:e.originType,...e.originNodeId?{originNodeId:e.originNodeId}:{}};return c={spec:o,until:Date.now()+F},E(o.flowId),publish({source:"react",category:"runtime",severity:"info",title:e.originType,fingerprint:_(e.originNodeId??e.originType,o.flowId),raw:{kind:"flow-origin",originNodeId:e.originNodeId,...e.continuesFlowId?{continuesFlowId:e.continuesFlowId}:{}}}),o}t(beginBackgroundFlow,"beginBackgroundFlow"),n(beginBackgroundFlow,"beginBackgroundFlow");export function flowForNewActivity(){const e=currentFlow();if(e)return e;const o=a();if(o)return b(o)?beginBackgroundFlow({originType:"timer",originNodeId:typeof location<"u"?`ambient:${location.pathname}`:"ambient",continuesFlowId:o.flowId}):o}t(flowForNewActivity,"flowForNewActivity"),n(flowForNewActivity,"flowForNewActivity");export const FLOW_ORIGIN_FINGERPRINT_PREFIX="flow-origin:";function _(e,o){return`${FLOW_ORIGIN_FINGERPRINT_PREFIX}${e}:${o}`}t(_,"M"),n(_,"originFingerprint");export function setPublisher(e){if(globalThis.__LENSMCP_PUBLISH__=e,e)for(;u.length;){const o=S();if(o)try{e(o)}catch{}}}t(setPublisher,"setPublisher"),n(setPublisher,"setPublisher");export function runInFlow(e,o){p.push(e),c={spec:e,until:Date.now()+F};try{return o()}finally{p.pop()}}t(runInFlow,"runInFlow"),n(runInFlow,"runInFlow");export function currentFlow(){return p[p.length-1]}t(currentFlow,"currentFlow"),n(currentFlow,"currentFlow");const B=Symbol.for("lensmcp.flowed"),A=2e3,f=new Map;function P(e){if(e==null||typeof e!="object")return;const o=e,i=o.nativeEvent;if(i!=null&&typeof i=="object"){const r=i.isTrusted;if(typeof r=="boolean")return r}if(typeof o.isTrusted=="boolean")return o.isTrusted}t(P,"v"),n(P,"eventTrust");function k(e){if(!(f.size<=64))for(const[o,i]of f)e>=i.until&&f.delete(o)}t(k,"X"),n(k,"pruneInputBursts");export function withFlow(e,o={}){if(typeof e!="function"||e[B])return e;const i=n(()=>{publish({source:"react",category:"runtime",severity:"info",title:o.originType??"user-click",fingerprint:_(o.originNodeId??"unknown",currentFlow()?.flowId??""),raw:{kind:"flow-origin",originNodeId:o.originNodeId}})},"publishOrigin"),r=n(function(...d){if(o.originType==="input-change"){if(P(d[0])===!1)return currentFlow()==null&&a()!=null&&extendFlowWindow(),e(...d);const T=o.originNodeId??"input",w=Date.now(),g=f.get(T);if(g&&w<g.until)return g.until=w+A,runInFlow(g.spec,()=>e(...d));const x={flowId:h(),originType:"input-change",originNodeId:o.originNodeId};return f.set(T,{spec:x,until:w+A}),k(w),runInFlow(x,()=>(i(),e(...d)))}const D=h();return runInFlow({flowId:D,originType:o.originType??"user-click",originNodeId:o.originNodeId},()=>(i(),e(...d)))},"flowed");return r[B]=!0,r}t(withFlow,"withFlow"),n(withFlow,"withFlow");let m=0;function h(){return m=(m+1)%65535,`flow:${Date.now().toString(36)}:${m.toString(36)}`}t(h,"E"),n(h,"newFlowId");export function publish(e){const o=currentFlow()??(e.context?.flowId?void 0:a()),i=o==null?e:{...e,context:{...o.flowId?{flowId:o.flowId}:{},...o.originType?{originType:o.originType}:{},...o.originNodeId?{originNodeId:o.originNodeId}:{},...o.causedByNodeId?{causedByNodeId:o.causedByNodeId}:{},...e.context}},r=globalThis.__LENSMCP_PUBLISH__;if(r)try{r(i);return}catch{}M(i)}t(publish,"publish"),n(publish,"publish");const j=W({burst:30,perSec:5});export function publishLazy(e,o){const i=e.startsWith(FLOW_ORIGIN_FINGERPRINT_PREFIX)?{ok:!0,suppressed:0}:j.admit(e);if(!i.ok)return;const r=o();if(i.suppressed>0&&r.raw!==null&&typeof r.raw=="object"){publish({...r,raw:{...r.raw,floodSuppressed:i.suppressed}});return}publish(r)}t(publishLazy,"publishLazy"),n(publishLazy,"publishLazy");export function resetFlowStateForTests(){p.length=0,c=void 0,l.clear(),f.clear(),y=void 0}t(resetFlowStateForTests,"resetFlowStateForTests"),n(resetFlowStateForTests,"resetFlowStateForTests");export function drainQueue(){return I.length=0,s=0,u.splice(0,u.length)}t(drainQueue,"drainQueue"),n(drainQueue,"drainQueue");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The slice of `window` this needs — named so a test (or a non-browser host) can provide its own. */
|
|
2
|
+
export interface RouteFlowEnvironment {
|
|
3
|
+
history: Pick<History, 'pushState' | 'replaceState'>;
|
|
4
|
+
location: Pick<Location, 'pathname'>;
|
|
5
|
+
addEventListener(type: 'popstate', listener: () => void): void;
|
|
6
|
+
removeEventListener(type: 'popstate', listener: () => void): void;
|
|
7
|
+
}
|
|
8
|
+
/** The node id of a route flow: `route:/companies/42/staff`. Pathname only, clipped. */
|
|
9
|
+
export declare function routeNodeId(pathname: string): string;
|
|
10
|
+
export declare function installRouteFlows(env?: RouteFlowEnvironment | undefined): () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var g=Object.defineProperty;var n=(e,o)=>g(e,"name",{value:o,configurable:!0});var S=Object.defineProperty,t=n((e,o)=>S(e,"name",{value:o,configurable:!0}),"e");import{activeFlow as m,beginBackgroundFlow as E}from"./publish.js";const f=200;function y(){const e=globalThis.window;if(!(!e?.history||!e.location||typeof e.addEventListener!="function"||typeof e.removeEventListener!="function"))return e}n(y,"E"),t(y,"browserEnvironment");export function routeNodeId(e){return`route:${e.length>f?e.slice(0,f):e}`}n(routeNodeId,"routeNodeId"),t(routeNodeId,"routeNodeId");let a;export function installRouteFlows(e=y()){if(!e)return()=>{};if(a)return()=>{};let o=e.location.pathname,s=!0;const i=t(()=>{if(!s)return;const r=e.location.pathname;r!==o&&(o=r,!m()&&E({originType:"route-load",originNodeId:routeNodeId(r)}))},"navigated"),u=t(r=>t(function(...v){const w=r.apply(this,v);try{i()}catch{}return w},"wrapped"),"wrap"),c=e.history.pushState,l=e.history.replaceState,p=u(c),h=u(l);e.history.pushState=p,e.history.replaceState=h,e.addEventListener("popstate",i);const d=t(()=>{s=!1,e.removeEventListener("popstate",i),e.history.pushState===p&&(e.history.pushState=c),e.history.replaceState===h&&(e.history.replaceState=l),a=void 0},"uninstall");return a=d,d}n(installRouteFlows,"installRouteFlows"),t(installRouteFlows,"installRouteFlows");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/react-instrumentation",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@lensmcp/protocol-types": "1.23.
|
|
22
|
+
"@lensmcp/protocol-types": "1.23.7",
|
|
23
23
|
"tslib": "^2.3.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|