@vxrn/compiler 2.8.1 → 2.9.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.
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/reactNativeCodegen.cjs +8 -5
- package/dist/cjs/transformHermesAsync.cjs +2 -1
- package/dist/cjs/transformMixedNativeModule.cjs +297 -0
- package/dist/cjs/transformWorklets.cjs +14 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +2 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/reactNativeCodegen.mjs +5 -5
- package/dist/esm/reactNativeCodegen.mjs.map +1 -1
- package/dist/esm/transformHermesAsync.mjs +2 -1
- package/dist/esm/transformHermesAsync.mjs.map +1 -1
- package/dist/esm/transformMixedNativeModule.mjs +272 -0
- package/dist/esm/transformMixedNativeModule.mjs.map +1 -0
- package/dist/esm/transformWorklets.mjs +14 -0
- package/dist/esm/transformWorklets.mjs.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +1 -0
- package/src/reactNativeCodegen.ts +6 -5
- package/src/transformHermesAsync.ts +6 -1
- package/src/transformMixedNativeModule.ts +402 -0
- package/src/transformWorklets.test.ts +38 -0
- package/src/transformWorklets.ts +23 -0
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/reactNativeCodegen.d.ts +1 -0
- package/types/reactNativeCodegen.d.ts.map +1 -1
- package/types/transformHermesAsync.d.ts +1 -1
- package/types/transformHermesAsync.d.ts.map +1 -1
- package/types/transformMixedNativeModule.d.ts +5 -0
- package/types/transformMixedNativeModule.d.ts.map +1 -0
- package/types/transformWorklets.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformWorklets.js","names":[],"sources":["esm/transformWorklets.js"],"sourcesContent":["import fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { configuration, isNativeWorkletsEnabled } from \"./configure\";\nimport {\n AUTOWORKLET_FUNCTION_ARGS,\n GESTURE_BUILDER_METHODS\n} from \"./worklets/autoworklet\";\nimport { executeWorkletTransform } from \"./worklets/transform\";\nimport { prepareWorkletsForReactCompiler } from \"./worklets/transform\";\nconst REANIMATED_AUTOWORKLETIZATION_KEYWORDS = [\n \"worklet\",\n \"useAnimatedGestureHandler\",\n \"useAnimatedScrollHandler\",\n \"useFrameCallback\",\n \"useAnimatedStyle\",\n \"useAnimatedProps\",\n \"createAnimatedPropAdapter\",\n \"useDerivedValue\",\n \"useAnimatedReaction\",\n \"useWorkletCallback\",\n \"withTiming\",\n \"withSpring\",\n \"withDecay\",\n \"withRepeat\",\n \"runOnUI\",\n \"executeOnUIRuntimeSync\"\n];\nconst REANIMATED_REGEX = new RegExp(\n [\n .../* @__PURE__ */ new Set([\n ...REANIMATED_AUTOWORKLETIZATION_KEYWORDS,\n ...Object.keys(AUTOWORKLET_FUNCTION_ARGS),\n // gesture callbacks are only workletized on a `Gesture.<Kind>()` chain,\n // but this file gate has to be permissive or a file whose only worklets\n // are gesture callbacks never reaches the transform at all.\n ...GESTURE_BUILDER_METHODS,\n \"withCallback\"\n ])\n ].map((name) => `\\\\b${name}\\\\b`).join(\"|\")\n);\nconst REANIMATED_IGNORED_PATHS = [\n \"react-native-prebuilt\",\n \"node_modules/.vxrn/react-native\",\n \"node_modules/react/\",\n \"node_modules/react-dom/\",\n \"node_modules/react-native/\",\n // react-native's own scoped packages are flow, and the worklets transform\n // runs before flow stripping in the vite pipeline. they never hold app\n // worklets, exactly like node_modules/react-native/ above.\n \"node_modules/@react-native/\",\n \"node_modules/react-native-web/\"\n];\nconst REANIMATED_IGNORED_PATHS_REGEX = new RegExp(REANIMATED_IGNORED_PATHS.join(\"|\"));\nfunction shouldTransformWorklets({ id, code }) {\n if (!isNativeWorkletsEnabled() || !configuration.enableReanimated) {\n return false;\n }\n const normalizedId = id.replace(/\\\\/g, \"/\");\n if (REANIMATED_IGNORED_PATHS_REGEX.test(normalizedId)) {\n return false;\n }\n return REANIMATED_REGEX.test(code);\n}\nfunction getWorkletsVersion(projectRoot, filename) {\n if (projectRoot) {\n try {\n const req = createRequire(path.resolve(projectRoot, \"package.json\"));\n try {\n const ver = req(\"react-native-worklets/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n try {\n const ver = req(\"react-native-reanimated/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n } catch {\n }\n throw new Error(\n `[@vxrn/compiler] Unable to resolve \"react-native-worklets\" or \"react-native-reanimated\" version from project root \"${projectRoot}\". Please ensure react-native-worklets is installed in your project.`\n );\n }\n if (filename && !filename.startsWith(\"\\0\") && fs.existsSync(filename)) {\n try {\n const req = createRequire(filename);\n try {\n const ver = req(\"react-native-worklets/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n try {\n const ver = req(\"react-native-reanimated/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n } catch {\n }\n }\n const fallbacks = [\n () => createRequire(path.resolve(process.cwd(), \"package.json\")),\n () => createRequire(import.meta.url)\n ];\n for (const getReq of fallbacks) {\n try {\n const req = getReq();\n try {\n const ver = req(\"react-native-worklets/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n try {\n const ver = req(\"react-native-reanimated/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n } catch {\n }\n }\n const target = filename || process.cwd();\n throw new Error(\n `[@vxrn/compiler] Unable to resolve \"react-native-worklets\" or \"react-native-reanimated\" version from \"${target}\". Please ensure react-native-worklets is installed in your project.`\n );\n}\nasync function transformWorklets(id, code, sourceMaps = false, options) {\n return executeWorkletTransform(id, code, sourceMaps, options, getWorkletsVersion);\n}\nexport {\n REANIMATED_AUTOWORKLETIZATION_KEYWORDS,\n getWorkletsVersion,\n prepareWorkletsForReactCompiler,\n shouldTransformWorklets,\n transformWorklets\n};\n//# sourceMappingURL=transformWorklets.js.map\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"transformWorklets.js","names":[],"sources":["esm/transformWorklets.js"],"sourcesContent":["import fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { configuration, isNativeWorkletsEnabled } from \"./configure\";\nimport {\n AUTOWORKLET_FUNCTION_ARGS,\n GESTURE_BUILDER_METHODS\n} from \"./worklets/autoworklet\";\nimport remapping from \"@jridgewell/remapping\";\nimport { isReactNativeCodegenSpec } from \"./reactNativeCodegen\";\nimport { stripFlowTypes } from \"./transformFlow\";\nimport { shouldStripFlow } from \"./transformSWC\";\nimport { executeWorkletTransform } from \"./worklets/transform\";\nimport { prepareWorkletsForReactCompiler } from \"./worklets/transform\";\nconst REANIMATED_AUTOWORKLETIZATION_KEYWORDS = [\n \"worklet\",\n \"useAnimatedGestureHandler\",\n \"useAnimatedScrollHandler\",\n \"useFrameCallback\",\n \"useAnimatedStyle\",\n \"useAnimatedProps\",\n \"createAnimatedPropAdapter\",\n \"useDerivedValue\",\n \"useAnimatedReaction\",\n \"useWorkletCallback\",\n \"withTiming\",\n \"withSpring\",\n \"withDecay\",\n \"withRepeat\",\n \"runOnUI\",\n \"executeOnUIRuntimeSync\"\n];\nconst REANIMATED_REGEX = new RegExp(\n [\n .../* @__PURE__ */ new Set([\n ...REANIMATED_AUTOWORKLETIZATION_KEYWORDS,\n ...Object.keys(AUTOWORKLET_FUNCTION_ARGS),\n // gesture callbacks are only workletized on a `Gesture.<Kind>()` chain,\n // but this file gate has to be permissive or a file whose only worklets\n // are gesture callbacks never reaches the transform at all.\n ...GESTURE_BUILDER_METHODS,\n \"withCallback\"\n ])\n ].map((name) => `\\\\b${name}\\\\b`).join(\"|\")\n);\nconst REANIMATED_IGNORED_PATHS = [\n \"react-native-prebuilt\",\n \"node_modules/.vxrn/react-native\",\n \"node_modules/react/\",\n \"node_modules/react-dom/\",\n \"node_modules/react-native/\",\n // react-native's own scoped packages are flow, and the worklets transform\n // runs before flow stripping in the vite pipeline. they never hold app\n // worklets, exactly like node_modules/react-native/ above.\n \"node_modules/@react-native/\",\n \"node_modules/react-native-web/\"\n];\nconst REANIMATED_IGNORED_PATHS_REGEX = new RegExp(REANIMATED_IGNORED_PATHS.join(\"|\"));\nfunction shouldTransformWorklets({ id, code }) {\n if (!isNativeWorkletsEnabled() || !configuration.enableReanimated) {\n return false;\n }\n const normalizedId = id.replace(/\\\\/g, \"/\");\n if (REANIMATED_IGNORED_PATHS_REGEX.test(normalizedId)) {\n return false;\n }\n return REANIMATED_REGEX.test(code);\n}\nfunction getWorkletsVersion(projectRoot, filename) {\n if (projectRoot) {\n try {\n const req = createRequire(path.resolve(projectRoot, \"package.json\"));\n try {\n const ver = req(\"react-native-worklets/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n try {\n const ver = req(\"react-native-reanimated/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n } catch {\n }\n throw new Error(\n `[@vxrn/compiler] Unable to resolve \"react-native-worklets\" or \"react-native-reanimated\" version from project root \"${projectRoot}\". Please ensure react-native-worklets is installed in your project.`\n );\n }\n if (filename && !filename.startsWith(\"\\0\") && fs.existsSync(filename)) {\n try {\n const req = createRequire(filename);\n try {\n const ver = req(\"react-native-worklets/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n try {\n const ver = req(\"react-native-reanimated/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n } catch {\n }\n }\n const fallbacks = [\n () => createRequire(path.resolve(process.cwd(), \"package.json\")),\n () => createRequire(import.meta.url)\n ];\n for (const getReq of fallbacks) {\n try {\n const req = getReq();\n try {\n const ver = req(\"react-native-worklets/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n try {\n const ver = req(\"react-native-reanimated/package.json\")?.version;\n if (ver) return ver;\n } catch {\n }\n } catch {\n }\n }\n const target = filename || process.cwd();\n throw new Error(\n `[@vxrn/compiler] Unable to resolve \"react-native-worklets\" or \"react-native-reanimated\" version from \"${target}\". Please ensure react-native-worklets is installed in your project.`\n );\n}\nasync function transformWorklets(id, code, sourceMaps = false, options) {\n if (shouldStripFlow(id, code)) {\n if (isReactNativeCodegenSpec(id, code)) return { code };\n const stripped = await stripFlowTypes(id, code, sourceMaps);\n const result = executeWorkletTransform(\n id,\n stripped.code,\n sourceMaps,\n options,\n getWorkletsVersion\n );\n if (!sourceMaps || !stripped.map) return result;\n return {\n code: result.code,\n map: result.map ? remapping([result.map, stripped.map], () => null) : stripped.map\n };\n }\n return executeWorkletTransform(id, code, sourceMaps, options, getWorkletsVersion);\n}\nexport {\n REANIMATED_AUTOWORKLETIZATION_KEYWORDS,\n getWorkletsVersion,\n prepareWorkletsForReactCompiler,\n shouldTransformWorklets,\n transformWorklets\n};\n//# sourceMappingURL=transformWorklets.js.map\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vxrn/compiler",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./package.json": "./package.json",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"@babel/plugin-transform-regenerator": "^7.28.4",
|
|
43
43
|
"@jridgewell/remapping": "^2.3.0",
|
|
44
44
|
"@swc/core": "1.16.18",
|
|
45
|
-
"@vxrn/utils": "2.
|
|
46
|
-
"@vxrn/vite-native-client": "2.
|
|
45
|
+
"@vxrn/utils": "2.9.0",
|
|
46
|
+
"@vxrn/vite-native-client": "2.9.0",
|
|
47
47
|
"astring": "1.9.0",
|
|
48
48
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
49
49
|
"babel-plugin-syntax-hermes-parser": "^0.37.0",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"publishConfig": {
|
|
77
77
|
"access": "public"
|
|
78
78
|
},
|
|
79
|
-
"releaseSourceCommit": "
|
|
79
|
+
"releaseSourceCommit": "28cc4531bbc4fa1e392a92dc05529d318278d832",
|
|
80
80
|
"repository": {
|
|
81
81
|
"type": "git",
|
|
82
82
|
"url": "git+https://github.com/onejs/one.git",
|
package/src/index.ts
CHANGED
|
@@ -71,6 +71,11 @@ function isCodegenNativeCommandsDeclaration(declaration: any): boolean {
|
|
|
71
71
|
)
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
// a native component spec whose codegen call still needs generating.
|
|
75
|
+
export function isReactNativeCodegenSpec(id: string, code: string) {
|
|
76
|
+
return CODEGEN_FILE_RE.test(normalizePath(id.split('?')[0])) && CODEGEN_CALL_RE.test(code)
|
|
77
|
+
}
|
|
78
|
+
|
|
74
79
|
export function transformReactNativeCodegen(
|
|
75
80
|
code: string,
|
|
76
81
|
id: string,
|
|
@@ -78,16 +83,12 @@ export function transformReactNativeCodegen(
|
|
|
78
83
|
): { code: string; map: any } | null | undefined {
|
|
79
84
|
const cleanId = normalizePath(id.split('?')[0])
|
|
80
85
|
|
|
81
|
-
if (!CODEGEN_FILE_RE.test(cleanId)) {
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
|
|
85
86
|
// the transform runs more than once over the same module, so it must not
|
|
86
87
|
// reject the output it just produced. matching the bare name matches the
|
|
87
88
|
// surviving `import codegenNativeComponent from ...` too; only a remaining
|
|
88
89
|
// CALL means the file still needs generating. a comment marker cannot do
|
|
89
90
|
// this job because oxc drops leading comments on the next pass.
|
|
90
|
-
if (!
|
|
91
|
+
if (!isReactNativeCodegenSpec(id, code)) {
|
|
91
92
|
return
|
|
92
93
|
}
|
|
93
94
|
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
// hermes v1 can lose an awaited value in async arrows with default parameters.
|
|
2
2
|
// lower async after worklets, keeping bigint and the earlier class-field semantics.
|
|
3
3
|
// metro also emits commonjs here so it does not need a second esbuild pass.
|
|
4
|
+
// esbuild renames nested bindings that shadow a top-level name (a lowered
|
|
5
|
+
// `export class Foo` declares an inner `function Foo2`), so an unminified
|
|
6
|
+
// bundle asks it to restore `.name` the way metro's babel output keeps it.
|
|
4
7
|
export async function transformHermesAsync(
|
|
5
8
|
code: string,
|
|
6
9
|
filename: string,
|
|
7
10
|
sourceMaps = false,
|
|
8
|
-
format?: 'cjs'
|
|
11
|
+
format?: 'cjs',
|
|
12
|
+
keepNames = false
|
|
9
13
|
): Promise<{ code: string; map?: any } | undefined> {
|
|
10
14
|
if (!format && !code.includes('async')) return
|
|
11
15
|
|
|
@@ -15,6 +19,7 @@ export async function transformHermesAsync(
|
|
|
15
19
|
loader: /\.[cm]?ts$/.test(cleanId) ? 'ts' : cleanId.endsWith('.tsx') ? 'tsx' : 'jsx',
|
|
16
20
|
jsx: 'preserve',
|
|
17
21
|
format,
|
|
22
|
+
keepNames,
|
|
18
23
|
supported: {
|
|
19
24
|
'async-await': false,
|
|
20
25
|
'async-generator': false,
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { parseSync } from 'oxc-parser'
|
|
2
|
+
import MagicString from 'magic-string'
|
|
3
|
+
import remapping from '@jridgewell/remapping'
|
|
4
|
+
|
|
5
|
+
// collect scopes before inspecting references so hoisted and later declarations
|
|
6
|
+
// shadow the commonjs wrapper just as earlier declarations do.
|
|
7
|
+
type Node = any
|
|
8
|
+
type Scope = { parent?: Scope; bindings: Set<string>; function: boolean }
|
|
9
|
+
|
|
10
|
+
function analyze(program: Node) {
|
|
11
|
+
const scopes = new WeakMap<object, Scope>()
|
|
12
|
+
const bindings = new WeakSet<object>()
|
|
13
|
+
const root: Scope = { bindings: new Set(), function: true }
|
|
14
|
+
function bind(pattern: Node, scope: Scope) {
|
|
15
|
+
if (!pattern) return
|
|
16
|
+
if (pattern.type === 'Identifier') {
|
|
17
|
+
scope.bindings.add(pattern.name)
|
|
18
|
+
bindings.add(pattern)
|
|
19
|
+
} else if (pattern.type === 'RestElement') bind(pattern.argument, scope)
|
|
20
|
+
else if (pattern.type === 'AssignmentPattern') bind(pattern.left, scope)
|
|
21
|
+
else if (pattern.type === 'ArrayPattern') {
|
|
22
|
+
for (const item of pattern.elements) bind(item, scope)
|
|
23
|
+
} else if (pattern.type === 'ObjectPattern') {
|
|
24
|
+
for (const item of pattern.properties)
|
|
25
|
+
bind(item.type === 'RestElement' ? item.argument : item.value, scope)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function visit(node: Node, parentScope: Scope) {
|
|
29
|
+
let scope = parentScope
|
|
30
|
+
const fn =
|
|
31
|
+
/^(?:FunctionDeclaration|FunctionExpression|ArrowFunctionExpression)$/.test(
|
|
32
|
+
node.type
|
|
33
|
+
)
|
|
34
|
+
if (node.type === 'FunctionDeclaration' || node.type === 'ClassDeclaration')
|
|
35
|
+
bind(node.id, parentScope)
|
|
36
|
+
if (
|
|
37
|
+
fn ||
|
|
38
|
+
/^(?:BlockStatement|CatchClause|ForStatement|ForInStatement|ForOfStatement|SwitchStatement|ClassExpression|ClassDeclaration|StaticBlock)$/.test(
|
|
39
|
+
node.type
|
|
40
|
+
)
|
|
41
|
+
) {
|
|
42
|
+
scope = {
|
|
43
|
+
parent: parentScope,
|
|
44
|
+
bindings: new Set(),
|
|
45
|
+
function: fn || node.type === 'StaticBlock',
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
scopes.set(node, scope)
|
|
49
|
+
if (fn) {
|
|
50
|
+
if (node.type === 'FunctionExpression') bind(node.id, scope)
|
|
51
|
+
for (const param of node.params) bind(param, scope)
|
|
52
|
+
}
|
|
53
|
+
if (node.type === 'ClassExpression' || node.type === 'ClassDeclaration')
|
|
54
|
+
bind(node.id, scope)
|
|
55
|
+
if (node.type === 'CatchClause') bind(node.param, scope)
|
|
56
|
+
if (node.type === 'VariableDeclaration') {
|
|
57
|
+
let target = scope
|
|
58
|
+
if (node.kind === 'var') while (!target.function) target = target.parent!
|
|
59
|
+
for (const declaration of node.declarations) bind(declaration.id, target)
|
|
60
|
+
}
|
|
61
|
+
if (node.type === 'ImportDeclaration')
|
|
62
|
+
for (const specifier of node.specifiers) bind(specifier.local, scope)
|
|
63
|
+
children(node, (child) => visit(child, scope))
|
|
64
|
+
if (
|
|
65
|
+
(node.type === 'FunctionDeclaration' || node.type === 'ClassDeclaration') &&
|
|
66
|
+
node.id
|
|
67
|
+
)
|
|
68
|
+
scopes.set(node.id, parentScope)
|
|
69
|
+
}
|
|
70
|
+
visit(program, root)
|
|
71
|
+
function binding(node: Node): Scope | undefined {
|
|
72
|
+
let scope = scopes.get(node)
|
|
73
|
+
while (scope && !scope.bindings.has(node.name)) scope = scope.parent
|
|
74
|
+
return scope
|
|
75
|
+
}
|
|
76
|
+
return { bindings, binding, rootBindings: root.bindings }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function children(node: Node, visit: (child: Node, key: string) => void) {
|
|
80
|
+
for (const key of Object.keys(node)) {
|
|
81
|
+
if (key === 'parent') continue
|
|
82
|
+
const value = node[key]
|
|
83
|
+
if (Array.isArray(value)) {
|
|
84
|
+
for (const child of value) if (child?.type) visit(child, key)
|
|
85
|
+
} else if (value?.type) visit(value, key)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function isReference(node: Node, parent: Node, key: string, bindings: WeakSet<object>) {
|
|
90
|
+
if (bindings.has(node)) return false
|
|
91
|
+
if (
|
|
92
|
+
(parent.type === 'MemberExpression' || parent.type === 'OptionalMemberExpression') &&
|
|
93
|
+
key === 'property' &&
|
|
94
|
+
!parent.computed
|
|
95
|
+
)
|
|
96
|
+
return false
|
|
97
|
+
if (
|
|
98
|
+
/^(?:Property|MethodDefinition|PropertyDefinition)$/.test(parent.type) &&
|
|
99
|
+
key === 'key' &&
|
|
100
|
+
!parent.computed
|
|
101
|
+
)
|
|
102
|
+
return false
|
|
103
|
+
if (
|
|
104
|
+
/^(?:Import.*Specifier|ExportSpecifier|LabeledStatement|BreakStatement|ContinueStatement|MetaProperty)$/.test(
|
|
105
|
+
parent.type
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
return false
|
|
109
|
+
return true
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// swc exposes local exports through getters. metro uses writable properties and
|
|
113
|
+
// updates them when the local binding changes. lower those assignments before
|
|
114
|
+
// swc handles imports, re-exports, and typescript.
|
|
115
|
+
function lowerLocalExports(
|
|
116
|
+
program: Node,
|
|
117
|
+
code: string,
|
|
118
|
+
analysis: ReturnType<typeof analyze>
|
|
119
|
+
) {
|
|
120
|
+
const edited = new MagicString(code)
|
|
121
|
+
let exportAccess = '__mixedExports'
|
|
122
|
+
while (code.includes(exportAccess)) exportAccess += '_'
|
|
123
|
+
// capture the wrapper binding outside source scopes, including functions whose
|
|
124
|
+
// parameters shadow exports. reading through a closure also honors a source
|
|
125
|
+
// assignment to the wrapper's exports variable.
|
|
126
|
+
const exportBinding = analysis.rootBindings.has('exports')
|
|
127
|
+
? `const ${exportAccess} = module.exports;`
|
|
128
|
+
: `const ${exportAccess} = () => exports;`
|
|
129
|
+
const exportObject = analysis.rootBindings.has('exports')
|
|
130
|
+
? exportAccess
|
|
131
|
+
: `${exportAccess}()`
|
|
132
|
+
const exported = new Map<string, { scope: Scope | undefined; names: string[] }>()
|
|
133
|
+
const imported = new Set<string>()
|
|
134
|
+
for (const node of program.body)
|
|
135
|
+
if (node.type === 'ImportDeclaration')
|
|
136
|
+
for (const specifier of node.specifiers) imported.add(specifier.local.name)
|
|
137
|
+
const hoisted: string[] = []
|
|
138
|
+
const defaultFunctions: string[] = []
|
|
139
|
+
function names(pattern: Node): Node[] {
|
|
140
|
+
if (!pattern) return []
|
|
141
|
+
if (pattern.type === 'Identifier') return [pattern]
|
|
142
|
+
if (pattern.type === 'RestElement') return names(pattern.argument)
|
|
143
|
+
if (pattern.type === 'AssignmentPattern') return names(pattern.left)
|
|
144
|
+
if (pattern.type === 'ArrayPattern') return pattern.elements.flatMap(names)
|
|
145
|
+
if (pattern.type === 'ObjectPattern')
|
|
146
|
+
return pattern.properties.flatMap((item: Node) =>
|
|
147
|
+
names(item.type === 'RestElement' ? item.argument : item.value)
|
|
148
|
+
)
|
|
149
|
+
return []
|
|
150
|
+
}
|
|
151
|
+
function add(id: Node, name: string) {
|
|
152
|
+
const entry = exported.get(id.name) || {
|
|
153
|
+
scope: analysis.binding(id),
|
|
154
|
+
names: [],
|
|
155
|
+
}
|
|
156
|
+
entry.names.push(name)
|
|
157
|
+
exported.set(id.name, entry)
|
|
158
|
+
}
|
|
159
|
+
const assignments = (id: string) =>
|
|
160
|
+
exported
|
|
161
|
+
.get(id)!
|
|
162
|
+
.names.map((name) => `${exportObject}[${JSON.stringify(name)}] = `)
|
|
163
|
+
.join('') + id
|
|
164
|
+
for (const node of program.body) {
|
|
165
|
+
if (node.type === 'ExportDefaultDeclaration') {
|
|
166
|
+
const declaration = node.declaration
|
|
167
|
+
if (
|
|
168
|
+
declaration.type === 'FunctionDeclaration' ||
|
|
169
|
+
(declaration.type === 'ClassDeclaration' && declaration.id)
|
|
170
|
+
) {
|
|
171
|
+
edited.remove(node.start, declaration.start)
|
|
172
|
+
if (declaration.id) {
|
|
173
|
+
add(declaration.id, 'default')
|
|
174
|
+
if (declaration.type === 'FunctionDeclaration')
|
|
175
|
+
hoisted.push(declaration.id.name)
|
|
176
|
+
else
|
|
177
|
+
edited.appendLeft(
|
|
178
|
+
node.end,
|
|
179
|
+
`;${exportObject}.default = ${declaration.id.name};`
|
|
180
|
+
)
|
|
181
|
+
} else {
|
|
182
|
+
let name = '__mixedDefault'
|
|
183
|
+
while (code.includes(name)) name += '_'
|
|
184
|
+
const prefix = code
|
|
185
|
+
.slice(declaration.start, declaration.body.start)
|
|
186
|
+
.match(/^(?:async\s+)?function\s*\*?/)![0]
|
|
187
|
+
edited.prependRight(declaration.start + prefix.length, ` ${name}`)
|
|
188
|
+
defaultFunctions.push(`${exportObject}.default = ${name};`)
|
|
189
|
+
}
|
|
190
|
+
} else if (declaration.type !== 'TSInterfaceDeclaration') {
|
|
191
|
+
edited.overwrite(node.start, declaration.start, `${exportObject}.default = (`)
|
|
192
|
+
edited.appendLeft(declaration.end, ')')
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (
|
|
196
|
+
node.type === 'ExportNamedDeclaration' &&
|
|
197
|
+
!node.source &&
|
|
198
|
+
node.exportKind !== 'type'
|
|
199
|
+
) {
|
|
200
|
+
const declaration = node.declaration
|
|
201
|
+
if (declaration) {
|
|
202
|
+
if (/^(?:TS|Interface|Type)/.test(declaration.type)) continue
|
|
203
|
+
const ids =
|
|
204
|
+
declaration.type === 'VariableDeclaration'
|
|
205
|
+
? declaration.declarations.flatMap((item: Node) => names(item.id))
|
|
206
|
+
: names(declaration.id)
|
|
207
|
+
for (const id of ids) add(id, id.name)
|
|
208
|
+
edited.remove(node.start, declaration.start)
|
|
209
|
+
if (declaration.type === 'FunctionDeclaration')
|
|
210
|
+
hoisted.push(...ids.map((id: Node) => id.name))
|
|
211
|
+
} else {
|
|
212
|
+
// imported re-exports retain swc's live getters.
|
|
213
|
+
const locals = node.specifiers.filter(
|
|
214
|
+
(item: Node) => item.exportKind !== 'type' && !imported.has(item.local.name)
|
|
215
|
+
)
|
|
216
|
+
for (const item of locals)
|
|
217
|
+
add(item.local, item.exported.name ?? item.exported.value)
|
|
218
|
+
if (locals.length === node.specifiers.length) edited.remove(node.start, node.end)
|
|
219
|
+
else if (locals.length) {
|
|
220
|
+
// preserve the remaining specifiers without overlapping edits.
|
|
221
|
+
const retained = node.specifiers.filter(
|
|
222
|
+
(other: Node) => !locals.includes(other)
|
|
223
|
+
)
|
|
224
|
+
edited.overwrite(
|
|
225
|
+
node.start,
|
|
226
|
+
node.end,
|
|
227
|
+
`export { ${retained.map((other: Node) => code.slice(other.start, other.end)).join(', ')} };`
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// export lists may precede their declaration or add aliases after it.
|
|
234
|
+
for (const node of program.body) {
|
|
235
|
+
const declaration = node.type === 'ExportNamedDeclaration' ? node.declaration : node
|
|
236
|
+
if (!declaration) continue
|
|
237
|
+
if (declaration.type === 'VariableDeclaration') {
|
|
238
|
+
for (const item of declaration.declarations)
|
|
239
|
+
for (const id of names(item.id)) {
|
|
240
|
+
if (exported.has(id.name)) {
|
|
241
|
+
if (item.id.type === 'Identifier' && item.init) {
|
|
242
|
+
const prefix = exported
|
|
243
|
+
.get(id.name)!
|
|
244
|
+
.names.map((name) => `${exportObject}[${JSON.stringify(name)}] = `)
|
|
245
|
+
.join('')
|
|
246
|
+
edited.prependRight(item.init.start, prefix + '(')
|
|
247
|
+
edited.appendLeft(item.init.end, ')')
|
|
248
|
+
} else if (item.id.type !== 'Identifier')
|
|
249
|
+
edited.appendLeft(node.end, `;${assignments(id.name)};`)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
} else if (
|
|
253
|
+
declaration.type === 'FunctionDeclaration' &&
|
|
254
|
+
exported.has(declaration.id?.name)
|
|
255
|
+
) {
|
|
256
|
+
if (!hoisted.includes(declaration.id.name)) hoisted.push(declaration.id.name)
|
|
257
|
+
} else if (
|
|
258
|
+
declaration.type === 'ClassDeclaration' &&
|
|
259
|
+
exported.has(declaration.id?.name)
|
|
260
|
+
) {
|
|
261
|
+
edited.appendLeft(node.end, `;${assignments(declaration.id.name)};`)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
let temporary = '__mixedExportResult'
|
|
265
|
+
while (code.includes(temporary)) temporary += '_'
|
|
266
|
+
// use paired inserts so nested assignment expressions retain their mappings.
|
|
267
|
+
function mutations(node: Node) {
|
|
268
|
+
if (node.type === 'ForOfStatement' || node.type === 'ForInStatement') {
|
|
269
|
+
const ids = (
|
|
270
|
+
node.left.type === 'VariableDeclaration'
|
|
271
|
+
? node.left.declarations.flatMap((item: Node) => names(item.id))
|
|
272
|
+
: names(node.left)
|
|
273
|
+
).filter(
|
|
274
|
+
(id: Node) =>
|
|
275
|
+
exported.has(id.name) && analysis.binding(id) === exported.get(id.name)!.scope
|
|
276
|
+
)
|
|
277
|
+
if (ids.length) {
|
|
278
|
+
const publish = ids.map((id: Node) => assignments(id.name) + ';').join('')
|
|
279
|
+
if (node.body.type === 'BlockStatement')
|
|
280
|
+
edited.prependRight(node.body.start + 1, publish)
|
|
281
|
+
else {
|
|
282
|
+
edited.prependRight(node.body.start, '{' + publish)
|
|
283
|
+
edited.appendLeft(node.body.end, '}')
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') {
|
|
288
|
+
const ids = names(
|
|
289
|
+
node.type === 'AssignmentExpression' ? node.left : node.argument
|
|
290
|
+
).filter(
|
|
291
|
+
(id: Node) =>
|
|
292
|
+
exported.has(id.name) && analysis.binding(id) === exported.get(id.name)!.scope
|
|
293
|
+
)
|
|
294
|
+
if (ids.length) {
|
|
295
|
+
edited.prependRight(
|
|
296
|
+
node.start,
|
|
297
|
+
`((${temporary}) => (${ids.map((id: Node) => assignments(id.name)).join(', ')}, ${temporary}))(`
|
|
298
|
+
)
|
|
299
|
+
edited.appendLeft(node.end, ')')
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
children(node, (child) => mutations(child))
|
|
303
|
+
}
|
|
304
|
+
mutations(program)
|
|
305
|
+
// leave directives first, including an explicit use strict from the author.
|
|
306
|
+
const first = program.body.find(
|
|
307
|
+
(node: Node) => !(node.type === 'ExpressionStatement' && node.directive)
|
|
308
|
+
)
|
|
309
|
+
const initialization = [...exported.values()]
|
|
310
|
+
.flatMap((entry) => entry.names)
|
|
311
|
+
.map((name) => `${exportObject}[${JSON.stringify(name)}] = void 0;`)
|
|
312
|
+
.join('')
|
|
313
|
+
edited.prependRight(
|
|
314
|
+
first?.start ?? code.length,
|
|
315
|
+
`export {};${exportBinding}${initialization}${hoisted.map((id) => assignments(id) + ';').join('')}${defaultFunctions.join('')}`
|
|
316
|
+
)
|
|
317
|
+
return edited
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export async function transformMixedNativeModule(
|
|
321
|
+
code: string,
|
|
322
|
+
filename: string,
|
|
323
|
+
sourceMaps = false
|
|
324
|
+
): Promise<{ code: string; map?: any } | undefined> {
|
|
325
|
+
if (!/\b(?:module|exports)\b/.test(code) || !/\b(?:import|export)\b/.test(code)) return
|
|
326
|
+
const typescript = /\.[cm]?tsx?$/.test(filename)
|
|
327
|
+
const parsed = parseSync(filename, code, {
|
|
328
|
+
lang: typescript ? (filename.endsWith('tsx') ? 'tsx' : 'ts') : 'jsx',
|
|
329
|
+
})
|
|
330
|
+
if (parsed.errors.length) throw new Error(parsed.errors[0]!.message)
|
|
331
|
+
let program = parsed.program
|
|
332
|
+
if (!program.body.some((node) => /^(?:Import|Export)/.test(node.type))) return
|
|
333
|
+
let analysis = analyze(program)
|
|
334
|
+
let mixed = false
|
|
335
|
+
function inspect(node: Node, parent: Node, key: string) {
|
|
336
|
+
if (
|
|
337
|
+
node.type === 'Identifier' &&
|
|
338
|
+
/^(?:module|exports)$/.test(node.name) &&
|
|
339
|
+
isReference(node, parent, key, analysis.bindings) &&
|
|
340
|
+
!analysis.binding(node)
|
|
341
|
+
)
|
|
342
|
+
mixed = true
|
|
343
|
+
children(node, (child, key) => inspect(child, node, key))
|
|
344
|
+
}
|
|
345
|
+
inspect(program, program, '')
|
|
346
|
+
if (!mixed) return
|
|
347
|
+
|
|
348
|
+
const { transform } = await import('@swc/core')
|
|
349
|
+
let typeMap: any
|
|
350
|
+
if (typescript) {
|
|
351
|
+
// lower runtime typescript declarations before assigning writable exports.
|
|
352
|
+
// otherwise enums and namespaces retain swc's getter-only module exports.
|
|
353
|
+
const stripped = await transform(code, {
|
|
354
|
+
filename,
|
|
355
|
+
swcrc: false,
|
|
356
|
+
configFile: false,
|
|
357
|
+
sourceMaps,
|
|
358
|
+
jsc: {
|
|
359
|
+
target: 'esnext',
|
|
360
|
+
parser: { syntax: 'typescript', tsx: filename.endsWith('.tsx') },
|
|
361
|
+
transform: { react: { runtime: 'preserve' } },
|
|
362
|
+
},
|
|
363
|
+
module: { type: 'es6' },
|
|
364
|
+
})
|
|
365
|
+
code = stripped.code
|
|
366
|
+
typeMap = stripped.map ? JSON.parse(stripped.map) : undefined
|
|
367
|
+
const javascript = parseSync(filename, code, { lang: 'jsx' })
|
|
368
|
+
if (javascript.errors.length) throw new Error(javascript.errors[0]!.message)
|
|
369
|
+
program = javascript.program
|
|
370
|
+
analysis = analyze(program)
|
|
371
|
+
}
|
|
372
|
+
const edited = lowerLocalExports(program, code, analysis)
|
|
373
|
+
const result = await transform(edited.toString(), {
|
|
374
|
+
filename,
|
|
375
|
+
swcrc: false,
|
|
376
|
+
configFile: false,
|
|
377
|
+
sourceMaps,
|
|
378
|
+
jsc: {
|
|
379
|
+
target: 'esnext',
|
|
380
|
+
parser: { syntax: 'ecmascript', jsx: true },
|
|
381
|
+
transform: { react: { runtime: 'preserve' } },
|
|
382
|
+
},
|
|
383
|
+
module: { type: 'commonjs', strictMode: false, allowTopLevelThis: true },
|
|
384
|
+
})
|
|
385
|
+
return {
|
|
386
|
+
code: result.code,
|
|
387
|
+
map: result.map
|
|
388
|
+
? remapping(
|
|
389
|
+
[
|
|
390
|
+
JSON.parse(result.map),
|
|
391
|
+
edited.generateMap({
|
|
392
|
+
source: filename,
|
|
393
|
+
includeContent: true,
|
|
394
|
+
hires: true,
|
|
395
|
+
}),
|
|
396
|
+
...(typeMap ? [typeMap] : []),
|
|
397
|
+
],
|
|
398
|
+
() => null
|
|
399
|
+
)
|
|
400
|
+
: undefined,
|
|
401
|
+
}
|
|
402
|
+
}
|
|
@@ -315,6 +315,44 @@ describe('transformWorklets', () => {
|
|
|
315
315
|
expect(result.map?.mappings).toBeDefined()
|
|
316
316
|
})
|
|
317
317
|
|
|
318
|
+
it('workletizes published Flow packages before the pipeline strips Flow', async () => {
|
|
319
|
+
const code = `/**
|
|
320
|
+
* @flow strict-local
|
|
321
|
+
*/
|
|
322
|
+
import type { Node } from 'react'
|
|
323
|
+
export function animate(value: number): number {
|
|
324
|
+
'worklet'
|
|
325
|
+
return value * 2
|
|
326
|
+
}
|
|
327
|
+
export const Picker = (props: { onChange: (v: string) => void }): Node => null
|
|
328
|
+
`
|
|
329
|
+
const result = await transformWorklets(
|
|
330
|
+
'/app/node_modules/flow-picker/js/Picker.ios.js',
|
|
331
|
+
code,
|
|
332
|
+
true
|
|
333
|
+
)
|
|
334
|
+
expect(result.code).toContain('__workletHash')
|
|
335
|
+
expect(result.code).not.toContain('import type')
|
|
336
|
+
expect(result.map?.sources).toContain('/app/node_modules/flow-picker/js/Picker.ios.js')
|
|
337
|
+
const serialized = result.code.match(/code: ("(?:\\.|[^"\\])*")/)?.[1]
|
|
338
|
+
expect((0, eval)(JSON.parse(serialized!))(21)).toBe(42)
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
it('leaves a Flow codegen spec typed for the codegen pass', async () => {
|
|
342
|
+
const code = `// @flow
|
|
343
|
+
import type { ViewProps } from 'react-native'
|
|
344
|
+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'
|
|
345
|
+
type NativeProps = $ReadOnly<{| ...ViewProps, onChange?: ?() => void |}>
|
|
346
|
+
export default (codegenNativeComponent<NativeProps>('FlowPicker'): HostComponent<NativeProps>)
|
|
347
|
+
`
|
|
348
|
+
const result = await transformWorklets(
|
|
349
|
+
'/app/node_modules/flow-picker/js/FlowPickerNativeComponent.js',
|
|
350
|
+
code,
|
|
351
|
+
false
|
|
352
|
+
)
|
|
353
|
+
expect(result.code).toBe(code)
|
|
354
|
+
})
|
|
355
|
+
|
|
318
356
|
it('rejects on transform errors instead of returning untransformed source', async () => {
|
|
319
357
|
await expect(
|
|
320
358
|
transformWorklets(
|
package/src/transformWorklets.ts
CHANGED
|
@@ -150,6 +150,10 @@ export type TransformWorkletsOptions = {
|
|
|
150
150
|
pluginVersion?: string
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
import remapping from '@jridgewell/remapping'
|
|
154
|
+
import { isReactNativeCodegenSpec } from './reactNativeCodegen'
|
|
155
|
+
import { stripFlowTypes } from './transformFlow'
|
|
156
|
+
import { shouldStripFlow } from './transformSWC'
|
|
153
157
|
import { executeWorkletTransform } from './worklets/transform'
|
|
154
158
|
export { prepareWorkletsForReactCompiler } from './worklets/transform'
|
|
155
159
|
|
|
@@ -159,5 +163,24 @@ export async function transformWorklets(
|
|
|
159
163
|
sourceMaps = false,
|
|
160
164
|
options?: TransformWorkletsOptions
|
|
161
165
|
): Promise<{ code: string; map?: any }> {
|
|
166
|
+
// published Flow packages reach this before the pipeline's Flow strip, and the
|
|
167
|
+
// worklet parser has no Flow support. a codegen spec keeps its types for the
|
|
168
|
+
// codegen pass after this one and never holds worklets.
|
|
169
|
+
if (shouldStripFlow(id, code)) {
|
|
170
|
+
if (isReactNativeCodegenSpec(id, code)) return { code }
|
|
171
|
+
const stripped = await stripFlowTypes(id, code, sourceMaps)
|
|
172
|
+
const result = executeWorkletTransform(
|
|
173
|
+
id,
|
|
174
|
+
stripped.code,
|
|
175
|
+
sourceMaps,
|
|
176
|
+
options,
|
|
177
|
+
getWorkletsVersion
|
|
178
|
+
)
|
|
179
|
+
if (!sourceMaps || !stripped.map) return result
|
|
180
|
+
return {
|
|
181
|
+
code: result.code,
|
|
182
|
+
map: result.map ? remapping([result.map, stripped.map], () => null) : stripped.map,
|
|
183
|
+
}
|
|
184
|
+
}
|
|
162
185
|
return executeWorkletTransform(id, code, sourceMaps, options, getWorkletsVersion)
|
|
163
186
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -19,4 +19,5 @@ export { JS_GLOBALS } from './worklets/globals';
|
|
|
19
19
|
export { getClosureVariables } from './worklets/scope';
|
|
20
20
|
export type { GetTransform } from './types';
|
|
21
21
|
export declare function createVXRNCompilerPlugin(optionsIn?: Partial<Options>): Promise<PluginOption[]>;
|
|
22
|
+
export * from './transformMixedNativeModule';
|
|
22
23
|
//# sourceMappingURL=index.d.ts.map
|
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,iBAAiB,CAAA;AAC/B,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
|
+
{"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,iBAAiB,CAAA;AAC/B,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;AACD,cAAc,8BAA8B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactNativeCodegen.d.ts","sourceRoot":"","sources":["../src/reactNativeCodegen.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reactNativeCodegen.d.ts","sourceRoot":"","sources":["../src/reactNativeCodegen.ts"],"names":[],"mappings":"AA0EA,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,WAEhE;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,WAAW,CAAC,EAAE,MAAM,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,GAAG,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAmG/C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function transformHermesAsync(code: string, filename: string, sourceMaps?: boolean, format?: 'cjs'): Promise<{
|
|
1
|
+
export declare function transformHermesAsync(code: string, filename: string, sourceMaps?: boolean, format?: 'cjs', keepNames?: boolean): Promise<{
|
|
2
2
|
code: string;
|
|
3
3
|
map?: any;
|
|
4
4
|
} | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformHermesAsync.d.ts","sourceRoot":"","sources":["../src/transformHermesAsync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transformHermesAsync.d.ts","sourceRoot":"","sources":["../src/transformHermesAsync.ts"],"names":[],"mappings":"AAMA,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,UAAQ,EAClB,MAAM,CAAC,EAAE,KAAK,EACd,SAAS,UAAQ,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,GAAG,SAAS,CAAC,CAsBlD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformMixedNativeModule.d.ts","sourceRoot":"","sources":["../src/transformMixedNativeModule.ts"],"names":[],"mappings":"AA+TA,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,UAAQ,GACjB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,GAAG,SAAS,CAAC,CA8ElD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformWorklets.d.ts","sourceRoot":"","sources":["../src/transformWorklets.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,sCAAsC,UAiBlD,CAAA;AAiCD,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,WAWjF;AAED,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CA8DlF;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;
|
|
1
|
+
{"version":3,"file":"transformWorklets.d.ts","sourceRoot":"","sources":["../src/transformWorklets.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,sCAAsC,UAiBlD,CAAA;AAiCD,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,WAWjF;AAED,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CA8DlF;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAOD,OAAO,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAA;AAEtE,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,UAAU,UAAQ,EAClB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC,CAqBtC"}
|