react-code-locator 0.1.9 → 0.1.13

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