@reticlehq/browser 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/actions-dom.js +10 -10
- package/dist/actions/actions.d.ts +13 -0
- package/dist/actions/actions.js +45 -15
- package/dist/actions/scroll.js +1 -1
- package/dist/commands/commands.js +39 -22
- package/dist/connect-options.d.ts +103 -0
- package/dist/connect-options.js +1 -0
- package/dist/dom/a11y.js +20 -20
- package/dist/dom/auto-anchor.js +1 -1
- package/dist/dom/blind-spots.js +1 -1
- package/dist/dom/chart.js +5 -5
- package/dist/dom/desktop-capture.d.ts +2 -1
- package/dist/dom/desktop-capture.js +4 -4
- package/dist/dom/occlusion.js +2 -2
- package/dist/dom/query.js +28 -18
- package/dist/dom/realm.js +13 -13
- package/dist/dom/refs.d.ts +14 -0
- package/dist/dom/refs.js +20 -1
- package/dist/dom/shadow-registry.js +2 -2
- package/dist/dom/snapshot.js +7 -7
- package/dist/dom/source.js +3 -3
- package/dist/dom/theme.js +6 -6
- package/dist/dom/virtualized.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/observers/blind-spots.js +2 -2
- package/dist/observers/console.js +3 -3
- package/dist/observers/dom.js +5 -5
- package/dist/observers/download.d.ts +2 -1
- package/dist/observers/download.js +2 -2
- package/dist/observers/focus.js +1 -1
- package/dist/observers/frames.js +1 -1
- package/dist/observers/health.js +70 -2
- package/dist/observers/install-all.d.ts +2 -1
- package/dist/observers/ipc.d.ts +2 -7
- package/dist/observers/ipc.js +7 -7
- package/dist/observers/network-body.js +2 -2
- package/dist/observers/network-redact.js +5 -5
- package/dist/observers/network-stream.js +2 -2
- package/dist/observers/network.d.ts +3 -3
- package/dist/observers/network.js +9 -9
- package/dist/observers/perf.js +1 -1
- package/dist/observers/scroll.js +1 -1
- package/dist/observers/state.js +1 -1
- package/dist/observers/storage.js +7 -7
- package/dist/presenter/presenter-brand.d.ts +19 -0
- package/dist/presenter/presenter-brand.js +21 -0
- package/dist/presenter/presenter-config.d.ts +17 -0
- package/dist/presenter/presenter-config.js +21 -0
- package/dist/presenter/presenter-controls.d.ts +1 -11
- package/dist/presenter/presenter-controls.js +6 -7
- package/dist/presenter/presenter-log.js +2 -2
- package/dist/presenter/presenter-run-state.js +1 -1
- package/dist/presenter/presenter-styles.d.ts +1 -1
- package/dist/presenter/presenter-styles.js +20 -9
- package/dist/presenter/presenter-tally.js +3 -3
- package/dist/presenter/presenter-test-helpers.d.ts +2 -1
- package/dist/presenter/presenter-test-helpers.js +2 -2
- package/dist/presenter/presenter-verbs.js +16 -11
- package/dist/presenter/presenter.js +13 -10
- package/dist/recorder/recorder.js +10 -9
- package/dist/registry/capabilities.d.ts +2 -0
- package/dist/registry/capabilities.js +16 -0
- package/dist/registry/store-adapters.d.ts +127 -1
- package/dist/registry/store-adapters.js +178 -0
- package/dist/registry/stores.js +3 -3
- package/dist/reticle-presenter-helpers.js +3 -3
- package/dist/reticle.d.ts +2 -57
- package/dist/reticle.js +57 -14
- package/dist/review/annotator.js +7 -7
- package/dist/security/serialization.js +9 -9
- package/dist/session-continuity.d.ts +17 -0
- package/dist/session-continuity.js +42 -0
- package/dist/timers/clock.js +4 -4
- package/dist/timers/native-console.js +1 -1
- package/dist/timers/native-timers.js +4 -4
- package/dist/transport/transport.d.ts +10 -0
- package/dist/transport/transport.js +19 -5
- package/package.json +11 -4
package/dist/timers/clock.js
CHANGED
|
@@ -12,7 +12,7 @@ export function isClockFrozen() {
|
|
|
12
12
|
return installed;
|
|
13
13
|
}
|
|
14
14
|
export function freezeClock() {
|
|
15
|
-
if (installed || typeof window
|
|
15
|
+
if (installed || 'undefined' === typeof window)
|
|
16
16
|
return;
|
|
17
17
|
installed = true;
|
|
18
18
|
virtualNow = 0;
|
|
@@ -81,7 +81,7 @@ export function advanceClock(ms) {
|
|
|
81
81
|
* in still has ~3s to go), and the ids the app is holding keep working — see the translation note.
|
|
82
82
|
*/
|
|
83
83
|
export function resetClock() {
|
|
84
|
-
if (!installed ||
|
|
84
|
+
if (!installed || null === originals)
|
|
85
85
|
return;
|
|
86
86
|
const natives = originals;
|
|
87
87
|
const pending = tasks;
|
|
@@ -95,7 +95,7 @@ export function resetClock() {
|
|
|
95
95
|
tasks = [];
|
|
96
96
|
installed = false;
|
|
97
97
|
virtualNow = 0;
|
|
98
|
-
if (pending.length
|
|
98
|
+
if (0 === pending.length)
|
|
99
99
|
return;
|
|
100
100
|
// Re-arm the app's pending work onto REAL timers, translating ids as we go.
|
|
101
101
|
//
|
|
@@ -112,7 +112,7 @@ export function resetClock() {
|
|
|
112
112
|
const reArmed = new Map();
|
|
113
113
|
const done = (virtualId) => {
|
|
114
114
|
reArmed.delete(virtualId);
|
|
115
|
-
if (reArmed.size
|
|
115
|
+
if (0 === reArmed.size)
|
|
116
116
|
restoreRawClears(natives);
|
|
117
117
|
};
|
|
118
118
|
for (const task of pending) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// MUST use this instead of bare `console.warn` — otherwise they emit spurious CONSOLE_WARN
|
|
4
4
|
// events to the agent, polluting the observation stream with SDK internals.
|
|
5
5
|
const g = globalThis;
|
|
6
|
-
const realWarn = typeof g.console?.warn
|
|
6
|
+
const realWarn = 'function' === typeof g.console?.warn ? g.console.warn.bind(g.console) : null;
|
|
7
7
|
export const nativeWarn = (...args) => {
|
|
8
8
|
realWarn?.(...args);
|
|
9
9
|
};
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
// Important: we bind the reference now. Resolving `setTimeout` at call time would pick up the
|
|
6
6
|
// patched (frozen) timer once reticle_clock freezes the clock — which would hang the SDK.
|
|
7
7
|
const g = globalThis;
|
|
8
|
-
const realSetTimeout = typeof g.setTimeout
|
|
9
|
-
const realClearTimeout = typeof g.clearTimeout
|
|
10
|
-
const realRaf = typeof g.requestAnimationFrame
|
|
11
|
-
const realPerfNow = typeof g.performance?.now
|
|
8
|
+
const realSetTimeout = 'function' === typeof g.setTimeout ? g.setTimeout.bind(g) : null;
|
|
9
|
+
const realClearTimeout = 'function' === typeof g.clearTimeout ? g.clearTimeout.bind(g) : null;
|
|
10
|
+
const realRaf = 'function' === typeof g.requestAnimationFrame ? g.requestAnimationFrame.bind(g) : null;
|
|
11
|
+
const realPerfNow = 'function' === typeof g.performance?.now ? g.performance.now.bind(g.performance) : null;
|
|
12
12
|
/**
|
|
13
13
|
* Monotonic "now" bound at load. clock.ts deliberately does NOT patch performance.now, so this
|
|
14
14
|
* stays live even when the app clock (reticle_clock) is frozen — the presenter state machine relies
|
|
@@ -45,6 +45,16 @@ export declare class Transport {
|
|
|
45
45
|
constructor(deps: TransportDeps);
|
|
46
46
|
connect(): void;
|
|
47
47
|
sendEvent(event: ReticleEvent): void;
|
|
48
|
+
/**
|
|
49
|
+
* Re-send the HELLO on a live socket.
|
|
50
|
+
*
|
|
51
|
+
* The hello carries `hasCapabilities`, and it goes out at connect() — before the app has had a
|
|
52
|
+
* chance to call `registerCapabilities`, which by design happens AFTER connect so `registerStore`
|
|
53
|
+
* has a live SDK to subscribe through. So an app that declared its whole testable surface still
|
|
54
|
+
* appeared to the agent as having none, and nothing ever corrected it. Cheap and idempotent: the
|
|
55
|
+
* bridge treats a hello as the session's current identity, not as a new session.
|
|
56
|
+
*/
|
|
57
|
+
reannounce(): void;
|
|
48
58
|
close(): void;
|
|
49
59
|
}
|
|
50
60
|
export {};
|
|
@@ -4,10 +4,10 @@ import { nativeWarn } from '../timers/native-console.js';
|
|
|
4
4
|
import { safeStringify } from '../security/serialization.js';
|
|
5
5
|
/** Default visibility source: fire `handler` whenever the document returns to the foreground. */
|
|
6
6
|
function subscribeDocumentVisible(handler) {
|
|
7
|
-
if (typeof document
|
|
7
|
+
if ('undefined' === typeof document)
|
|
8
8
|
return () => undefined;
|
|
9
9
|
const listener = () => {
|
|
10
|
-
if (document.visibilityState
|
|
10
|
+
if ('visible' === document.visibilityState)
|
|
11
11
|
handler();
|
|
12
12
|
};
|
|
13
13
|
document.addEventListener('visibilitychange', listener);
|
|
@@ -60,7 +60,7 @@ export class Transport {
|
|
|
60
60
|
this.#now = deps.now ?? nativeNow;
|
|
61
61
|
}
|
|
62
62
|
connect() {
|
|
63
|
-
if (typeof WebSocket
|
|
63
|
+
if ('undefined' === typeof WebSocket)
|
|
64
64
|
return;
|
|
65
65
|
this.#closed = false;
|
|
66
66
|
this.#unsubscribeVisible ??= (this.#deps.onVisible ?? subscribeDocumentVisible)(() => this.#onVisible());
|
|
@@ -114,7 +114,7 @@ export class Transport {
|
|
|
114
114
|
};
|
|
115
115
|
ws.onmessage = (event) => {
|
|
116
116
|
const data = event.data;
|
|
117
|
-
void this.#onMessage(typeof data
|
|
117
|
+
void this.#onMessage('string' === typeof data ? data : String(data));
|
|
118
118
|
};
|
|
119
119
|
ws.onclose = (event) => {
|
|
120
120
|
this.#ws = undefined;
|
|
@@ -189,7 +189,7 @@ export class Transport {
|
|
|
189
189
|
// failure mode where the cause is knowable and was being thrown away. Reply if we can recover
|
|
190
190
|
// an id; a message without one is not a command we can answer at all.
|
|
191
191
|
const id = parsed?.id;
|
|
192
|
-
if (typeof id
|
|
192
|
+
if ('string' === typeof id && id.length > 0) {
|
|
193
193
|
this.#sendRaw(safeStringify({
|
|
194
194
|
kind: MessageKind.COMMAND_RESULT,
|
|
195
195
|
id,
|
|
@@ -243,6 +243,20 @@ export class Transport {
|
|
|
243
243
|
t: event.t,
|
|
244
244
|
});
|
|
245
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Re-send the HELLO on a live socket.
|
|
248
|
+
*
|
|
249
|
+
* The hello carries `hasCapabilities`, and it goes out at connect() — before the app has had a
|
|
250
|
+
* chance to call `registerCapabilities`, which by design happens AFTER connect so `registerStore`
|
|
251
|
+
* has a live SDK to subscribe through. So an app that declared its whole testable surface still
|
|
252
|
+
* appeared to the agent as having none, and nothing ever corrected it. Cheap and idempotent: the
|
|
253
|
+
* bridge treats a hello as the session's current identity, not as a new session.
|
|
254
|
+
*/
|
|
255
|
+
reannounce() {
|
|
256
|
+
if (this.#ws === undefined || this.#ws.readyState !== WebSocket.OPEN)
|
|
257
|
+
return;
|
|
258
|
+
this.#ws.send(JSON.stringify(this.#deps.hello()));
|
|
259
|
+
}
|
|
246
260
|
#sendRaw(text, event) {
|
|
247
261
|
if (this.#ws !== undefined && this.#ws.readyState === WebSocket.OPEN) {
|
|
248
262
|
this.#ws.send(text);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reticlehq/browser",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Reticle browser SDK — installs observers, builds semantic snapshots, executes actions, talks to the bridge.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"default": "./dist/index.js"
|
|
12
|
-
}
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
16
|
"@testing-library/dom": "^10.4.1",
|
|
16
|
-
"@reticlehq/core": "2.
|
|
17
|
+
"@reticlehq/core": "2.5.0"
|
|
17
18
|
},
|
|
18
19
|
"devDependencies": {
|
|
19
20
|
"@tanstack/query-core": "^5.101.4",
|
|
@@ -21,7 +22,12 @@
|
|
|
21
22
|
"jotai": "^2.20.2",
|
|
22
23
|
"jsdom": "^29.1.1",
|
|
23
24
|
"mobx": "^7.0.0",
|
|
25
|
+
"pinia": "^4.0.2",
|
|
26
|
+
"react": "^19.2.8",
|
|
27
|
+
"recoil": "^0.7.7",
|
|
28
|
+
"svelte": "^5.56.8",
|
|
24
29
|
"valtio": "^2.3.2",
|
|
30
|
+
"vue": "^3.5.41",
|
|
25
31
|
"xstate": "^5.32.5"
|
|
26
32
|
},
|
|
27
33
|
"license": "Apache-2.0",
|
|
@@ -56,6 +62,7 @@
|
|
|
56
62
|
"build": "tsc -b",
|
|
57
63
|
"typecheck": "tsc -b",
|
|
58
64
|
"lint": "eslint src",
|
|
59
|
-
"test:unit": "vitest run src --passWithNoTests"
|
|
65
|
+
"test:unit": "vitest run src --passWithNoTests",
|
|
66
|
+
"test:coverage": "vitest run src --passWithNoTests --coverage.enabled --coverage.provider=v8 --coverage.reporter=text-summary --coverage.include='src/**/*.ts' --coverage.exclude='src/**/*.test.ts'"
|
|
60
67
|
}
|
|
61
68
|
}
|