@wix/zero-config-implementation 1.5.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 (78) hide show
  1. package/README.md +72 -0
  2. package/dist/component-loader.d.ts +42 -0
  3. package/dist/component-renderer.d.ts +31 -0
  4. package/dist/converters/data-item-builder.d.ts +15 -0
  5. package/dist/converters/index.d.ts +1 -0
  6. package/dist/converters/to-editor-component.d.ts +3 -0
  7. package/dist/converters/utils.d.ts +16 -0
  8. package/dist/errors.d.ts +230 -0
  9. package/dist/index.d.ts +42 -0
  10. package/dist/index.js +51978 -0
  11. package/dist/information-extractors/css/index.d.ts +3 -0
  12. package/dist/information-extractors/css/parse.d.ts +7 -0
  13. package/dist/information-extractors/css/selector-matcher.d.ts +3 -0
  14. package/dist/information-extractors/css/types.d.ts +49 -0
  15. package/dist/information-extractors/react/extractors/core/index.d.ts +6 -0
  16. package/dist/information-extractors/react/extractors/core/runner.d.ts +19 -0
  17. package/dist/information-extractors/react/extractors/core/store.d.ts +17 -0
  18. package/dist/information-extractors/react/extractors/core/tree-builder.d.ts +15 -0
  19. package/dist/information-extractors/react/extractors/core/types.d.ts +40 -0
  20. package/dist/information-extractors/react/extractors/css-properties.d.ts +20 -0
  21. package/dist/information-extractors/react/extractors/index.d.ts +11 -0
  22. package/dist/information-extractors/react/extractors/prop-tracker.d.ts +24 -0
  23. package/dist/information-extractors/react/index.d.ts +9 -0
  24. package/dist/information-extractors/react/types.d.ts +51 -0
  25. package/dist/information-extractors/react/utils/mock-generator.d.ts +9 -0
  26. package/dist/information-extractors/react/utils/prop-spy.d.ts +10 -0
  27. package/dist/information-extractors/ts/components.d.ts +9 -0
  28. package/dist/information-extractors/ts/css-imports.d.ts +2 -0
  29. package/dist/information-extractors/ts/index.d.ts +3 -0
  30. package/dist/information-extractors/ts/types.d.ts +47 -0
  31. package/dist/information-extractors/ts/utils/semantic-type-resolver.d.ts +3 -0
  32. package/dist/jsx-runtime-interceptor.d.ts +42 -0
  33. package/dist/jsx-runtime-interceptor.js +63 -0
  34. package/dist/jsx-runtime-loader.d.ts +23 -0
  35. package/dist/jsx-runtime-loader.js +7 -0
  36. package/dist/manifest-pipeline.d.ts +33 -0
  37. package/dist/schema.d.ts +167 -0
  38. package/dist/ts-compiler.d.ts +13 -0
  39. package/package.json +81 -0
  40. package/src/component-loader.test.ts +277 -0
  41. package/src/component-loader.ts +256 -0
  42. package/src/component-renderer.ts +192 -0
  43. package/src/converters/data-item-builder.ts +354 -0
  44. package/src/converters/index.ts +1 -0
  45. package/src/converters/to-editor-component.ts +167 -0
  46. package/src/converters/utils.ts +21 -0
  47. package/src/errors.ts +103 -0
  48. package/src/index.ts +223 -0
  49. package/src/information-extractors/css/README.md +3 -0
  50. package/src/information-extractors/css/index.ts +3 -0
  51. package/src/information-extractors/css/parse.ts +450 -0
  52. package/src/information-extractors/css/selector-matcher.ts +88 -0
  53. package/src/information-extractors/css/types.ts +56 -0
  54. package/src/information-extractors/react/extractors/core/index.ts +6 -0
  55. package/src/information-extractors/react/extractors/core/runner.ts +89 -0
  56. package/src/information-extractors/react/extractors/core/store.ts +36 -0
  57. package/src/information-extractors/react/extractors/core/tree-builder.ts +273 -0
  58. package/src/information-extractors/react/extractors/core/types.ts +48 -0
  59. package/src/information-extractors/react/extractors/css-properties.ts +214 -0
  60. package/src/information-extractors/react/extractors/index.ts +27 -0
  61. package/src/information-extractors/react/extractors/prop-tracker.ts +132 -0
  62. package/src/information-extractors/react/index.ts +53 -0
  63. package/src/information-extractors/react/types.ts +70 -0
  64. package/src/information-extractors/react/utils/mock-generator.ts +331 -0
  65. package/src/information-extractors/react/utils/prop-spy.ts +168 -0
  66. package/src/information-extractors/ts/components.ts +300 -0
  67. package/src/information-extractors/ts/css-imports.ts +26 -0
  68. package/src/information-extractors/ts/index.ts +3 -0
  69. package/src/information-extractors/ts/types.ts +56 -0
  70. package/src/information-extractors/ts/utils/semantic-type-resolver.ts +377 -0
  71. package/src/jsx-runtime-interceptor.ts +146 -0
  72. package/src/jsx-runtime-loader.ts +38 -0
  73. package/src/manifest-pipeline.ts +362 -0
  74. package/src/schema.ts +174 -0
  75. package/src/ts-compiler.ts +41 -0
  76. package/tsconfig.json +17 -0
  77. package/typedoc.json +18 -0
  78. package/vite.config.ts +45 -0
@@ -0,0 +1,256 @@
1
+ import { createRequire } from 'node:module'
2
+ import { dirname, join, resolve } from 'node:path'
3
+ import { pascalCase } from 'case-anything'
4
+ import { ResultAsync, errAsync, okAsync } from 'neverthrow'
5
+ import { getPackageEntryPoints } from 'pkg-entry-points'
6
+ import type { ComponentType } from 'react'
7
+ import { readPackageUpSync } from 'read-package-up'
8
+ import { IoError, NotFoundError } from './errors'
9
+
10
+ type NotFoundErrorInstance = InstanceType<typeof NotFoundError>
11
+ type IoErrorInstance = InstanceType<typeof IoError>
12
+ export type LoaderError = NotFoundErrorInstance | IoErrorInstance
13
+
14
+ export interface ComponentLoaderResult {
15
+ loadComponent: (name: string) => ComponentType<unknown> | null
16
+ packageName: string
17
+ entryPath: string | undefined
18
+ exportNames: string[]
19
+ }
20
+
21
+ /**
22
+ * Creates a component loader that dynamically loads components from the
23
+ * user's package. Finds the nearest package.json, resolves its entry point,
24
+ * and loads the module.
25
+ *
26
+ * The returned `loadComponent` is synchronous (required by processComponent).
27
+ * ESM modules are loaded via async `import()` during creation, so this
28
+ * function itself is async.
29
+ *
30
+ * @returns A `ResultAsync` containing a `ComponentLoaderResult` on success.
31
+ * @errors {NotFoundError} When no package.json is found or the package has no resolvable entry points.
32
+ * @errors {IoError} When module loading fails (CJS require or ESM import).
33
+ */
34
+ export function createComponentLoader(componentPath: string): ResultAsync<ComponentLoaderResult, LoaderError> {
35
+ // 1. Find nearest package.json
36
+ const result = readPackageUpSync({ cwd: dirname(resolve(componentPath)) })
37
+ if (!result) {
38
+ return errAsync(new NotFoundError('No package.json found', { props: { phase: 'load' } }))
39
+ }
40
+
41
+ const { packageJson, path: packageJsonPath } = result
42
+ const packageDir = dirname(packageJsonPath)
43
+ const packageName = packageJson.name
44
+
45
+ // 2. Resolve entry point(s) via pkg-entry-points (handles exports + legacy main/module)
46
+ return ResultAsync.fromPromise(
47
+ getPackageEntryPoints(packageDir),
48
+ (err) =>
49
+ new IoError(`Failed to resolve entry points for "${packageName}"`, {
50
+ cause: err instanceof Error ? err : new Error(String(err)),
51
+ props: { phase: 'load' },
52
+ }),
53
+ ).andThen((entryPoints) => {
54
+ return loadFromEntryPoints(entryPoints, packageDir, packageName, packageJsonPath)
55
+ })
56
+ }
57
+
58
+ /**
59
+ * Given resolved entry points, load the appropriate module(s) and construct the
60
+ * `ComponentLoaderResult`.
61
+ *
62
+ * @returns A `ResultAsync` containing a `ComponentLoaderResult` on success.
63
+ * @errors {NotFoundError} When the package has no resolvable or loadable entry points.
64
+ * @errors {IoError} When module loading fails.
65
+ */
66
+ function loadFromEntryPoints(
67
+ entryPoints: Record<string, [string[], string][]>,
68
+ packageDir: string,
69
+ packageName: string | undefined,
70
+ packageJsonPath: string,
71
+ ): ResultAsync<ComponentLoaderResult, LoaderError> {
72
+ const subpaths = Object.keys(entryPoints)
73
+
74
+ if (subpaths.length === 0) {
75
+ return errAsync(
76
+ new NotFoundError(
77
+ `Package "${packageName}" has no resolvable entry point. Add an "exports", "module", or "main" field to ${packageJsonPath}`,
78
+ { props: { phase: 'load' } },
79
+ ),
80
+ )
81
+ }
82
+
83
+ // 3. Load module(s)
84
+ const dotEntry = entryPoints['.']
85
+ if (dotEntry || subpaths.length === 1) {
86
+ // Single entry point: either explicit "." or the only available subpath
87
+ const tuples = dotEntry ?? entryPoints[subpaths[0]]
88
+ const resolved = selectBestPath(tuples)
89
+ if (!resolved) {
90
+ return errAsync(
91
+ new NotFoundError(`Package "${packageName}" has no loadable exports`, {
92
+ props: { phase: 'load' },
93
+ }),
94
+ )
95
+ }
96
+ const entryPath = join(packageDir, resolved)
97
+ return loadModule(entryPath).map((exports) => {
98
+ return {
99
+ loadComponent: (name: string) => findComponent(exports, name),
100
+ packageName: packageName ?? packageDir,
101
+ entryPath,
102
+ exportNames: Object.keys(exports),
103
+ }
104
+ })
105
+ }
106
+
107
+ // Multiple subpaths (no ".") — load all
108
+ return loadAllSubpaths(entryPoints, subpaths, packageDir, packageName)
109
+ }
110
+
111
+ /**
112
+ * Loads all subpath entry points and merges them into a single loader result.
113
+ *
114
+ * @returns A `ResultAsync` containing a `ComponentLoaderResult` on success.
115
+ * @errors {NotFoundError} When none of the subpath modules could be loaded.
116
+ * @errors {IoError} When module loading fails.
117
+ */
118
+ function loadAllSubpaths(
119
+ entryPoints: Record<string, [string[], string][]>,
120
+ subpaths: string[],
121
+ packageDir: string,
122
+ packageName: string | undefined,
123
+ ): ResultAsync<ComponentLoaderResult, LoaderError> {
124
+ const allModules: Record<string, unknown>[] = []
125
+ const allExportNames: string[] = []
126
+ const loadErrors: IoErrorInstance[] = []
127
+
128
+ // Build a sequential chain that loads each subpath
129
+ let chain: ResultAsync<void, never> = okAsync(undefined)
130
+
131
+ for (const subpath of subpaths) {
132
+ const resolved = selectBestPath(entryPoints[subpath])
133
+ if (!resolved) {
134
+ continue
135
+ }
136
+ const subEntryPath = join(packageDir, resolved)
137
+
138
+ chain = chain.andThen(() =>
139
+ loadModule(subEntryPath)
140
+ .map((exports) => {
141
+ allModules.push(exports)
142
+ allExportNames.push(...Object.keys(exports))
143
+ })
144
+ .orElse((err) => {
145
+ loadErrors.push(err)
146
+ return okAsync(undefined)
147
+ }),
148
+ )
149
+ }
150
+
151
+ return chain.andThen(() => {
152
+ if (allModules.length === 0) {
153
+ const message = loadErrors[0]?.message ?? `Package "${packageName}" has no loadable exports`
154
+ return errAsync(
155
+ new NotFoundError(message, {
156
+ cause: loadErrors[0],
157
+ props: { phase: 'load' },
158
+ }),
159
+ )
160
+ }
161
+
162
+ return okAsync({
163
+ loadComponent: (name: string) => {
164
+ for (const mod of allModules) {
165
+ const found = findComponent(mod, name)
166
+ if (found) return found
167
+ }
168
+ return null
169
+ },
170
+ packageName: packageName ?? packageDir,
171
+ entryPath: undefined,
172
+ exportNames: allExportNames,
173
+ } satisfies ComponentLoaderResult)
174
+ })
175
+ }
176
+
177
+ /**
178
+ * Attempts to load a module, first via ESM `import()`, then via CJS `require`.
179
+ *
180
+ * ESM `import()` is preferred because it participates in the ESM loader hook
181
+ * pipeline (registered via `module.register()` in the CLI). This is required
182
+ * for JSX interception to work — the loader hook redirects `react/jsx-runtime`
183
+ * to the interceptable version. CJS `require()` bypasses ESM hooks even when
184
+ * loading ESM modules (Node 22+), so it's only used as a fallback.
185
+ *
186
+ * @param entryPath - Absolute path to the module entry point.
187
+ * @returns A `ResultAsync` containing the module exports on success.
188
+ * @errors {IoError} When both ESM import and CJS require fail.
189
+ */
190
+ export function loadModule(entryPath: string): ResultAsync<Record<string, unknown>, IoErrorInstance> {
191
+ return ResultAsync.fromPromise(import(entryPath) as Promise<Record<string, unknown>>, () => null).orElse(() => {
192
+ try {
193
+ const require = createRequire(import.meta.url)
194
+ const exports = require(entryPath)
195
+ return okAsync(exports as Record<string, unknown>)
196
+ } catch (requireErr) {
197
+ const cause = requireErr instanceof Error ? requireErr : new Error(String(requireErr))
198
+ return errAsync(
199
+ new IoError(`Failed to load ${entryPath}: ${cause.message}`, {
200
+ cause,
201
+ props: { phase: 'load' },
202
+ }),
203
+ )
204
+ }
205
+ })
206
+ }
207
+
208
+ function selectBestPath(tuples: [string[], string][]): string | undefined {
209
+ const preferred = ['import', 'node', 'default']
210
+ for (const cond of preferred) {
211
+ const match = tuples.find(([c]) => c.includes(cond) && !c.includes('types'))
212
+ if (match) {
213
+ return match[1]
214
+ }
215
+ }
216
+ const fallback = tuples.find(([c]) => !c.includes('types'))?.[1]
217
+ return fallback
218
+ }
219
+
220
+ function isPascalCase(name: string): boolean {
221
+ return name.length > 0 && pascalCase(name) === name
222
+ }
223
+
224
+ function isComponent(value: unknown): value is ComponentType<unknown> {
225
+ if (typeof value === 'function') return isPascalCase(value.name)
226
+ // React.memo() and React.forwardRef() return objects, not functions
227
+ if (typeof value === 'object' && value !== null && '$$typeof' in value) return true
228
+ return false
229
+ }
230
+
231
+ export function findComponent(moduleExports: Record<string, unknown>, name: string): ComponentType<unknown> | null {
232
+ // Direct named export
233
+ const direct = moduleExports[name]
234
+ if ((typeof direct === 'function' && isPascalCase(name)) || isComponent(direct)) {
235
+ return direct as ComponentType<unknown>
236
+ }
237
+
238
+ // Check default export
239
+ const defaultExport = moduleExports.default
240
+ if (defaultExport) {
241
+ // default is the component itself (matches by function name)
242
+ if (typeof defaultExport === 'function' && defaultExport.name === name) {
243
+ return defaultExport as ComponentType<unknown>
244
+ }
245
+
246
+ // CJS interop: default is an object with named exports
247
+ if (typeof defaultExport === 'object' && defaultExport !== null) {
248
+ const nested = (defaultExport as Record<string, unknown>)[name]
249
+ if (isComponent(nested)) {
250
+ return nested as ComponentType<unknown>
251
+ }
252
+ }
253
+ }
254
+
255
+ return null
256
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Component Renderer - Renders React components with createElement interception
3
+ *
4
+ * This module intercepts React's element creation functions to track
5
+ * DOM element creation during server-side rendering. This allows tracking which props
6
+ * flow into which DOM elements.
7
+ *
8
+ * ## Interception Strategy
9
+ *
10
+ * Three complementary layers ensure interception regardless of how JSX is compiled:
11
+ *
12
+ * 1. **Vite alias** — `react/jsx-runtime` is aliased to `jsx-runtime-interceptor.ts`
13
+ * in vite.config.ts. This handles ESM imports resolved at build time.
14
+ *
15
+ * 2. **`React.createElement` monkey-patch** — Classic JSX transform and explicit
16
+ * `React.createElement()` calls are intercepted by temporarily replacing the
17
+ * function on the React module object.
18
+ *
19
+ * 3. **CJS module export patch** — Pre-built CJS bundles call
20
+ * `require('react/jsx-runtime')` at runtime, bypassing the Vite alias. We use
21
+ * `createRequire` to obtain the real CJS module objects and temporarily replace
22
+ * their `jsx`/`jsxs`/`jsxDEV` exports during rendering. This is safe because
23
+ * CJS module exports are mutable (`writable: true`).
24
+ *
25
+ * ## Intercepted Functions
26
+ *
27
+ * - `React.createElement` - Classic JSX transform (monkey-patched)
28
+ * - `jsx` / `jsxs` from `react/jsx-runtime` - New JSX transform via interceptor module
29
+ * - `jsx` / `jsxs` / `jsxDEV` on the real CJS `react/jsx-runtime` and
30
+ * `react/jsx-dev-runtime` module objects (monkey-patched for CJS consumers)
31
+ *
32
+ * ## Known Limitations
33
+ *
34
+ * 1. **Global state** - During render, we temporarily replace element creation
35
+ * functions globally. This is not thread-safe and could cause issues if multiple
36
+ * renders happen concurrently. Interceptors are restored in a finally block.
37
+ *
38
+ * 2. **React version compatibility** - This approach may break with future React versions
39
+ * if the internal rendering pipeline changes. Tested with React 18.x.
40
+ *
41
+ * @module component-renderer
42
+ */
43
+
44
+ import { createRequire } from 'node:module'
45
+ import React from 'react'
46
+ import type { ComponentType, ReactElement } from 'react'
47
+ import { renderToStaticMarkup } from 'react-dom/server'
48
+
49
+ import type { ExtractorStore } from './information-extractors/react/extractors/core/store'
50
+ import type { CreateElementEvent } from './information-extractors/react/extractors/core/types'
51
+
52
+ // Import the interceptor API - use direct path since vite alias doesn't apply to all packages
53
+ import { getOriginals, setJsxInterceptors } from './jsx-runtime-interceptor'
54
+
55
+ export const TRACE_ATTR = 'data-trace-id'
56
+
57
+ export type { CreateElementEvent }
58
+
59
+ export interface CreateElementListener {
60
+ onCreateElement: (event: CreateElementEvent) => void
61
+ }
62
+
63
+ // ─────────────────────────────────────────────────────────────────────────────
64
+ // Interception
65
+ // ─────────────────────────────────────────────────────────────────────────────
66
+
67
+ const isDOMTag = (type: unknown): type is string => typeof type === 'string' && /^[a-z]/.test(type)
68
+
69
+ type ElementCreator = (type: unknown, props: unknown, ...rest: unknown[]) => ReactElement
70
+
71
+ /**
72
+ * Creates an intercepted version of an element creation function.
73
+ * Works with both createElement (children as rest params) and jsx/jsxs (children in props).
74
+ */
75
+ function createInterceptor(
76
+ original: ElementCreator,
77
+ listeners: CreateElementListener[],
78
+ getNextId: () => string,
79
+ store: ExtractorStore,
80
+ ): ElementCreator {
81
+ return (type, elementProps, ...rest) => {
82
+ if (!isDOMTag(type)) {
83
+ return original(type, elementProps, ...rest)
84
+ }
85
+
86
+ const props = (elementProps ?? {}) as Record<string, unknown>
87
+ const traceId = getNextId()
88
+
89
+ // Children location differs: createElement uses rest params, jsx/jsxs uses props.children
90
+ const children = rest.length > 0 ? rest : props.children ? [props.children] : []
91
+
92
+ const event: CreateElementEvent = {
93
+ tag: type,
94
+ props: { ...props, children },
95
+ traceId,
96
+ children: children as unknown[],
97
+ store,
98
+ }
99
+
100
+ listeners.forEach((listener) => listener.onCreateElement(event))
101
+
102
+ const stampedProps = { ...props, [TRACE_ATTR]: traceId }
103
+ return original(type, stampedProps, ...rest)
104
+ }
105
+ }
106
+
107
+ // ─────────────────────────────────────────────────────────────────────────────
108
+ // Renderer
109
+ // ─────────────────────────────────────────────────────────────────────────────
110
+
111
+ /**
112
+ * Renders a React component to static HTML while intercepting element creation.
113
+ *
114
+ * Uses monkey-patching of React.createElement and jsx/jsxs to notify listeners
115
+ * when DOM elements are created. Each DOM element gets a unique `data-trace-id`
116
+ * attribute for tracking.
117
+ *
118
+ * @param Component - The React component to render
119
+ * @param componentProps - Props to pass to the component
120
+ * @param listeners - Listeners to notify on each DOM element creation
121
+ * @param store - Shared ExtractorStore, included in each CreateElementEvent
122
+ * @returns Static HTML string with trace IDs on DOM elements
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * const store = new ExtractorStore()
127
+ * const tracker = createPropTracker(getSpyMetadata)
128
+ * const html = renderWithExtractors(MyComponent, { title: 'Hello' }, [tracker], store)
129
+ * // html contains: <div data-trace-id="t1">...</div>
130
+ * // tracker.stores now has prop→DOM bindings
131
+ * ```
132
+ */
133
+ export function renderWithExtractors(
134
+ Component: ComponentType<unknown>,
135
+ componentProps: unknown,
136
+ listeners: CreateElementListener[],
137
+ store: ExtractorStore,
138
+ ): string {
139
+ let nextId = 0
140
+ const getNextId = () => `t${++nextId}`
141
+
142
+ // Store originals
143
+ const originalCreateElement = React.createElement
144
+ const { jsx: originalJsx, jsxs: originalJsxs, jsxDEV: originalJsxDEV } = getOriginals()
145
+
146
+ // Obtain real CJS module objects so we can patch them for pre-built CJS consumers
147
+ const cjsRequire = createRequire(import.meta.url)
148
+ const cjsRuntime = cjsRequire('react/jsx-runtime') as Record<string, unknown>
149
+ const cjsDevRuntime = cjsRequire('react/jsx-dev-runtime') as Record<string, unknown>
150
+
151
+ // Save the original CJS exports
152
+ const origCjsJsx = cjsRuntime.jsx
153
+ const origCjsJsxs = cjsRuntime.jsxs
154
+ const origCjsJsxDEV = cjsDevRuntime.jsxDEV
155
+
156
+ // Create interceptors
157
+ const interceptedCreateElement = createInterceptor(
158
+ originalCreateElement as ElementCreator,
159
+ listeners,
160
+ getNextId,
161
+ store,
162
+ )
163
+ const interceptedJsx = createInterceptor(originalJsx as ElementCreator, listeners, getNextId, store)
164
+ const interceptedJsxs = createInterceptor(originalJsxs as ElementCreator, listeners, getNextId, store)
165
+ const interceptedJsxDEV = createInterceptor(originalJsxDEV as ElementCreator, listeners, getNextId, store)
166
+
167
+ try {
168
+ // @ts-expect-error Monkey-patch createElement
169
+ React.createElement = interceptedCreateElement
170
+ // Use the interceptor API for jsx-runtime (includes jsxDEV for dev mode)
171
+ setJsxInterceptors(
172
+ interceptedJsx as typeof originalJsx,
173
+ interceptedJsxs as typeof originalJsxs,
174
+ interceptedJsxDEV as typeof originalJsxDEV,
175
+ )
176
+ // Patch real CJS module exports for pre-built CJS bundles
177
+ cjsRuntime.jsx = interceptedJsx
178
+ cjsRuntime.jsxs = interceptedJsxs
179
+ cjsDevRuntime.jsxDEV = interceptedJsxDEV
180
+
181
+ const element = React.createElement(Component, componentProps as Record<string, unknown>)
182
+ return renderToStaticMarkup(element)
183
+ } finally {
184
+ // Restore originals
185
+ React.createElement = originalCreateElement
186
+ setJsxInterceptors() // Restores to originals
187
+ // Restore CJS module exports
188
+ cjsRuntime.jsx = origCjsJsx
189
+ cjsRuntime.jsxs = origCjsJsxs
190
+ cjsDevRuntime.jsxDEV = origCjsJsxDEV
191
+ }
192
+ }