@vxrn/compiler 2.0.0-beta.33.1 → 2.0.0-beta.362.1
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.
- package/dist/cjs/cache.cjs +112 -109
- package/dist/cjs/configure.cjs +26 -28
- package/dist/cjs/constants.cjs +56 -60
- package/dist/cjs/index.cjs +428 -438
- package/dist/cjs/reactNativeCodegen.cjs +105 -114
- package/dist/cjs/reactNativeViewConfig.cjs +362 -381
- package/dist/cjs/refresh-runtime.cjs +390 -397
- package/dist/cjs/transformBabel.cjs +247 -221
- package/dist/cjs/transformHermesAsync.cjs +36 -47
- package/dist/cjs/transformHermesClasses.cjs +51 -0
- package/dist/cjs/transformHermesLoops.cjs +279 -281
- package/dist/cjs/transformSWC.cjs +183 -200
- package/dist/cjs/transformWorklets.cjs +107 -95
- package/dist/cjs/types.cjs +9 -11
- package/dist/cjs/workletUtils.cjs +30 -0
- package/dist/cjs/worklets/autoworklet.cjs +277 -222
- package/dist/cjs/worklets/globals.cjs +145 -60
- package/dist/cjs/worklets/hash.cjs +23 -27
- package/dist/cjs/worklets/scope.cjs +338 -359
- package/dist/cjs/worklets/serialize.cjs +73 -75
- package/dist/cjs/worklets/transform.cjs +217 -222
- package/dist/cjs/worklets/types.cjs +9 -11
- package/dist/esm/cache.mjs +96 -89
- package/dist/esm/cache.mjs.map +1 -1
- package/dist/esm/configure.mjs +11 -10
- package/dist/esm/configure.mjs.map +1 -1
- package/dist/esm/constants.mjs +41 -41
- package/dist/esm/constants.mjs.map +1 -1
- package/dist/esm/index.js +426 -420
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +426 -420
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/reactNativeCodegen.mjs +90 -88
- package/dist/esm/reactNativeCodegen.mjs.map +1 -1
- package/dist/esm/reactNativeViewConfig.mjs +347 -362
- package/dist/esm/reactNativeViewConfig.mjs.map +1 -1
- package/dist/esm/refresh-runtime.mjs +372 -376
- package/dist/esm/refresh-runtime.mjs.map +1 -1
- package/dist/esm/transformBabel.mjs +231 -198
- package/dist/esm/transformBabel.mjs.map +1 -1
- package/dist/esm/transformHermesAsync.mjs +20 -21
- package/dist/esm/transformHermesAsync.mjs.map +1 -1
- package/dist/esm/transformHermesClasses.mjs +25 -0
- package/dist/esm/transformHermesClasses.mjs.map +1 -0
- package/dist/esm/transformHermesLoops.mjs +264 -255
- package/dist/esm/transformHermesLoops.mjs.map +1 -1
- package/dist/esm/transformSWC.mjs +163 -171
- package/dist/esm/transformSWC.mjs.map +1 -1
- package/dist/esm/transformWorklets.mjs +89 -69
- package/dist/esm/transformWorklets.mjs.map +1 -1
- package/dist/esm/types.mjs +0 -2
- package/dist/esm/workletUtils.mjs +5 -0
- package/dist/esm/worklets/autoworklet.mjs +258 -200
- package/dist/esm/worklets/autoworklet.mjs.map +1 -1
- package/dist/esm/worklets/globals.mjs +130 -42
- package/dist/esm/worklets/globals.mjs.map +1 -1
- package/dist/esm/worklets/hash.mjs +10 -9
- package/dist/esm/worklets/hash.mjs.map +1 -1
- package/dist/esm/worklets/scope.mjs +325 -341
- package/dist/esm/worklets/scope.mjs.map +1 -1
- package/dist/esm/worklets/serialize.mjs +60 -58
- package/dist/esm/worklets/serialize.mjs.map +1 -1
- package/dist/esm/worklets/transform.mjs +201 -197
- package/dist/esm/worklets/transform.mjs.map +1 -1
- package/dist/esm/worklets/types.mjs +0 -2
- package/package.json +15 -6
- package/src/cache.ts +37 -7
- package/src/index.ts +44 -19
- package/src/reactNativeViewConfig.ts +6 -1
- package/src/transformBabel.test.ts +351 -17
- package/src/transformBabel.ts +137 -96
- package/src/transformHermesClasses.ts +34 -0
- package/src/transformSWC.ts +12 -1
- package/src/transformWorklets.test.ts +80 -5
- package/src/workletUtils.ts +4 -0
- package/src/worklets/autoworklet.ts +5 -2
- package/src/worklets/globals.ts +23 -0
- package/src/worklets/serialize.ts +1 -1
- package/types/cache.d.ts +2 -2
- package/types/cache.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/reactNativeViewConfig.d.ts.map +1 -1
- package/types/transformBabel.d.ts +16 -1
- package/types/transformBabel.d.ts.map +1 -1
- package/types/transformHermesClasses.d.ts +5 -0
- package/types/transformHermesClasses.d.ts.map +1 -0
- package/types/transformSWC.d.ts +1 -4
- package/types/transformSWC.d.ts.map +1 -1
- package/types/workletUtils.d.ts +4 -0
- package/types/workletUtils.d.ts.map +1 -0
- package/types/worklets/autoworklet.d.ts.map +1 -1
- package/types/worklets/globals.d.ts.map +1 -1
- package/dist/cjs/transformBabel.test.cjs +0 -360
- package/dist/cjs/transformHermesLoops.test.cjs +0 -257
- package/dist/cjs/transformSWC.test.cjs +0 -117
- package/dist/cjs/transformWorklets.test.cjs +0 -604
- package/dist/esm/transformBabel.test.mjs +0 -337
- package/dist/esm/transformBabel.test.mjs.map +0 -1
- package/dist/esm/transformHermesLoops.test.mjs +0 -234
- package/dist/esm/transformHermesLoops.test.mjs.map +0 -1
- package/dist/esm/transformSWC.test.mjs +0 -118
- package/dist/esm/transformSWC.test.mjs.map +0 -1
- package/dist/esm/transformWorklets.test.mjs +0 -581
- package/dist/esm/transformWorklets.test.mjs.map +0 -1
- package/dist/esm/types.mjs.map +0 -1
- package/dist/esm/worklets/types.mjs.map +0 -1
- package/types/transformBabel.test.d.ts +0 -2
- package/types/transformBabel.test.d.ts.map +0 -1
- package/types/transformHermesLoops.test.d.ts +0 -2
- package/types/transformHermesLoops.test.d.ts.map +0 -1
- package/types/transformSWC.test.d.ts +0 -2
- package/types/transformSWC.test.d.ts.map +0 -1
- package/types/transformWorklets.test.d.ts +0 -2
- package/types/transformWorklets.test.d.ts.map +0 -1
package/src/transformBabel.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { extname, join } from 'node:path'
|
|
2
3
|
// type-only, so that importing this module does not drag babel in. every metro
|
|
3
4
|
// worker loads it through the package index, and on the native transform path
|
|
4
5
|
// babel is never called at all: loading it there is pure startup cost.
|
|
@@ -13,6 +14,38 @@ type Props = GetTransformProps & {
|
|
|
13
14
|
userSetting?: GetTransformResponse
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
const USER_BABEL_CONFIG_FILES = [
|
|
18
|
+
'babel.config.js',
|
|
19
|
+
'babel.config.cjs',
|
|
20
|
+
'babel.config.mjs',
|
|
21
|
+
'babel.config.json',
|
|
22
|
+
'.babelrc',
|
|
23
|
+
'.babelrc.js',
|
|
24
|
+
'.babelrc.json',
|
|
25
|
+
] as const
|
|
26
|
+
|
|
27
|
+
// matches ONE_GENERATED_MARKER in one/src/cli/generateBundlerConfig.ts
|
|
28
|
+
const ONE_GENERATED_MARKER = '@one/generated bundler-config'
|
|
29
|
+
|
|
30
|
+
export function findUserBabelConfig(projectRoot?: string): string | null {
|
|
31
|
+
if (!projectRoot) return null
|
|
32
|
+
for (const name of USER_BABEL_CONFIG_FILES) {
|
|
33
|
+
const fullPath = join(projectRoot, name)
|
|
34
|
+
if (existsSync(fullPath)) {
|
|
35
|
+
try {
|
|
36
|
+
const content = readFileSync(fullPath, 'utf8')
|
|
37
|
+
if (content.includes(ONE_GENERATED_MARKER)) {
|
|
38
|
+
continue
|
|
39
|
+
}
|
|
40
|
+
} catch {
|
|
41
|
+
continue
|
|
42
|
+
}
|
|
43
|
+
return fullPath
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return null
|
|
47
|
+
}
|
|
48
|
+
|
|
16
49
|
export function getBabelOptions(props: Props): babel.TransformOptions | null {
|
|
17
50
|
// unify caller contracts (the Vite plugin hands POSIX ids; the native/patches
|
|
18
51
|
// path hands OS-native ids) so every path matcher below can assume forward
|
|
@@ -20,22 +53,50 @@ export function getBabelOptions(props: Props): babel.TransformOptions | null {
|
|
|
20
53
|
// reason. without it, RN's own files aren't matched on Windows.
|
|
21
54
|
props = { ...props, id: normalizePath(props.id.split('?')[0]) }
|
|
22
55
|
|
|
56
|
+
const isProjectFile = !props.id.includes('node_modules')
|
|
57
|
+
const userBabelConfig =
|
|
58
|
+
isProjectFile && props.projectRoot ? findUserBabelConfig(props.projectRoot) : null
|
|
59
|
+
|
|
23
60
|
if (props.userSetting === 'babel') {
|
|
24
|
-
return getOptions(props, true)
|
|
61
|
+
return getOptions(props, true, userBabelConfig)
|
|
25
62
|
}
|
|
26
63
|
if (
|
|
27
64
|
typeof props.userSetting === 'undefined' ||
|
|
28
65
|
(typeof props.userSetting === 'object' && props.userSetting.transform === 'babel')
|
|
29
66
|
) {
|
|
30
67
|
if (props.userSetting?.excludeDefaultPlugins) {
|
|
31
|
-
return
|
|
68
|
+
return {
|
|
69
|
+
caller: getBabelCaller(props),
|
|
70
|
+
...props.userSetting,
|
|
71
|
+
...(userBabelConfig ? { configFile: userBabelConfig, babelrc: true } : {}),
|
|
72
|
+
}
|
|
32
73
|
}
|
|
33
|
-
return getOptions(props)
|
|
74
|
+
return getOptions(props, false, userBabelConfig)
|
|
75
|
+
}
|
|
76
|
+
// an explicit per-file opt-out of babel survives a user config. without
|
|
77
|
+
// this, merely adding babel.config.js flips swc/oxc files to babel.
|
|
78
|
+
const userSetting = props.userSetting
|
|
79
|
+
if (
|
|
80
|
+
userSetting === 'swc' ||
|
|
81
|
+
userSetting === 'oxc' ||
|
|
82
|
+
userSetting === false ||
|
|
83
|
+
(typeof userSetting === 'object' &&
|
|
84
|
+
userSetting !== null &&
|
|
85
|
+
(userSetting.transform === 'swc' || userSetting.transform === 'oxc'))
|
|
86
|
+
) {
|
|
87
|
+
return null
|
|
88
|
+
}
|
|
89
|
+
if (userBabelConfig) {
|
|
90
|
+
return getOptions(props, false, userBabelConfig)
|
|
34
91
|
}
|
|
35
92
|
return null
|
|
36
93
|
}
|
|
37
94
|
|
|
38
|
-
const getOptions = (
|
|
95
|
+
const getOptions = (
|
|
96
|
+
props: Props,
|
|
97
|
+
force = false,
|
|
98
|
+
userBabelConfig: string | null = null
|
|
99
|
+
): babel.TransformOptions | null => {
|
|
39
100
|
let plugins: babel.PluginItem[] = []
|
|
40
101
|
|
|
41
102
|
if (force || shouldBabelGenerators(props)) {
|
|
@@ -56,29 +117,37 @@ const getOptions = (props: Props, force = false): babel.TransformOptions | null
|
|
|
56
117
|
}
|
|
57
118
|
}
|
|
58
119
|
|
|
59
|
-
if (enableNativewind || shouldBabelReanimated(props)) {
|
|
60
|
-
try {
|
|
61
|
-
const workletsPlugin = resolvePath(
|
|
62
|
-
'react-native-worklets/plugin',
|
|
63
|
-
props.projectRoot
|
|
64
|
-
)
|
|
65
|
-
debug?.(`Using babel worklets on file ${props.id}`)
|
|
66
|
-
plugins.push(workletsPlugin)
|
|
67
|
-
} catch {}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
120
|
if (shouldBabelReactCompiler(props)) {
|
|
71
121
|
debug?.(`Using babel react compiler on file`)
|
|
72
122
|
plugins.push(getBabelReactCompilerPlugin(props))
|
|
73
123
|
}
|
|
74
124
|
|
|
75
|
-
if (plugins.length) {
|
|
76
|
-
return {
|
|
125
|
+
if (plugins.length || userBabelConfig) {
|
|
126
|
+
return {
|
|
127
|
+
plugins,
|
|
128
|
+
caller: getBabelCaller(props),
|
|
129
|
+
...(userBabelConfig ? { configFile: userBabelConfig, babelrc: true } : {}),
|
|
130
|
+
}
|
|
77
131
|
}
|
|
78
132
|
|
|
79
133
|
return null
|
|
80
134
|
}
|
|
81
135
|
|
|
136
|
+
function getBabelCaller(props: Props): babel.TransformOptions['caller'] {
|
|
137
|
+
// babel hands every caller field to presets (babel-preset-expo reads platform
|
|
138
|
+
// and isDev), but its types list only the esm support flags, so the extra
|
|
139
|
+
// fields go through a named value rather than a checked literal.
|
|
140
|
+
const caller = {
|
|
141
|
+
name: 'vxrn',
|
|
142
|
+
platform:
|
|
143
|
+
props.environment === 'ios' || props.environment === 'android'
|
|
144
|
+
? props.environment
|
|
145
|
+
: 'web',
|
|
146
|
+
isDev: props.development,
|
|
147
|
+
}
|
|
148
|
+
return caller
|
|
149
|
+
}
|
|
150
|
+
|
|
82
151
|
/**
|
|
83
152
|
* Run the react compiler through oxc's rust port instead of babel.
|
|
84
153
|
*
|
|
@@ -91,14 +160,27 @@ const getOptions = (props: Props, force = false): babel.TransformOptions | null
|
|
|
91
160
|
export async function transformOxcReactCompiler(
|
|
92
161
|
id: string,
|
|
93
162
|
code: string,
|
|
94
|
-
|
|
163
|
+
optionsOrTarget: '18' | '19' | (Record<string, any> & { target?: '18' | '19' }) = '19',
|
|
95
164
|
sourceMap = false
|
|
96
165
|
) {
|
|
97
166
|
const { transform } = await import('oxc-transform-react')
|
|
167
|
+
const compilerOptions =
|
|
168
|
+
typeof optionsOrTarget === 'string'
|
|
169
|
+
? { target: optionsOrTarget }
|
|
170
|
+
: optionsOrTarget || {}
|
|
171
|
+
|
|
172
|
+
const target = compilerOptions.target ?? '19'
|
|
98
173
|
const result = await transform(id, code, {
|
|
99
174
|
jsx: 'preserve',
|
|
100
175
|
sourcemap: sourceMap,
|
|
101
|
-
reactCompiler: {
|
|
176
|
+
reactCompiler: {
|
|
177
|
+
target,
|
|
178
|
+
...compilerOptions,
|
|
179
|
+
environment: {
|
|
180
|
+
enableCustomTypeDefinitionForReanimated: true,
|
|
181
|
+
...compilerOptions.environment,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
102
184
|
})
|
|
103
185
|
|
|
104
186
|
// `errors` with fatal:false are react compiler BAILOUTS ("Cannot access refs
|
|
@@ -119,7 +201,10 @@ export async function transformOxcReactCompiler(
|
|
|
119
201
|
)
|
|
120
202
|
}
|
|
121
203
|
|
|
122
|
-
return {
|
|
204
|
+
return {
|
|
205
|
+
code: result.code,
|
|
206
|
+
map: sourceMap ? (result.map as any) : undefined,
|
|
207
|
+
}
|
|
123
208
|
}
|
|
124
209
|
|
|
125
210
|
/**
|
|
@@ -137,14 +222,30 @@ export async function transformBabel(
|
|
|
137
222
|
const extension = extname(id)
|
|
138
223
|
const isTSX = extension === '.tsx'
|
|
139
224
|
const isTS = isTSX || extension === '.ts'
|
|
140
|
-
const babelOptions = {
|
|
225
|
+
const babelOptions: babel.TransformOptions = {
|
|
141
226
|
filename: id,
|
|
142
227
|
compact: false,
|
|
143
|
-
babelrc: false,
|
|
144
|
-
configFile: false,
|
|
228
|
+
babelrc: options.babelrc ?? false,
|
|
229
|
+
configFile: options.configFile ?? false,
|
|
145
230
|
sourceMaps: false,
|
|
146
231
|
minified: false,
|
|
147
232
|
...options,
|
|
233
|
+
...(!isTS
|
|
234
|
+
? {
|
|
235
|
+
parserOpts: {
|
|
236
|
+
...options.parserOpts,
|
|
237
|
+
plugins: [...(options.parserOpts?.plugins || []), 'jsx'],
|
|
238
|
+
},
|
|
239
|
+
}
|
|
240
|
+
: {}),
|
|
241
|
+
// vite and rolldown own module syntax and import.meta, so presets written for
|
|
242
|
+
// metro (babel-preset-expo) must keep esm instead of rewriting it for metro's runtime
|
|
243
|
+
caller: {
|
|
244
|
+
name: 'vxrn',
|
|
245
|
+
...options.caller,
|
|
246
|
+
supportsStaticESM: true,
|
|
247
|
+
supportsDynamicImport: true,
|
|
248
|
+
},
|
|
148
249
|
presets: [
|
|
149
250
|
isTS
|
|
150
251
|
? [
|
|
@@ -168,7 +269,10 @@ export async function transformBabel(
|
|
|
168
269
|
plugins: [
|
|
169
270
|
...(isTS
|
|
170
271
|
? []
|
|
171
|
-
: [
|
|
272
|
+
: [
|
|
273
|
+
[hermesParserPlugin, { parseLangTypes: 'flow', reactRuntimeTarget: '19' }],
|
|
274
|
+
'babel-plugin-transform-flow-enums',
|
|
275
|
+
]),
|
|
172
276
|
...(options.plugins || []),
|
|
173
277
|
...(isTS ? [] : ['@babel/plugin-transform-flow-strip-types']),
|
|
174
278
|
],
|
|
@@ -184,6 +288,14 @@ export async function transformBabel(
|
|
|
184
288
|
})
|
|
185
289
|
}
|
|
186
290
|
|
|
291
|
+
export async function stripFlowTypes(id: string, code: string, sourceMaps = true) {
|
|
292
|
+
const result = await transformBabel(id, code, { sourceMaps })
|
|
293
|
+
return {
|
|
294
|
+
code: result.code!,
|
|
295
|
+
map: result.map,
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
187
299
|
const getBasePlugins = ({ development }: Props) =>
|
|
188
300
|
[
|
|
189
301
|
['@babel/plugin-transform-destructuring'],
|
|
@@ -294,74 +406,3 @@ function shouldBabelGenerators({ code }: Props) {
|
|
|
294
406
|
return asyncGeneratorRegex.test(code)
|
|
295
407
|
}
|
|
296
408
|
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* ------- reanimated --------
|
|
300
|
-
*/
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Taken from https://github.com/software-mansion/react-native-reanimated/blob/3.15.1/packages/react-native-reanimated/plugin/src/autoworkletization.ts#L19-L59, need to check if this is up-to-date when supporting newer versions of react-native-reanimated.
|
|
304
|
-
*/
|
|
305
|
-
const REANIMATED_AUTOWORKLETIZATION_KEYWORDS = [
|
|
306
|
-
'worklet',
|
|
307
|
-
'useAnimatedGestureHandler',
|
|
308
|
-
'useAnimatedScrollHandler',
|
|
309
|
-
'useFrameCallback',
|
|
310
|
-
'useAnimatedStyle',
|
|
311
|
-
'useAnimatedProps',
|
|
312
|
-
'createAnimatedPropAdapter',
|
|
313
|
-
'useDerivedValue',
|
|
314
|
-
'useAnimatedReaction',
|
|
315
|
-
'useWorkletCallback',
|
|
316
|
-
'withTiming',
|
|
317
|
-
'withSpring',
|
|
318
|
-
'withDecay',
|
|
319
|
-
'withRepeat',
|
|
320
|
-
'runOnUI',
|
|
321
|
-
'executeOnUIRuntimeSync',
|
|
322
|
-
]
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Regex to test if a piece of code should be processed by react-native-reanimated's Babel plugin.
|
|
326
|
-
*/
|
|
327
|
-
const REANIMATED_REGEX = new RegExp(REANIMATED_AUTOWORKLETIZATION_KEYWORDS.join('|'))
|
|
328
|
-
|
|
329
|
-
// Packages to skip for reanimated babel transform
|
|
330
|
-
// These either have false positives (mention keywords but don't use worklets)
|
|
331
|
-
// or cause issues when transformed
|
|
332
|
-
const REANIMATED_IGNORED_PATHS = [
|
|
333
|
-
// Prebuilt/vendored react-native that shouldn't be transformed
|
|
334
|
-
'react-native-prebuilt',
|
|
335
|
-
'node_modules/.vxrn/react-native',
|
|
336
|
-
// Known false positives - they mention worklet keywords in comments/strings but don't use them
|
|
337
|
-
'node_modules/react/',
|
|
338
|
-
'node_modules/react-dom/',
|
|
339
|
-
'node_modules/react-native/',
|
|
340
|
-
'node_modules/react-native-web/',
|
|
341
|
-
]
|
|
342
|
-
|
|
343
|
-
// `id`s are normalized to forward slashes at getBabelOptions' entry, so these
|
|
344
|
-
// plain forward-slash paths match on every OS. before that normalization the
|
|
345
|
-
// backslash `id`s Windows hands us slipped past this list, pushing react-native's
|
|
346
|
-
// own files through the reanimated babel pass, which has no JSX/TS parser.
|
|
347
|
-
const REANIMATED_IGNORED_PATHS_REGEX = new RegExp(REANIMATED_IGNORED_PATHS.join('|'))
|
|
348
|
-
|
|
349
|
-
function shouldBabelReanimated({ code, id }: Props) {
|
|
350
|
-
if (!configuration.enableReanimated) {
|
|
351
|
-
return false
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// Check if path should be ignored
|
|
355
|
-
if (REANIMATED_IGNORED_PATHS_REGEX.test(id)) {
|
|
356
|
-
return false
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// Check regex for all files (both node_modules and user code)
|
|
360
|
-
if (REANIMATED_REGEX.test(code)) {
|
|
361
|
-
const location = id.includes('node_modules') ? 'node_modules' : 'user-code'
|
|
362
|
-
debug?.(` 🪄 [reanimated/${location}] ${relative(process.cwd(), id)}`)
|
|
363
|
-
return true
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
return false
|
|
367
|
-
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Hermes before V1 cannot parse ES6 classes. Oxc lowers fields but has an
|
|
2
|
+
// ES2015 target floor, so classes and lexical bindings need Babel afterward.
|
|
3
|
+
export async function transformHermesClasses(
|
|
4
|
+
code: string,
|
|
5
|
+
filename: string,
|
|
6
|
+
sourceMaps = false
|
|
7
|
+
): Promise<{ code: string; map?: any } | undefined> {
|
|
8
|
+
if (!/\b(?:class(?:\s|\{)|(?:let|const)\s)/.test(code)) return
|
|
9
|
+
const [
|
|
10
|
+
{ transformAsync },
|
|
11
|
+
{ default: transformClasses },
|
|
12
|
+
{ default: transformBlockScoping },
|
|
13
|
+
] = await Promise.all([
|
|
14
|
+
import('@babel/core'),
|
|
15
|
+
import('@babel/plugin-transform-classes'),
|
|
16
|
+
import('@babel/plugin-transform-block-scoping'),
|
|
17
|
+
])
|
|
18
|
+
const result = await transformAsync(code, {
|
|
19
|
+
filename,
|
|
20
|
+
babelrc: false,
|
|
21
|
+
configFile: false,
|
|
22
|
+
sourceMaps,
|
|
23
|
+
// the caller composes stage maps itself; a file's own sourceMappingURL
|
|
24
|
+
// composed here would give the stage map several sources
|
|
25
|
+
// @ts-expect-error @types/babel__core omits false, which babel accepts
|
|
26
|
+
inputSourceMap: false,
|
|
27
|
+
parserOpts: { plugins: ['jsx'] },
|
|
28
|
+
// Legacy Hermes hoists lexical names, including in class-free functions.
|
|
29
|
+
// Lower block scope so minification cannot shadow parameters or constructors.
|
|
30
|
+
plugins: [transformClasses, transformBlockScoping],
|
|
31
|
+
})
|
|
32
|
+
if (!result?.code) return
|
|
33
|
+
return { code: result.code, map: result.map }
|
|
34
|
+
}
|
package/src/transformSWC.ts
CHANGED
|
@@ -22,7 +22,18 @@ export function shouldStripFlow(id: string, code: string): boolean {
|
|
|
22
22
|
const header =
|
|
23
23
|
code.match(/^(?:#![^\r\n]*(?:\r?\n|$))?(?:\s|\/\*[\s\S]*?\*\/|\/\/[^\r\n]*)*/)?.[0] ||
|
|
24
24
|
''
|
|
25
|
-
return
|
|
25
|
+
return (
|
|
26
|
+
/@flow\b/.test(header) ||
|
|
27
|
+
/\b(?:import|export)\s+type\b/.test(code) ||
|
|
28
|
+
// Some published Flow sources omit the pragma and use ordinary imports.
|
|
29
|
+
// Typed function returns, declarations, and class fields still need stripping.
|
|
30
|
+
/\(\s*(?:\.\.\.)?[\w$]+\??\s*:\s*/.test(code) ||
|
|
31
|
+
/\)\s*:\s*(?:[\w$]+(?:<[^;{}]*>)?(?:\[\])?\s*)(?:=>|\{)/.test(code) ||
|
|
32
|
+
/^\s*[\w$]+\??\s*:\s*(?:string|number|boolean|any|mixed|void|[A-Z][\w$]*)(?:[^;\r\n=]*)(?:=[^;\r\n]*)?;/m.test(
|
|
33
|
+
code
|
|
34
|
+
) ||
|
|
35
|
+
/\b(?:opaque\s+)?type\s+[\w$]+(?:\s*<[^;{}]*>)?\s*=/.test(code)
|
|
36
|
+
)
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
export async function transformSWC(
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs'
|
|
2
2
|
import os from 'node:os'
|
|
3
|
+
import { createRequire } from 'node:module'
|
|
3
4
|
import path from 'node:path'
|
|
5
|
+
import { runInNewContext } from 'node:vm'
|
|
4
6
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
5
7
|
import { configureVXRNCompilerPlugin } from './configure'
|
|
6
8
|
import { shouldTransformWorklets, transformWorklets } from './transformWorklets'
|
|
@@ -64,6 +66,11 @@ describe('transformWorklets', () => {
|
|
|
64
66
|
expect(result.code).toContain('__initData')
|
|
65
67
|
expect(result.code).toContain('__closure')
|
|
66
68
|
expect(result.map).toBeUndefined()
|
|
69
|
+
const serialized = result.code.match(/code: ("(?:\\.|[^"\\])*")/)?.[1]
|
|
70
|
+
expect(serialized, 'serialized worklet code').toBeTruthy()
|
|
71
|
+
const worklet = (0, eval)(JSON.parse(serialized!))
|
|
72
|
+
expect(worklet).toBeTypeOf('function')
|
|
73
|
+
expect(worklet()).toBe(42)
|
|
67
74
|
})
|
|
68
75
|
|
|
69
76
|
it('ignores calls whose callee name collides with Object.prototype', async () => {
|
|
@@ -136,7 +143,7 @@ describe('transformWorklets', () => {
|
|
|
136
143
|
`
|
|
137
144
|
const result = await transformWorklets('/app/handler.ts', code, false)
|
|
138
145
|
expect(result.code).toContain('__workletHash')
|
|
139
|
-
expect(result.code).toMatch(/code: "function _worklet\(e\)/)
|
|
146
|
+
expect(result.code).toMatch(/code: "\(function _worklet\(e\)/)
|
|
140
147
|
expect(result.code).toContain('var _worklet = function _worklet(e)')
|
|
141
148
|
})
|
|
142
149
|
|
|
@@ -162,12 +169,38 @@ describe('transformWorklets', () => {
|
|
|
162
169
|
const result = await transformWorklets('/app/setupLoop.ts', code, false)
|
|
163
170
|
|
|
164
171
|
expect(result.code).toMatch(/setupLoop\.__closure = \{\s*\}/)
|
|
165
|
-
const init = result.code.match(/code: "function setupLoop[^"]*"/)
|
|
172
|
+
const init = result.code.match(/code: "\(function setupLoop[^"]*"/)
|
|
166
173
|
expect(init, 'serialized worklet code').toBeTruthy()
|
|
167
174
|
expect(init![0]).not.toContain('this.__closure')
|
|
168
175
|
expect(init![0]).toContain('flushQueue')
|
|
169
176
|
})
|
|
170
177
|
|
|
178
|
+
it('keeps Reanimated UI-runtime globals out of the JavaScript closure', async () => {
|
|
179
|
+
const result = await transformWorklets(
|
|
180
|
+
'/app/valueUnpacker.ts',
|
|
181
|
+
`function valueUnpacker(value) { 'worklet'; return _toString(value) }
|
|
182
|
+
globalThis.__unpacker = valueUnpacker`,
|
|
183
|
+
false,
|
|
184
|
+
{ pluginVersion: '3.19.1' }
|
|
185
|
+
)
|
|
186
|
+
const mainRuntime: any = {}
|
|
187
|
+
runInNewContext(result.code, mainRuntime)
|
|
188
|
+
expect(Object.keys(mainRuntime.__unpacker.__closure)).toEqual([])
|
|
189
|
+
const uiRuntime: any = { _toString: String }
|
|
190
|
+
const unpack = runInNewContext(mainRuntime.__unpacker.__initData.code, uiRuntime)
|
|
191
|
+
expect(unpack(42)).toBe('42')
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it('keeps strict global configuration explicit for UI-runtime helpers', async () => {
|
|
195
|
+
const result = await transformWorklets(
|
|
196
|
+
'/app/strictGlobals.ts',
|
|
197
|
+
`function unpack(value) { 'worklet'; return _toString(value) }`,
|
|
198
|
+
false,
|
|
199
|
+
{ pluginVersion: '3.19.1', strictGlobal: true }
|
|
200
|
+
)
|
|
201
|
+
expect(result.code).toMatch(/__closure = \{\s*_toString/)
|
|
202
|
+
})
|
|
203
|
+
|
|
171
204
|
it('honors no-worklet-closure and limit-init-data-hoisting the way the worklets runtime needs', async () => {
|
|
172
205
|
// this is the shape react-native-worklets uses for its unpacker installers.
|
|
173
206
|
// the outer worklet is serialized to a string and evaluated on a worklet
|
|
@@ -190,7 +223,7 @@ describe('transformWorklets', () => {
|
|
|
190
223
|
`
|
|
191
224
|
const result = await transformWorklets('/app/installUnpacker.ts', code, false)
|
|
192
225
|
|
|
193
|
-
const outerInit = result.code.match(/code: "function installUnpacker[^"]*"/)
|
|
226
|
+
const outerInit = result.code.match(/code: "\(function installUnpacker[^"]*"/)
|
|
194
227
|
expect(outerInit, 'outer worklet serialized code').toBeTruthy()
|
|
195
228
|
// no unpacker line: nothing is read off `this` on the worklet runtime.
|
|
196
229
|
expect(outerInit![0]).not.toContain('this.__closure')
|
|
@@ -201,7 +234,7 @@ describe('transformWorklets', () => {
|
|
|
201
234
|
// the inner worklet's init data is declared inside the outer function body,
|
|
202
235
|
// not hoisted to module scope where the worklet runtime cannot see it.
|
|
203
236
|
const innerVar = result.code.match(
|
|
204
|
-
/var (_worklet_\d+_init_data) = \{\s*code: "function _worklet/
|
|
237
|
+
/var (_worklet_\d+_init_data) = \{\s*code: "\(function _worklet/
|
|
205
238
|
)
|
|
206
239
|
expect(innerVar, 'inner worklet init data').toBeTruthy()
|
|
207
240
|
// only look past the serialized string, which mentions the same name inside
|
|
@@ -381,7 +414,12 @@ describe('transformWorklets', () => {
|
|
|
381
414
|
expect(typeof scaleFn).toBe('function')
|
|
382
415
|
expect(scaleFn.__workletHash).toBeDefined()
|
|
383
416
|
expect(typeof scaleFn.__workletHash).toBe('number')
|
|
384
|
-
|
|
417
|
+
// /app has no package.json, so the stamp comes from the worklets runtime
|
|
418
|
+
// this workspace actually installs
|
|
419
|
+
const installedWorklets = createRequire(path.resolve(process.cwd(), 'package.json'))(
|
|
420
|
+
'react-native-worklets/package.json'
|
|
421
|
+
).version
|
|
422
|
+
expect(scaleFn.__pluginVersion).toBe(installedWorklets)
|
|
385
423
|
expect(scaleFn.__closure).toEqual({ multiplier: 5 })
|
|
386
424
|
expect(scaleFn.__initData).toBeDefined()
|
|
387
425
|
expect(scaleFn.__initData.code).toContain('__closure')
|
|
@@ -613,6 +651,43 @@ describe('transformWorklets', () => {
|
|
|
613
651
|
expect(uiRes).toBe(7)
|
|
614
652
|
})
|
|
615
653
|
|
|
654
|
+
it('captures the outer binding a property worklet shares its key with', async () => {
|
|
655
|
+
// react-native-gesture-handler's NativeProxy: the property worklet calls the
|
|
656
|
+
// module-level host function of the same name. naming the worklet after its
|
|
657
|
+
// key made it capture itself, so serializing its closure never ended.
|
|
658
|
+
const code = `
|
|
659
|
+
const updateConfig = (tag) => tag * 2
|
|
660
|
+
export const proxy = {
|
|
661
|
+
updateConfig: (tag) => {
|
|
662
|
+
'worklet'
|
|
663
|
+
return updateConfig(tag)
|
|
664
|
+
},
|
|
665
|
+
flush: function (tag) {
|
|
666
|
+
'worklet'
|
|
667
|
+
return updateConfig(tag) + 1
|
|
668
|
+
},
|
|
669
|
+
}
|
|
670
|
+
`
|
|
671
|
+
const result = await transformWorklets('/app/proxy.ts', code, false)
|
|
672
|
+
|
|
673
|
+
const sandbox = { global: globalThis, exports: {} as any }
|
|
674
|
+
const runner = new Function(
|
|
675
|
+
'exports',
|
|
676
|
+
'global',
|
|
677
|
+
result.code.replace('export const proxy', 'exports.proxy')
|
|
678
|
+
)
|
|
679
|
+
runner(sandbox.exports, sandbox.global)
|
|
680
|
+
const { proxy } = sandbox.exports
|
|
681
|
+
|
|
682
|
+
for (const worklet of [proxy.updateConfig, proxy.flush]) {
|
|
683
|
+
expect(worklet.__closure.updateConfig).not.toBe(worklet)
|
|
684
|
+
const reconstructed = eval(`(${worklet.__initData.code})`)
|
|
685
|
+
expect(reconstructed.call({ __closure: worklet.__closure }, 3)).toBe(worklet(3))
|
|
686
|
+
}
|
|
687
|
+
expect(proxy.updateConfig(3)).toBe(6)
|
|
688
|
+
expect(proxy.flush(3)).toBe(7)
|
|
689
|
+
})
|
|
690
|
+
|
|
616
691
|
it('transforms nested worklets with bottom-up composition', async () => {
|
|
617
692
|
const code = `
|
|
618
693
|
export function outer() {
|
|
@@ -306,7 +306,10 @@ export function findWorkletCandidates(program: any): WorkletCandidate[] {
|
|
|
306
306
|
: fn.type === 'ArrowFunctionExpression'
|
|
307
307
|
? 'arrow_function'
|
|
308
308
|
: 'function_expression',
|
|
309
|
-
|
|
309
|
+
// only a method is named by its key, as upstream's plugin does: a
|
|
310
|
+
// property's function has no binding of that name, so naming it would
|
|
311
|
+
// shadow an outer binding it closes over with the worklet itself.
|
|
312
|
+
name: node.method ? node.key?.name : fn.id?.name,
|
|
310
313
|
parent,
|
|
311
314
|
isAutoWorklet: false,
|
|
312
315
|
})
|
|
@@ -368,7 +371,7 @@ export function findWorkletCandidates(program: any): WorkletCandidate[] {
|
|
|
368
371
|
prop.value.type === 'ArrowFunctionExpression'
|
|
369
372
|
? 'arrow_function'
|
|
370
373
|
: 'function_expression',
|
|
371
|
-
name: prop.
|
|
374
|
+
name: prop.value.id?.name,
|
|
372
375
|
parent: prop,
|
|
373
376
|
isAutoWorklet: true,
|
|
374
377
|
})
|
package/src/worklets/globals.ts
CHANGED
|
@@ -108,6 +108,29 @@ export const DEFAULT_GLOBALS = new Set([
|
|
|
108
108
|
'clearInterval',
|
|
109
109
|
'HermesInternal',
|
|
110
110
|
'_WORKLET',
|
|
111
|
+
// Reanimated installs these in the UI runtime. Capturing them on the JS
|
|
112
|
+
// thread fails before its value unpacker can initialize (Reanimated 3).
|
|
113
|
+
'ReanimatedError',
|
|
114
|
+
'__reanimatedLoggerConfig',
|
|
115
|
+
'_IS_FABRIC',
|
|
116
|
+
'_log',
|
|
117
|
+
'_toString',
|
|
118
|
+
'_scheduleHostFunctionOnJS',
|
|
119
|
+
'_scheduleRemoteFunctionOnJS',
|
|
120
|
+
'_scheduleOnRuntime',
|
|
121
|
+
'_makeShareableClone',
|
|
122
|
+
'_updatePropsPaper',
|
|
123
|
+
'_updatePropsFabric',
|
|
124
|
+
'_measurePaper',
|
|
125
|
+
'_measureFabric',
|
|
126
|
+
'_scrollToPaper',
|
|
127
|
+
'_dispatchCommandPaper',
|
|
128
|
+
'_dispatchCommandFabric',
|
|
129
|
+
'_setGestureState',
|
|
130
|
+
'_notifyAboutProgress',
|
|
131
|
+
'_notifyAboutEnd',
|
|
132
|
+
'_runOnUIQueue',
|
|
133
|
+
'_getAnimationTimestamp',
|
|
111
134
|
])
|
|
112
135
|
|
|
113
136
|
export function createGlobalsSet(
|
|
@@ -64,7 +64,7 @@ export function serializeWorkletForUI(
|
|
|
64
64
|
|
|
65
65
|
const transformed = transformSync('worklet.ts', fullFn)
|
|
66
66
|
assertTransformed(transformed, name, 'serialized')
|
|
67
|
-
return transformed.code.trim()
|
|
67
|
+
return `(${transformed.code.trim().replace(/;$/, '')})`
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
package/types/cache.d.ts
CHANGED
|
@@ -4,14 +4,14 @@ interface CacheStats {
|
|
|
4
4
|
writes: 0;
|
|
5
5
|
errors: 0;
|
|
6
6
|
}
|
|
7
|
-
export declare function getCachedTransform(filePath: string, code: string, environment: string): {
|
|
7
|
+
export declare function getCachedTransform(filePath: string, code: string, environment: string, userBabelConfigPath?: string | null): {
|
|
8
8
|
code: string;
|
|
9
9
|
map?: any;
|
|
10
10
|
} | null;
|
|
11
11
|
export declare function setCachedTransform(filePath: string, code: string, result: {
|
|
12
12
|
code: string;
|
|
13
13
|
map?: any;
|
|
14
|
-
}, environment: string): void;
|
|
14
|
+
}, environment: string, userBabelConfigPath?: string | null): void;
|
|
15
15
|
/** Drop every cached transform, for `react-native bundle --reset-cache`. */
|
|
16
16
|
export declare function clearTransformCache(): void;
|
|
17
17
|
export declare function getCacheStats(): CacheStats;
|
package/types/cache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AA4BA,UAAU,UAAU;IAClB,IAAI,EAAE,CAAC,CAAA;IACP,MAAM,EAAE,CAAC,CAAA;IACT,MAAM,EAAE,CAAC,CAAA;IACT,MAAM,EAAE,CAAC,CAAA;CACV;
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AA4BA,UAAU,UAAU;IAClB,IAAI,EAAE,CAAC,CAAA;IACP,MAAM,EAAE,CAAC,CAAA;IACT,MAAM,EAAE,CAAC,CAAA;IACT,MAAM,EAAE,CAAC,CAAA;CACV;AA6ED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,GAAG,IAAI,CAoCpC;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,EACnC,WAAW,EAAE,MAAM,EACnB,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,GAClC,IAAI,CAwBN;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,aAAa,IAAI,UAAU,CAE1C;AAED,wBAAgB,aAAa,IAAI,IAAI,CAapC"}
|
package/types/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * from './transformWorklets';
|
|
|
12
12
|
export * from './reactNativeCodegen';
|
|
13
13
|
export * from './transformHermesLoops';
|
|
14
14
|
export * from './transformHermesAsync';
|
|
15
|
+
export * from './transformHermesClasses';
|
|
15
16
|
export { clearTransformCache } from './cache';
|
|
16
17
|
export { JS_GLOBALS } from './worklets/globals';
|
|
17
18
|
export { getClosureVariables } from './worklets/scope';
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,YAAY,EAA8B,MAAM,MAAM,CAAA;AAcpE,OAAO,KAAK,EAAkC,OAAO,EAAE,MAAM,SAAS,CAAA;AAGtE,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,YAAY,EAA8B,MAAM,MAAM,CAAA;AAcpE,OAAO,KAAK,EAAkC,OAAO,EAAE,MAAM,SAAS,CAAA;AAGtE,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AA8S3C,wBAAsB,wBAAwB,CAC5C,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAC3B,OAAO,CAAC,YAAY,EAAE,CAAC,CAkWzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactNativeViewConfig.d.ts","sourceRoot":"","sources":["../src/reactNativeViewConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;
|
|
1
|
+
{"version":3,"file":"reactNativeViewConfig.d.ts","sourceRoot":"","sources":["../src/reactNativeViewConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAieH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAuBnF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,GACX;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsE5C;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,UAEjF;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIvD"}
|
|
@@ -3,6 +3,7 @@ import type { GetTransformProps, GetTransformResponse } from './types';
|
|
|
3
3
|
type Props = GetTransformProps & {
|
|
4
4
|
userSetting?: GetTransformResponse;
|
|
5
5
|
};
|
|
6
|
+
export declare function findUserBabelConfig(projectRoot?: string): string | null;
|
|
6
7
|
export declare function getBabelOptions(props: Props): babel.TransformOptions | null;
|
|
7
8
|
/**
|
|
8
9
|
* Run the react compiler through oxc's rust port instead of babel.
|
|
@@ -13,7 +14,9 @@ export declare function getBabelOptions(props: Props): babel.TransformOptions |
|
|
|
13
14
|
* still applies the project's jsxImportSource and dev-mode settings, exactly
|
|
14
15
|
* as it did when babel only stripped types here.
|
|
15
16
|
*/
|
|
16
|
-
export declare function transformOxcReactCompiler(id: string, code: string,
|
|
17
|
+
export declare function transformOxcReactCompiler(id: string, code: string, optionsOrTarget?: '18' | '19' | (Record<string, any> & {
|
|
18
|
+
target?: '18' | '19';
|
|
19
|
+
}), sourceMap?: boolean): Promise<{
|
|
17
20
|
code: string;
|
|
18
21
|
map: any;
|
|
19
22
|
}>;
|
|
@@ -21,5 +24,17 @@ export declare function transformOxcReactCompiler(id: string, code: string, targ
|
|
|
21
24
|
* Transform input to mostly ES5 compatible code, keep ESM syntax, and transform generators.
|
|
22
25
|
*/
|
|
23
26
|
export declare function transformBabel(id: string, code: string, options: babel.TransformOptions): Promise<babel.BabelFileResult>;
|
|
27
|
+
export declare function stripFlowTypes(id: string, code: string, sourceMaps?: boolean): Promise<{
|
|
28
|
+
code: string;
|
|
29
|
+
map: {
|
|
30
|
+
version: number;
|
|
31
|
+
sources: string[];
|
|
32
|
+
names: string[];
|
|
33
|
+
sourceRoot?: string | undefined;
|
|
34
|
+
sourcesContent?: string[] | undefined;
|
|
35
|
+
mappings: string;
|
|
36
|
+
file: string;
|
|
37
|
+
} | null | undefined;
|
|
38
|
+
}>;
|
|
24
39
|
export {};
|
|
25
40
|
//# sourceMappingURL=transformBabel.d.ts.map
|