@reticlehq/vite-plugin 3.9.0 → 3.10.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/dist/index.cjs +39 -0
- package/dist/index.js +5 -0
- package/dist/pre-attach-errors.d.ts +26 -0
- package/dist/pre-attach-errors.js +44 -0
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -6019,6 +6019,16 @@ var EventType = {
|
|
|
6019
6019
|
DOM_TEXT: "dom.text",
|
|
6020
6020
|
NET_REQUEST: "net.request",
|
|
6021
6021
|
NET_PENDING: "net.pending",
|
|
6022
|
+
/**
|
|
6023
|
+
* A fetch or XHR that the browser recorded in resource timing, and that no patched transport saw.
|
|
6024
|
+
*
|
|
6025
|
+
* The app sent it through a `fetch` reference it saved before Reticle patched `fetch`. It is NOT a
|
|
6026
|
+
* `net.request`: it has no method, and its status is only a hint (0 cross-origin without
|
|
6027
|
+
* `Timing-Allow-Origin`). A second record for one call would also raise a false duplicate. It
|
|
6028
|
+
* exists so a `net` miss over its URL reads `unknown`, not `no`.
|
|
6029
|
+
* `data: { url, urlRaw?, initiator, status? }`.
|
|
6030
|
+
*/
|
|
6031
|
+
NET_UNPATCHED: "net.unpatched",
|
|
6022
6032
|
/** An SSE (EventSource) or WebSocket frame — a message on a long-lived streaming connection. */
|
|
6023
6033
|
NET_STREAM: "net.stream",
|
|
6024
6034
|
/** A web-perf metric a screenshot can't verify: LCP, cumulative layout shift, or a long task. */
|
|
@@ -6347,6 +6357,7 @@ var RING_BUFFER_DEFAULTS = {
|
|
|
6347
6357
|
MAX_BYTES: TRANSPORT_LIMITS.MAX_BUFFER_BYTES
|
|
6348
6358
|
};
|
|
6349
6359
|
var RETICLE_RENDER_PREHOOK = "__reticleRenderPreHook";
|
|
6360
|
+
var RETICLE_EARLY_CAPTURE = "__reticleEarlyCapture";
|
|
6350
6361
|
var CONSOLE_LEVEL_PREFIX = "console.";
|
|
6351
6362
|
var CONSOLE_LEVELS = [
|
|
6352
6363
|
EventType.CONSOLE_LOG,
|
|
@@ -6355,6 +6366,9 @@ var CONSOLE_LEVELS = [
|
|
|
6355
6366
|
EventType.CONSOLE_INFO
|
|
6356
6367
|
].map((type) => type.slice(CONSOLE_LEVEL_PREFIX.length));
|
|
6357
6368
|
|
|
6369
|
+
// ../../../core/dist/wire/constants/console-event.js
|
|
6370
|
+
var RETICLE_PRE_ATTACH_ERRORS = "__reticlePreAttach";
|
|
6371
|
+
|
|
6358
6372
|
// ../../../core/dist/identity/source-constants.js
|
|
6359
6373
|
var DATA_RETICLE_SOURCE_ATTR = "data-reticle-source";
|
|
6360
6374
|
var RETICLE_ROOT_GLOBAL = "__RETICLE_ROOT__";
|
|
@@ -7260,6 +7274,27 @@ function isVitestBrowserServer(config2) {
|
|
|
7260
7274
|
return true === browser.enabled;
|
|
7261
7275
|
}
|
|
7262
7276
|
|
|
7277
|
+
// src/pre-attach-errors.ts
|
|
7278
|
+
var PRE_ATTACH_ERRORS_LIMIT = 50;
|
|
7279
|
+
var PRE_ATTACH_ERRORS_SOURCE = `(function(){try{
|
|
7280
|
+
var P='${RETICLE_PRE_ATTACH_ERRORS}',D='${RETICLE_EARLY_CAPTURE}',g=globalThis;
|
|
7281
|
+
if(g[P]!==undefined||g[D]!==undefined||typeof g.addEventListener!=='function')return;
|
|
7282
|
+
var B={open:true},q=[],n=0;
|
|
7283
|
+
g[P]=B;
|
|
7284
|
+
var keep=function(item){if(!B.open)return;if(q.length<${String(PRE_ATTACH_ERRORS_LIMIT)}){q.push(item);}else{n++;}};
|
|
7285
|
+
var onEvent=function(e){keep({event:e});};
|
|
7286
|
+
g.addEventListener('error',onEvent,true);
|
|
7287
|
+
g.addEventListener('unhandledrejection',onEvent,true);
|
|
7288
|
+
var c=g.console,ne=c&&c.error;
|
|
7289
|
+
if(typeof ne==='function'){c.error=function(){keep({args:Array.prototype.slice.call(arguments)});return ne.apply(this,arguments);};}
|
|
7290
|
+
B.drain=function(onError,onRejection,onConsole,dropped){
|
|
7291
|
+
if(!B.open)return;
|
|
7292
|
+
var kept=q,i,it;B.open=false;q=[];
|
|
7293
|
+
g.removeEventListener('error',onEvent,true);g.removeEventListener('unhandledrejection',onEvent,true);
|
|
7294
|
+
for(i=0;i<kept.length;i++){it=kept[i];try{dropped(i===0?n:0);
|
|
7295
|
+
if(it.args){onConsole('error',it.args);}else if(it.event.type==='unhandledrejection'){onRejection(it.event);}else{onError(it.event);}}catch(e){}}};
|
|
7296
|
+
}catch(e){}})();`;
|
|
7297
|
+
|
|
7263
7298
|
// src/index.ts
|
|
7264
7299
|
var RETICLE_PACKAGE2 = "@reticlehq/react";
|
|
7265
7300
|
var RETICLE_SENSOR = "@reticlehq/browser";
|
|
@@ -7637,6 +7672,10 @@ ${code}`;
|
|
|
7637
7672
|
if (!inject || desktop) return [];
|
|
7638
7673
|
if (true !== options.inject && vitestBrowser) return [];
|
|
7639
7674
|
return [
|
|
7675
|
+
// Classic and inline for the same reason as the render pre-hook below, and first: it has to
|
|
7676
|
+
// be listening before anything else on the page can load, fail or throw. See
|
|
7677
|
+
// PRE_ATTACH_ERRORS_SOURCE.
|
|
7678
|
+
{ tag: "script", children: PRE_ATTACH_ERRORS_SOURCE, injectTo: "head-prepend" },
|
|
7640
7679
|
// A CLASSIC inline script in <head>, and it has to be both.
|
|
7641
7680
|
//
|
|
7642
7681
|
// React reads `__REACT_DEVTOOLS_GLOBAL_HOOK__` when its renderer injects — which happens as
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,7 @@ export const RETICLE_CONNECT_MODULE = '/@reticle-connect';
|
|
|
49
49
|
*/
|
|
50
50
|
import { mergeIgnored } from './watch-ignore.js';
|
|
51
51
|
import { isVitestBrowserServer } from './vitest-browser.js';
|
|
52
|
+
import { PRE_ATTACH_ERRORS_SOURCE } from './pre-attach-errors.js';
|
|
52
53
|
export function connectModuleUrl(base) {
|
|
53
54
|
if (undefined === base || !base.startsWith('/'))
|
|
54
55
|
return RETICLE_CONNECT_MODULE;
|
|
@@ -657,6 +658,10 @@ export function reticle(options = {}) {
|
|
|
657
658
|
if (true !== options.inject && vitestBrowser)
|
|
658
659
|
return [];
|
|
659
660
|
return [
|
|
661
|
+
// Classic and inline for the same reason as the render pre-hook below, and first: it has to
|
|
662
|
+
// be listening before anything else on the page can load, fail or throw. See
|
|
663
|
+
// PRE_ATTACH_ERRORS_SOURCE.
|
|
664
|
+
{ tag: 'script', children: PRE_ATTACH_ERRORS_SOURCE, injectTo: 'head-prepend' },
|
|
660
665
|
// A CLASSIC inline script in <head>, and it has to be both.
|
|
661
666
|
//
|
|
662
667
|
// React reads `__REACT_DEVTOOLS_GLOBAL_HOOK__` when its renderer injects — which happens as
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** How many errors the pre-attach buffer keeps. The first ones name the cause; later ones are counted. */
|
|
2
|
+
export declare const PRE_ATTACH_ERRORS_LIMIT = 50;
|
|
3
|
+
/**
|
|
4
|
+
* The pre-attach error buffer, as source for an inline <head> script (#1540).
|
|
5
|
+
*
|
|
6
|
+
* The SDK installs its console observer in `connect()`, and the connect module runs after the app's
|
|
7
|
+
* entry module. So an entry module that 404s, is served as HTML or throws, a rejection, or a
|
|
8
|
+
* `console.error` during start-up all happened while nothing was listening: the agent saw an empty
|
|
9
|
+
* page and an empty console, and could not tell a blank page from an app that crashed on load.
|
|
10
|
+
*
|
|
11
|
+
* This runs during parse, before any module. It keeps the raw `error` events (capture phase, because
|
|
12
|
+
* a failed `<script>` dispatches on the element and does not bubble), the unhandled rejections and
|
|
13
|
+
* the `console.error` arguments. When the SDK's console observer installs, it calls
|
|
14
|
+
* `drain(onError, onRejection, onConsole, dropped)` once. The buffer stops keeping and removes its
|
|
15
|
+
* listeners, then hands each entry to the SDK's own handler. Before each one it calls `dropped`:
|
|
16
|
+
* with the count of the entries it did not keep before the first, and with 0 after that. The SDK
|
|
17
|
+
* marks what it gets during this call as pre-attach itself. The handling code lives here and not
|
|
18
|
+
* in the SDK, so a page pays nothing for it in the SDK bundle.
|
|
19
|
+
* The `console.error` wrapper stays in the chain after that and only calls through.
|
|
20
|
+
*
|
|
21
|
+
* It does not install on a page Reticle drives: that page already has the pool's early capture
|
|
22
|
+
* (RETICLE_EARLY_CAPTURE), which hands the same errors to the SDK.
|
|
23
|
+
*
|
|
24
|
+
* The same rules as the render pre-hook: dependency-free ES5 in a try/catch.
|
|
25
|
+
*/
|
|
26
|
+
export declare const PRE_ATTACH_ERRORS_SOURCE: string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { RETICLE_EARLY_CAPTURE, RETICLE_PRE_ATTACH_ERRORS } from '@reticlehq/core';
|
|
2
|
+
/** How many errors the pre-attach buffer keeps. The first ones name the cause; later ones are counted. */
|
|
3
|
+
export const PRE_ATTACH_ERRORS_LIMIT = 50;
|
|
4
|
+
/**
|
|
5
|
+
* The pre-attach error buffer, as source for an inline <head> script (#1540).
|
|
6
|
+
*
|
|
7
|
+
* The SDK installs its console observer in `connect()`, and the connect module runs after the app's
|
|
8
|
+
* entry module. So an entry module that 404s, is served as HTML or throws, a rejection, or a
|
|
9
|
+
* `console.error` during start-up all happened while nothing was listening: the agent saw an empty
|
|
10
|
+
* page and an empty console, and could not tell a blank page from an app that crashed on load.
|
|
11
|
+
*
|
|
12
|
+
* This runs during parse, before any module. It keeps the raw `error` events (capture phase, because
|
|
13
|
+
* a failed `<script>` dispatches on the element and does not bubble), the unhandled rejections and
|
|
14
|
+
* the `console.error` arguments. When the SDK's console observer installs, it calls
|
|
15
|
+
* `drain(onError, onRejection, onConsole, dropped)` once. The buffer stops keeping and removes its
|
|
16
|
+
* listeners, then hands each entry to the SDK's own handler. Before each one it calls `dropped`:
|
|
17
|
+
* with the count of the entries it did not keep before the first, and with 0 after that. The SDK
|
|
18
|
+
* marks what it gets during this call as pre-attach itself. The handling code lives here and not
|
|
19
|
+
* in the SDK, so a page pays nothing for it in the SDK bundle.
|
|
20
|
+
* The `console.error` wrapper stays in the chain after that and only calls through.
|
|
21
|
+
*
|
|
22
|
+
* It does not install on a page Reticle drives: that page already has the pool's early capture
|
|
23
|
+
* (RETICLE_EARLY_CAPTURE), which hands the same errors to the SDK.
|
|
24
|
+
*
|
|
25
|
+
* The same rules as the render pre-hook: dependency-free ES5 in a try/catch.
|
|
26
|
+
*/
|
|
27
|
+
export const PRE_ATTACH_ERRORS_SOURCE = `(function(){try{
|
|
28
|
+
var P='${RETICLE_PRE_ATTACH_ERRORS}',D='${RETICLE_EARLY_CAPTURE}',g=globalThis;
|
|
29
|
+
if(g[P]!==undefined||g[D]!==undefined||typeof g.addEventListener!=='function')return;
|
|
30
|
+
var B={open:true},q=[],n=0;
|
|
31
|
+
g[P]=B;
|
|
32
|
+
var keep=function(item){if(!B.open)return;if(q.length<${String(PRE_ATTACH_ERRORS_LIMIT)}){q.push(item);}else{n++;}};
|
|
33
|
+
var onEvent=function(e){keep({event:e});};
|
|
34
|
+
g.addEventListener('error',onEvent,true);
|
|
35
|
+
g.addEventListener('unhandledrejection',onEvent,true);
|
|
36
|
+
var c=g.console,ne=c&&c.error;
|
|
37
|
+
if(typeof ne==='function'){c.error=function(){keep({args:Array.prototype.slice.call(arguments)});return ne.apply(this,arguments);};}
|
|
38
|
+
B.drain=function(onError,onRejection,onConsole,dropped){
|
|
39
|
+
if(!B.open)return;
|
|
40
|
+
var kept=q,i,it;B.open=false;q=[];
|
|
41
|
+
g.removeEventListener('error',onEvent,true);g.removeEventListener('unhandledrejection',onEvent,true);
|
|
42
|
+
for(i=0;i<kept.length;i++){it=kept[i];try{dropped(i===0?n:0);
|
|
43
|
+
if(it.args){onConsole('error',it.args);}else if(it.event.type==='unhandledrejection'){onRejection(it.event);}else{onError(it.event);}}catch(e){}}};
|
|
44
|
+
}catch(e){}})();`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reticlehq/vite-plugin",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.1",
|
|
4
4
|
"description": "Vite plugin for Reticle: dev-only source-map stamping plus auto-injected reticle.connect(). apply:'serve' guarantees it never ships to production.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@babel/core": "^7.26.0",
|
|
44
|
-
"@reticlehq/babel-plugin": "3.
|
|
45
|
-
"@reticlehq/core": "3.
|
|
44
|
+
"@reticlehq/babel-plugin": "3.10.1",
|
|
45
|
+
"@reticlehq/core": "3.10.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/babel__core": "^7.20.5",
|
|
49
49
|
"esbuild": "^0.28.2",
|
|
50
|
-
"svelte": "^5.57.
|
|
50
|
+
"svelte": "^5.57.3",
|
|
51
51
|
"vite": "^8",
|
|
52
|
-
"@reticlehq/react": "3.
|
|
52
|
+
"@reticlehq/react": "3.10.1"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"vite": ">=4"
|