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,170 @@
1
+ // src/vite/helpers/name-declarations.ts
2
+ import { parse } from "@babel/parser";
3
+ var EMPTY = { names: [], defaultCall: null };
4
+ function pluginSets(file) {
5
+ const ext = file?.replace(/[?#].*$/, "").match(/\.([cm]?[jt]sx?)$/)?.[1];
6
+ if (ext === "tsx") return [["typescript", "jsx"]];
7
+ if (ext === "ts" || ext === "mts" || ext === "cts") return [["typescript"]];
8
+ if (ext === "js" || ext === "jsx" || ext === "mjs" || ext === "cjs") return [["jsx"]];
9
+ return [["typescript", "jsx"], ["typescript"]];
10
+ }
11
+ function parseModule(code, file) {
12
+ for (const plugins of pluginSets(file)) {
13
+ try {
14
+ return parse(code, { sourceType: "module", plugins: [...plugins, "decorators-legacy"], errorRecovery: true }).program.body;
15
+ } catch {
16
+ }
17
+ }
18
+ return null;
19
+ }
20
+ function unwrap(node) {
21
+ let e = node;
22
+ while (e.type === "TSAsExpression" || e.type === "TSSatisfiesExpression" || e.type === "TSNonNullExpression" || e.type === "TSTypeAssertion" || e.type === "ParenthesizedExpression")
23
+ e = e.expression;
24
+ return e;
25
+ }
26
+ function calleeName(callee, allowReactPrefix) {
27
+ if (callee.type === "Identifier") return callee.name;
28
+ if (callee.type === "CallExpression") return calleeName(callee.callee, allowReactPrefix);
29
+ if (callee.type === "TSInstantiationExpression") return calleeName(callee.expression, allowReactPrefix);
30
+ if (allowReactPrefix && callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "React" && callee.property.type === "Identifier")
31
+ return callee.property.name;
32
+ return null;
33
+ }
34
+ function scanModule(code, callees, { allowReactPrefix = false, file } = {}) {
35
+ if (!callees.length || !callees.some((c) => code.includes(c))) return EMPTY;
36
+ const body = parseModule(code, file);
37
+ if (!body) return EMPTY;
38
+ const isCall = (node) => {
39
+ if (!node) return false;
40
+ const e = unwrap(node);
41
+ if (e.type !== "CallExpression") return false;
42
+ const name = calleeName(e.callee, allowReactPrefix);
43
+ return name !== null && callees.includes(name);
44
+ };
45
+ const names = [];
46
+ let defaultCall = null;
47
+ for (const statement of body) {
48
+ const declaration = statement.type === "ExportNamedDeclaration" ? statement.declaration : statement;
49
+ if (declaration?.type === "VariableDeclaration" && declaration.kind !== "var") {
50
+ for (const d of declaration.declarations) if (d.id.type === "Identifier" && isCall(d.init) && !names.includes(d.id.name)) names.push(d.id.name);
51
+ }
52
+ if (statement.type === "ExportDefaultDeclaration") {
53
+ const e = statement.declaration;
54
+ if (e.start != null && e.end != null && isCall(e)) defaultCall = { start: e.start, end: e.end };
55
+ }
56
+ }
57
+ return { names, defaultCall };
58
+ }
59
+ function findDeclarations(code, callees, options = {}) {
60
+ return scanModule(code, callees, options).names;
61
+ }
62
+ function appendLines(code, lines) {
63
+ if (!lines.length) return null;
64
+ return `${code}
65
+ ${lines.join("\n")}
66
+ `;
67
+ }
68
+ var ifDeclared = (name, call) => `if (typeof ${name} !== "undefined") ${call}`;
69
+
70
+ // src/vite/helpers/filter.ts
71
+ import path from "path";
72
+ var cleanId = (id) => id.split("?")[0].replace(/\\/g, "/");
73
+ var globToRegExp = (glob) => {
74
+ let re = "";
75
+ for (let i = 0; i < glob.length; i++) {
76
+ const c = glob[i];
77
+ if (c === "*" && glob[i + 1] === "*") {
78
+ re += ".*";
79
+ i++;
80
+ if (glob[i + 1] === "/") i++;
81
+ } else if (c === "*") re += "[^/]*";
82
+ else if (c === "?") re += "[^/]";
83
+ else if (c === "{") {
84
+ const end = glob.indexOf("}", i);
85
+ re += `(?:${glob.slice(i + 1, end).split(",").map((p) => p.replace(/[.+^$()|[\]\\]/g, "\\$&")).join("|")})`;
86
+ i = end;
87
+ } else re += c.replace(/[.+^$()|[\]\\]/g, "\\$&");
88
+ }
89
+ return new RegExp(`^${re}$`);
90
+ };
91
+ function createFilter(root, include, exclude = []) {
92
+ const inc = include.map(globToRegExp);
93
+ const exc = exclude.map(globToRegExp);
94
+ return (id) => {
95
+ if (!id || id.startsWith("\0") || id.includes("/node_modules/")) return false;
96
+ const file = cleanId(id);
97
+ const rel = path.isAbsolute(file) ? path.relative(root(), file).replace(/\\/g, "/") : file.replace(/^\//, "");
98
+ if (rel.startsWith("..")) return false;
99
+ return inc.some((re) => re.test(rel)) && !exc.some((re) => re.test(rel));
100
+ };
101
+ }
102
+ var relativeToRoot = (root, id) => path.relative(root, cleanId(id)).replace(/\\/g, "/");
103
+
104
+ // src/vite/helpers/proxy-module.ts
105
+ function packageOf(id) {
106
+ const path2 = id.replace(/\?.*$/, "");
107
+ const optimized = /\/deps\/([^/]+)\.js$/.exec(path2);
108
+ if (optimized) return optimized[1].startsWith("chunk-") ? "" : optimized[1].replace(/_/g, "/");
109
+ const at = path2.lastIndexOf("/node_modules/");
110
+ if (at < 0) return "";
111
+ return path2.slice(at + "/node_modules/".length).replace(/\.[cm]?js$/, "").replace(/\/index$/, "");
112
+ }
113
+ function proxyModule(pluginName, options) {
114
+ const id = `\0react-perf-recorder:${pluginName}:${options.source}`;
115
+ return {
116
+ id,
117
+ resolveId(source, importer) {
118
+ if (source === id) return id;
119
+ if (!importer || importer === id || importer.startsWith("\0")) return null;
120
+ if (source !== options.source && packageOf(source) !== options.source) return null;
121
+ return options.importer(importer) ? id : null;
122
+ },
123
+ load(loadId) {
124
+ return loadId === id ? options.code() : null;
125
+ },
126
+ rewrite(code) {
127
+ const quoted = options.source.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
128
+ const imports = new RegExp(`((?:^|[\\s{(,;])(?:from|import)\\s*)(['"])${quoted}\\2`, "g");
129
+ if (!imports.test(code)) return null;
130
+ imports.lastIndex = 0;
131
+ return code.replace(imports, (_all, head, quote) => `${head}${quote}${id}${quote}`);
132
+ }
133
+ };
134
+ }
135
+ function combineProxies(proxies) {
136
+ return {
137
+ id: proxies[0]?.id ?? "",
138
+ resolveId: (source, importer) => {
139
+ for (const p of proxies) {
140
+ const id = p.resolveId(source, importer);
141
+ if (id) return id;
142
+ }
143
+ return null;
144
+ },
145
+ load: (id) => {
146
+ for (const p of proxies) {
147
+ const code = p.load(id);
148
+ if (code != null) return code;
149
+ }
150
+ return null;
151
+ },
152
+ rewrite: (code) => {
153
+ let out = null;
154
+ for (const p of proxies) out = p.rewrite(out ?? code) ?? out;
155
+ return out;
156
+ }
157
+ };
158
+ }
159
+
160
+ export {
161
+ parseModule,
162
+ scanModule,
163
+ findDeclarations,
164
+ appendLines,
165
+ ifDeclared,
166
+ createFilter,
167
+ relativeToRoot,
168
+ proxyModule,
169
+ combineProxies
170
+ };
@@ -0,0 +1,61 @@
1
+ type Primitive = string | number | boolean | null;
2
+ type JsonValue = Primitive | JsonValue[] | {
3
+ [key: string]: JsonValue;
4
+ };
5
+
6
+ interface BuildContext {
7
+ /** Project root, known after Vite resolves the config. */
8
+ root(): string;
9
+ }
10
+ type Loose = Record<string, any>;
11
+ /**
12
+ * A Vite plugin described structurally: the public types never import `vite`, so a linked or hoisted copy of the
13
+ * package with its own Vite and Rollup versions still type-checks against the project's Vite 5–7.
14
+ */
15
+ interface VitePluginLike {
16
+ name: string;
17
+ enforce?: 'pre' | 'post';
18
+ apply?: (config: any, env: {
19
+ command: string;
20
+ mode: string;
21
+ }) => boolean;
22
+ config?: (config: any, env?: any) => Loose | void;
23
+ configResolved?: (config: any) => void;
24
+ resolveId?: (source: string, importer?: string, options?: any) => string | null;
25
+ load?: (id: string) => string | null;
26
+ transform?: (code: string, id: string) => {
27
+ code: string;
28
+ map: null;
29
+ } | null;
30
+ transformIndexHtml?: () => Array<{
31
+ tag: string;
32
+ attrs?: Record<string, string>;
33
+ injectTo?: 'head' | 'body' | 'head-prepend' | 'body-prepend';
34
+ }>;
35
+ configureServer?: (server: any) => void;
36
+ }
37
+ /**
38
+ * A plugin of the recorder. Both halves are optional: `vite` hooks run only in the dev server, `runtime` is a module
39
+ * imported into the page before the app, whose default export is a `definePlugin` factory called with `options`.
40
+ */
41
+ interface PerfRecorderPlugin {
42
+ name: string;
43
+ vite?: {
44
+ config?: (config: Loose) => Loose | void;
45
+ resolveId?: (source: string, importer: string | undefined) => string | null | undefined;
46
+ load?: (id: string) => string | null | undefined;
47
+ transform?: (code: string, id: string) => {
48
+ code: string;
49
+ map: null;
50
+ } | string | null | undefined;
51
+ };
52
+ runtime?: {
53
+ module: string;
54
+ options?: JsonValue;
55
+ };
56
+ /** Receives the core's context once the config is resolved. */
57
+ init?: (ctx: BuildContext) => void;
58
+ }
59
+ declare const definePerfRecorderPlugin: (plugin: PerfRecorderPlugin) => PerfRecorderPlugin;
60
+
61
+ export { type BuildContext as B, type PerfRecorderPlugin as P, type VitePluginLike as V, definePerfRecorderPlugin as d };
@@ -0,0 +1,61 @@
1
+ type Primitive = string | number | boolean | null;
2
+ type JsonValue = Primitive | JsonValue[] | {
3
+ [key: string]: JsonValue;
4
+ };
5
+
6
+ interface BuildContext {
7
+ /** Project root, known after Vite resolves the config. */
8
+ root(): string;
9
+ }
10
+ type Loose = Record<string, any>;
11
+ /**
12
+ * A Vite plugin described structurally: the public types never import `vite`, so a linked or hoisted copy of the
13
+ * package with its own Vite and Rollup versions still type-checks against the project's Vite 5–7.
14
+ */
15
+ interface VitePluginLike {
16
+ name: string;
17
+ enforce?: 'pre' | 'post';
18
+ apply?: (config: any, env: {
19
+ command: string;
20
+ mode: string;
21
+ }) => boolean;
22
+ config?: (config: any, env?: any) => Loose | void;
23
+ configResolved?: (config: any) => void;
24
+ resolveId?: (source: string, importer?: string, options?: any) => string | null;
25
+ load?: (id: string) => string | null;
26
+ transform?: (code: string, id: string) => {
27
+ code: string;
28
+ map: null;
29
+ } | null;
30
+ transformIndexHtml?: () => Array<{
31
+ tag: string;
32
+ attrs?: Record<string, string>;
33
+ injectTo?: 'head' | 'body' | 'head-prepend' | 'body-prepend';
34
+ }>;
35
+ configureServer?: (server: any) => void;
36
+ }
37
+ /**
38
+ * A plugin of the recorder. Both halves are optional: `vite` hooks run only in the dev server, `runtime` is a module
39
+ * imported into the page before the app, whose default export is a `definePlugin` factory called with `options`.
40
+ */
41
+ interface PerfRecorderPlugin {
42
+ name: string;
43
+ vite?: {
44
+ config?: (config: Loose) => Loose | void;
45
+ resolveId?: (source: string, importer: string | undefined) => string | null | undefined;
46
+ load?: (id: string) => string | null | undefined;
47
+ transform?: (code: string, id: string) => {
48
+ code: string;
49
+ map: null;
50
+ } | string | null | undefined;
51
+ };
52
+ runtime?: {
53
+ module: string;
54
+ options?: JsonValue;
55
+ };
56
+ /** Receives the core's context once the config is resolved. */
57
+ init?: (ctx: BuildContext) => void;
58
+ }
59
+ declare const definePerfRecorderPlugin: (plugin: PerfRecorderPlugin) => PerfRecorderPlugin;
60
+
61
+ export { type BuildContext as B, type PerfRecorderPlugin as P, type VitePluginLike as V, definePerfRecorderPlugin as d };
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/plugins/proxy-memoize/index.ts
31
+ var proxy_memoize_exports = {};
32
+ __export(proxy_memoize_exports, {
33
+ proxyMemoize: () => proxyMemoize
34
+ });
35
+ module.exports = __toCommonJS(proxy_memoize_exports);
36
+
37
+ // src/vite/helpers/filter.ts
38
+ var import_node_path = __toESM(require("path"), 1);
39
+ var cleanId = (id) => id.split("?")[0].replace(/\\/g, "/");
40
+ var globToRegExp = (glob) => {
41
+ let re = "";
42
+ for (let i = 0; i < glob.length; i++) {
43
+ const c = glob[i];
44
+ if (c === "*" && glob[i + 1] === "*") {
45
+ re += ".*";
46
+ i++;
47
+ if (glob[i + 1] === "/") i++;
48
+ } else if (c === "*") re += "[^/]*";
49
+ else if (c === "?") re += "[^/]";
50
+ else if (c === "{") {
51
+ const end = glob.indexOf("}", i);
52
+ re += `(?:${glob.slice(i + 1, end).split(",").map((p) => p.replace(/[.+^$()|[\]\\]/g, "\\$&")).join("|")})`;
53
+ i = end;
54
+ } else re += c.replace(/[.+^$()|[\]\\]/g, "\\$&");
55
+ }
56
+ return new RegExp(`^${re}$`);
57
+ };
58
+ function createFilter(root, include, exclude = []) {
59
+ const inc = include.map(globToRegExp);
60
+ const exc = exclude.map(globToRegExp);
61
+ return (id) => {
62
+ if (!id || id.startsWith("\0") || id.includes("/node_modules/")) return false;
63
+ const file = cleanId(id);
64
+ const rel = import_node_path.default.isAbsolute(file) ? import_node_path.default.relative(root(), file).replace(/\\/g, "/") : file.replace(/^\//, "");
65
+ if (rel.startsWith("..")) return false;
66
+ return inc.some((re) => re.test(rel)) && !exc.some((re) => re.test(rel));
67
+ };
68
+ }
69
+ var relativeToRoot = (root, id) => import_node_path.default.relative(root, cleanId(id)).replace(/\\/g, "/");
70
+
71
+ // src/vite/helpers/name-declarations.ts
72
+ var import_parser = require("@babel/parser");
73
+ var EMPTY = { names: [], defaultCall: null };
74
+ function pluginSets(file) {
75
+ const ext = file?.replace(/[?#].*$/, "").match(/\.([cm]?[jt]sx?)$/)?.[1];
76
+ if (ext === "tsx") return [["typescript", "jsx"]];
77
+ if (ext === "ts" || ext === "mts" || ext === "cts") return [["typescript"]];
78
+ if (ext === "js" || ext === "jsx" || ext === "mjs" || ext === "cjs") return [["jsx"]];
79
+ return [["typescript", "jsx"], ["typescript"]];
80
+ }
81
+ function parseModule(code, file) {
82
+ for (const plugins of pluginSets(file)) {
83
+ try {
84
+ return (0, import_parser.parse)(code, { sourceType: "module", plugins: [...plugins, "decorators-legacy"], errorRecovery: true }).program.body;
85
+ } catch {
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ function unwrap(node) {
91
+ let e = node;
92
+ while (e.type === "TSAsExpression" || e.type === "TSSatisfiesExpression" || e.type === "TSNonNullExpression" || e.type === "TSTypeAssertion" || e.type === "ParenthesizedExpression")
93
+ e = e.expression;
94
+ return e;
95
+ }
96
+ function calleeName(callee, allowReactPrefix) {
97
+ if (callee.type === "Identifier") return callee.name;
98
+ if (callee.type === "CallExpression") return calleeName(callee.callee, allowReactPrefix);
99
+ if (callee.type === "TSInstantiationExpression") return calleeName(callee.expression, allowReactPrefix);
100
+ if (allowReactPrefix && callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "React" && callee.property.type === "Identifier")
101
+ return callee.property.name;
102
+ return null;
103
+ }
104
+ function scanModule(code, callees, { allowReactPrefix = false, file } = {}) {
105
+ if (!callees.length || !callees.some((c) => code.includes(c))) return EMPTY;
106
+ const body = parseModule(code, file);
107
+ if (!body) return EMPTY;
108
+ const isCall = (node) => {
109
+ if (!node) return false;
110
+ const e = unwrap(node);
111
+ if (e.type !== "CallExpression") return false;
112
+ const name = calleeName(e.callee, allowReactPrefix);
113
+ return name !== null && callees.includes(name);
114
+ };
115
+ const names = [];
116
+ let defaultCall = null;
117
+ for (const statement of body) {
118
+ const declaration = statement.type === "ExportNamedDeclaration" ? statement.declaration : statement;
119
+ if (declaration?.type === "VariableDeclaration" && declaration.kind !== "var") {
120
+ for (const d of declaration.declarations) if (d.id.type === "Identifier" && isCall(d.init) && !names.includes(d.id.name)) names.push(d.id.name);
121
+ }
122
+ if (statement.type === "ExportDefaultDeclaration") {
123
+ const e = statement.declaration;
124
+ if (e.start != null && e.end != null && isCall(e)) defaultCall = { start: e.start, end: e.end };
125
+ }
126
+ }
127
+ return { names, defaultCall };
128
+ }
129
+ function findDeclarations(code, callees, options = {}) {
130
+ return scanModule(code, callees, options).names;
131
+ }
132
+ function appendLines(code, lines) {
133
+ if (!lines.length) return null;
134
+ return `${code}
135
+ ${lines.join("\n")}
136
+ `;
137
+ }
138
+ var ifDeclared = (name, call) => `if (typeof ${name} !== "undefined") ${call}`;
139
+
140
+ // src/vite/helpers/proxy-module.ts
141
+ function packageOf(id) {
142
+ const path2 = id.replace(/\?.*$/, "");
143
+ const optimized = /\/deps\/([^/]+)\.js$/.exec(path2);
144
+ if (optimized) return optimized[1].startsWith("chunk-") ? "" : optimized[1].replace(/_/g, "/");
145
+ const at = path2.lastIndexOf("/node_modules/");
146
+ if (at < 0) return "";
147
+ return path2.slice(at + "/node_modules/".length).replace(/\.[cm]?js$/, "").replace(/\/index$/, "");
148
+ }
149
+ function proxyModule(pluginName, options) {
150
+ const id = `\0react-perf-recorder:${pluginName}:${options.source}`;
151
+ return {
152
+ id,
153
+ resolveId(source, importer) {
154
+ if (source === id) return id;
155
+ if (!importer || importer === id || importer.startsWith("\0")) return null;
156
+ if (source !== options.source && packageOf(source) !== options.source) return null;
157
+ return options.importer(importer) ? id : null;
158
+ },
159
+ load(loadId) {
160
+ return loadId === id ? options.code() : null;
161
+ },
162
+ rewrite(code) {
163
+ const quoted = options.source.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
164
+ const imports = new RegExp(`((?:^|[\\s{(,;])(?:from|import)\\s*)(['"])${quoted}\\2`, "g");
165
+ if (!imports.test(code)) return null;
166
+ imports.lastIndex = 0;
167
+ return code.replace(imports, (_all, head, quote) => `${head}${quote}${id}${quote}`);
168
+ }
169
+ };
170
+ }
171
+
172
+ // src/plugins/proxy-memoize/index.ts
173
+ var RUNTIME = "react-perf-recorder/plugins/proxy-memoize/runtime";
174
+ function proxyMemoize(options = {}) {
175
+ const functions = options.functions ?? ["memoize", "memoizeWithArgs"];
176
+ const source = options.module ?? "proxy-memoize";
177
+ let context = null;
178
+ const root = () => context?.root() ?? process.cwd();
179
+ const filter = createFilter(root, options.include ?? ["src/**/*.{ts,tsx,js,jsx}"], options.exclude);
180
+ const proxy = proxyModule("proxy-memoize", {
181
+ source,
182
+ importer: filter,
183
+ code: () => [
184
+ `import * as original from ${JSON.stringify(source)};`,
185
+ `import { instrument } from ${JSON.stringify(RUNTIME)};`,
186
+ `export * from ${JSON.stringify(source)};`,
187
+ ...functions.map((fn) => `export const ${fn} = instrument(original.${fn}, ${JSON.stringify(fn)}, 0);`)
188
+ ].join("\n")
189
+ });
190
+ return {
191
+ name: "proxy-memoize",
192
+ init: (ctx) => void (context = ctx),
193
+ vite: {
194
+ config: () => ({ optimizeDeps: { include: [source] } }),
195
+ resolveId: (id, importer) => proxy.resolveId(id, importer),
196
+ load: (id) => proxy.load(id),
197
+ transform(code, id) {
198
+ if (!filter(id) || !functions.some((fn) => code.includes(fn))) return null;
199
+ const names = findDeclarations(code, functions, { file: id });
200
+ const file = relativeToRoot(root(), id);
201
+ const out = appendLines(code, [
202
+ `import { nameMemoized as __rprNameMemoized } from ${JSON.stringify(RUNTIME)};`,
203
+ ...names.map((name) => ifDeclared(name, `__rprNameMemoized(${name}, ${JSON.stringify(name)}, ${JSON.stringify(file)});`))
204
+ ]);
205
+ return names.length && out ? { code: out, map: null } : null;
206
+ }
207
+ },
208
+ runtime: { module: RUNTIME }
209
+ };
210
+ }
211
+ // Annotate the CommonJS export names for ESM import in node:
212
+ 0 && (module.exports = {
213
+ proxyMemoize
214
+ });
@@ -0,0 +1,16 @@
1
+ import { P as PerfRecorderPlugin } from '../plugin-api-zXFxjYba.cjs';
2
+
3
+ interface ProxyMemoizeOptions {
4
+ /** Exports of the module that create memoized functions. */
5
+ functions?: string[];
6
+ module?: string;
7
+ include?: string[];
8
+ exclude?: string[];
9
+ }
10
+ /**
11
+ * Names memoized selectors and counts their calls and recomputes: `memoizeWithArgs` keeps one entry by default, and
12
+ * rows or cells that call it with different arguments evict each other on every store update.
13
+ */
14
+ declare function proxyMemoize(options?: ProxyMemoizeOptions): PerfRecorderPlugin;
15
+
16
+ export { type ProxyMemoizeOptions, proxyMemoize };
@@ -0,0 +1,16 @@
1
+ import { P as PerfRecorderPlugin } from '../plugin-api-zXFxjYba.js';
2
+
3
+ interface ProxyMemoizeOptions {
4
+ /** Exports of the module that create memoized functions. */
5
+ functions?: string[];
6
+ module?: string;
7
+ include?: string[];
8
+ exclude?: string[];
9
+ }
10
+ /**
11
+ * Names memoized selectors and counts their calls and recomputes: `memoizeWithArgs` keeps one entry by default, and
12
+ * rows or cells that call it with different arguments evict each other on every store update.
13
+ */
14
+ declare function proxyMemoize(options?: ProxyMemoizeOptions): PerfRecorderPlugin;
15
+
16
+ export { type ProxyMemoizeOptions, proxyMemoize };
@@ -0,0 +1,51 @@
1
+ import {
2
+ appendLines,
3
+ createFilter,
4
+ findDeclarations,
5
+ ifDeclared,
6
+ proxyModule,
7
+ relativeToRoot
8
+ } from "../chunk-HS2BJBJX.js";
9
+
10
+ // src/plugins/proxy-memoize/index.ts
11
+ var RUNTIME = "react-perf-recorder/plugins/proxy-memoize/runtime";
12
+ function proxyMemoize(options = {}) {
13
+ const functions = options.functions ?? ["memoize", "memoizeWithArgs"];
14
+ const source = options.module ?? "proxy-memoize";
15
+ let context = null;
16
+ const root = () => context?.root() ?? process.cwd();
17
+ const filter = createFilter(root, options.include ?? ["src/**/*.{ts,tsx,js,jsx}"], options.exclude);
18
+ const proxy = proxyModule("proxy-memoize", {
19
+ source,
20
+ importer: filter,
21
+ code: () => [
22
+ `import * as original from ${JSON.stringify(source)};`,
23
+ `import { instrument } from ${JSON.stringify(RUNTIME)};`,
24
+ `export * from ${JSON.stringify(source)};`,
25
+ ...functions.map((fn) => `export const ${fn} = instrument(original.${fn}, ${JSON.stringify(fn)}, 0);`)
26
+ ].join("\n")
27
+ });
28
+ return {
29
+ name: "proxy-memoize",
30
+ init: (ctx) => void (context = ctx),
31
+ vite: {
32
+ config: () => ({ optimizeDeps: { include: [source] } }),
33
+ resolveId: (id, importer) => proxy.resolveId(id, importer),
34
+ load: (id) => proxy.load(id),
35
+ transform(code, id) {
36
+ if (!filter(id) || !functions.some((fn) => code.includes(fn))) return null;
37
+ const names = findDeclarations(code, functions, { file: id });
38
+ const file = relativeToRoot(root(), id);
39
+ const out = appendLines(code, [
40
+ `import { nameMemoized as __rprNameMemoized } from ${JSON.stringify(RUNTIME)};`,
41
+ ...names.map((name) => ifDeclared(name, `__rprNameMemoized(${name}, ${JSON.stringify(name)}, ${JSON.stringify(file)});`))
42
+ ]);
43
+ return names.length && out ? { code: out, map: null } : null;
44
+ }
45
+ },
46
+ runtime: { module: RUNTIME }
47
+ };
48
+ }
49
+ export {
50
+ proxyMemoize
51
+ };
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/plugins/react-query/index.ts
21
+ var react_query_exports = {};
22
+ __export(react_query_exports, {
23
+ reactQuery: () => reactQuery
24
+ });
25
+ module.exports = __toCommonJS(react_query_exports);
26
+ function reactQuery() {
27
+ return { name: "react-query", runtime: { module: "react-perf-recorder/plugins/react-query/runtime" } };
28
+ }
29
+ // Annotate the CommonJS export names for ESM import in node:
30
+ 0 && (module.exports = {
31
+ reactQuery
32
+ });
@@ -0,0 +1,6 @@
1
+ import { P as PerfRecorderPlugin } from '../plugin-api-zXFxjYba.cjs';
2
+
3
+ /** Query cache events (fetch, success, error, invalidate) as causes of the commits that follow them. */
4
+ declare function reactQuery(): PerfRecorderPlugin;
5
+
6
+ export { reactQuery };
@@ -0,0 +1,6 @@
1
+ import { P as PerfRecorderPlugin } from '../plugin-api-zXFxjYba.js';
2
+
3
+ /** Query cache events (fetch, success, error, invalidate) as causes of the commits that follow them. */
4
+ declare function reactQuery(): PerfRecorderPlugin;
5
+
6
+ export { reactQuery };
@@ -0,0 +1,7 @@
1
+ // src/plugins/react-query/index.ts
2
+ function reactQuery() {
3
+ return { name: "react-query", runtime: { module: "react-perf-recorder/plugins/react-query/runtime" } };
4
+ }
5
+ export {
6
+ reactQuery
7
+ };