@goliapkg/sentori-react-native 0.8.2 → 0.8.3
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/lib/capture.d.ts.map +1 -1
- package/lib/capture.js +30 -0
- package/lib/capture.js.map +1 -1
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -1
- package/lib/state-snapshots.d.ts +33 -0
- package/lib/state-snapshots.d.ts.map +1 -0
- package/lib/state-snapshots.js +109 -0
- package/lib/state-snapshots.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/state-snapshots.test.ts +119 -0
- package/src/capture.ts +38 -0
- package/src/index.ts +10 -0
- package/src/state-snapshots.ts +133 -0
package/lib/capture.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAoD,IAAI,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5F,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAgB5D,eAAO,MAAM,+BAA+B,QAAO,IAElD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,IAAI,GAAG,IAAI,KAAG,IAE3C,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,IAAI,GAAG,IAAa,CAAC;AAEhD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;qDAGiD;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAU,OAAO;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,KAAG,OAAO,CAAC,IAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,CAKxD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK,EAAE,SAAS,aAAa,KAAG,IAqEnE,CAAC;AAiEF,eAAO,MAAM,gBAAgB,UAtIO,KAAK,WAAW,aAAa,KAAG,IAsIxB,CAAC"}
|
package/lib/capture.js
CHANGED
|
@@ -3,6 +3,7 @@ import { addBreadcrumb, getBreadcrumbs } from './breadcrumbs';
|
|
|
3
3
|
import { getBundleInfo } from './bundle-info';
|
|
4
4
|
import { getConfig, isInitialized } from './config';
|
|
5
5
|
import { getFeatureFlagSnapshot } from './feature-flags';
|
|
6
|
+
import { clearStateSnapshots, getStateSnapshots } from './state-snapshots';
|
|
6
7
|
import { symbolicateErrorViaMetro } from './handlers/dev-symbolicate';
|
|
7
8
|
import { captureScreenshot } from './handlers/screenshot';
|
|
8
9
|
import { markSessionErrored } from './session-tracker';
|
|
@@ -112,10 +113,39 @@ export const captureError = (error, extras) => {
|
|
|
112
113
|
if (config.sessionTrailEnabled && trail.size() > 0) {
|
|
113
114
|
await captureAndAttachSessionTrail(event);
|
|
114
115
|
}
|
|
116
|
+
// v0.9.2 +S2 — state time-travel attachment. Only if anything has
|
|
117
|
+
// been bound or recorded; cleared on success so the next crash's
|
|
118
|
+
// ring doesn't carry stale entries.
|
|
119
|
+
const stateSnapshots = getStateSnapshots();
|
|
120
|
+
if (stateSnapshots.length > 0) {
|
|
121
|
+
await captureAndAttachStateSnapshots(event, stateSnapshots);
|
|
122
|
+
clearStateSnapshots();
|
|
123
|
+
}
|
|
115
124
|
enqueue(event);
|
|
116
125
|
};
|
|
117
126
|
void pipeline();
|
|
118
127
|
};
|
|
128
|
+
/** v0.9.2 +S2 — upload the rolling state-snapshot ring as a
|
|
129
|
+
* `stateSnapshot` attachment so the dashboard time-travel viewer can
|
|
130
|
+
* scrub through diffs alongside the breadcrumb timeline. */
|
|
131
|
+
async function captureAndAttachStateSnapshots(event, snapshots) {
|
|
132
|
+
try {
|
|
133
|
+
const payload = JSON.stringify({ snapshots });
|
|
134
|
+
const base64 = typeof globalThis.btoa === 'function'
|
|
135
|
+
? globalThis.btoa(payload)
|
|
136
|
+
: // Bun / node fallback
|
|
137
|
+
Buffer.from(payload, 'utf8').toString('base64');
|
|
138
|
+
const meta = await uploadAttachment(event.id, 'stateSnapshot', { base64, mediaType: 'application/json' }, { source: 'js' });
|
|
139
|
+
if (meta) {
|
|
140
|
+
if (!event.attachments)
|
|
141
|
+
event.attachments = [];
|
|
142
|
+
event.attachments.push(meta);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// best-effort
|
|
147
|
+
}
|
|
148
|
+
}
|
|
119
149
|
/**
|
|
120
150
|
* Phase 46 — seal the trail buffer, upload it as a `sessionTrail`
|
|
121
151
|
* attachment, attach the ref. Best-effort: any failure leaves a
|
package/lib/capture.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ErrorBoundary } from './error-boundary';
|
|
|
2
2
|
import { type FeedbackButtonHandle, type FeedbackButtonProps } from './feedback-widget';
|
|
3
3
|
import { clearMaskQuery, registerMaskQuery } from './mask';
|
|
4
4
|
import { measureFn } from './measure';
|
|
5
|
+
import { bindState, recordState, unbindState } from './state-snapshots';
|
|
5
6
|
import { startMoment } from '@goliapkg/sentori-core';
|
|
6
7
|
import { flushMetrics, recordMetric } from './metrics';
|
|
7
8
|
import { RageTapCapture } from './rage-tap';
|
|
@@ -27,6 +28,9 @@ export declare const sentori: {
|
|
|
27
28
|
flushMetrics: typeof flushMetrics;
|
|
28
29
|
measureFn: typeof measureFn;
|
|
29
30
|
startMoment: typeof startMoment;
|
|
31
|
+
bindState: typeof bindState;
|
|
32
|
+
recordState: typeof recordState;
|
|
33
|
+
unbindState: typeof unbindState;
|
|
30
34
|
setFeatureFlag: (name: string, value: string) => void;
|
|
31
35
|
clearFeatureFlag: (name: string) => void;
|
|
32
36
|
clearAllFeatureFlags: () => void;
|
|
@@ -51,6 +55,7 @@ export { clearMaskQuery, registerMaskQuery } from './mask';
|
|
|
51
55
|
export { flushMetrics, recordMetric } from './metrics';
|
|
52
56
|
export { measureFn } from './measure';
|
|
53
57
|
export { MomentHandle, type MomentProperties, startMoment } from '@goliapkg/sentori-core';
|
|
58
|
+
export { bindState, recordState, type StateSnapshot, unbindState, } from './state-snapshots';
|
|
54
59
|
export { RageTapCapture } from './rage-tap';
|
|
55
60
|
export { startAnrWatchdog, stopAnrWatchdog, triggerNativeCrash, } from './native';
|
|
56
61
|
export { endSession, markSessionCrashed, startSession, } from './session-tracker';
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAkB,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAOxG,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAO5C,eAAO,MAAM,OAAO;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAkB,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAOxG,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAO5C,eAAO,MAAM,OAAO;;;;;;;;;;aAuFiS,CAAC;eAAmB,CAAC;YAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;CA3D1V,CAAC;AAEF,eAAe,OAAO,CAAC;AAEvB,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxG,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EACL,SAAS,EACT,WAAW,EACX,KAAK,aAAa,EAClB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE1E,YAAY,EACV,KAAK,EACL,YAAY,EACZ,KAAK,EACL,UAAU,EACV,cAAc,EACd,MAAM,EACN,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,QAAQ,GACT,MAAM,SAAS,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { FeedbackButton } from './feedback-widget';
|
|
|
6
6
|
import { clearAllFeatureFlags, clearFeatureFlag, getFeatureFlags, setFeatureFlag, } from './feature-flags';
|
|
7
7
|
import { clearMaskQuery, registerMaskQuery } from './mask';
|
|
8
8
|
import { measureFn } from './measure';
|
|
9
|
+
import { bindState, recordState, unbindState } from './state-snapshots';
|
|
9
10
|
import { startMoment } from '@goliapkg/sentori-core';
|
|
10
11
|
import { flushMetrics, recordMetric } from './metrics';
|
|
11
12
|
import { RageTapCapture } from './rage-tap';
|
|
@@ -23,6 +24,9 @@ export const sentori = {
|
|
|
23
24
|
flushMetrics,
|
|
24
25
|
measureFn,
|
|
25
26
|
startMoment,
|
|
27
|
+
bindState,
|
|
28
|
+
recordState,
|
|
29
|
+
unbindState,
|
|
26
30
|
setFeatureFlag,
|
|
27
31
|
clearFeatureFlag,
|
|
28
32
|
clearAllFeatureFlags,
|
|
@@ -47,6 +51,7 @@ export { clearMaskQuery, registerMaskQuery } from './mask';
|
|
|
47
51
|
export { flushMetrics, recordMetric } from './metrics';
|
|
48
52
|
export { measureFn } from './measure';
|
|
49
53
|
export { MomentHandle, startMoment } from '@goliapkg/sentori-core';
|
|
54
|
+
export { bindState, recordState, unbindState, } from './state-snapshots';
|
|
50
55
|
export { RageTapCapture } from './rage-tap';
|
|
51
56
|
export { startAnrWatchdog, stopAnrWatchdog, triggerNativeCrash, } from './native';
|
|
52
57
|
export { endSession, markSessionCrashed, startSession, } from './session-tracker';
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAuD,MAAM,mBAAmB,CAAC;AACxG,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,IAAI;IACJ,aAAa;IACb,OAAO;IACP,OAAO;IACP,YAAY;IACZ,gBAAgB;IAChB,WAAW;IACX,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ,SAAS;IACT,WAAW;IACX,cAAc;IACd,gBAAgB;IAChB,oBAAoB;IACpB,eAAe;IACf,aAAa;IACb,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,cAAc;IACd,YAAY;IACZ,UAAU;IACV,kBAAkB;CACnB,CAAC;AAEF,eAAe,OAAO,CAAC;AAEvB,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAuD,MAAM,mBAAmB,CAAC;AACxG,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAyB,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA0B,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAuD,MAAM,mBAAmB,CAAC;AACxG,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,IAAI;IACJ,aAAa;IACb,OAAO;IACP,OAAO;IACP,YAAY;IACZ,gBAAgB;IAChB,WAAW;IACX,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ,SAAS;IACT,WAAW;IACX,SAAS;IACT,WAAW;IACX,WAAW;IACX,cAAc;IACd,gBAAgB;IAChB,oBAAoB;IACpB,eAAe;IACf,aAAa;IACb,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,cAAc;IACd,YAAY;IACZ,UAAU;IACV,kBAAkB;CACnB,CAAC;AAEF,eAAe,OAAO,CAAC;AAEvB,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAuD,MAAM,mBAAmB,CAAC;AACxG,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAyB,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EACL,SAAS,EACT,WAAW,EAEX,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA0B,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type StoreLike = {
|
|
2
|
+
getState?: () => unknown;
|
|
3
|
+
subscribe?: (cb: () => void) => () => void;
|
|
4
|
+
};
|
|
5
|
+
export type StateSnapshot = {
|
|
6
|
+
/** Wall-clock when the diff fired. */
|
|
7
|
+
ts: number;
|
|
8
|
+
/** Top-level key/value diff vs the previous snapshot. Empty diff
|
|
9
|
+
* doesn't get recorded. */
|
|
10
|
+
diff: Record<string, unknown>;
|
|
11
|
+
/** Source label so the viewer can show "Redux" / "Zustand" / "Manual". */
|
|
12
|
+
source: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function bindState(opts: {
|
|
15
|
+
redux?: StoreLike;
|
|
16
|
+
zustand?: StoreLike;
|
|
17
|
+
/** Additional named stores. The label is used as the snapshot's
|
|
18
|
+
* `source` and as the diff bucket key. */
|
|
19
|
+
custom?: Record<string, StoreLike>;
|
|
20
|
+
}): void;
|
|
21
|
+
export declare function unbindState(): void;
|
|
22
|
+
/** Manual recording for state not in a subscribed store. */
|
|
23
|
+
export declare function recordState(snapshot: Record<string, unknown>, source?: string): void;
|
|
24
|
+
export declare function getStateSnapshots(): StateSnapshot[];
|
|
25
|
+
export declare function clearStateSnapshots(): void;
|
|
26
|
+
/** Returns the top-level key/value diff (next has the value, prev
|
|
27
|
+
* may not contain the key). Empty diff returns `{}` so callers can
|
|
28
|
+
* no-op on empty. */
|
|
29
|
+
export declare function shallowDiff(prev: unknown, next: unknown): null | Record<string, unknown>;
|
|
30
|
+
/** Test-only. */
|
|
31
|
+
export declare function __resetStateSnapshotsForTests(): void;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=state-snapshots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-snapshots.d.ts","sourceRoot":"","sources":["../src/state-snapshots.ts"],"names":[],"mappings":"AAwBA,KAAK,SAAS,GAAG;IACf,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX;gCAC4B;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAMF,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;+CAC2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACpC,GAAG,IAAI,CASP;AAsBD,wBAAgB,WAAW,IAAI,IAAI,CAUlC;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,SAAW,GAAG,IAAI,CAEtF;AAED,wBAAgB,iBAAiB,IAAI,aAAa,EAAE,CAEnD;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAOD;;sBAEsB;AACtB,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAaxF;AAED,iBAAiB;AACjB,wBAAgB,6BAA6B,IAAI,IAAI,CAGpD"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// v0.9.2 +S2 — State Time-travel (SDK side).
|
|
2
|
+
//
|
|
3
|
+
// `sentori.bindState({ redux, zustand })` subscribes to a store-like
|
|
4
|
+
// object and records a shallow diff every time it emits a change.
|
|
5
|
+
// A ring buffer of the last N snapshots travels with each
|
|
6
|
+
// captureException as a `stateSnapshot` attachment — the dashboard's
|
|
7
|
+
// time-travel viewer (v0.9.2.1) renders the timeline.
|
|
8
|
+
//
|
|
9
|
+
// Why diffs and not full snapshots:
|
|
10
|
+
// • prod stores can be huge (carts, paginated lists, etc.)
|
|
11
|
+
// • a diff drops to ~1% of full snapshot size in typical apps
|
|
12
|
+
// • the viewer rehydrates by applying diffs forward from a baseline
|
|
13
|
+
//
|
|
14
|
+
// `recordState(obj)` is the manual escape hatch for state that isn't
|
|
15
|
+
// in a redux/zustand store (e.g. `useState` in a deeply-nested
|
|
16
|
+
// component, or React Context). The host calls it where it makes sense.
|
|
17
|
+
//
|
|
18
|
+
// Privacy: the same mask query that protects screenshots is consulted
|
|
19
|
+
// before serializing — any path matching `nativeID` shape isn't yet,
|
|
20
|
+
// but `mask.matchPath` can be added later. v0.9.2 ships without
|
|
21
|
+
// path masking; consumers should keep PII out of bindState scopes.
|
|
22
|
+
const MAX_SNAPSHOTS = 50;
|
|
23
|
+
let _snapshots = [];
|
|
24
|
+
let _unsubscribers = [];
|
|
25
|
+
let _lastByLabel = {};
|
|
26
|
+
export function bindState(opts) {
|
|
27
|
+
unbindState();
|
|
28
|
+
bindOne('redux', opts.redux);
|
|
29
|
+
bindOne('zustand', opts.zustand);
|
|
30
|
+
if (opts.custom) {
|
|
31
|
+
for (const [label, store] of Object.entries(opts.custom)) {
|
|
32
|
+
bindOne(label, store);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function bindOne(label, store) {
|
|
37
|
+
if (!store)
|
|
38
|
+
return;
|
|
39
|
+
if (typeof store.getState !== 'function' || typeof store.subscribe !== 'function')
|
|
40
|
+
return;
|
|
41
|
+
try {
|
|
42
|
+
_lastByLabel[label] = store.getState();
|
|
43
|
+
const unsub = store.subscribe(() => {
|
|
44
|
+
const next = store.getState();
|
|
45
|
+
const prev = _lastByLabel[label];
|
|
46
|
+
const diff = shallowDiff(prev, next);
|
|
47
|
+
if (diff && Object.keys(diff).length > 0) {
|
|
48
|
+
push({ diff, source: label, ts: Date.now() });
|
|
49
|
+
}
|
|
50
|
+
_lastByLabel[label] = next;
|
|
51
|
+
});
|
|
52
|
+
_unsubscribers.push(unsub);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// ignore bad stores
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function unbindState() {
|
|
59
|
+
for (const u of _unsubscribers) {
|
|
60
|
+
try {
|
|
61
|
+
u();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// ignore
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
_unsubscribers = [];
|
|
68
|
+
_lastByLabel = {};
|
|
69
|
+
}
|
|
70
|
+
/** Manual recording for state not in a subscribed store. */
|
|
71
|
+
export function recordState(snapshot, source = 'manual') {
|
|
72
|
+
push({ diff: snapshot, source, ts: Date.now() });
|
|
73
|
+
}
|
|
74
|
+
export function getStateSnapshots() {
|
|
75
|
+
return _snapshots.slice();
|
|
76
|
+
}
|
|
77
|
+
export function clearStateSnapshots() {
|
|
78
|
+
_snapshots = [];
|
|
79
|
+
}
|
|
80
|
+
function push(s) {
|
|
81
|
+
_snapshots.push(s);
|
|
82
|
+
while (_snapshots.length > MAX_SNAPSHOTS)
|
|
83
|
+
_snapshots.shift();
|
|
84
|
+
}
|
|
85
|
+
/** Returns the top-level key/value diff (next has the value, prev
|
|
86
|
+
* may not contain the key). Empty diff returns `{}` so callers can
|
|
87
|
+
* no-op on empty. */
|
|
88
|
+
export function shallowDiff(prev, next) {
|
|
89
|
+
if (typeof next !== 'object' || next === null)
|
|
90
|
+
return null;
|
|
91
|
+
const nObj = next;
|
|
92
|
+
if (typeof prev !== 'object' || prev === null) {
|
|
93
|
+
return { ...nObj };
|
|
94
|
+
}
|
|
95
|
+
const pObj = prev;
|
|
96
|
+
const out = {};
|
|
97
|
+
const keys = new Set([...Object.keys(pObj), ...Object.keys(nObj)]);
|
|
98
|
+
for (const k of keys) {
|
|
99
|
+
if (pObj[k] !== nObj[k])
|
|
100
|
+
out[k] = nObj[k];
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
/** Test-only. */
|
|
105
|
+
export function __resetStateSnapshotsForTests() {
|
|
106
|
+
unbindState();
|
|
107
|
+
_snapshots = [];
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=state-snapshots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-snapshots.js","sourceRoot":"","sources":["../src/state-snapshots.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goliapkg/sentori-react-native",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "Sentori SDK for React Native \u2014 JS-layer error capture, native crash handlers (iOS / Android), batched transport, fetch + react-navigation tracing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://sentori.golia.jp",
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
__resetStateSnapshotsForTests,
|
|
5
|
+
bindState,
|
|
6
|
+
getStateSnapshots,
|
|
7
|
+
recordState,
|
|
8
|
+
shallowDiff,
|
|
9
|
+
unbindState,
|
|
10
|
+
} from '../state-snapshots';
|
|
11
|
+
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
__resetStateSnapshotsForTests();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('shallowDiff', () => {
|
|
17
|
+
test('emits only changed top-level keys', () => {
|
|
18
|
+
const a = { foo: 1, bar: 2 };
|
|
19
|
+
const b = { bar: 2, foo: 3 };
|
|
20
|
+
expect(shallowDiff(a, b)).toEqual({ foo: 3 });
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('emits new keys from next', () => {
|
|
24
|
+
expect(shallowDiff({ a: 1 }, { a: 1, b: 2 })).toEqual({ b: 2 });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('treats deletion as undefined', () => {
|
|
28
|
+
expect(shallowDiff({ a: 1, b: 2 }, { a: 1 })).toEqual({ b: undefined });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('no change returns empty object', () => {
|
|
32
|
+
expect(shallowDiff({ a: 1 }, { a: 1 })).toEqual({});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('non-object prev → full clone of next', () => {
|
|
36
|
+
expect(shallowDiff(undefined, { a: 1 })).toEqual({ a: 1 });
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('recordState', () => {
|
|
41
|
+
test('appends snapshot with default source=manual', () => {
|
|
42
|
+
recordState({ cart: 3 });
|
|
43
|
+
const snaps = getStateSnapshots();
|
|
44
|
+
expect(snaps.length).toBe(1);
|
|
45
|
+
expect(snaps[0]!.source).toBe('manual');
|
|
46
|
+
expect(snaps[0]!.diff).toEqual({ cart: 3 });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('caps at 50 snapshots (ring buffer)', () => {
|
|
50
|
+
for (let i = 0; i < 60; i++) recordState({ n: i });
|
|
51
|
+
expect(getStateSnapshots().length).toBe(50);
|
|
52
|
+
// oldest 10 dropped; first kept entry has n=10
|
|
53
|
+
expect(getStateSnapshots()[0]!.diff).toEqual({ n: 10 });
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('bindState', () => {
|
|
58
|
+
test('subscribes to a redux-like store and records diffs', () => {
|
|
59
|
+
let state: { count: number } = { count: 0 };
|
|
60
|
+
const listeners: (() => void)[] = [];
|
|
61
|
+
const store = {
|
|
62
|
+
getState: () => state,
|
|
63
|
+
subscribe: (cb: () => void) => {
|
|
64
|
+
listeners.push(cb);
|
|
65
|
+
return () => {
|
|
66
|
+
const i = listeners.indexOf(cb);
|
|
67
|
+
if (i >= 0) listeners.splice(i, 1);
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
bindState({ redux: store });
|
|
72
|
+
state = { count: 1 };
|
|
73
|
+
listeners.forEach((l) => l());
|
|
74
|
+
state = { count: 2 };
|
|
75
|
+
listeners.forEach((l) => l());
|
|
76
|
+
|
|
77
|
+
const snaps = getStateSnapshots();
|
|
78
|
+
expect(snaps.length).toBe(2);
|
|
79
|
+
expect(snaps[0]!.diff).toEqual({ count: 1 });
|
|
80
|
+
expect(snaps[1]!.diff).toEqual({ count: 2 });
|
|
81
|
+
expect(snaps[0]!.source).toBe('redux');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('unbindState stops recording', () => {
|
|
85
|
+
let state: { v: number } = { v: 0 };
|
|
86
|
+
const listeners: (() => void)[] = [];
|
|
87
|
+
const store = {
|
|
88
|
+
getState: () => state,
|
|
89
|
+
subscribe: (cb: () => void) => {
|
|
90
|
+
listeners.push(cb);
|
|
91
|
+
return () => listeners.splice(listeners.indexOf(cb), 1);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
bindState({ redux: store });
|
|
95
|
+
state = { v: 1 };
|
|
96
|
+
listeners.forEach((l) => l());
|
|
97
|
+
unbindState();
|
|
98
|
+
state = { v: 2 };
|
|
99
|
+
listeners.forEach((l) => l());
|
|
100
|
+
|
|
101
|
+
expect(getStateSnapshots().length).toBe(1);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('custom stores produce labeled snapshots', () => {
|
|
105
|
+
let auth = { user: null };
|
|
106
|
+
const listeners: (() => void)[] = [];
|
|
107
|
+
const store = {
|
|
108
|
+
getState: () => auth,
|
|
109
|
+
subscribe: (cb: () => void) => {
|
|
110
|
+
listeners.push(cb);
|
|
111
|
+
return () => listeners.splice(listeners.indexOf(cb), 1);
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
bindState({ custom: { auth: store } });
|
|
115
|
+
auth = { user: 'alice' as never };
|
|
116
|
+
listeners.forEach((l) => l());
|
|
117
|
+
expect(getStateSnapshots()[0]!.source).toBe('auth');
|
|
118
|
+
});
|
|
119
|
+
});
|
package/src/capture.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { addBreadcrumb, getBreadcrumbs } from './breadcrumbs';
|
|
|
4
4
|
import { getBundleInfo } from './bundle-info';
|
|
5
5
|
import { getConfig, isInitialized } from './config';
|
|
6
6
|
import { getFeatureFlagSnapshot } from './feature-flags';
|
|
7
|
+
import { clearStateSnapshots, getStateSnapshots } from './state-snapshots';
|
|
7
8
|
import { symbolicateErrorViaMetro } from './handlers/dev-symbolicate';
|
|
8
9
|
import { captureScreenshot } from './handlers/screenshot';
|
|
9
10
|
import { markSessionErrored } from './session-tracker';
|
|
@@ -144,11 +145,48 @@ export const captureError = (error: Error, extras?: CaptureExtras): void => {
|
|
|
144
145
|
if (config.sessionTrailEnabled && trail.size() > 0) {
|
|
145
146
|
await captureAndAttachSessionTrail(event);
|
|
146
147
|
}
|
|
148
|
+
// v0.9.2 +S2 — state time-travel attachment. Only if anything has
|
|
149
|
+
// been bound or recorded; cleared on success so the next crash's
|
|
150
|
+
// ring doesn't carry stale entries.
|
|
151
|
+
const stateSnapshots = getStateSnapshots();
|
|
152
|
+
if (stateSnapshots.length > 0) {
|
|
153
|
+
await captureAndAttachStateSnapshots(event, stateSnapshots);
|
|
154
|
+
clearStateSnapshots();
|
|
155
|
+
}
|
|
147
156
|
enqueue(event);
|
|
148
157
|
};
|
|
149
158
|
void pipeline();
|
|
150
159
|
};
|
|
151
160
|
|
|
161
|
+
/** v0.9.2 +S2 — upload the rolling state-snapshot ring as a
|
|
162
|
+
* `stateSnapshot` attachment so the dashboard time-travel viewer can
|
|
163
|
+
* scrub through diffs alongside the breadcrumb timeline. */
|
|
164
|
+
async function captureAndAttachStateSnapshots(
|
|
165
|
+
event: Event,
|
|
166
|
+
snapshots: ReturnType<typeof getStateSnapshots>,
|
|
167
|
+
): Promise<void> {
|
|
168
|
+
try {
|
|
169
|
+
const payload = JSON.stringify({ snapshots });
|
|
170
|
+
const base64 =
|
|
171
|
+
typeof globalThis.btoa === 'function'
|
|
172
|
+
? globalThis.btoa(payload)
|
|
173
|
+
: // Bun / node fallback
|
|
174
|
+
Buffer.from(payload, 'utf8').toString('base64');
|
|
175
|
+
const meta = await uploadAttachment(
|
|
176
|
+
event.id,
|
|
177
|
+
'stateSnapshot',
|
|
178
|
+
{ base64, mediaType: 'application/json' },
|
|
179
|
+
{ source: 'js' },
|
|
180
|
+
);
|
|
181
|
+
if (meta) {
|
|
182
|
+
if (!event.attachments) event.attachments = [];
|
|
183
|
+
event.attachments.push(meta);
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
// best-effort
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
152
190
|
/**
|
|
153
191
|
* Phase 46 — seal the trail buffer, upload it as a `sessionTrail`
|
|
154
192
|
* attachment, attach the ref. Best-effort: any failure leaves a
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from './feature-flags';
|
|
19
19
|
import { clearMaskQuery, registerMaskQuery } from './mask';
|
|
20
20
|
import { measureFn } from './measure';
|
|
21
|
+
import { bindState, recordState, unbindState } from './state-snapshots';
|
|
21
22
|
import { startMoment } from '@goliapkg/sentori-core';
|
|
22
23
|
import { flushMetrics, recordMetric } from './metrics';
|
|
23
24
|
import { RageTapCapture } from './rage-tap';
|
|
@@ -40,6 +41,9 @@ export const sentori = {
|
|
|
40
41
|
flushMetrics,
|
|
41
42
|
measureFn,
|
|
42
43
|
startMoment,
|
|
44
|
+
bindState,
|
|
45
|
+
recordState,
|
|
46
|
+
unbindState,
|
|
43
47
|
setFeatureFlag,
|
|
44
48
|
clearFeatureFlag,
|
|
45
49
|
clearAllFeatureFlags,
|
|
@@ -78,6 +82,12 @@ export { clearMaskQuery, registerMaskQuery } from './mask';
|
|
|
78
82
|
export { flushMetrics, recordMetric } from './metrics';
|
|
79
83
|
export { measureFn } from './measure';
|
|
80
84
|
export { MomentHandle, type MomentProperties, startMoment } from '@goliapkg/sentori-core';
|
|
85
|
+
export {
|
|
86
|
+
bindState,
|
|
87
|
+
recordState,
|
|
88
|
+
type StateSnapshot,
|
|
89
|
+
unbindState,
|
|
90
|
+
} from './state-snapshots';
|
|
81
91
|
export { RageTapCapture } from './rage-tap';
|
|
82
92
|
export {
|
|
83
93
|
startAnrWatchdog,
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// v0.9.2 +S2 — State Time-travel (SDK side).
|
|
2
|
+
//
|
|
3
|
+
// `sentori.bindState({ redux, zustand })` subscribes to a store-like
|
|
4
|
+
// object and records a shallow diff every time it emits a change.
|
|
5
|
+
// A ring buffer of the last N snapshots travels with each
|
|
6
|
+
// captureException as a `stateSnapshot` attachment — the dashboard's
|
|
7
|
+
// time-travel viewer (v0.9.2.1) renders the timeline.
|
|
8
|
+
//
|
|
9
|
+
// Why diffs and not full snapshots:
|
|
10
|
+
// • prod stores can be huge (carts, paginated lists, etc.)
|
|
11
|
+
// • a diff drops to ~1% of full snapshot size in typical apps
|
|
12
|
+
// • the viewer rehydrates by applying diffs forward from a baseline
|
|
13
|
+
//
|
|
14
|
+
// `recordState(obj)` is the manual escape hatch for state that isn't
|
|
15
|
+
// in a redux/zustand store (e.g. `useState` in a deeply-nested
|
|
16
|
+
// component, or React Context). The host calls it where it makes sense.
|
|
17
|
+
//
|
|
18
|
+
// Privacy: the same mask query that protects screenshots is consulted
|
|
19
|
+
// before serializing — any path matching `nativeID` shape isn't yet,
|
|
20
|
+
// but `mask.matchPath` can be added later. v0.9.2 ships without
|
|
21
|
+
// path masking; consumers should keep PII out of bindState scopes.
|
|
22
|
+
|
|
23
|
+
const MAX_SNAPSHOTS = 50;
|
|
24
|
+
|
|
25
|
+
type StoreLike = {
|
|
26
|
+
getState?: () => unknown;
|
|
27
|
+
subscribe?: (cb: () => void) => () => void;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type StateSnapshot = {
|
|
31
|
+
/** Wall-clock when the diff fired. */
|
|
32
|
+
ts: number;
|
|
33
|
+
/** Top-level key/value diff vs the previous snapshot. Empty diff
|
|
34
|
+
* doesn't get recorded. */
|
|
35
|
+
diff: Record<string, unknown>;
|
|
36
|
+
/** Source label so the viewer can show "Redux" / "Zustand" / "Manual". */
|
|
37
|
+
source: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let _snapshots: StateSnapshot[] = [];
|
|
41
|
+
let _unsubscribers: (() => void)[] = [];
|
|
42
|
+
let _lastByLabel: Record<string, unknown> = {};
|
|
43
|
+
|
|
44
|
+
export function bindState(opts: {
|
|
45
|
+
redux?: StoreLike;
|
|
46
|
+
zustand?: StoreLike;
|
|
47
|
+
/** Additional named stores. The label is used as the snapshot's
|
|
48
|
+
* `source` and as the diff bucket key. */
|
|
49
|
+
custom?: Record<string, StoreLike>;
|
|
50
|
+
}): void {
|
|
51
|
+
unbindState();
|
|
52
|
+
bindOne('redux', opts.redux);
|
|
53
|
+
bindOne('zustand', opts.zustand);
|
|
54
|
+
if (opts.custom) {
|
|
55
|
+
for (const [label, store] of Object.entries(opts.custom)) {
|
|
56
|
+
bindOne(label, store);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function bindOne(label: string, store?: StoreLike): void {
|
|
62
|
+
if (!store) return;
|
|
63
|
+
if (typeof store.getState !== 'function' || typeof store.subscribe !== 'function') return;
|
|
64
|
+
try {
|
|
65
|
+
_lastByLabel[label] = store.getState();
|
|
66
|
+
const unsub = store.subscribe(() => {
|
|
67
|
+
const next = store.getState!();
|
|
68
|
+
const prev = _lastByLabel[label];
|
|
69
|
+
const diff = shallowDiff(prev, next);
|
|
70
|
+
if (diff && Object.keys(diff).length > 0) {
|
|
71
|
+
push({ diff, source: label, ts: Date.now() });
|
|
72
|
+
}
|
|
73
|
+
_lastByLabel[label] = next;
|
|
74
|
+
});
|
|
75
|
+
_unsubscribers.push(unsub);
|
|
76
|
+
} catch {
|
|
77
|
+
// ignore bad stores
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function unbindState(): void {
|
|
82
|
+
for (const u of _unsubscribers) {
|
|
83
|
+
try {
|
|
84
|
+
u();
|
|
85
|
+
} catch {
|
|
86
|
+
// ignore
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
_unsubscribers = [];
|
|
90
|
+
_lastByLabel = {};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Manual recording for state not in a subscribed store. */
|
|
94
|
+
export function recordState(snapshot: Record<string, unknown>, source = 'manual'): void {
|
|
95
|
+
push({ diff: snapshot, source, ts: Date.now() });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function getStateSnapshots(): StateSnapshot[] {
|
|
99
|
+
return _snapshots.slice();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function clearStateSnapshots(): void {
|
|
103
|
+
_snapshots = [];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function push(s: StateSnapshot): void {
|
|
107
|
+
_snapshots.push(s);
|
|
108
|
+
while (_snapshots.length > MAX_SNAPSHOTS) _snapshots.shift();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Returns the top-level key/value diff (next has the value, prev
|
|
112
|
+
* may not contain the key). Empty diff returns `{}` so callers can
|
|
113
|
+
* no-op on empty. */
|
|
114
|
+
export function shallowDiff(prev: unknown, next: unknown): null | Record<string, unknown> {
|
|
115
|
+
if (typeof next !== 'object' || next === null) return null;
|
|
116
|
+
const nObj = next as Record<string, unknown>;
|
|
117
|
+
if (typeof prev !== 'object' || prev === null) {
|
|
118
|
+
return { ...nObj };
|
|
119
|
+
}
|
|
120
|
+
const pObj = prev as Record<string, unknown>;
|
|
121
|
+
const out: Record<string, unknown> = {};
|
|
122
|
+
const keys = new Set([...Object.keys(pObj), ...Object.keys(nObj)]);
|
|
123
|
+
for (const k of keys) {
|
|
124
|
+
if (pObj[k] !== nObj[k]) out[k] = nObj[k];
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Test-only. */
|
|
130
|
+
export function __resetStateSnapshotsForTests(): void {
|
|
131
|
+
unbindState();
|
|
132
|
+
_snapshots = [];
|
|
133
|
+
}
|