react-code-locator 0.1.8 → 0.1.12

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 (52) hide show
  1. package/README.md +49 -44
  2. package/dist/babel.cjs +427 -40
  3. package/dist/babel.cjs.map +1 -1
  4. package/dist/babel.d.cts +12 -1
  5. package/dist/babel.d.ts +12 -1
  6. package/dist/babel.js +424 -29
  7. package/dist/babel.js.map +1 -1
  8. package/dist/babelInjectComponentSource.cjs +403 -38
  9. package/dist/babelInjectComponentSource.cjs.map +1 -1
  10. package/dist/babelInjectComponentSource.d.cts +3 -4
  11. package/dist/babelInjectComponentSource.d.ts +3 -4
  12. package/dist/babelInjectComponentSource.js +403 -28
  13. package/dist/babelInjectComponentSource.js.map +1 -1
  14. package/dist/client-sm5wi0uT.d.cts +15 -0
  15. package/dist/client-sm5wi0uT.d.ts +15 -0
  16. package/dist/client.cjs +166 -27
  17. package/dist/client.cjs.map +1 -1
  18. package/dist/client.d.cts +1 -14
  19. package/dist/client.d.ts +1 -14
  20. package/dist/client.js +166 -27
  21. package/dist/client.js.map +1 -1
  22. package/dist/esbuild.cjs +615 -0
  23. package/dist/esbuild.cjs.map +1 -0
  24. package/dist/esbuild.d.cts +25 -0
  25. package/dist/esbuild.d.ts +25 -0
  26. package/dist/esbuild.js +588 -0
  27. package/dist/esbuild.js.map +1 -0
  28. package/dist/index.cjs +833 -29
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +9 -1
  31. package/dist/index.d.ts +9 -1
  32. package/dist/index.js +820 -28
  33. package/dist/index.js.map +1 -1
  34. package/dist/sourceAdapter-DLWo_ABo.d.cts +15 -0
  35. package/dist/sourceAdapter-DLWo_ABo.d.ts +15 -0
  36. package/dist/swc.cjs +588 -0
  37. package/dist/swc.cjs.map +1 -0
  38. package/dist/swc.d.cts +29 -0
  39. package/dist/swc.d.ts +29 -0
  40. package/dist/swc.js +559 -0
  41. package/dist/swc.js.map +1 -0
  42. package/dist/vite.cjs +525 -84
  43. package/dist/vite.cjs.map +1 -1
  44. package/dist/vite.d.cts +20 -6
  45. package/dist/vite.d.ts +20 -6
  46. package/dist/vite.js +520 -72
  47. package/dist/vite.js.map +1 -1
  48. package/dist/webpackRuntimeEntry.cjs +166 -27
  49. package/dist/webpackRuntimeEntry.cjs.map +1 -1
  50. package/dist/webpackRuntimeEntry.js +166 -27
  51. package/dist/webpackRuntimeEntry.js.map +1 -1
  52. package/package.json +12 -1
package/dist/vite.cjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,80 +15,146 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
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
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/vite.ts
31
21
  var vite_exports = {};
32
22
  __export(vite_exports, {
33
23
  babelInjectComponentSource: () => babelInjectComponentSource,
34
- elementLocatorReact: () => elementLocatorReact,
35
- reactComponentJump: () => elementLocatorReact
24
+ createViteClientInjector: () => createViteClientInjector,
25
+ createViteSourceAdapter: () => createViteSourceAdapter,
26
+ reactComponentJump: () => createViteClientInjector,
27
+ viteSourceAdapter: () => viteSourceAdapter,
28
+ viteSourceTransformPlugin: () => viteSourceTransformPlugin
36
29
  });
37
30
  module.exports = __toCommonJS(vite_exports);
38
31
 
39
- // src/elementLocatorReact.ts
40
- var VIRTUAL_CLIENT_MODULE_ID = "virtual:react-code-locator/client";
41
- var RESOLVED_VIRTUAL_CLIENT_MODULE_ID = `\0${VIRTUAL_CLIENT_MODULE_ID}`;
42
- function createClientInjector(locatorOptions = {}) {
43
- const serialized = JSON.stringify(locatorOptions);
44
- return {
45
- name: "element-locator-client-injector",
46
- apply: "serve",
47
- resolveId(id) {
48
- if (id === VIRTUAL_CLIENT_MODULE_ID) {
49
- return RESOLVED_VIRTUAL_CLIENT_MODULE_ID;
50
- }
51
- return null;
52
- },
53
- load(id) {
54
- if (id !== RESOLVED_VIRTUAL_CLIENT_MODULE_ID) {
55
- return null;
56
- }
57
- return `
58
- import { enableReactComponentJump } from "react-code-locator/client";
59
-
60
- enableReactComponentJump(${serialized});
61
- `;
62
- },
63
- transformIndexHtml() {
64
- return [
65
- {
66
- tag: "script",
67
- attrs: {
68
- type: "module",
69
- src: `/@id/__x00__${VIRTUAL_CLIENT_MODULE_ID}`
70
- },
71
- injectTo: "head"
72
- }
73
- ];
74
- }
75
- };
76
- }
77
- function elementLocatorReact(options = {}) {
78
- const { command = "serve", locator = {}, injectClient = true } = options;
79
- const isServe = command === "serve";
80
- return [isServe && injectClient ? createClientInjector(locator) : null].filter(Boolean);
32
+ // src/sourceAdapter.ts
33
+ function defineSourceAdapter(descriptor) {
34
+ return descriptor;
81
35
  }
82
36
 
37
+ // src/sourceTransform.ts
38
+ var import_core2 = require("@babel/core");
39
+
83
40
  // src/babelInjectComponentSource.ts
84
- var import_node_path = __toESM(require("path"), 1);
85
41
  var import_core = require("@babel/core");
86
42
 
87
43
  // src/constants.ts
88
44
  var SOURCE_PROP = "__componentSourceLoc";
45
+ var JSX_SOURCE_PROP = "$componentSourceLoc";
46
+ var JSX_SOURCE_REGISTRY_SYMBOL = "react-code-locator.jsxSourceRegistry";
47
+
48
+ // src/sourceMetadata.ts
49
+ function normalizeSlashes(value) {
50
+ return value.replace(/\\/g, "/");
51
+ }
52
+ function trimTrailingSlash(value) {
53
+ return value.replace(/\/+$/, "");
54
+ }
55
+ function splitPathSegments(value) {
56
+ return normalizeSlashes(value).split("/").filter(Boolean);
57
+ }
58
+ function computeRelativePath(fromPath, toPath) {
59
+ const fromSegments = splitPathSegments(fromPath);
60
+ const toSegments = splitPathSegments(toPath);
61
+ let sharedIndex = 0;
62
+ while (sharedIndex < fromSegments.length && sharedIndex < toSegments.length && fromSegments[sharedIndex] === toSegments[sharedIndex]) {
63
+ sharedIndex += 1;
64
+ }
65
+ const upSegments = new Array(Math.max(0, fromSegments.length - sharedIndex)).fill("..");
66
+ const downSegments = toSegments.slice(sharedIndex);
67
+ const relativeSegments = [...upSegments, ...downSegments];
68
+ return relativeSegments.length > 0 ? relativeSegments.join("/") : ".";
69
+ }
70
+ function normalizeProjectRoot(projectRoot) {
71
+ if (projectRoot) {
72
+ return trimTrailingSlash(normalizeSlashes(projectRoot));
73
+ }
74
+ if (typeof process !== "undefined" && typeof process.cwd === "function") {
75
+ return trimTrailingSlash(normalizeSlashes(process.cwd()));
76
+ }
77
+ return "";
78
+ }
79
+ function toRelativeSource(filename, loc, projectRoot) {
80
+ if (!filename || !loc) {
81
+ return null;
82
+ }
83
+ const root = normalizeProjectRoot(projectRoot);
84
+ const normalizedFilename = normalizeSlashes(filename);
85
+ const relPath = root && normalizedFilename.startsWith(`${root}/`) ? normalizedFilename.slice(root.length + 1) : root ? computeRelativePath(root, normalizedFilename) : normalizedFilename;
86
+ return `${relPath}:${loc.line}:${loc.column + 1}`;
87
+ }
88
+ function isProjectLocalFile(filename, projectRoot) {
89
+ if (!filename) {
90
+ return false;
91
+ }
92
+ const root = normalizeProjectRoot(projectRoot);
93
+ const normalizedFilename = normalizeSlashes(filename);
94
+ if (!root) {
95
+ return !normalizedFilename.startsWith("../") && !normalizedFilename.startsWith("/") && !/^[A-Za-z]:\//.test(normalizedFilename);
96
+ }
97
+ if (normalizedFilename.startsWith(`${root}/`) || normalizedFilename === root) {
98
+ return true;
99
+ }
100
+ const relativePath = computeRelativePath(root, normalizedFilename);
101
+ return !relativePath.startsWith("../");
102
+ }
103
+ function isExternalToProjectRoot(filename, projectRoot) {
104
+ return !isProjectLocalFile(filename, projectRoot);
105
+ }
89
106
 
90
107
  // src/babelInjectComponentSource.ts
108
+ var SOURCE_PROP_LOCAL = "_componentSourceLoc";
109
+ var SOURCE_PROPS_REST = "__reactCodeLocatorProps";
91
110
  function isComponentName(name) {
92
111
  return /^[A-Z]/.test(name);
93
112
  }
113
+ function isCustomComponentTag(name) {
114
+ if (import_core.types.isJSXIdentifier(name)) {
115
+ return isComponentName(name.name);
116
+ }
117
+ if (import_core.types.isJSXMemberExpression(name)) {
118
+ return true;
119
+ }
120
+ return false;
121
+ }
122
+ function isIntrinsicElementTag(name) {
123
+ return import_core.types.isJSXIdentifier(name) && /^[a-z]/.test(name.name);
124
+ }
125
+ function isElementFactoryIdentifier(name) {
126
+ return name === "jsx" || name === "jsxs" || name === "jsxDEV" || name === "_jsx" || name === "_jsxs" || name === "_jsxDEV" || name === "createElement";
127
+ }
128
+ function isReactElementFactoryCall(pathNode) {
129
+ const callee = pathNode.node.callee;
130
+ if (import_core.types.isIdentifier(callee)) {
131
+ return isElementFactoryIdentifier(callee.name);
132
+ }
133
+ return import_core.types.isMemberExpression(callee) && import_core.types.isIdentifier(callee.object, { name: "React" }) && import_core.types.isIdentifier(callee.property, { name: "createElement" });
134
+ }
135
+ function getRootJsxIdentifierName(name) {
136
+ if (import_core.types.isJSXIdentifier(name)) {
137
+ return name.name;
138
+ }
139
+ if (import_core.types.isJSXMemberExpression(name)) {
140
+ return getRootJsxIdentifierName(name.object);
141
+ }
142
+ return null;
143
+ }
144
+ function isStyledModuleImport(binding) {
145
+ if (!binding) {
146
+ return false;
147
+ }
148
+ if (!binding.path.isImportSpecifier() && !binding.path.isImportDefaultSpecifier() && !binding.path.isImportNamespaceSpecifier()) {
149
+ return false;
150
+ }
151
+ const source = binding.path.parentPath.isImportDeclaration() ? binding.path.parentPath.node.source.value : null;
152
+ if (typeof source !== "string") {
153
+ return false;
154
+ }
155
+ const normalized = source.replace(/\\/g, "/");
156
+ return normalized === "./styled" || normalized === "../styled" || normalized.endsWith("/styled");
157
+ }
94
158
  function isSupportedComponentInit(node) {
95
159
  if (!node) {
96
160
  return false;
@@ -106,13 +170,104 @@ function isSupportedComponentInit(node) {
106
170
  }
107
171
  return import_core.types.isMemberExpression(node.callee) && import_core.types.isIdentifier(node.callee.object, { name: "React" }) && import_core.types.isIdentifier(node.callee.property) && (node.callee.property.name === "memo" || node.callee.property.name === "forwardRef");
108
172
  }
109
- function getSourceValue(state, loc) {
173
+ function hasSourcePropBinding(pattern) {
174
+ return pattern.properties.some((property) => {
175
+ if (!import_core.types.isObjectProperty(property)) {
176
+ return false;
177
+ }
178
+ return import_core.types.isIdentifier(property.key) && property.key.name === JSX_SOURCE_PROP;
179
+ });
180
+ }
181
+ function injectSourcePropBinding(pattern) {
182
+ if (hasSourcePropBinding(pattern)) {
183
+ return;
184
+ }
185
+ const sourceBinding = import_core.types.objectProperty(
186
+ import_core.types.identifier(JSX_SOURCE_PROP),
187
+ import_core.types.identifier(SOURCE_PROP_LOCAL),
188
+ false,
189
+ false
190
+ );
191
+ const restIndex = pattern.properties.findIndex(
192
+ (property) => import_core.types.isRestElement(property)
193
+ );
194
+ if (restIndex === -1) {
195
+ pattern.properties.push(sourceBinding);
196
+ return;
197
+ }
198
+ pattern.properties.splice(restIndex, 0, sourceBinding);
199
+ }
200
+ function injectSourcePropIntoIdentifierParam(node, param) {
201
+ if (!import_core.types.isBlockStatement(node.body)) {
202
+ node.body = import_core.types.blockStatement([import_core.types.returnStatement(node.body)]);
203
+ }
204
+ const alreadyInjected = node.body.body.some(
205
+ (statement) => import_core.types.isVariableDeclaration(statement) && statement.declarations.some(
206
+ (declaration) => import_core.types.isIdentifier(declaration.id) && declaration.id.name === SOURCE_PROPS_REST
207
+ )
208
+ );
209
+ if (alreadyInjected) {
210
+ return;
211
+ }
212
+ node.body.body.unshift(
213
+ import_core.types.variableDeclaration("const", [
214
+ import_core.types.variableDeclarator(
215
+ import_core.types.objectPattern([
216
+ import_core.types.objectProperty(
217
+ import_core.types.identifier(JSX_SOURCE_PROP),
218
+ import_core.types.identifier(SOURCE_PROP_LOCAL),
219
+ false,
220
+ false
221
+ ),
222
+ import_core.types.restElement(import_core.types.identifier(SOURCE_PROPS_REST))
223
+ ]),
224
+ param
225
+ )
226
+ ]),
227
+ import_core.types.expressionStatement(
228
+ import_core.types.assignmentExpression(
229
+ "=",
230
+ import_core.types.identifier(param.name),
231
+ import_core.types.identifier(SOURCE_PROPS_REST)
232
+ )
233
+ )
234
+ );
235
+ }
236
+ function injectSourcePropIntoFunctionParams(node) {
237
+ const firstParam = node.params[0];
238
+ if (!firstParam) {
239
+ return;
240
+ }
241
+ if (import_core.types.isObjectPattern(firstParam)) {
242
+ injectSourcePropBinding(firstParam);
243
+ return;
244
+ }
245
+ if (import_core.types.isIdentifier(firstParam)) {
246
+ injectSourcePropIntoIdentifierParam(node, firstParam);
247
+ }
248
+ }
249
+ function injectSourcePropIntoExpression(node) {
250
+ if (!node) {
251
+ return;
252
+ }
253
+ if (import_core.types.isFunctionExpression(node) || import_core.types.isArrowFunctionExpression(node)) {
254
+ injectSourcePropIntoFunctionParams(node);
255
+ return;
256
+ }
257
+ if (!import_core.types.isCallExpression(node)) {
258
+ return;
259
+ }
260
+ const firstArg = node.arguments[0];
261
+ if (firstArg && !import_core.types.isSpreadElement(firstArg) && (import_core.types.isFunctionExpression(firstArg) || import_core.types.isArrowFunctionExpression(firstArg))) {
262
+ injectSourcePropIntoFunctionParams(firstArg);
263
+ }
264
+ }
265
+ function getSourceValue(state, loc, projectRoot) {
110
266
  const filename = state.file?.opts?.filename;
111
267
  if (!filename || !loc) {
112
268
  return null;
113
269
  }
114
- const relPath = import_node_path.default.relative(process.cwd(), filename).replace(/\\/g, "/");
115
- return `${relPath}:${loc.line}:${loc.column + 1}`;
270
+ return toRelativeSource(filename, loc, projectRoot);
116
271
  }
117
272
  function buildAssignment(name, sourceValue) {
118
273
  return import_core.types.expressionStatement(
@@ -123,13 +278,98 @@ function buildAssignment(name, sourceValue) {
123
278
  )
124
279
  );
125
280
  }
126
- function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
281
+ function buildIntrinsicSourceHelper() {
282
+ return import_core.types.functionDeclaration(
283
+ import_core.types.identifier("_markIntrinsicElementSource"),
284
+ [import_core.types.identifier("element"), import_core.types.identifier("source")],
285
+ import_core.types.blockStatement([
286
+ import_core.types.variableDeclaration("const", [
287
+ import_core.types.variableDeclarator(
288
+ import_core.types.identifier("registryKey"),
289
+ import_core.types.callExpression(
290
+ import_core.types.memberExpression(import_core.types.identifier("Symbol"), import_core.types.identifier("for")),
291
+ [import_core.types.stringLiteral(JSX_SOURCE_REGISTRY_SYMBOL)]
292
+ )
293
+ )
294
+ ]),
295
+ import_core.types.variableDeclaration("let", [
296
+ import_core.types.variableDeclarator(
297
+ import_core.types.identifier("registry"),
298
+ import_core.types.memberExpression(import_core.types.identifier("globalThis"), import_core.types.identifier("registryKey"), true)
299
+ )
300
+ ]),
301
+ import_core.types.ifStatement(
302
+ import_core.types.unaryExpression(
303
+ "!",
304
+ import_core.types.binaryExpression("instanceof", import_core.types.identifier("registry"), import_core.types.identifier("WeakMap"))
305
+ ),
306
+ import_core.types.blockStatement([
307
+ import_core.types.expressionStatement(
308
+ import_core.types.assignmentExpression(
309
+ "=",
310
+ import_core.types.identifier("registry"),
311
+ import_core.types.assignmentExpression(
312
+ "=",
313
+ import_core.types.memberExpression(import_core.types.identifier("globalThis"), import_core.types.identifier("registryKey"), true),
314
+ import_core.types.newExpression(import_core.types.identifier("WeakMap"), [])
315
+ )
316
+ )
317
+ )
318
+ ])
319
+ ),
320
+ import_core.types.ifStatement(
321
+ import_core.types.logicalExpression(
322
+ "&&",
323
+ import_core.types.identifier("element"),
324
+ import_core.types.logicalExpression(
325
+ "&&",
326
+ import_core.types.binaryExpression("===", import_core.types.unaryExpression("typeof", import_core.types.identifier("element")), import_core.types.stringLiteral("object")),
327
+ import_core.types.binaryExpression(
328
+ "===",
329
+ import_core.types.unaryExpression("typeof", import_core.types.memberExpression(import_core.types.identifier("element"), import_core.types.identifier("props"))),
330
+ import_core.types.stringLiteral("object")
331
+ )
332
+ )
333
+ ),
334
+ import_core.types.blockStatement([
335
+ import_core.types.expressionStatement(
336
+ import_core.types.callExpression(
337
+ import_core.types.memberExpression(import_core.types.identifier("registry"), import_core.types.identifier("set")),
338
+ [import_core.types.memberExpression(import_core.types.identifier("element"), import_core.types.identifier("props")), import_core.types.identifier("source")]
339
+ )
340
+ )
341
+ ])
342
+ ),
343
+ import_core.types.returnStatement(import_core.types.identifier("element"))
344
+ ])
345
+ );
346
+ }
347
+ function ensureIntrinsicSourceHelper(programPath, state) {
348
+ if (state.injectedIntrinsicHelper) {
349
+ return;
350
+ }
351
+ const alreadyExists = programPath.node.body.some(
352
+ (node) => import_core.types.isFunctionDeclaration(node) && import_core.types.isIdentifier(node.id, { name: "_markIntrinsicElementSource" })
353
+ );
354
+ if (!alreadyExists) {
355
+ programPath.unshiftContainer("body", buildIntrinsicSourceHelper());
356
+ }
357
+ state.injectedIntrinsicHelper = true;
358
+ }
359
+ function visitDeclaration(declarationPath, insertAfterPath, state, seen, projectRoot) {
127
360
  if (declarationPath.isFunctionDeclaration() || declarationPath.isClassDeclaration()) {
128
361
  const name = declarationPath.node.id?.name;
129
362
  if (!name || !isComponentName(name) || seen.has(name)) {
130
363
  return;
131
364
  }
132
- const sourceValue = getSourceValue(state, declarationPath.node.loc?.start);
365
+ if (declarationPath.isFunctionDeclaration()) {
366
+ injectSourcePropIntoFunctionParams(declarationPath.node);
367
+ }
368
+ const sourceValue = getSourceValue(
369
+ state,
370
+ declarationPath.node.loc?.start,
371
+ projectRoot
372
+ );
133
373
  if (!sourceValue) {
134
374
  return;
135
375
  }
@@ -140,38 +380,128 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
140
380
  if (!declarationPath.isVariableDeclaration()) {
141
381
  return;
142
382
  }
143
- const assignments = declarationPath.node.declarations.flatMap((declarator) => {
144
- if (!import_core.types.isIdentifier(declarator.id) || !isComponentName(declarator.id.name) || seen.has(declarator.id.name)) {
145
- return [];
146
- }
147
- if (!declarator.init) {
148
- return [];
149
- }
150
- if (!isSupportedComponentInit(declarator.init)) {
151
- return [];
152
- }
153
- const sourceValue = getSourceValue(state, declarator.loc?.start ?? declarator.init.loc?.start);
154
- if (!sourceValue) {
155
- return [];
383
+ const assignments = declarationPath.node.declarations.flatMap(
384
+ (declarator) => {
385
+ if (!import_core.types.isIdentifier(declarator.id) || !isComponentName(declarator.id.name) || seen.has(declarator.id.name)) {
386
+ return [];
387
+ }
388
+ if (!declarator.init) {
389
+ return [];
390
+ }
391
+ if (!isSupportedComponentInit(declarator.init)) {
392
+ return [];
393
+ }
394
+ injectSourcePropIntoExpression(declarator.init);
395
+ const sourceValue = getSourceValue(
396
+ state,
397
+ declarator.loc?.start ?? declarator.init.loc?.start,
398
+ projectRoot
399
+ );
400
+ if (!sourceValue) {
401
+ return [];
402
+ }
403
+ seen.add(declarator.id.name);
404
+ return [buildAssignment(declarator.id.name, sourceValue)];
156
405
  }
157
- seen.add(declarator.id.name);
158
- return [buildAssignment(declarator.id.name, sourceValue)];
159
- });
406
+ );
160
407
  if (assignments.length > 0) {
161
408
  insertAfterPath.insertAfter(assignments);
162
409
  }
163
410
  }
164
411
  function babelInjectComponentSource(options = {}) {
165
- const { injectJsxSource = false, injectComponentSource = true } = options;
412
+ const {
413
+ injectJsxSource = true,
414
+ injectComponentSource = true,
415
+ projectRoot
416
+ } = options;
166
417
  return {
167
418
  name: "babel-inject-component-source",
168
419
  visitor: {
420
+ CallExpression(pathNode, state) {
421
+ if (!injectJsxSource) {
422
+ return;
423
+ }
424
+ if (!isReactElementFactoryCall(pathNode)) {
425
+ return;
426
+ }
427
+ if (pathNode.parentPath.isCallExpression() && import_core.types.isIdentifier(pathNode.parentPath.node.callee, {
428
+ name: "_markIntrinsicElementSource"
429
+ })) {
430
+ return;
431
+ }
432
+ const sourceValue = getSourceValue(
433
+ state,
434
+ pathNode.node.loc?.start,
435
+ projectRoot
436
+ );
437
+ if (!sourceValue) {
438
+ return;
439
+ }
440
+ const programPath = pathNode.findParent((parent) => parent.isProgram());
441
+ if (!programPath || !programPath.isProgram()) {
442
+ return;
443
+ }
444
+ ensureIntrinsicSourceHelper(programPath, state);
445
+ pathNode.replaceWith(
446
+ import_core.types.callExpression(import_core.types.identifier("_markIntrinsicElementSource"), [
447
+ pathNode.node,
448
+ import_core.types.stringLiteral(sourceValue)
449
+ ])
450
+ );
451
+ pathNode.skip();
452
+ },
453
+ JSXElement: {
454
+ exit(pathNode, state) {
455
+ if (!injectJsxSource) {
456
+ return;
457
+ }
458
+ if (!isIntrinsicElementTag(pathNode.node.openingElement.name)) {
459
+ return;
460
+ }
461
+ if (pathNode.parentPath.isCallExpression() && import_core.types.isIdentifier(pathNode.parentPath.node.callee, { name: "_markIntrinsicElementSource" })) {
462
+ return;
463
+ }
464
+ const sourceValue = getSourceValue(
465
+ state,
466
+ pathNode.node.openingElement.loc?.start,
467
+ projectRoot
468
+ );
469
+ if (!sourceValue) {
470
+ return;
471
+ }
472
+ const programPath = pathNode.findParent((parent) => parent.isProgram());
473
+ if (!programPath || !programPath.isProgram()) {
474
+ return;
475
+ }
476
+ ensureIntrinsicSourceHelper(programPath, state);
477
+ const wrappedNode = import_core.types.callExpression(import_core.types.identifier("_markIntrinsicElementSource"), [
478
+ pathNode.node,
479
+ import_core.types.stringLiteral(sourceValue)
480
+ ]);
481
+ if (pathNode.parentPath.isJSXElement() || pathNode.parentPath.isJSXFragment()) {
482
+ pathNode.replaceWith(import_core.types.jsxExpressionContainer(wrappedNode));
483
+ return;
484
+ }
485
+ if (pathNode.parentPath.isJSXExpressionContainer()) {
486
+ pathNode.parentPath.replaceWith(import_core.types.jsxExpressionContainer(wrappedNode));
487
+ return;
488
+ }
489
+ pathNode.replaceWith(wrappedNode);
490
+ }
491
+ },
169
492
  JSXOpeningElement(pathNode, state) {
170
493
  if (!injectJsxSource) {
171
494
  return;
172
495
  }
496
+ if (!isCustomComponentTag(pathNode.node.name)) {
497
+ return;
498
+ }
499
+ const rootIdentifierName = getRootJsxIdentifierName(pathNode.node.name);
500
+ if (rootIdentifierName && isExternalToProjectRoot(state.file?.opts?.filename, projectRoot) && isStyledModuleImport(pathNode.scope.getBinding(rootIdentifierName))) {
501
+ return;
502
+ }
173
503
  const hasSourceProp = pathNode.node.attributes.some(
174
- (attr) => import_core.types.isJSXAttribute(attr) && import_core.types.isJSXIdentifier(attr.name) && attr.name.name === SOURCE_PROP
504
+ (attr) => import_core.types.isJSXAttribute(attr) && import_core.types.isJSXIdentifier(attr.name) && attr.name.name === JSX_SOURCE_PROP
175
505
  );
176
506
  if (hasSourceProp) {
177
507
  return;
@@ -183,8 +513,10 @@ function babelInjectComponentSource(options = {}) {
183
513
  }
184
514
  pathNode.node.attributes.push(
185
515
  import_core.types.jsxAttribute(
186
- import_core.types.jsxIdentifier(SOURCE_PROP),
187
- import_core.types.stringLiteral(getSourceValue(state, loc) ?? `${filename.replace(/\\/g, "/")}:${loc.line}:${loc.column + 1}`)
516
+ import_core.types.jsxIdentifier(JSX_SOURCE_PROP),
517
+ import_core.types.stringLiteral(
518
+ getSourceValue(state, loc, projectRoot) ?? `${filename.replace(/\\/g, "/")}:${loc.line}:${loc.column + 1}`
519
+ )
188
520
  )
189
521
  );
190
522
  },
@@ -197,20 +529,129 @@ function babelInjectComponentSource(options = {}) {
197
529
  if (childPath.isExportNamedDeclaration() || childPath.isExportDefaultDeclaration()) {
198
530
  const declarationPath = childPath.get("declaration");
199
531
  if (!Array.isArray(declarationPath) && declarationPath.node) {
200
- visitDeclaration(declarationPath, childPath, state, seen);
532
+ visitDeclaration(declarationPath, childPath, state, seen, projectRoot);
201
533
  }
202
534
  continue;
203
535
  }
204
- visitDeclaration(childPath, childPath, state, seen);
536
+ visitDeclaration(childPath, childPath, state, seen, projectRoot);
537
+ }
538
+ }
539
+ }
540
+ };
541
+ }
542
+
543
+ // src/sourceTransform.ts
544
+ async function transformSourceWithLocator(code, options) {
545
+ const { filename, sourceMaps = true, ...pluginOptions } = options;
546
+ const result = await (0, import_core2.transformAsync)(code, {
547
+ filename,
548
+ babelrc: false,
549
+ configFile: false,
550
+ sourceMaps,
551
+ parserOpts: {
552
+ sourceType: "module",
553
+ plugins: ["jsx", "typescript"]
554
+ },
555
+ generatorOpts: {
556
+ retainLines: true
557
+ },
558
+ plugins: [[babelInjectComponentSource, pluginOptions]]
559
+ });
560
+ return {
561
+ code: result?.code ?? code,
562
+ map: result?.map ?? null
563
+ };
564
+ }
565
+
566
+ // src/viteClientInjector.ts
567
+ var VIRTUAL_CLIENT_MODULE_ID = "virtual:react-code-locator/client";
568
+ var RESOLVED_VIRTUAL_CLIENT_MODULE_ID = `\0${VIRTUAL_CLIENT_MODULE_ID}`;
569
+ function createClientInjector(locatorOptions = {}) {
570
+ const serialized = JSON.stringify(locatorOptions);
571
+ return {
572
+ name: "react-code-locator-client-injector",
573
+ apply: "serve",
574
+ resolveId(id) {
575
+ if (id === VIRTUAL_CLIENT_MODULE_ID) {
576
+ return RESOLVED_VIRTUAL_CLIENT_MODULE_ID;
577
+ }
578
+ return null;
579
+ },
580
+ load(id) {
581
+ if (id !== RESOLVED_VIRTUAL_CLIENT_MODULE_ID) {
582
+ return null;
583
+ }
584
+ return `
585
+ import { enableReactComponentJump } from "react-code-locator/client";
586
+
587
+ enableReactComponentJump(${serialized});
588
+ `;
589
+ },
590
+ transformIndexHtml() {
591
+ return [
592
+ {
593
+ tag: "script",
594
+ attrs: {
595
+ type: "module",
596
+ src: `/@id/__x00__${VIRTUAL_CLIENT_MODULE_ID}`
597
+ },
598
+ injectTo: "head"
205
599
  }
600
+ ];
601
+ }
602
+ };
603
+ }
604
+ function createViteClientInjector(options = {}) {
605
+ const { command = "serve", locator = {}, injectClient = true } = options;
606
+ const isServe = command === "serve";
607
+ return [isServe && injectClient ? createClientInjector(locator) : null].filter(Boolean);
608
+ }
609
+
610
+ // src/vite.ts
611
+ function shouldTransformSource(id) {
612
+ if (id.includes("/node_modules/") || id.startsWith("\0")) {
613
+ return false;
614
+ }
615
+ return /\.[mc]?[jt]sx?$/.test(id);
616
+ }
617
+ function viteSourceTransformPlugin(options = {}) {
618
+ return {
619
+ name: "react-code-locator-source-transform",
620
+ enforce: "pre",
621
+ async transform(code, id) {
622
+ if (!shouldTransformSource(id)) {
623
+ return null;
206
624
  }
625
+ return transformSourceWithLocator(code, {
626
+ filename: id,
627
+ ...options
628
+ });
207
629
  }
208
630
  };
209
631
  }
632
+ function createViteSourceAdapter(options = {}) {
633
+ const { babel = {}, ...viteOptions } = options;
634
+ const plugins = [
635
+ viteSourceTransformPlugin(babel),
636
+ ...createViteClientInjector(viteOptions)
637
+ ].filter(Boolean);
638
+ return defineSourceAdapter({
639
+ kind: "vite",
640
+ name: "react-code-locator/vite",
641
+ options,
642
+ config: {
643
+ plugins
644
+ }
645
+ });
646
+ }
647
+ var viteSourceAdapter = createViteSourceAdapter();
210
648
  // Annotate the CommonJS export names for ESM import in node:
211
649
  0 && (module.exports = {
212
650
  babelInjectComponentSource,
213
- elementLocatorReact,
214
- reactComponentJump
651
+ createViteClientInjector,
652
+ createViteSourceAdapter,
653
+ reactComponentJump,
654
+ viteSourceAdapter,
655
+ viteSourceTransformPlugin
215
656
  });
216
657
  //# sourceMappingURL=vite.cjs.map