@reticlehq/vite-plugin 3.1.0 → 3.3.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/README.md +15 -0
- package/dist/connect-args.d.ts +10 -0
- package/dist/connect-args.js +71 -0
- package/dist/disabled-browser-stub.d.ts +3 -0
- package/dist/disabled-browser-stub.js +185 -0
- package/dist/index.cjs +467 -161
- package/dist/index.d.cts +22 -11
- package/dist/index.d.ts +22 -11
- package/dist/index.js +33 -107
- package/dist/stamping.d.ts +36 -0
- package/dist/stamping.js +99 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -58,4 +58,19 @@ reticle({
|
|
|
58
58
|
|
|
59
59
|
`desktop: true` makes the plugin apply to `vite build` as well and calls `connect()` with `allowInProduction`, because a packaged desktop renderer is a production build with no dev server. That means an instrumented production bundle, which a web app must never ship. Keep it behind your own dev-only build target.
|
|
60
60
|
|
|
61
|
+
### Opting one file out of source stamping
|
|
62
|
+
|
|
63
|
+
A file whose **first non-empty line** is a comment carrying `@reticle-ignore` is not stamped, and its elements will have no `file:line`:
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
// @reticle-ignore
|
|
67
|
+
export function Generated() { … }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`/* @reticle-ignore */` works the same way, and a `.svelte` component uses `<!-- @reticle-ignore -->` because it has no line for a `//` before its markup.
|
|
71
|
+
|
|
72
|
+
Whole file, first line, on purpose. The reasons to opt out are file-shaped — a generated component, a snapshot test the stamp would break — and a marker that worked from line 40 would be a marker nobody can find. `include`/`exclude` globs still exist for whole directories; this is for the one file whose reason sits with the file.
|
|
73
|
+
|
|
74
|
+
It is not silent. The plugin reports each opted-out file once, by name, in the dev-server output, so an opt-out is something a reader sees rather than something they discover months later from a pointer that never resolves.
|
|
75
|
+
|
|
61
76
|
Apache-2.0.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `reticle.connect` argument literal the plugin bakes into the generated connect call.
|
|
3
|
+
*
|
|
4
|
+
* Split out of index.ts, which sits six lines under its 1000-line cap on main -- this option could
|
|
5
|
+
* not be added inline. Cohesive on its own terms: one function, whose whole job is deciding which
|
|
6
|
+
* of the plugin's options the PAGE needs to be told about.
|
|
7
|
+
*/
|
|
8
|
+
import type { ReticleVitePluginOptions } from './index.js';
|
|
9
|
+
/** Build the `reticle.connect` argument literal — only includes keys the user set. */
|
|
10
|
+
export declare function connectArgs(options: ReticleVitePluginOptions): string;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `reticle.connect` argument literal the plugin bakes into the generated connect call.
|
|
3
|
+
*
|
|
4
|
+
* Split out of index.ts, which sits six lines under its 1000-line cap on main -- this option could
|
|
5
|
+
* not be added inline. Cohesive on its own terms: one function, whose whole job is deciding which
|
|
6
|
+
* of the plugin's options the PAGE needs to be told about.
|
|
7
|
+
*/
|
|
8
|
+
import { RETICLE_DEFAULT_PORT, bridgeWsUrl } from '@reticlehq/core';
|
|
9
|
+
/** Build the `reticle.connect` argument literal — only includes keys the user set. */
|
|
10
|
+
export function connectArgs(options) {
|
|
11
|
+
const args = {};
|
|
12
|
+
const port = options.port ?? RETICLE_DEFAULT_PORT;
|
|
13
|
+
if (port !== RETICLE_DEFAULT_PORT)
|
|
14
|
+
args['url'] = bridgeWsUrl(port);
|
|
15
|
+
if (options.session !== undefined)
|
|
16
|
+
args['session'] = options.session;
|
|
17
|
+
if (options.projectId !== undefined)
|
|
18
|
+
args['projectId'] = options.projectId;
|
|
19
|
+
if (options.token !== undefined)
|
|
20
|
+
args['token'] = options.token;
|
|
21
|
+
// Passed as connect ARGUMENTS, not as a `define`. A define substitutes a bare identifier in the
|
|
22
|
+
// source it transforms; the SDK reads these as `globalThis[NAME]`, a dynamic lookup no define can
|
|
23
|
+
// ever reach — so defining them looked right, shipped, and did nothing. Baking them into the
|
|
24
|
+
// generated connect call is a literal in generated source: no bundler subtleties, works the same
|
|
25
|
+
// in dev and in a desktop build.
|
|
26
|
+
if (options.root !== undefined && options.root.length > 0)
|
|
27
|
+
args['root'] = options.root;
|
|
28
|
+
if (options.sdkVersion !== undefined && options.sdkVersion.length > 0) {
|
|
29
|
+
args['sdkVersion'] = options.sdkVersion;
|
|
30
|
+
}
|
|
31
|
+
// A desktop renderer is a production build by construction; without this the SDK's prod backstop
|
|
32
|
+
// refuses to connect and the app is silently uninstrumented.
|
|
33
|
+
if (true === options.desktop)
|
|
34
|
+
args['allowInProduction'] = true;
|
|
35
|
+
// Env wins nothing — it only turns the flag ON, so a config that never set it can still be
|
|
36
|
+
// switched on for one debugging session without editing vite.config and restarting the mental
|
|
37
|
+
// model with it.
|
|
38
|
+
if (true === options.captureNetworkBodies || '1' === process.env['VITE_RETICLE_CAPTURE_BODIES']) {
|
|
39
|
+
args['captureNetworkBodies'] = true;
|
|
40
|
+
}
|
|
41
|
+
// Only the OPT-OUT is announced, never the default. The daemon reads absence as "unknown", so
|
|
42
|
+
// sending `true` here would say nothing it does not already assume — while sending `false` is the
|
|
43
|
+
// one fact a red verdict needs to stop prescribing a plugin this project has deliberately muted.
|
|
44
|
+
if (false === options.sourceMapping)
|
|
45
|
+
args['sourceMapping'] = false;
|
|
46
|
+
// The one option that defaults ON, so the env var and the config flag both DISABLE rather than
|
|
47
|
+
// enable. Emitted only when switched off; the default stays implicit in the SDK.
|
|
48
|
+
if (false === options.captureErrorBodies || '1' === process.env['VITE_RETICLE_NO_ERROR_BODIES']) {
|
|
49
|
+
args['captureErrorBodies'] = false;
|
|
50
|
+
}
|
|
51
|
+
// Same shape, same reason -- except this one carries a VALUE, so the env var is parsed rather
|
|
52
|
+
// than tested for '1'. A non-numeric env var is ignored rather than fatal: it must not take down
|
|
53
|
+
// an app's dev server, and the SDK clamps whatever does arrive.
|
|
54
|
+
const envBodyChars = Number(process.env['VITE_RETICLE_BODY_MAX_CHARS']);
|
|
55
|
+
const bodyChars = options.networkBodyMaxChars ??
|
|
56
|
+
(Number.isFinite(envBodyChars) && envBodyChars > 0 ? envBodyChars : undefined);
|
|
57
|
+
if (bodyChars !== undefined) {
|
|
58
|
+
args['networkBodyMaxChars'] = bodyChars;
|
|
59
|
+
}
|
|
60
|
+
// Same shape, same reason. Off unless asked for, in a config or for one session.
|
|
61
|
+
if (true === options.exposePresenter || '1' === process.env['VITE_RETICLE_EXPOSE_PRESENTER']) {
|
|
62
|
+
args['exposePresenter'] = true;
|
|
63
|
+
}
|
|
64
|
+
// Same shape, same reason: without it an app that cannot be served on localhost has no way to
|
|
65
|
+
// reach the SDK option at all. The pairing token still applies — see the option's docstring.
|
|
66
|
+
if (true === options.allowNonLocalhost ||
|
|
67
|
+
'1' === process.env['VITE_RETICLE_ALLOW_NON_LOCALHOST']) {
|
|
68
|
+
args['allowNonLocalhost'] = true;
|
|
69
|
+
}
|
|
70
|
+
return Object.keys(args).length > 0 ? JSON.stringify(args) : '';
|
|
71
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const RETICLE_DISABLED_STUB = "\0reticle-disabled-stub";
|
|
2
|
+
export declare const isReticleDisabledWebBuild: (desktop: boolean, command: string | undefined) => boolean;
|
|
3
|
+
export declare const RETICLE_DISABLED_STUB_CODE = "\nexport class Reticle {\n connect() {}\n signal() {}\n state() {}\n renderCommit() {}\n describe() {}\n endSession() {}\n observeHotUpdates() {}\n disconnect() {}\n\n get connected() {\n return false;\n }\n}\n\nexport const reticle = new Reticle();\n\nexport const SESSION_AUTO = 'auto';\n\nexport function setIgnoreSelectors() {}\n\nexport function registerAdapter() {}\nexport function identifyComponent() {\n return null;\n}\nexport function readComponentState() {\n return undefined;\n}\nexport function elementHasHoverHandlers() {\n return false;\n}\nexport function adapterNames() {\n return [];\n}\n\nexport function registerStore() {}\nexport function unregisterStore() {}\nexport function storeNames() {\n return [];\n}\nexport function readStores() {\n return {};\n}\nexport function readStoresWithTruncation() {\n return { stores: {} };\n}\nexport function sourceOwner() {\n return undefined;\n}\nexport function markAdapterSource() {}\n\nexport function tanstackQueryStore() {\n return undefined;\n}\nexport function jotaiStore() {\n return undefined;\n}\nexport function xstateStore() {\n return undefined;\n}\nexport function valtioStore() {\n return undefined;\n}\nexport function mobxStore() {\n return undefined;\n}\nexport function recoilStore() {\n return undefined;\n}\nexport function svelteStore() {\n return undefined;\n}\nexport function piniaStore() {\n return undefined;\n}\nexport function pushStore() {\n return undefined;\n}\n\nexport function registerCapabilities() {}\nexport function getCapabilities() {\n return {};\n}\nexport function hasCapabilities() {\n return false;\n}\nexport function setCapabilitiesListener() {}\n\nexport function createReticleEmitter() {\n return {\n signal() {},\n state() {},\n };\n}\n\nexport function commitAndSignal() {}\nexport function registerReticleDomain() {}\n\nexport function buildSnapshot() {\n return {};\n}\n\nexport function inspectChart() {\n return {};\n}\nexport function canvasChartData() {\n return {};\n}\n\nexport function matchQuery() {\n return false;\n}\nexport function runQuery() {\n return undefined;\n}\n\nexport function executeAction() {\n return undefined;\n}\nexport function executeSequence() {\n return undefined;\n}\n\nexport function describe() {\n return undefined;\n}\nexport function getRole() {\n return undefined;\n}\nexport function getAccessibleName() {\n return undefined;\n}\nexport function getStates() {\n return {};\n}\nexport function isVisible() {\n return false;\n}\n\nexport class RefRegistry {\n get size() {\n return 0;\n }\n\n markEdited() {}\n\n mintedBeforeLastEdit() {\n return false;\n }\n\n refFor() {\n return undefined;\n }\n\n resolve() {\n return null;\n }\n}\n\nexport const refs = new RefRegistry();\n\nexport class Annotator {\n constructor() {}\n\n get active() {\n return false;\n }\n\n get markCount() {\n return 0;\n }\n\n mount() {}\n unmount() {}\n}\n\nexport function installAnnotator() {}\n\nexport function resolveMarkAnchor() {\n return undefined;\n}\n";
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
export const RETICLE_DISABLED_STUB = '\0reticle-disabled-stub';
|
|
2
|
+
export const isReticleDisabledWebBuild = (desktop, command) => !desktop && 'build' === command;
|
|
3
|
+
export const RETICLE_DISABLED_STUB_CODE = `
|
|
4
|
+
export class Reticle {
|
|
5
|
+
connect() {}
|
|
6
|
+
signal() {}
|
|
7
|
+
state() {}
|
|
8
|
+
renderCommit() {}
|
|
9
|
+
describe() {}
|
|
10
|
+
endSession() {}
|
|
11
|
+
observeHotUpdates() {}
|
|
12
|
+
disconnect() {}
|
|
13
|
+
|
|
14
|
+
get connected() {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const reticle = new Reticle();
|
|
20
|
+
|
|
21
|
+
export const SESSION_AUTO = 'auto';
|
|
22
|
+
|
|
23
|
+
export function setIgnoreSelectors() {}
|
|
24
|
+
|
|
25
|
+
export function registerAdapter() {}
|
|
26
|
+
export function identifyComponent() {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
export function readComponentState() {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
export function elementHasHoverHandlers() {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
export function adapterNames() {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function registerStore() {}
|
|
40
|
+
export function unregisterStore() {}
|
|
41
|
+
export function storeNames() {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
export function readStores() {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
export function readStoresWithTruncation() {
|
|
48
|
+
return { stores: {} };
|
|
49
|
+
}
|
|
50
|
+
export function sourceOwner() {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
export function markAdapterSource() {}
|
|
54
|
+
|
|
55
|
+
export function tanstackQueryStore() {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
export function jotaiStore() {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
export function xstateStore() {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
export function valtioStore() {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
export function mobxStore() {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
export function recoilStore() {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
export function svelteStore() {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
export function piniaStore() {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
export function pushStore() {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function registerCapabilities() {}
|
|
84
|
+
export function getCapabilities() {
|
|
85
|
+
return {};
|
|
86
|
+
}
|
|
87
|
+
export function hasCapabilities() {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
export function setCapabilitiesListener() {}
|
|
91
|
+
|
|
92
|
+
export function createReticleEmitter() {
|
|
93
|
+
return {
|
|
94
|
+
signal() {},
|
|
95
|
+
state() {},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function commitAndSignal() {}
|
|
100
|
+
export function registerReticleDomain() {}
|
|
101
|
+
|
|
102
|
+
export function buildSnapshot() {
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function inspectChart() {
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
109
|
+
export function canvasChartData() {
|
|
110
|
+
return {};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function matchQuery() {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
export function runQuery() {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function executeAction() {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
export function executeSequence() {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function describe() {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
export function getRole() {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
export function getAccessibleName() {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
export function getStates() {
|
|
137
|
+
return {};
|
|
138
|
+
}
|
|
139
|
+
export function isVisible() {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export class RefRegistry {
|
|
144
|
+
get size() {
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
markEdited() {}
|
|
149
|
+
|
|
150
|
+
mintedBeforeLastEdit() {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
refFor() {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
resolve() {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const refs = new RefRegistry();
|
|
164
|
+
|
|
165
|
+
export class Annotator {
|
|
166
|
+
constructor() {}
|
|
167
|
+
|
|
168
|
+
get active() {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
get markCount() {
|
|
173
|
+
return 0;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
mount() {}
|
|
177
|
+
unmount() {}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function installAnnotator() {}
|
|
181
|
+
|
|
182
|
+
export function resolveMarkAnchor() {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
`;
|