@vxrn/compiler 2.13.4 → 2.13.5

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.
@@ -47,6 +47,7 @@ var import_transform2 = require("./worklets/transform.cjs");
47
47
  const import_meta = {};
48
48
  const REANIMATED_AUTOWORKLETIZATION_KEYWORDS = [
49
49
  "worklet",
50
+ "__workletClass",
50
51
  "useAnimatedGestureHandler",
51
52
  "useAnimatedScrollHandler",
52
53
  "useFrameCallback",
@@ -0,0 +1,198 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all) __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+ var classes_exports = {};
22
+ __export(classes_exports, {
23
+ WORKLET_CLASS_FACTORY_SUFFIX: () => WORKLET_CLASS_FACTORY_SUFFIX,
24
+ WORKLET_CLASS_MARKER: () => WORKLET_CLASS_MARKER,
25
+ buildClassFactoryDeclaration: () => buildClassFactoryDeclaration,
26
+ classFactoryName: () => classFactoryName,
27
+ findConstructedNames: () => findConstructedNames,
28
+ findUnambiguousClassNames: () => findUnambiguousClassNames,
29
+ findWorkletClasses: () => findWorkletClasses
30
+ });
31
+ module.exports = __toCommonJS(classes_exports);
32
+ const WORKLET_CLASS_MARKER = "__workletClass";
33
+ const WORKLET_CLASS_FACTORY_SUFFIX = "__classFactory";
34
+ const MARKER_FIELD_TYPES = /* @__PURE__ */ new Set([
35
+ "PropertyDefinition",
36
+ "AccessorProperty",
37
+ "TSAbstractPropertyDefinition"
38
+ ]);
39
+ function isMarkerField(element) {
40
+ return MARKER_FIELD_TYPES.has(element?.type) && !element.computed && element.key?.type === "Identifier" && element.key.name === WORKLET_CLASS_MARKER;
41
+ }
42
+ function findWorkletClasses(program) {
43
+ const candidates = [];
44
+ function walk(node, parent) {
45
+ if (!node || typeof node !== "object") return;
46
+ if (node.type === "ClassDeclaration" && node.id?.type === "Identifier" && !node.declare && !(node.decorators?.length > 0)) {
47
+ const marker = node.body?.body?.find(isMarkerField);
48
+ if (marker) {
49
+ candidates.push({
50
+ node,
51
+ name: node.id.name,
52
+ parent,
53
+ marker
54
+ });
55
+ }
56
+ }
57
+ for (const key of Object.keys(node)) {
58
+ if (key === "start" || key === "end" || key === "loc" || key === "range") continue;
59
+ const child = node[key];
60
+ if (Array.isArray(child)) {
61
+ for (const item of child) walk(item, node);
62
+ } else if (child && typeof child === "object") {
63
+ walk(child, node);
64
+ }
65
+ }
66
+ }
67
+ walk(program, null);
68
+ return candidates.filter((candidate) => !candidates.some((other) => other !== candidate && other.node.start <= candidate.node.start && other.node.end >= candidate.node.end));
69
+ }
70
+ function classFactoryName(className) {
71
+ return `${className}${WORKLET_CLASS_FACTORY_SUFFIX}`;
72
+ }
73
+ function collectPatternNames(pattern, count) {
74
+ if (!pattern || typeof pattern !== "object") return;
75
+ switch (pattern.type) {
76
+ case "Identifier":
77
+ count(pattern.name);
78
+ return;
79
+ case "AssignmentPattern":
80
+ collectPatternNames(pattern.left, count);
81
+ return;
82
+ case "RestElement":
83
+ collectPatternNames(pattern.argument, count);
84
+ return;
85
+ case "ArrayPattern":
86
+ for (const element of pattern.elements ?? []) collectPatternNames(element, count);
87
+ return;
88
+ case "ObjectPattern":
89
+ for (const property of pattern.properties ?? []) {
90
+ if (property?.type === "Property") collectPatternNames(property.value, count);
91
+ else if (property?.type === "RestElement") collectPatternNames(property.argument, count);
92
+ }
93
+ return;
94
+ case "TSParameterProperty":
95
+ collectPatternNames(pattern.parameter, count);
96
+ return;
97
+ }
98
+ }
99
+ function findUnambiguousClassNames(program, candidates) {
100
+ const wanted = new Set(candidates.map((candidate) => candidate.name));
101
+ const counts = /* @__PURE__ */ new Map();
102
+ const count = (name) => {
103
+ if (wanted.has(name)) counts.set(name, (counts.get(name) ?? 0) + 1);
104
+ };
105
+ function walk(node) {
106
+ if (!node || typeof node !== "object") return;
107
+ if (Array.isArray(node)) {
108
+ for (const item of node) walk(item);
109
+ return;
110
+ }
111
+ switch (node.type) {
112
+ case "VariableDeclarator":
113
+ collectPatternNames(node.id, count);
114
+ break;
115
+ case "FunctionDeclaration":
116
+ case "FunctionExpression":
117
+ if (node.id?.type === "Identifier") count(node.id.name);
118
+ for (const param of node.params ?? []) collectPatternNames(param, count);
119
+ break;
120
+ case "ArrowFunctionExpression":
121
+ for (const param of node.params ?? []) collectPatternNames(param, count);
122
+ break;
123
+ case "ClassDeclaration":
124
+ case "ClassExpression":
125
+ if (node.id?.type === "Identifier") count(node.id.name);
126
+ break;
127
+ case "CatchClause":
128
+ collectPatternNames(node.param, count);
129
+ break;
130
+ case "ImportSpecifier":
131
+ case "ImportDefaultSpecifier":
132
+ case "ImportNamespaceSpecifier":
133
+ if (node.local?.type === "Identifier") count(node.local.name);
134
+ break;
135
+ case "TSEnumDeclaration":
136
+ case "TSModuleDeclaration":
137
+ if (node.id?.type === "Identifier") count(node.id.name);
138
+ break;
139
+ }
140
+ for (const key of Object.keys(node)) {
141
+ if (key === "start" || key === "end" || key === "loc" || key === "range") continue;
142
+ walk(node[key]);
143
+ }
144
+ }
145
+ walk(program);
146
+ return new Set(candidates.filter((candidate) => counts.get(candidate.name) === 1).map((c) => c.name));
147
+ }
148
+ const ABSTRACT_MEMBER_TYPES = /* @__PURE__ */ new Set(["TSAbstractMethodDefinition", "TSAbstractPropertyDefinition"]);
149
+ function buildClassFactoryDeclaration(candidate, code) {
150
+ const { node, name, marker } = candidate;
151
+ const factory = classFactoryName(name);
152
+ const removals = [[marker.decorators?.[0]?.start ?? marker.start, marker.end]];
153
+ for (const element of node.body?.body ?? []) {
154
+ if (ABSTRACT_MEMBER_TYPES.has(element?.type)) {
155
+ removals.push([element.start, element.end]);
156
+ }
157
+ }
158
+ removals.sort((a, b) => a[0] - b[0]);
159
+ let classSrc = "";
160
+ let cursor = node.start;
161
+ for (const [start, end] of removals) {
162
+ if (start < cursor) continue;
163
+ classSrc += code.slice(cursor, start);
164
+ cursor = end;
165
+ }
166
+ classSrc += code.slice(cursor, node.end);
167
+ const classExpr = classSrc.replace(/^abstract\s+/, "");
168
+ return [
169
+ `function ${factory}() {`,
170
+ `'worklet';`,
171
+ `const ${name} = ${classExpr};`,
172
+ `${name}.${factory} = ${factory};`,
173
+ `return ${name};`,
174
+ `}`
175
+ ].join("\n");
176
+ }
177
+ function findConstructedNames(fnNode) {
178
+ const names = [];
179
+ const seen = /* @__PURE__ */ new Set();
180
+ function walk(node) {
181
+ if (!node || typeof node !== "object") return;
182
+ if (Array.isArray(node)) {
183
+ for (const item of node) walk(item);
184
+ return;
185
+ }
186
+ if (node.type === "NewExpression" && node.callee?.type === "Identifier" && !seen.has(node.callee.name)) {
187
+ seen.add(node.callee.name);
188
+ names.push(node.callee.name);
189
+ }
190
+ for (const key of Object.keys(node)) {
191
+ if (key === "start" || key === "end" || key === "loc" || key === "range") continue;
192
+ walk(node[key]);
193
+ }
194
+ }
195
+ walk(fnNode.body);
196
+ for (const param of fnNode.params ?? []) walk(param);
197
+ return names;
198
+ }
@@ -255,6 +255,9 @@ function getClosureVariables(fnNode, globals) {
255
255
  if (node.id && node.id.name) {
256
256
  currentScope.bindings.add(node.id.name);
257
257
  }
258
+ if (node.decorators) {
259
+ for (const decorator of node.decorators) walk(decorator);
260
+ }
258
261
  if (node.superClass) walk(node.superClass);
259
262
  pushScope(false);
260
263
  walk(node.body);
@@ -275,13 +278,32 @@ function getClosureVariables(fnNode, globals) {
275
278
  walk(node.value);
276
279
  return;
277
280
  }
278
- case "MethodDefinition": {
281
+ case "MethodDefinition":
282
+ case "TSAbstractMethodDefinition": {
279
283
  if (node.computed) {
280
284
  walk(node.key);
281
285
  }
286
+ if (node.decorators) {
287
+ for (const decorator of node.decorators) walk(decorator);
288
+ }
282
289
  walk(node.value);
283
290
  return;
284
291
  }
292
+ case "PropertyDefinition":
293
+ case "AccessorProperty":
294
+ case "TSAbstractPropertyDefinition": {
295
+ if (node.computed) {
296
+ walk(node.key);
297
+ }
298
+ if (node.decorators) {
299
+ for (const decorator of node.decorators) walk(decorator);
300
+ }
301
+ if (node.value) walk(node.value);
302
+ return;
303
+ }
304
+ case "TSIndexSignature": {
305
+ return;
306
+ }
285
307
  case "Identifier": {
286
308
  resolveIdentifier(node.name);
287
309
  return;
@@ -35,7 +35,7 @@ function assertTransformed(transformed, name, what) {
35
35
  throw new Error(`[worklets] built empty ${what} code for ${name || "anonymous worklet"}`);
36
36
  }
37
37
  }
38
- function serializeWorkletForUI(fnNode, code, name, closureVars) {
38
+ function serializeWorkletForUI(fnNode, code, name, closureVars, reconstructions = []) {
39
39
  let rawParams = "";
40
40
  if (fnNode.params && fnNode.params.length > 0) {
41
41
  const pStart = fnNode.params[0].start;
@@ -52,11 +52,13 @@ function serializeWorkletForUI(fnNode, code, name, closureVars) {
52
52
  }
53
53
  const unpacker = closureVars.length > 0 ? `const [${closureVars.join(", ")}] = this.__closure;
54
54
  ` : "";
55
+ const rebuilt = reconstructions.length > 0 ? reconstructions.map(({ name: name2, factory }) => `const ${name2} = ${factory}();
56
+ `).join("") : "";
55
57
  const asyncPrefix = fnNode.async ? "async " : "";
56
58
  const genPrefix = fnNode.generator ? "*" : "";
57
59
  const fnName = name || "_worklet";
58
60
  const fullFn = `${asyncPrefix}function${genPrefix} ${fnName}(${rawParams}) {
59
- ${unpacker}${rawBody}
61
+ ${unpacker}${rebuilt}${rawBody}
60
62
  }`;
61
63
  const transformed = (0, import_oxc_transform.transformSync)("worklet.ts", fullFn);
62
64
  assertTransformed(transformed, name, "serialized");
@@ -35,6 +35,7 @@ var import_magic_string = __toESM(require("magic-string"), 1);
35
35
  var import_remapping = __toESM(require("@jridgewell/remapping"), 1);
36
36
  var import_oxc_parser = require("oxc-parser");
37
37
  var import_autoworklet = require("./autoworklet.cjs");
38
+ var import_classes = require("./classes.cjs");
38
39
  var import_globals = require("./globals.cjs");
39
40
  var import_hash = require("./hash.cjs");
40
41
  var import_scope = require("./scope.cjs");
@@ -108,7 +109,10 @@ function executeWorkletTransform(id, code, sourceMaps = false, options, resolveV
108
109
  throw new Error(err.codeframe || err.message || "Syntax Error while parsing worklet");
109
110
  }
110
111
  const initialCandidates = (0, import_autoworklet.findWorkletCandidates)(initialParse.program);
111
- if (initialCandidates.length === 0) {
112
+ const workletClassesEnabled = !options?.disableWorkletClasses && !options?.bundleMode;
113
+ const initialClasses = workletClassesEnabled ? (0, import_classes.findWorkletClasses)(initialParse.program) : [];
114
+ const resolvableClassNames = initialClasses.length > 0 ? (0, import_classes.findUnambiguousClassNames)(initialParse.program, initialClasses) : /* @__PURE__ */ new Set();
115
+ if (initialCandidates.length === 0 && initialClasses.length === 0) {
112
116
  let map2 = void 0;
113
117
  if (sourceMaps) {
114
118
  const ms = new import_magic_string.default(code);
@@ -133,6 +137,33 @@ function executeWorkletTransform(id, code, sourceMaps = false, options, resolveV
133
137
  let currentCode = code;
134
138
  const initDataDefs = /* @__PURE__ */ new Map();
135
139
  const passMaps = [];
140
+ if (initialClasses.length > 0) {
141
+ const ms = new import_magic_string.default(currentCode);
142
+ for (const candidate of initialClasses) {
143
+ const factoryDecl = (0, import_classes.buildClassFactoryDeclaration)(candidate, currentCode);
144
+ const rebound = `const ${candidate.name} = ${(0, import_classes.classFactoryName)(candidate.name)}();`;
145
+ if (candidate.parent?.type === "ExportNamedDeclaration") {
146
+ ms.overwrite(candidate.parent.start, candidate.parent.end, `${factoryDecl}
147
+ export ${rebound}`);
148
+ } else if (candidate.parent?.type === "ExportDefaultDeclaration") {
149
+ ms.overwrite(candidate.parent.start, candidate.parent.end, `${factoryDecl}
150
+ ${rebound}
151
+ export default ${candidate.name};`);
152
+ } else {
153
+ ms.overwrite(candidate.node.start, candidate.node.end, `${factoryDecl}
154
+ ${rebound}`);
155
+ }
156
+ }
157
+ if (sourceMaps) {
158
+ passMaps.push(ms.generateMap({
159
+ source: cleanId,
160
+ file: cleanId,
161
+ hires: true,
162
+ includeContent: true
163
+ }));
164
+ }
165
+ currentCode = ms.toString();
166
+ }
136
167
  let remainingPassBudget = 100;
137
168
  while (remainingPassBudget-- > 0) {
138
169
  const parseResult = (0, import_oxc_parser.parseSync)(cleanId, currentCode, {
@@ -156,9 +187,31 @@ function executeWorkletTransform(id, code, sourceMaps = false, options, resolveV
156
187
  const ms = new import_magic_string.default(currentCode);
157
188
  const inlinedInitData = /* @__PURE__ */ new Map();
158
189
  for (const candidate of innermostCandidates) {
159
- const closureVars = (0, import_autoworklet.hasDirective)(candidate.fnNode, "no-worklet-closure") ? [] : (0, import_scope.getClosureVariables)(candidate.fnNode, globals);
190
+ let closureVars = (0, import_autoworklet.hasDirective)(candidate.fnNode, "no-worklet-closure") ? [] : (0, import_scope.getClosureVariables)(candidate.fnNode, globals);
191
+ const reconstructions = [];
192
+ if (workletClassesEnabled && closureVars.length > 0) {
193
+ const captured = new Set(closureVars);
194
+ const rewriteToFactory = (name) => {
195
+ if (!captured.has(name)) return;
196
+ const factory = (0, import_classes.classFactoryName)(name);
197
+ captured.delete(name);
198
+ captured.add(factory);
199
+ if (!reconstructions.some((r) => r.factory === factory)) {
200
+ reconstructions.push({
201
+ name,
202
+ factory
203
+ });
204
+ }
205
+ };
206
+ const knownCaptures = [...captured].filter((name) => resolvableClassNames.has(name));
207
+ for (const name of knownCaptures) rewriteToFactory(name);
208
+ for (const constructed of (0, import_classes.findConstructedNames)(candidate.fnNode)) {
209
+ rewriteToFactory(constructed);
210
+ }
211
+ closureVars = [...captured].sort();
212
+ }
160
213
  const fnName = candidate.name;
161
- const serializedCode = (0, import_serialize.serializeWorkletForUI)(candidate.fnNode, currentCode, fnName, closureVars);
214
+ const serializedCode = (0, import_serialize.serializeWorkletForUI)(candidate.fnNode, currentCode, fnName, closureVars, reconstructions);
162
215
  const workletHash = (0, import_hash.calculateWorkletHash)(serializedCode);
163
216
  const initDataVar = `_worklet_${workletHash}_init_data`;
164
217
  const initDataDecl = `var ${initDataVar} = {
@@ -184,7 +237,8 @@ ${initDataDecl}
184
237
  }
185
238
  const localFnCode = (0, import_serialize.buildLocalFunction)(candidate.fnNode, currentCode, fnName);
186
239
  const localName = fnName || "_worklet";
187
- const closureValues = closureVars.join(", ");
240
+ const factoryOwners = new Map(reconstructions.map((r) => [r.factory, r.name]));
241
+ const closureValues = closureVars.map((v) => factoryOwners.has(v) ? `${factoryOwners.get(v)}.${v}` : v).join(", ");
188
242
  const iife = `(function () {
189
243
  var _e = [new (typeof global !== 'undefined' ? global : globalThis).Error(), 1, -27];
190
244
  var ${localName} = ${localFnCode};
@@ -11,6 +11,7 @@ import { executeWorkletTransform, prepareWorkletsForReactCompiler } from "./work
11
11
 
12
12
  const REANIMATED_AUTOWORKLETIZATION_KEYWORDS = [
13
13
  "worklet",
14
+ "__workletClass",
14
15
  "useAnimatedGestureHandler",
15
16
  "useAnimatedScrollHandler",
16
17
  "useFrameCallback",
@@ -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 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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"}
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 // a marked class in its own file carries no worklet keyword, but importing\n // files reconstruct it from its factory, so the defining file must reach\n // the transform too.\n \"__workletClass\",\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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"}
@@ -0,0 +1,170 @@
1
+ const WORKLET_CLASS_MARKER = "__workletClass";
2
+ const WORKLET_CLASS_FACTORY_SUFFIX = "__classFactory";
3
+ const MARKER_FIELD_TYPES = /* @__PURE__ */ new Set([
4
+ "PropertyDefinition",
5
+ "AccessorProperty",
6
+ "TSAbstractPropertyDefinition"
7
+ ]);
8
+ function isMarkerField(element) {
9
+ return MARKER_FIELD_TYPES.has(element?.type) && !element.computed && element.key?.type === "Identifier" && element.key.name === "__workletClass";
10
+ }
11
+ function findWorkletClasses(program) {
12
+ const candidates = [];
13
+ function walk(node, parent) {
14
+ if (!node || typeof node !== "object") return;
15
+ if (node.type === "ClassDeclaration" && node.id?.type === "Identifier" && !node.declare && !(node.decorators?.length > 0)) {
16
+ const marker = node.body?.body?.find(isMarkerField);
17
+ if (marker) {
18
+ candidates.push({
19
+ node,
20
+ name: node.id.name,
21
+ parent,
22
+ marker
23
+ });
24
+ }
25
+ }
26
+ for (const key of Object.keys(node)) {
27
+ if (key === "start" || key === "end" || key === "loc" || key === "range") continue;
28
+ const child = node[key];
29
+ if (Array.isArray(child)) {
30
+ for (const item of child) walk(item, node);
31
+ } else if (child && typeof child === "object") {
32
+ walk(child, node);
33
+ }
34
+ }
35
+ }
36
+ walk(program, null);
37
+ return candidates.filter((candidate) => !candidates.some((other) => other !== candidate && other.node.start <= candidate.node.start && other.node.end >= candidate.node.end));
38
+ }
39
+ function classFactoryName(className) {
40
+ return `${className}${WORKLET_CLASS_FACTORY_SUFFIX}`;
41
+ }
42
+ function collectPatternNames(pattern, count) {
43
+ if (!pattern || typeof pattern !== "object") return;
44
+ switch (pattern.type) {
45
+ case "Identifier":
46
+ count(pattern.name);
47
+ return;
48
+ case "AssignmentPattern":
49
+ collectPatternNames(pattern.left, count);
50
+ return;
51
+ case "RestElement":
52
+ collectPatternNames(pattern.argument, count);
53
+ return;
54
+ case "ArrayPattern":
55
+ for (const element of pattern.elements ?? []) collectPatternNames(element, count);
56
+ return;
57
+ case "ObjectPattern":
58
+ for (const property of pattern.properties ?? []) {
59
+ if (property?.type === "Property") collectPatternNames(property.value, count);
60
+ else if (property?.type === "RestElement") collectPatternNames(property.argument, count);
61
+ }
62
+ return;
63
+ case "TSParameterProperty":
64
+ collectPatternNames(pattern.parameter, count);
65
+ return;
66
+ }
67
+ }
68
+ function findUnambiguousClassNames(program, candidates) {
69
+ const wanted = new Set(candidates.map((candidate) => candidate.name));
70
+ const counts = /* @__PURE__ */ new Map();
71
+ const count = (name) => {
72
+ if (wanted.has(name)) counts.set(name, (counts.get(name) ?? 0) + 1);
73
+ };
74
+ function walk(node) {
75
+ if (!node || typeof node !== "object") return;
76
+ if (Array.isArray(node)) {
77
+ for (const item of node) walk(item);
78
+ return;
79
+ }
80
+ switch (node.type) {
81
+ case "VariableDeclarator":
82
+ collectPatternNames(node.id, count);
83
+ break;
84
+ case "FunctionDeclaration":
85
+ case "FunctionExpression":
86
+ if (node.id?.type === "Identifier") count(node.id.name);
87
+ for (const param of node.params ?? []) collectPatternNames(param, count);
88
+ break;
89
+ case "ArrowFunctionExpression":
90
+ for (const param of node.params ?? []) collectPatternNames(param, count);
91
+ break;
92
+ case "ClassDeclaration":
93
+ case "ClassExpression":
94
+ if (node.id?.type === "Identifier") count(node.id.name);
95
+ break;
96
+ case "CatchClause":
97
+ collectPatternNames(node.param, count);
98
+ break;
99
+ case "ImportSpecifier":
100
+ case "ImportDefaultSpecifier":
101
+ case "ImportNamespaceSpecifier":
102
+ if (node.local?.type === "Identifier") count(node.local.name);
103
+ break;
104
+ case "TSEnumDeclaration":
105
+ case "TSModuleDeclaration":
106
+ if (node.id?.type === "Identifier") count(node.id.name);
107
+ break;
108
+ }
109
+ for (const key of Object.keys(node)) {
110
+ if (key === "start" || key === "end" || key === "loc" || key === "range") continue;
111
+ walk(node[key]);
112
+ }
113
+ }
114
+ walk(program);
115
+ return new Set(candidates.filter((candidate) => counts.get(candidate.name) === 1).map((c) => c.name));
116
+ }
117
+ const ABSTRACT_MEMBER_TYPES = /* @__PURE__ */ new Set(["TSAbstractMethodDefinition", "TSAbstractPropertyDefinition"]);
118
+ function buildClassFactoryDeclaration(candidate, code) {
119
+ const { node, name, marker } = candidate;
120
+ const factory = classFactoryName(name);
121
+ const removals = [[marker.decorators?.[0]?.start ?? marker.start, marker.end]];
122
+ for (const element of node.body?.body ?? []) {
123
+ if (ABSTRACT_MEMBER_TYPES.has(element?.type)) {
124
+ removals.push([element.start, element.end]);
125
+ }
126
+ }
127
+ removals.sort((a, b) => a[0] - b[0]);
128
+ let classSrc = "";
129
+ let cursor = node.start;
130
+ for (const [start, end] of removals) {
131
+ if (start < cursor) continue;
132
+ classSrc += code.slice(cursor, start);
133
+ cursor = end;
134
+ }
135
+ classSrc += code.slice(cursor, node.end);
136
+ const classExpr = classSrc.replace(/^abstract\s+/, "");
137
+ return [
138
+ `function ${factory}() {`,
139
+ `'worklet';`,
140
+ `const ${name} = ${classExpr};`,
141
+ `${name}.${factory} = ${factory};`,
142
+ `return ${name};`,
143
+ `}`
144
+ ].join("\n");
145
+ }
146
+ function findConstructedNames(fnNode) {
147
+ const names = [];
148
+ const seen = /* @__PURE__ */ new Set();
149
+ function walk(node) {
150
+ if (!node || typeof node !== "object") return;
151
+ if (Array.isArray(node)) {
152
+ for (const item of node) walk(item);
153
+ return;
154
+ }
155
+ if (node.type === "NewExpression" && node.callee?.type === "Identifier" && !seen.has(node.callee.name)) {
156
+ seen.add(node.callee.name);
157
+ names.push(node.callee.name);
158
+ }
159
+ for (const key of Object.keys(node)) {
160
+ if (key === "start" || key === "end" || key === "loc" || key === "range") continue;
161
+ walk(node[key]);
162
+ }
163
+ }
164
+ walk(fnNode.body);
165
+ for (const param of fnNode.params ?? []) walk(param);
166
+ return names;
167
+ }
168
+
169
+ export { WORKLET_CLASS_FACTORY_SUFFIX, WORKLET_CLASS_MARKER, buildClassFactoryDeclaration, classFactoryName, findConstructedNames, findUnambiguousClassNames, findWorkletClasses };
170
+ //# sourceMappingURL=classes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classes.js","names":[],"sources":["esm/worklets/classes.js"],"sourcesContent":["const WORKLET_CLASS_MARKER = \"__workletClass\";\nconst WORKLET_CLASS_FACTORY_SUFFIX = \"__classFactory\";\nconst MARKER_FIELD_TYPES = /* @__PURE__ */ new Set([\n \"PropertyDefinition\",\n \"AccessorProperty\",\n \"TSAbstractPropertyDefinition\"\n]);\nfunction isMarkerField(element) {\n return MARKER_FIELD_TYPES.has(element?.type) && !element.computed && element.key?.type === \"Identifier\" && element.key.name === WORKLET_CLASS_MARKER;\n}\nfunction findWorkletClasses(program) {\n const candidates = [];\n function walk(node, parent) {\n if (!node || typeof node !== \"object\") return;\n if (node.type === \"ClassDeclaration\" && node.id?.type === \"Identifier\" && !node.declare && // class-level decorators sit outside the class range upstream's factory\n // shape can carry, so decorated classes keep today's raw capture.\n !(node.decorators?.length > 0)) {\n const marker = node.body?.body?.find(isMarkerField);\n if (marker) {\n candidates.push({ node, name: node.id.name, parent, marker });\n }\n }\n for (const key of Object.keys(node)) {\n if (key === \"start\" || key === \"end\" || key === \"loc\" || key === \"range\") continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) walk(item, node);\n } else if (child && typeof child === \"object\") {\n walk(child, node);\n }\n }\n }\n walk(program, null);\n return candidates.filter(\n (candidate) => !candidates.some(\n (other) => other !== candidate && other.node.start <= candidate.node.start && other.node.end >= candidate.node.end\n )\n );\n}\nfunction classFactoryName(className) {\n return `${className}${WORKLET_CLASS_FACTORY_SUFFIX}`;\n}\nfunction collectPatternNames(pattern, count) {\n if (!pattern || typeof pattern !== \"object\") return;\n switch (pattern.type) {\n case \"Identifier\":\n count(pattern.name);\n return;\n case \"AssignmentPattern\":\n collectPatternNames(pattern.left, count);\n return;\n case \"RestElement\":\n collectPatternNames(pattern.argument, count);\n return;\n case \"ArrayPattern\":\n for (const element of pattern.elements ?? []) collectPatternNames(element, count);\n return;\n case \"ObjectPattern\":\n for (const property of pattern.properties ?? []) {\n if (property?.type === \"Property\") collectPatternNames(property.value, count);\n else if (property?.type === \"RestElement\")\n collectPatternNames(property.argument, count);\n }\n return;\n case \"TSParameterProperty\":\n collectPatternNames(pattern.parameter, count);\n return;\n }\n}\nfunction findUnambiguousClassNames(program, candidates) {\n const wanted = new Set(candidates.map((candidate) => candidate.name));\n const counts = /* @__PURE__ */ new Map();\n const count = (name) => {\n if (wanted.has(name)) counts.set(name, (counts.get(name) ?? 0) + 1);\n };\n function walk(node) {\n if (!node || typeof node !== \"object\") return;\n if (Array.isArray(node)) {\n for (const item of node) walk(item);\n return;\n }\n switch (node.type) {\n case \"VariableDeclarator\":\n collectPatternNames(node.id, count);\n break;\n case \"FunctionDeclaration\":\n case \"FunctionExpression\":\n if (node.id?.type === \"Identifier\") count(node.id.name);\n for (const param of node.params ?? []) collectPatternNames(param, count);\n break;\n case \"ArrowFunctionExpression\":\n for (const param of node.params ?? []) collectPatternNames(param, count);\n break;\n case \"ClassDeclaration\":\n case \"ClassExpression\":\n if (node.id?.type === \"Identifier\") count(node.id.name);\n break;\n case \"CatchClause\":\n collectPatternNames(node.param, count);\n break;\n case \"ImportSpecifier\":\n case \"ImportDefaultSpecifier\":\n case \"ImportNamespaceSpecifier\":\n if (node.local?.type === \"Identifier\") count(node.local.name);\n break;\n case \"TSEnumDeclaration\":\n case \"TSModuleDeclaration\":\n if (node.id?.type === \"Identifier\") count(node.id.name);\n break;\n }\n for (const key of Object.keys(node)) {\n if (key === \"start\" || key === \"end\" || key === \"loc\" || key === \"range\") continue;\n walk(node[key]);\n }\n }\n walk(program);\n return new Set(\n candidates.filter((candidate) => counts.get(candidate.name) === 1).map((c) => c.name)\n );\n}\nconst ABSTRACT_MEMBER_TYPES = /* @__PURE__ */ new Set([\n \"TSAbstractMethodDefinition\",\n \"TSAbstractPropertyDefinition\"\n]);\nfunction buildClassFactoryDeclaration(candidate, code) {\n const { node, name, marker } = candidate;\n const factory = classFactoryName(name);\n const removals = [\n [marker.decorators?.[0]?.start ?? marker.start, marker.end]\n ];\n for (const element of node.body?.body ?? []) {\n if (ABSTRACT_MEMBER_TYPES.has(element?.type)) {\n removals.push([element.start, element.end]);\n }\n }\n removals.sort((a, b) => a[0] - b[0]);\n let classSrc = \"\";\n let cursor = node.start;\n for (const [start, end] of removals) {\n if (start < cursor) continue;\n classSrc += code.slice(cursor, start);\n cursor = end;\n }\n classSrc += code.slice(cursor, node.end);\n const classExpr = classSrc.replace(/^abstract\\s+/, \"\");\n return [\n `function ${factory}() {`,\n `'worklet';`,\n `const ${name} = ${classExpr};`,\n `${name}.${factory} = ${factory};`,\n `return ${name};`,\n `}`\n ].join(\"\\n\");\n}\nfunction findConstructedNames(fnNode) {\n const names = [];\n const seen = /* @__PURE__ */ new Set();\n function walk(node) {\n if (!node || typeof node !== \"object\") return;\n if (Array.isArray(node)) {\n for (const item of node) walk(item);\n return;\n }\n if (node.type === \"NewExpression\" && node.callee?.type === \"Identifier\" && !seen.has(node.callee.name)) {\n seen.add(node.callee.name);\n names.push(node.callee.name);\n }\n for (const key of Object.keys(node)) {\n if (key === \"start\" || key === \"end\" || key === \"loc\" || key === \"range\") continue;\n walk(node[key]);\n }\n }\n walk(fnNode.body);\n for (const param of fnNode.params ?? []) walk(param);\n return names;\n}\nexport {\n WORKLET_CLASS_FACTORY_SUFFIX,\n WORKLET_CLASS_MARKER,\n buildClassFactoryDeclaration,\n classFactoryName,\n findConstructedNames,\n findUnambiguousClassNames,\n findWorkletClasses\n};\n//# sourceMappingURL=classes.js.map\n"],"mappings":"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"}
@@ -232,6 +232,9 @@ function getClosureVariables(fnNode, globals) {
232
232
  if (node.id && node.id.name) {
233
233
  currentScope.bindings.add(node.id.name);
234
234
  }
235
+ if (node.decorators) {
236
+ for (const decorator of node.decorators) walk(decorator);
237
+ }
235
238
  if (node.superClass) walk(node.superClass);
236
239
  pushScope(false);
237
240
  walk(node.body);
@@ -252,13 +255,32 @@ function getClosureVariables(fnNode, globals) {
252
255
  walk(node.value);
253
256
  return;
254
257
  }
255
- case "MethodDefinition": {
258
+ case "MethodDefinition":
259
+ case "TSAbstractMethodDefinition": {
256
260
  if (node.computed) {
257
261
  walk(node.key);
258
262
  }
263
+ if (node.decorators) {
264
+ for (const decorator of node.decorators) walk(decorator);
265
+ }
259
266
  walk(node.value);
260
267
  return;
261
268
  }
269
+ case "PropertyDefinition":
270
+ case "AccessorProperty":
271
+ case "TSAbstractPropertyDefinition": {
272
+ if (node.computed) {
273
+ walk(node.key);
274
+ }
275
+ if (node.decorators) {
276
+ for (const decorator of node.decorators) walk(decorator);
277
+ }
278
+ if (node.value) walk(node.value);
279
+ return;
280
+ }
281
+ case "TSIndexSignature": {
282
+ return;
283
+ }
262
284
  case "Identifier": {
263
285
  resolveIdentifier(node.name);
264
286
  return;