react-perf-recorder 0.1.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/claude/README.md +10 -0
  4. package/claude/agents/perf-recorder.md +44 -0
  5. package/claude/mcp.json +8 -0
  6. package/claude/skills/react-perf-recorder/SKILL.md +52 -0
  7. package/claude/skills/react-perf-recorder/references/causes-and-actions.md +47 -0
  8. package/claude/skills/react-perf-recorder/references/from-scripts.md +36 -0
  9. package/claude/skills/react-perf-recorder/references/getting-a-recording.md +41 -0
  10. package/claude/skills/react-perf-recorder/references/measuring-a-fix.md +42 -0
  11. package/claude/skills/react-perf-recorder/references/panel.md +21 -0
  12. package/claude/skills/react-perf-recorder/references/reading-a-recording.md +55 -0
  13. package/dist/browser/chunk-7DJUCCWG.js +447 -0
  14. package/dist/browser/chunk-NTY2W4HE.js +182 -0
  15. package/dist/browser/client.d.ts +589 -0
  16. package/dist/browser/client.js +7161 -0
  17. package/dist/browser/index-BlkKhwHe.d.ts +585 -0
  18. package/dist/browser/plugins/proxy-memoize.d.ts +7 -0
  19. package/dist/browser/plugins/proxy-memoize.js +41 -0
  20. package/dist/browser/plugins/react-query.d.ts +5 -0
  21. package/dist/browser/plugins/react-query.js +74 -0
  22. package/dist/browser/plugins/zustand.d.ts +11 -0
  23. package/dist/browser/plugins/zustand.js +171 -0
  24. package/dist/browser/runtime.d.ts +1 -0
  25. package/dist/browser/runtime.js +12 -0
  26. package/dist/cli.js +23119 -0
  27. package/dist/engine.iife.js +3661 -0
  28. package/dist/node/chunk-HS2BJBJX.js +170 -0
  29. package/dist/node/plugin-api-zXFxjYba.d.cts +61 -0
  30. package/dist/node/plugin-api-zXFxjYba.d.ts +61 -0
  31. package/dist/node/plugins/proxy-memoize.cjs +214 -0
  32. package/dist/node/plugins/proxy-memoize.d.cts +16 -0
  33. package/dist/node/plugins/proxy-memoize.d.ts +16 -0
  34. package/dist/node/plugins/proxy-memoize.js +51 -0
  35. package/dist/node/plugins/react-query.cjs +32 -0
  36. package/dist/node/plugins/react-query.d.cts +6 -0
  37. package/dist/node/plugins/react-query.d.ts +6 -0
  38. package/dist/node/plugins/react-query.js +7 -0
  39. package/dist/node/plugins/zustand.cjs +247 -0
  40. package/dist/node/plugins/zustand.d.cts +17 -0
  41. package/dist/node/plugins/zustand.d.ts +17 -0
  42. package/dist/node/plugins/zustand.js +61 -0
  43. package/dist/node/vite.cjs +1262 -0
  44. package/dist/node/vite.d.cts +103 -0
  45. package/dist/node/vite.d.ts +103 -0
  46. package/dist/node/vite.js +1072 -0
  47. package/docs/contributing.md +24 -0
  48. package/docs/how-it-works.md +34 -0
  49. package/docs/mcp.md +62 -0
  50. package/docs/measuring-a-fix.md +65 -0
  51. package/docs/options.md +22 -0
  52. package/docs/panel.md +59 -0
  53. package/docs/plugins.md +57 -0
  54. package/docs/recording.md +44 -0
  55. package/package.json +139 -0
@@ -0,0 +1,103 @@
1
+ import { P as PerfRecorderPlugin, V as VitePluginLike } from './plugin-api-zXFxjYba.cjs';
2
+ export { B as BuildContext, d as definePerfRecorderPlugin } from './plugin-api-zXFxjYba.cjs';
3
+
4
+ interface ComponentNamesOptions {
5
+ include?: string[];
6
+ exclude?: string[];
7
+ /** Calls whose result gets a `displayName`: memo and forwardRef components, contexts. */
8
+ wrappers?: string[];
9
+ }
10
+ /**
11
+ * `const Row = memo(...)` → `if (!Row.displayName) Row.displayName = "Row";`, so a memo over an arrow function is not
12
+ * `Memo`/`Anonymous`. `export default memo(...)` is named after its file.
13
+ */
14
+ declare function addComponentNames(code: string, wrappers?: string[], file?: string): string | null;
15
+
16
+ interface ProxyModuleOptions {
17
+ /** The bare specifier to replace, e.g. `proxy-memoize` or `zustand/react/shallow`. */
18
+ source: string;
19
+ /** Only these importers get the proxy; the proxy itself, node_modules and virtual modules keep the original. */
20
+ importer: (importer: string | undefined) => boolean;
21
+ /** Body of the proxy module; it imports the original by the same specifier. */
22
+ code: () => string;
23
+ }
24
+ interface ProxyHooks {
25
+ /** The id of the proxy module, for a transform that wants to import it by name rather than wait to be asked. */
26
+ readonly id: string;
27
+ resolveId(source: string, importer?: string): string | null;
28
+ load(id: string): string | null;
29
+ /** Points a module's imports of the source at the proxy, whatever the resolver would have done with them. */
30
+ rewrite(code: string): string | null;
31
+ }
32
+ declare function proxyModule(pluginName: string, options: ProxyModuleOptions): ProxyHooks;
33
+ /** Several proxies as one pair of hooks. */
34
+ declare function combineProxies(proxies: ProxyHooks[]): ProxyHooks;
35
+
36
+ interface ScanOptions {
37
+ /** `React.memo(…)` counts as `memo(…)`. */
38
+ allowReactPrefix?: boolean;
39
+ /** The module's id: its extension says whether it is TypeScript and whether it has JSX. */
40
+ file?: string;
41
+ }
42
+ /**
43
+ * Top-level `const X = callee(…)` / `export const X = callee<T>(…)` declarations. Nested calls and anything written
44
+ * inside a string, a template literal or a comment are not named.
45
+ */
46
+ declare function findDeclarations(code: string, callees: string[], options?: ScanOptions): string[];
47
+ /** Appends generated lines at the end of the module: line numbers stay the same, so no source map is needed. */
48
+ declare function appendLines(code: string, lines: string[]): string | null;
49
+
50
+ /**
51
+ * Include/exclude globs relative to the project root. Virtual modules and node_modules never match: only the app's
52
+ * own code gets transformed or proxied.
53
+ */
54
+ declare function createFilter(root: () => string, include: string[], exclude?: string[]): (id: string | undefined) => boolean;
55
+
56
+ interface PerfRecorderOptions {
57
+ /** Defaults to the dev server only: never in `vite build`, never under Vitest. */
58
+ enabled?: boolean;
59
+ /**
60
+ * Whether recordings are sent to the dev server to be kept; true when it serves the page. A build made with
61
+ * `enabled: true` (a demo) has no server, and its recordings stay in the tab.
62
+ */
63
+ save?: boolean;
64
+ /** Where sessions are written: relative to the root or absolute. Falls back to REACT_PERF_RECORDER_DIR, then `.agent-artifacts/perf-recorder`. */
65
+ outDir?: string;
66
+ /** Largest request body, the final recording included. */
67
+ maxBytes?: number;
68
+ retain?: {
69
+ sessions?: number;
70
+ bytes?: number;
71
+ };
72
+ actions?: {
73
+ values?: boolean;
74
+ secretSelector?: string;
75
+ };
76
+ components?: false | (ComponentNamesOptions & {
77
+ wrapperPattern?: string;
78
+ });
79
+ panel?: false | {
80
+ corner?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
81
+ highlight?: boolean;
82
+ shortcuts?: {
83
+ record?: string;
84
+ pick?: string;
85
+ };
86
+ };
87
+ /** `timers: false` leaves setTimeout, setInterval and requestAnimationFrame unwrapped: no timer causes. */
88
+ engine?: {
89
+ bigCommit?: number;
90
+ timelineLimit?: number;
91
+ maxDurationMs?: number;
92
+ timers?: boolean;
93
+ };
94
+ plugins?: PerfRecorderPlugin[];
95
+ }
96
+ declare function resolveOutDir(root: string, outDir: string | undefined): string;
97
+ /**
98
+ * Records React re-renders from the page: injects the recorder into the dev page, names memo components and
99
+ * contexts, runs the plugins' build halves and stores sessions for the MCP server. Returns several Vite plugins.
100
+ */
101
+ declare function perfRecorder(options?: PerfRecorderOptions): VitePluginLike[];
102
+
103
+ export { type PerfRecorderOptions, PerfRecorderPlugin, type ProxyModuleOptions, VitePluginLike, addComponentNames, appendLines, combineProxies, createFilter, findDeclarations, perfRecorder, proxyModule, resolveOutDir };
@@ -0,0 +1,103 @@
1
+ import { P as PerfRecorderPlugin, V as VitePluginLike } from './plugin-api-zXFxjYba.js';
2
+ export { B as BuildContext, d as definePerfRecorderPlugin } from './plugin-api-zXFxjYba.js';
3
+
4
+ interface ComponentNamesOptions {
5
+ include?: string[];
6
+ exclude?: string[];
7
+ /** Calls whose result gets a `displayName`: memo and forwardRef components, contexts. */
8
+ wrappers?: string[];
9
+ }
10
+ /**
11
+ * `const Row = memo(...)` → `if (!Row.displayName) Row.displayName = "Row";`, so a memo over an arrow function is not
12
+ * `Memo`/`Anonymous`. `export default memo(...)` is named after its file.
13
+ */
14
+ declare function addComponentNames(code: string, wrappers?: string[], file?: string): string | null;
15
+
16
+ interface ProxyModuleOptions {
17
+ /** The bare specifier to replace, e.g. `proxy-memoize` or `zustand/react/shallow`. */
18
+ source: string;
19
+ /** Only these importers get the proxy; the proxy itself, node_modules and virtual modules keep the original. */
20
+ importer: (importer: string | undefined) => boolean;
21
+ /** Body of the proxy module; it imports the original by the same specifier. */
22
+ code: () => string;
23
+ }
24
+ interface ProxyHooks {
25
+ /** The id of the proxy module, for a transform that wants to import it by name rather than wait to be asked. */
26
+ readonly id: string;
27
+ resolveId(source: string, importer?: string): string | null;
28
+ load(id: string): string | null;
29
+ /** Points a module's imports of the source at the proxy, whatever the resolver would have done with them. */
30
+ rewrite(code: string): string | null;
31
+ }
32
+ declare function proxyModule(pluginName: string, options: ProxyModuleOptions): ProxyHooks;
33
+ /** Several proxies as one pair of hooks. */
34
+ declare function combineProxies(proxies: ProxyHooks[]): ProxyHooks;
35
+
36
+ interface ScanOptions {
37
+ /** `React.memo(…)` counts as `memo(…)`. */
38
+ allowReactPrefix?: boolean;
39
+ /** The module's id: its extension says whether it is TypeScript and whether it has JSX. */
40
+ file?: string;
41
+ }
42
+ /**
43
+ * Top-level `const X = callee(…)` / `export const X = callee<T>(…)` declarations. Nested calls and anything written
44
+ * inside a string, a template literal or a comment are not named.
45
+ */
46
+ declare function findDeclarations(code: string, callees: string[], options?: ScanOptions): string[];
47
+ /** Appends generated lines at the end of the module: line numbers stay the same, so no source map is needed. */
48
+ declare function appendLines(code: string, lines: string[]): string | null;
49
+
50
+ /**
51
+ * Include/exclude globs relative to the project root. Virtual modules and node_modules never match: only the app's
52
+ * own code gets transformed or proxied.
53
+ */
54
+ declare function createFilter(root: () => string, include: string[], exclude?: string[]): (id: string | undefined) => boolean;
55
+
56
+ interface PerfRecorderOptions {
57
+ /** Defaults to the dev server only: never in `vite build`, never under Vitest. */
58
+ enabled?: boolean;
59
+ /**
60
+ * Whether recordings are sent to the dev server to be kept; true when it serves the page. A build made with
61
+ * `enabled: true` (a demo) has no server, and its recordings stay in the tab.
62
+ */
63
+ save?: boolean;
64
+ /** Where sessions are written: relative to the root or absolute. Falls back to REACT_PERF_RECORDER_DIR, then `.agent-artifacts/perf-recorder`. */
65
+ outDir?: string;
66
+ /** Largest request body, the final recording included. */
67
+ maxBytes?: number;
68
+ retain?: {
69
+ sessions?: number;
70
+ bytes?: number;
71
+ };
72
+ actions?: {
73
+ values?: boolean;
74
+ secretSelector?: string;
75
+ };
76
+ components?: false | (ComponentNamesOptions & {
77
+ wrapperPattern?: string;
78
+ });
79
+ panel?: false | {
80
+ corner?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
81
+ highlight?: boolean;
82
+ shortcuts?: {
83
+ record?: string;
84
+ pick?: string;
85
+ };
86
+ };
87
+ /** `timers: false` leaves setTimeout, setInterval and requestAnimationFrame unwrapped: no timer causes. */
88
+ engine?: {
89
+ bigCommit?: number;
90
+ timelineLimit?: number;
91
+ maxDurationMs?: number;
92
+ timers?: boolean;
93
+ };
94
+ plugins?: PerfRecorderPlugin[];
95
+ }
96
+ declare function resolveOutDir(root: string, outDir: string | undefined): string;
97
+ /**
98
+ * Records React re-renders from the page: injects the recorder into the dev page, names memo components and
99
+ * contexts, runs the plugins' build halves and stores sessions for the MCP server. Returns several Vite plugins.
100
+ */
101
+ declare function perfRecorder(options?: PerfRecorderOptions): VitePluginLike[];
102
+
103
+ export { type PerfRecorderOptions, PerfRecorderPlugin, type ProxyModuleOptions, VitePluginLike, addComponentNames, appendLines, combineProxies, createFilter, findDeclarations, perfRecorder, proxyModule, resolveOutDir };