@wix/zero-config-implementation 1.70.0 → 1.72.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 (42) hide show
  1. package/dist/{index-D_XmjZkE.js → index-CSi4SZpQ.js} +1 -1
  2. package/dist/{index-DnxDZx90.js → index-CdHu4-o-.js} +20462 -18723
  3. package/dist/index.d.ts +15 -8
  4. package/dist/index.js +1 -1
  5. package/package.json +4 -3
  6. package/src/__fixtures__/cjs-ref-element-entry.cjs +1 -0
  7. package/src/__fixtures__/cjs-ref-element-lazy-entry.cjs +3 -0
  8. package/src/__fixtures__/cjs-ref-element-order-entry.cjs +8 -0
  9. package/src/__fixtures__/cjs-ref-element-order-target.cjs +7 -0
  10. package/src/__fixtures__/cjs-ref-element-target.cjs +5 -0
  11. package/src/__fixtures__/esm-ref-element-entry.mjs +3 -0
  12. package/src/component-renderer.ts +12 -9
  13. package/src/converters/data-item-builder.test.ts +33 -0
  14. package/src/converters/to-editor-component.ts +24 -6
  15. package/src/index.ts +121 -54
  16. package/src/information-extractors/react/extractors/core/tree-builder.ts +3 -3
  17. package/src/information-extractors/react/extractors/core/types.ts +4 -5
  18. package/src/information-extractors/react/extractors/css-properties.ts +2 -0
  19. package/src/information-extractors/react/extractors/prop-tracker.test.ts +251 -0
  20. package/src/information-extractors/react/extractors/prop-tracker.ts +78 -14
  21. package/src/information-extractors/react/types.ts +1 -1
  22. package/src/information-extractors/react/utils/mock-generator.test.ts +131 -0
  23. package/src/information-extractors/react/utils/mock-generator.ts +38 -13
  24. package/src/information-extractors/ts/components.test.ts +52 -0
  25. package/src/information-extractors/ts/components.ts +3 -1
  26. package/src/manifest-pipeline.ts +19 -14
  27. package/src/module-loader.test.ts +150 -0
  28. package/src/module-loader.ts +48 -8
  29. package/src/react-runtime-interceptor.ts +64 -0
  30. package/src/react-runtime-loader.ts +656 -0
  31. package/src/ref-elements/component-tag.ts +105 -0
  32. package/src/ref-elements/context.test.ts +179 -0
  33. package/src/ref-elements/context.ts +280 -0
  34. package/src/ref-elements/eligible-paths.ts +45 -0
  35. package/src/ref-elements/module-resolution.test.ts +50 -0
  36. package/src/ref-elements/module-resolution.ts +21 -0
  37. package/src/ref-elements/module-specifier.ts +17 -0
  38. package/src/ref-elements/path-utils.test.ts +14 -0
  39. package/src/ref-elements/path-utils.ts +55 -0
  40. package/src/ref-elements/types.ts +17 -0
  41. package/src/utils/css-class.ts +15 -0
  42. package/src/jsx-runtime-interceptor.ts +0 -245
@@ -0,0 +1,656 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { createRequire, register } from 'node:module'
3
+ import { fileURLToPath, pathToFileURL } from 'node:url'
4
+ import { MessageChannel, MessagePort } from 'node:worker_threads'
5
+ import { buildRefElementTaggerSource, tagRefElementComponentForCleanup } from './ref-elements/component-tag'
6
+ import type { RefElementModule } from './ref-elements/types'
7
+
8
+ const JSX_INTERCEPTOR_STATE_KEY = 'zero-config:jsx-interceptor'
9
+ const JSX_ORIGINALS_KEY = 'zero-config:jsx-originals'
10
+ const REACT_ORIGINALS_KEY = 'zero-config:react-originals'
11
+ const LOADER_REGISTERED_KEY = Symbol.for('zero-config:jsx-loader-registered')
12
+ const RUNTIME_STATE_KEY = Symbol.for('zero-config:ref-element-runtime-state')
13
+ const REF_ELEMENT_LOADER_REQUEST_TIMEOUT_MS = 1_000
14
+ const REF_ELEMENT_ENTRY_SIGNATURE_QUERY_PARAM = 'zero-config-ref-entry'
15
+
16
+ interface RegisteredRefElementModuleState {
17
+ exportNames: string[]
18
+ resolvedModuleUrl: string
19
+ refComponentType: string
20
+ }
21
+
22
+ interface PreparedRefElementEsmImport {
23
+ cleanup: () => Promise<void>
24
+ importUrl: string
25
+ }
26
+
27
+ interface RefElementLoaderRequest {
28
+ modulesByResolvedUrl: Record<string, RegisteredRefElementModuleState>
29
+ requestId: number
30
+ signature: string
31
+ }
32
+
33
+ interface RefElementLoaderResponse {
34
+ error?: string
35
+ requestId: number
36
+ success: boolean
37
+ }
38
+
39
+ interface PendingLoaderRequest {
40
+ reject: (error: Error) => void
41
+ resolve: () => void
42
+ }
43
+
44
+ interface ActiveCjsRefElementExtraction {
45
+ cleanupHandlers: Array<() => void>
46
+ id: number
47
+ runtimeModulesByResolvedPath: Map<string, RegisteredRefElementModuleState[]>
48
+ }
49
+
50
+ interface InternalModuleApi {
51
+ _load: (request: string, parent: NodeJS.Module | null | undefined, isMain: boolean) => unknown
52
+ _resolveFilename: (
53
+ request: string,
54
+ parent: NodeJS.Module | null | undefined,
55
+ isMain: boolean,
56
+ options?: unknown,
57
+ ) => string
58
+ }
59
+
60
+ interface RefElementRuntimeState {
61
+ activeCjsExtractions: Map<number, ActiveCjsRefElementExtraction>
62
+ loaderPort: MessagePort | null
63
+ nextCjsExtractionId: number
64
+ nextLoaderRequestId: number
65
+ pendingLoaderRequests: Map<number, PendingLoaderRequest>
66
+ registeredEsmModulesByResolvedUrl: Map<string, RegisteredRefElementModuleState>
67
+ originalModuleLoad: InternalModuleApi['_load'] | null
68
+ }
69
+
70
+ export async function prepareRefElementEsmImport(
71
+ entryPath: string,
72
+ runtimeModules: RefElementModule[] = [],
73
+ ): Promise<PreparedRefElementEsmImport> {
74
+ ensureReactRuntimeLoader()
75
+
76
+ if (runtimeModules.length === 0) {
77
+ return {
78
+ cleanup: async () => {},
79
+ importUrl: pathToFileURL(entryPath).href,
80
+ }
81
+ }
82
+
83
+ const registeredModules = mergeRefElementModules(runtimeModules)
84
+ const refElementEntrySignature = buildRefElementEntrySignature(registeredModules)
85
+ await registerEsmRefElementModules(refElementEntrySignature, registeredModules)
86
+ const entryImportUrl = pathToFileURL(entryPath)
87
+ entryImportUrl.searchParams.set(REF_ELEMENT_ENTRY_SIGNATURE_QUERY_PARAM, refElementEntrySignature)
88
+
89
+ return {
90
+ cleanup: async () => {},
91
+ importUrl: entryImportUrl.href,
92
+ }
93
+ }
94
+
95
+ export function ensureReactRuntimeLoader(): void {
96
+ const globalRecord = globalThis as Record<symbol, unknown>
97
+ if (globalRecord[LOADER_REGISTERED_KEY]) {
98
+ return
99
+ }
100
+ const runtimeState = readRefElementRuntimeState()
101
+ const { port1: runtimePort, port2: loaderPort } = new MessageChannel()
102
+ try {
103
+ runtimeState.loaderPort = runtimePort
104
+ runtimePort.on('message', (message: RefElementLoaderResponse) => {
105
+ const pendingLoaderRequest = runtimeState.pendingLoaderRequests.get(message.requestId)
106
+ if (!pendingLoaderRequest) {
107
+ return
108
+ }
109
+
110
+ runtimeState.pendingLoaderRequests.delete(message.requestId)
111
+ if (message.success) {
112
+ pendingLoaderRequest.resolve()
113
+ return
114
+ }
115
+
116
+ pendingLoaderRequest.reject(new Error(message.error ?? 'Failed to register ref-element modules in the loader'))
117
+ })
118
+ runtimePort.unref()
119
+ loaderPort.unref()
120
+
121
+ const require = createRequire(import.meta.url)
122
+ const reactRuntime = require('react/jsx-runtime') as typeof import('react/jsx-runtime')
123
+ const reactDevRuntime = require('react/jsx-dev-runtime') as typeof import('react/jsx-dev-runtime')
124
+ const reactModule = require('react') as Record<string, unknown>
125
+ ;(globalThis as Record<PropertyKey, unknown>)[Symbol.for(JSX_ORIGINALS_KEY)] = {
126
+ Fragment: reactRuntime.Fragment,
127
+ jsx: reactRuntime.jsx,
128
+ jsxDEV: reactDevRuntime.jsxDEV,
129
+ jsxs: reactRuntime.jsxs,
130
+ }
131
+ ;(globalThis as Record<PropertyKey, unknown>)[Symbol.for(REACT_ORIGINALS_KEY)] = reactModule
132
+
133
+ const reactModuleUrl = `data:text/javascript,${encodeURIComponent(buildReactModuleShimSource(Object.keys(reactModule)))}`
134
+ const interceptorModuleUrl = `data:text/javascript,${encodeURIComponent(buildJsxRuntimeInterceptorSource())}`
135
+ const loaderSource = buildReactRuntimeLoaderSource({
136
+ interceptorModuleUrl,
137
+ reactModuleUrl,
138
+ taggerSource: buildRefElementTaggerSource(),
139
+ })
140
+
141
+ register(`data:text/javascript,${encodeURIComponent(loaderSource)}`, {
142
+ data: { port: loaderPort },
143
+ transferList: [loaderPort],
144
+ })
145
+ globalRecord[LOADER_REGISTERED_KEY] = true
146
+ } catch (error) {
147
+ runtimeState.loaderPort = null
148
+ runtimePort.close()
149
+ loaderPort.close()
150
+ throw error
151
+ }
152
+ }
153
+
154
+ export function readRegisteredRefElementModuleUrlsForTests(): string[] {
155
+ return [...readRefElementRuntimeState().registeredEsmModulesByResolvedUrl.keys()]
156
+ }
157
+
158
+ export function readLoaderPortRefStateForTests(): boolean | null {
159
+ const loaderPort = readRefElementRuntimeState().loaderPort
160
+ if (!(loaderPort instanceof MessagePort)) {
161
+ return null
162
+ }
163
+
164
+ return (loaderPort as MessagePort & { hasRef: () => boolean }).hasRef()
165
+ }
166
+
167
+ export function loadTaggedCjsModule(
168
+ entryPath: string,
169
+ runtimeModules: RefElementModule[] = [],
170
+ ): { cleanup: () => Promise<void>; moduleExports: Record<string, unknown> } {
171
+ const runtimeState = readRefElementRuntimeState()
172
+ const entryRequire = createRequire(entryPath)
173
+ const activeExtraction = createActiveCjsRefElementExtraction(runtimeState, runtimeModules)
174
+ installCjsRefElementInterception(runtimeState)
175
+
176
+ tagCachedCjsRefElementModules(entryRequire, activeExtraction)
177
+
178
+ let didCleanup = false
179
+ try {
180
+ const moduleExports = entryRequire(entryPath) as Record<string, unknown>
181
+
182
+ return {
183
+ cleanup: async () => {
184
+ if (didCleanup) {
185
+ return
186
+ }
187
+
188
+ didCleanup = true
189
+ cleanupActiveCjsRefElementExtraction(runtimeState, activeExtraction.id)
190
+ },
191
+ moduleExports,
192
+ }
193
+ } catch (error) {
194
+ cleanupActiveCjsRefElementExtraction(runtimeState, activeExtraction.id)
195
+ throw error
196
+ }
197
+ }
198
+
199
+ function readRefElementRuntimeState(): RefElementRuntimeState {
200
+ const globalRecord = globalThis as Record<symbol, RefElementRuntimeState | undefined>
201
+ const runtimeState = globalRecord[RUNTIME_STATE_KEY]
202
+ if (runtimeState) {
203
+ return runtimeState
204
+ }
205
+
206
+ const nextRuntimeState: RefElementRuntimeState = {
207
+ activeCjsExtractions: new Map(),
208
+ loaderPort: null,
209
+ nextCjsExtractionId: 0,
210
+ nextLoaderRequestId: 0,
211
+ pendingLoaderRequests: new Map(),
212
+ registeredEsmModulesByResolvedUrl: new Map(),
213
+ originalModuleLoad: null,
214
+ }
215
+ globalRecord[RUNTIME_STATE_KEY] = nextRuntimeState
216
+ return nextRuntimeState
217
+ }
218
+
219
+ async function registerEsmRefElementModules(
220
+ refElementEntrySignature: string,
221
+ runtimeModules: RegisteredRefElementModuleState[],
222
+ ): Promise<void> {
223
+ const runtimeState = readRefElementRuntimeState()
224
+ const modulesByResolvedUrl: Record<string, RegisteredRefElementModuleState> = {}
225
+
226
+ for (const runtimeModule of runtimeModules) {
227
+ const registeredModule = upsertRefElementModule(runtimeState.registeredEsmModulesByResolvedUrl, runtimeModule)
228
+ modulesByResolvedUrl[registeredModule.resolvedModuleUrl] = registeredModule
229
+ }
230
+
231
+ await postRefElementLoaderRequest({
232
+ modulesByResolvedUrl,
233
+ signature: refElementEntrySignature,
234
+ })
235
+ }
236
+
237
+ function postRefElementLoaderRequest(request: Omit<RefElementLoaderRequest, 'requestId'>): Promise<void> {
238
+ const runtimeState = readRefElementRuntimeState()
239
+ const loaderPort = runtimeState.loaderPort
240
+ if (!(loaderPort instanceof MessagePort)) {
241
+ return Promise.reject(new Error('Ref-element loader has not been initialized'))
242
+ }
243
+
244
+ runtimeState.nextLoaderRequestId += 1
245
+ const requestId = runtimeState.nextLoaderRequestId
246
+
247
+ return new Promise<void>((resolve, reject) => {
248
+ const requestTimeout = setTimeout(() => {
249
+ runtimeState.pendingLoaderRequests.delete(requestId)
250
+ reject(new Error('Timed out waiting for ref-element loader registration'))
251
+ }, REF_ELEMENT_LOADER_REQUEST_TIMEOUT_MS)
252
+
253
+ runtimeState.pendingLoaderRequests.set(requestId, {
254
+ reject: (error) => {
255
+ clearTimeout(requestTimeout)
256
+ reject(error)
257
+ },
258
+ resolve: () => {
259
+ clearTimeout(requestTimeout)
260
+ resolve()
261
+ },
262
+ })
263
+
264
+ loaderPort.postMessage({
265
+ ...request,
266
+ requestId,
267
+ } satisfies RefElementLoaderRequest)
268
+ })
269
+ }
270
+
271
+ function createActiveCjsRefElementExtraction(
272
+ runtimeState: RefElementRuntimeState,
273
+ runtimeModules: RefElementModule[],
274
+ ): ActiveCjsRefElementExtraction {
275
+ runtimeState.nextCjsExtractionId += 1
276
+
277
+ const activeExtraction: ActiveCjsRefElementExtraction = {
278
+ cleanupHandlers: [],
279
+ id: runtimeState.nextCjsExtractionId,
280
+ runtimeModulesByResolvedPath: new Map(),
281
+ }
282
+
283
+ for (const runtimeModule of mergeRefElementModules(runtimeModules)) {
284
+ if (!runtimeModule.resolvedModuleUrl.startsWith('file:')) {
285
+ continue
286
+ }
287
+
288
+ const resolvedModulePath = fileURLToPath(runtimeModule.resolvedModuleUrl)
289
+ const existingRuntimeModules = activeExtraction.runtimeModulesByResolvedPath.get(resolvedModulePath) ?? []
290
+ existingRuntimeModules.push(runtimeModule)
291
+ activeExtraction.runtimeModulesByResolvedPath.set(resolvedModulePath, existingRuntimeModules)
292
+ }
293
+
294
+ runtimeState.activeCjsExtractions.set(activeExtraction.id, activeExtraction)
295
+ return activeExtraction
296
+ }
297
+
298
+ function installCjsRefElementInterception(runtimeState: RefElementRuntimeState): void {
299
+ if (runtimeState.originalModuleLoad) {
300
+ return
301
+ }
302
+
303
+ const internalModule = readInternalModuleApi()
304
+ runtimeState.originalModuleLoad = internalModule._load
305
+ internalModule._load = function (
306
+ request: string,
307
+ parent: NodeJS.Module | null | undefined,
308
+ isMain: boolean,
309
+ ): unknown {
310
+ const moduleExports = runtimeState.originalModuleLoad?.call(this, request, parent, isMain)
311
+ const resolvedModulePath = resolveRequestedCjsModulePath(request, parent, isMain)
312
+
313
+ if (resolvedModulePath) {
314
+ tagActiveCjsRefElementModules(runtimeState, resolvedModulePath, moduleExports)
315
+ }
316
+
317
+ return moduleExports
318
+ }
319
+ }
320
+
321
+ function cleanupActiveCjsRefElementExtraction(runtimeState: RefElementRuntimeState, extractionId: number): void {
322
+ const activeExtraction = runtimeState.activeCjsExtractions.get(extractionId)
323
+ if (!activeExtraction) {
324
+ return
325
+ }
326
+
327
+ runtimeState.activeCjsExtractions.delete(extractionId)
328
+
329
+ for (const cleanupHandler of activeExtraction.cleanupHandlers.reverse()) {
330
+ cleanupHandler()
331
+ }
332
+
333
+ if (runtimeState.activeCjsExtractions.size !== 0) {
334
+ return
335
+ }
336
+
337
+ const internalModule = readInternalModuleApi()
338
+ if (runtimeState.originalModuleLoad) {
339
+ internalModule._load = runtimeState.originalModuleLoad
340
+ runtimeState.originalModuleLoad = null
341
+ }
342
+ }
343
+
344
+ function tagCachedCjsRefElementModules(
345
+ entryRequire: NodeJS.Require,
346
+ activeExtraction: ActiveCjsRefElementExtraction,
347
+ ): void {
348
+ for (const [resolvedModulePath, runtimeModules] of activeExtraction.runtimeModulesByResolvedPath) {
349
+ const cachedModule = entryRequire.cache[resolvedModulePath]
350
+ if (!cachedModule) {
351
+ continue
352
+ }
353
+
354
+ for (const runtimeModule of runtimeModules) {
355
+ activeExtraction.cleanupHandlers.push(...tagCjsRefElementModuleExports(cachedModule.exports, runtimeModule))
356
+ }
357
+ }
358
+ }
359
+
360
+ function tagActiveCjsRefElementModules(
361
+ runtimeState: RefElementRuntimeState,
362
+ resolvedModulePath: string,
363
+ moduleExports: unknown,
364
+ ): void {
365
+ for (const activeExtraction of runtimeState.activeCjsExtractions.values()) {
366
+ const runtimeModules = activeExtraction.runtimeModulesByResolvedPath.get(resolvedModulePath)
367
+ if (!runtimeModules) {
368
+ continue
369
+ }
370
+
371
+ for (const runtimeModule of runtimeModules) {
372
+ activeExtraction.cleanupHandlers.push(...tagCjsRefElementModuleExports(moduleExports, runtimeModule))
373
+ }
374
+ }
375
+ }
376
+
377
+ function readInternalModuleApi(): InternalModuleApi {
378
+ const require = createRequire(import.meta.url)
379
+ return require('node:module') as InternalModuleApi
380
+ }
381
+
382
+ function resolveRequestedCjsModulePath(
383
+ request: string,
384
+ parent: NodeJS.Module | null | undefined,
385
+ isMain: boolean,
386
+ ): string | undefined {
387
+ try {
388
+ return readInternalModuleApi()._resolveFilename(request, parent, isMain)
389
+ } catch {
390
+ return undefined
391
+ }
392
+ }
393
+
394
+ function tagCjsRefElementModuleExports(
395
+ moduleExports: unknown,
396
+ runtimeModule: RegisteredRefElementModuleState,
397
+ ): Array<() => void> {
398
+ const cleanupHandlers: Array<() => void> = []
399
+
400
+ for (const exportName of runtimeModule.exportNames) {
401
+ const exportValue = readModuleExportValue(moduleExports, exportName)
402
+ const cleanupHandler = tagRefElementComponentForCleanup(exportValue, runtimeModule.refComponentType)
403
+ if (cleanupHandler) {
404
+ cleanupHandlers.push(cleanupHandler)
405
+ }
406
+ }
407
+
408
+ return cleanupHandlers
409
+ }
410
+
411
+ function mergeRefElementModules(runtimeModules: RefElementModule[]): RegisteredRefElementModuleState[] {
412
+ const registeredModulesByResolvedUrl = new Map<string, RegisteredRefElementModuleState>()
413
+
414
+ for (const runtimeModule of runtimeModules) {
415
+ upsertRefElementModule(registeredModulesByResolvedUrl, {
416
+ exportNames: [...runtimeModule.exportNames],
417
+ resolvedModuleUrl: runtimeModule.resolvedModuleUrl,
418
+ refComponentType: runtimeModule.refComponentType,
419
+ })
420
+ }
421
+
422
+ return [...registeredModulesByResolvedUrl.values()]
423
+ }
424
+
425
+ function upsertRefElementModule(
426
+ registeredModulesByResolvedUrl: Map<string, RegisteredRefElementModuleState>,
427
+ nextModule: RegisteredRefElementModuleState,
428
+ ): RegisteredRefElementModuleState {
429
+ const existingModule = registeredModulesByResolvedUrl.get(nextModule.resolvedModuleUrl)
430
+ if (!existingModule) {
431
+ registeredModulesByResolvedUrl.set(nextModule.resolvedModuleUrl, nextModule)
432
+ return nextModule
433
+ }
434
+
435
+ if (existingModule.refComponentType !== nextModule.refComponentType) {
436
+ throw new Error(
437
+ `Conflicting ref-element types for ${nextModule.resolvedModuleUrl}: ` +
438
+ `${existingModule.refComponentType} vs ${nextModule.refComponentType}`,
439
+ )
440
+ }
441
+
442
+ existingModule.exportNames = [...new Set([...existingModule.exportNames, ...nextModule.exportNames])]
443
+ return existingModule
444
+ }
445
+
446
+ function buildRefElementEntrySignature(registeredModules: RegisteredRefElementModuleState[]): string {
447
+ const stableSignatureInput = registeredModules
448
+ .map((registeredModule) => ({
449
+ exportNames: [...registeredModule.exportNames].sort(),
450
+ refComponentType: registeredModule.refComponentType,
451
+ resolvedModuleUrl: registeredModule.resolvedModuleUrl,
452
+ }))
453
+ .sort((leftModule, rightModule) => JSON.stringify(leftModule).localeCompare(JSON.stringify(rightModule)))
454
+
455
+ return createHash('sha1').update(JSON.stringify(stableSignatureInput)).digest('hex')
456
+ }
457
+
458
+ function readModuleExportValue(moduleExports: unknown, exportName: string): unknown {
459
+ if (exportName === 'default') {
460
+ if (isComponent(moduleExports)) {
461
+ return moduleExports
462
+ }
463
+
464
+ if (typeof moduleExports === 'object' && moduleExports !== null) {
465
+ return (moduleExports as Record<string, unknown>).default
466
+ }
467
+
468
+ return undefined
469
+ }
470
+
471
+ if (typeof moduleExports !== 'object' || moduleExports === null) {
472
+ return undefined
473
+ }
474
+
475
+ return (moduleExports as Record<string, unknown>)[exportName]
476
+ }
477
+
478
+ function isComponent(value: unknown): boolean {
479
+ if (typeof value === 'function') {
480
+ return true
481
+ }
482
+
483
+ return typeof value === 'object' && value !== null && '$$typeof' in value
484
+ }
485
+
486
+ function buildReactModuleShimSource(reactExportNames: string[]): string {
487
+ const reactExportLines = reactExportNames
488
+ .map((exportName) => {
489
+ if (exportName === 'createElement') {
490
+ return `export function createElement() {
491
+ var state = globalThis[STATE_KEY];
492
+ if (state && state.currentCreateElement) return state.currentCreateElement.apply(null, arguments);
493
+ return reactModule.createElement.apply(null, arguments);
494
+ }`
495
+ }
496
+
497
+ return `export var ${exportName} = reactModule.${exportName};`
498
+ })
499
+ .join('\n')
500
+
501
+ return `
502
+ var REACT_KEY = Symbol.for(${JSON.stringify(REACT_ORIGINALS_KEY)});
503
+ var STATE_KEY = Symbol.for(${JSON.stringify(JSX_INTERCEPTOR_STATE_KEY)});
504
+ var reactModule = globalThis[REACT_KEY];
505
+ export default reactModule;
506
+ ${reactExportLines}
507
+ `
508
+ }
509
+
510
+ function buildJsxRuntimeInterceptorSource(): string {
511
+ return `
512
+ const ORIGINALS_KEY = Symbol.for(${JSON.stringify(JSX_ORIGINALS_KEY)});
513
+ const STATE_KEY = Symbol.for(${JSON.stringify(JSX_INTERCEPTOR_STATE_KEY)});
514
+ const originals = globalThis[ORIGINALS_KEY];
515
+ function getState() {
516
+ if (!globalThis[STATE_KEY]) {
517
+ globalThis[STATE_KEY] = {
518
+ currentJsx: originals.jsx, currentJsxs: originals.jsxs,
519
+ currentJsxDEV: originals.jsxDEV, isInsideOriginal: false,
520
+ };
521
+ }
522
+ return globalThis[STATE_KEY];
523
+ }
524
+ export const Fragment = originals.Fragment;
525
+ export function jsx(type, props, key) {
526
+ const state = getState();
527
+ if (state.isInsideOriginal) return originals.jsx(type, props, key);
528
+ state.isInsideOriginal = true;
529
+ try { return state.currentJsx(type, props, key); }
530
+ finally { state.isInsideOriginal = false; }
531
+ }
532
+ export function jsxs(type, props, key) {
533
+ const state = getState();
534
+ if (state.isInsideOriginal) return originals.jsxs(type, props, key);
535
+ state.isInsideOriginal = true;
536
+ try { return state.currentJsxs(type, props, key); }
537
+ finally { state.isInsideOriginal = false; }
538
+ }
539
+ export function jsxDEV(type, props, key, isStaticChildren, source, self) {
540
+ const state = getState();
541
+ if (state.isInsideOriginal) return originals.jsxDEV(type, props, key, isStaticChildren, source, self);
542
+ state.isInsideOriginal = true;
543
+ try { return state.currentJsxDEV(type, props, key, isStaticChildren, source, self); }
544
+ finally { state.isInsideOriginal = false; }
545
+ }
546
+ `
547
+ }
548
+
549
+ function buildReactRuntimeLoaderSource(options: {
550
+ interceptorModuleUrl: string
551
+ reactModuleUrl: string
552
+ taggerSource: string
553
+ }): string {
554
+ return `
555
+ const INTERCEPTOR_URL = ${JSON.stringify(options.interceptorModuleUrl)};
556
+ const REACT_MODULE_URL = ${JSON.stringify(options.reactModuleUrl)};
557
+ const TAGGER_SOURCE = ${JSON.stringify(options.taggerSource)};
558
+ const REF_ELEMENT_ENTRY_SIGNATURE_QUERY_PARAM = ${JSON.stringify(REF_ELEMENT_ENTRY_SIGNATURE_QUERY_PARAM)};
559
+ const refElementModulesBySignature = Object.create(null);
560
+ export function initialize(data) {
561
+ data.port.on('message', (message) => {
562
+ try {
563
+ const registeredModulesByResolvedUrl = refElementModulesBySignature[message.signature] ?? Object.create(null);
564
+ Object.assign(registeredModulesByResolvedUrl, message.modulesByResolvedUrl);
565
+ refElementModulesBySignature[message.signature] = registeredModulesByResolvedUrl;
566
+
567
+ data.port.postMessage({ requestId: message.requestId, success: true });
568
+ } catch (error) {
569
+ data.port.postMessage({
570
+ error: error instanceof Error ? error.message : String(error),
571
+ requestId: message.requestId,
572
+ success: false,
573
+ });
574
+ }
575
+ });
576
+ }
577
+ function createTaggedRefElementModuleUrl(realUrl, moduleState) {
578
+ const realModuleImportUrl = new URL(realUrl);
579
+ realModuleImportUrl.searchParams.set('zero-config-ref-real', moduleState.refComponentType);
580
+ const namedExportLines = moduleState.exportNames
581
+ .filter((exportName) => exportName !== 'default')
582
+ .map((exportName) => \`export const \${exportName} = safelyTagRefElementComponent(realModule.\${exportName}, REF_COMPONENT_TYPE);\`)
583
+ .join('\\n');
584
+ const taggedModuleSource = \`
585
+ import * as realModule from \${JSON.stringify(realModuleImportUrl.href)};
586
+ const REF_COMPONENT_TYPE = \${JSON.stringify(moduleState.refComponentType)};
587
+ \${TAGGER_SOURCE}
588
+ export default safelyTagRefElementComponent(realModule.default ?? realModule, REF_COMPONENT_TYPE);
589
+ \${namedExportLines}
590
+ export * from \${JSON.stringify(realModuleImportUrl.href)};
591
+ \`;
592
+
593
+ return \`data:text/javascript,\${encodeURIComponent(taggedModuleSource)}\`;
594
+ }
595
+ function readRefElementEntrySignature(urlString) {
596
+ if (!urlString) {
597
+ return undefined;
598
+ }
599
+
600
+ try {
601
+ const url = new URL(urlString);
602
+ return url.searchParams.get(REF_ELEMENT_ENTRY_SIGNATURE_QUERY_PARAM) ?? undefined;
603
+ } catch {
604
+ return undefined;
605
+ }
606
+ }
607
+ function shouldPropagateRefElementEntrySignature(resolvedUrl) {
608
+ return resolvedUrl.startsWith('file:') && !resolvedUrl.includes('/node_modules/');
609
+ }
610
+ function addRefElementEntrySignature(resolvedUrl, refElementEntrySignature) {
611
+ const signedUrl = new URL(resolvedUrl);
612
+ if (!signedUrl.searchParams.has(REF_ELEMENT_ENTRY_SIGNATURE_QUERY_PARAM)) {
613
+ signedUrl.searchParams.set(REF_ELEMENT_ENTRY_SIGNATURE_QUERY_PARAM, refElementEntrySignature);
614
+ }
615
+ return signedUrl.href;
616
+ }
617
+ export async function resolve(specifier, context, nextResolve) {
618
+ if (specifier === 'react/jsx-runtime' || specifier === 'react/jsx-dev-runtime') {
619
+ return { shortCircuit: true, url: INTERCEPTOR_URL };
620
+ }
621
+ if (specifier === 'react') {
622
+ return { shortCircuit: true, url: REACT_MODULE_URL };
623
+ }
624
+
625
+ const resolvedModule = await nextResolve(specifier, context);
626
+ if (new URL(resolvedModule.url).searchParams.has('zero-config-ref-real')) {
627
+ return resolvedModule;
628
+ }
629
+
630
+ const refElementEntrySignature = readRefElementEntrySignature(context.parentURL);
631
+ if (!refElementEntrySignature) {
632
+ return resolvedModule;
633
+ }
634
+
635
+ const refElementModulesByResolvedUrl = refElementModulesBySignature[refElementEntrySignature] ?? Object.create(null);
636
+ const moduleState = refElementModulesByResolvedUrl[resolvedModule.url];
637
+ if (moduleState) {
638
+ return {
639
+ ...resolvedModule,
640
+ shortCircuit: true,
641
+ url: createTaggedRefElementModuleUrl(resolvedModule.url, moduleState),
642
+ };
643
+ }
644
+
645
+ if (shouldPropagateRefElementEntrySignature(resolvedModule.url)) {
646
+ return {
647
+ ...resolvedModule,
648
+ shortCircuit: true,
649
+ url: addRefElementEntrySignature(resolvedModule.url, refElementEntrySignature),
650
+ };
651
+ }
652
+
653
+ return resolvedModule;
654
+ }
655
+ `
656
+ }