@rn-org/react-native-thread 0.5.0 → 0.6.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/README.md +143 -22
- package/lib/module/babel-plugin.js +328 -2
- package/lib/module/babel-plugin.js.map +1 -1
- package/lib/module/index.js +59 -8
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/babel-plugin.js +411 -2
- package/src/index.tsx +83 -12
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Run JavaScript on real background threads in React Native — no Workers, no Wor
|
|
|
19
19
|
- [destroyThread](#destroythread)
|
|
20
20
|
- [onMessage](#onmessage)
|
|
21
21
|
- [ThreadHandle](#threadhandle)
|
|
22
|
+
- [ThreadError](#threaderror)
|
|
22
23
|
- [ThreadInfo](#threadinfo)
|
|
23
24
|
- [ThreadTask](#threadtask)
|
|
24
25
|
- [Thread globals](#thread-globals)
|
|
@@ -26,6 +27,12 @@ Run JavaScript on real background threads in React Native — no Workers, no Wor
|
|
|
26
27
|
- [console](#console)
|
|
27
28
|
- [`__params__`](#__params__)
|
|
28
29
|
- [Hermes & Babel plugin](#hermes--babel-plugin-deep-dive)
|
|
30
|
+
- [Task function](#task-function-first-argument)
|
|
31
|
+
- [Function params](#function-params-second-argument)
|
|
32
|
+
- [Cross-module imports](#cross-module-imports)
|
|
33
|
+
- [Supported call sites](#supported-call-sites)
|
|
34
|
+
- [What the plugin captures](#what-the-plugin-captures-in-params)
|
|
35
|
+
- [Limitations](#limitations)
|
|
29
36
|
- [Constraints](#constraints)
|
|
30
37
|
- [Contributing](#contributing)
|
|
31
38
|
- [License](#license)
|
|
@@ -38,8 +45,11 @@ Run JavaScript on real background threads in React Native — no Workers, no Wor
|
|
|
38
45
|
- **Unlimited threads** — create as many threads as you need; each is isolated.
|
|
39
46
|
- **Shared thread** (`runOnJS`) — fire-and-forget tasks on a single persistent background thread; no teardown required.
|
|
40
47
|
- **Per-thread message passing** — call `resolveThreadMessage(data)` from any thread, receive it on the main thread with `onMessage` (callback or `await`).
|
|
41
|
-
- **Parameter injection** — pass
|
|
48
|
+
- **Parameter injection** — pass values from the main thread into the background function as a typed argument `(args) => { ... }`. Supports primitives, objects, arrays, **and functions**.
|
|
49
|
+
- **Function params** — pass functions (including imported ones) alongside plain data in the params object. The Babel plugin extracts their source at compile time, captures closed-over variables transitively, and downlevels to ES5 for Rhino compatibility.
|
|
50
|
+
- **Cross-module function params** — functions imported from other files (e.g. `import { compute } from './math'`) are automatically resolved and inlined by the Babel plugin.
|
|
42
51
|
- **Named threads** — give threads friendly names; list or destroy them by name.
|
|
52
|
+
- **Error handling** — thread exceptions are automatically caught and forwarded to the main thread. Use `onError` or `.catch()` on the `onMessage()` promise.
|
|
43
53
|
- **Full `console` support** — `console.log/info/warn/error/debug` work inside threads and appear in Logcat / Xcode logs.
|
|
44
54
|
- **Hermes-safe** — ships a Babel plugin that extracts function source at compile time so Hermes bytecode never breaks serialisation.
|
|
45
55
|
- **New Architecture only** — built on the TurboModule / Codegen pipeline.
|
|
@@ -77,7 +87,14 @@ cd ios && pod install
|
|
|
77
87
|
|
|
78
88
|
## Babel plugin (required for Hermes)
|
|
79
89
|
|
|
80
|
-
Hermes compiles your JS to bytecode at build time. That means `fn.toString()` at runtime returns a placeholder (`"function () { [bytecode] }"`) instead of source code. The library includes a Babel plugin that
|
|
90
|
+
Hermes compiles your JS to bytecode at build time. That means `fn.toString()` at runtime returns a placeholder (`"function () { [bytecode] }"`) instead of source code. The library includes a Babel plugin that:
|
|
91
|
+
|
|
92
|
+
1. Extracts the **task function** (first argument) source at compile time and replaces it with a string literal.
|
|
93
|
+
2. Detects **function-valued properties** in the params object (second argument) and inlines their source.
|
|
94
|
+
3. **Captures closed-over variables** transitively — if a function references outer `const`/`let`/`var` bindings (literals or other functions), those are bundled into a self-contained IIFE.
|
|
95
|
+
4. **Resolves cross-module imports** — functions imported from relative paths (e.g. `import { fn } from './utils'`) are read from disk and inlined.
|
|
96
|
+
5. **Downlevels ES6+ to ES5** — arrow functions, `let`/`const`, template literals, etc. are transpiled for Rhino (Android's JS engine).
|
|
97
|
+
6. **Strips TypeScript** annotations automatically when the source file is `.ts` or `.tsx`.
|
|
81
98
|
|
|
82
99
|
Add the plugin to your app's `babel.config.js`:
|
|
83
100
|
|
|
@@ -109,7 +126,7 @@ runOnJS((args) => {
|
|
|
109
126
|
// ── 2. Create a named, persistent thread ────────────────────────────────────
|
|
110
127
|
const thread = createThread('MyThread');
|
|
111
128
|
|
|
112
|
-
// Send work + params
|
|
129
|
+
// Send work + params (including plain values)
|
|
113
130
|
thread.run(
|
|
114
131
|
(args) => {
|
|
115
132
|
var result = 0;
|
|
@@ -119,6 +136,40 @@ thread.run(
|
|
|
119
136
|
{ limit: 1_000_000 }
|
|
120
137
|
);
|
|
121
138
|
|
|
139
|
+
// ── 2b. Pass functions as params ────────────────────────────────────────────
|
|
140
|
+
function multiply(a, b) {
|
|
141
|
+
return a * b;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
thread.run(
|
|
145
|
+
(args) => {
|
|
146
|
+
const result = args.multiply(args.x, args.y);
|
|
147
|
+
resolveThreadMessage(result);
|
|
148
|
+
},
|
|
149
|
+
{ x: 6, y: 7, multiply }
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// Functions that close over outer variables work too:
|
|
153
|
+
const factor = 10;
|
|
154
|
+
const scale = (n) => n * factor;
|
|
155
|
+
|
|
156
|
+
thread.run(
|
|
157
|
+
(args) => {
|
|
158
|
+
resolveThreadMessage(args.scale(5)); // 50
|
|
159
|
+
},
|
|
160
|
+
{ scale }
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
// Imported functions are also supported:
|
|
164
|
+
import { checkEvenOdd } from './utils';
|
|
165
|
+
|
|
166
|
+
thread.run(
|
|
167
|
+
(args) => {
|
|
168
|
+
resolveThreadMessage(args.checkEvenOdd(args.num));
|
|
169
|
+
},
|
|
170
|
+
{ num: 42, checkEvenOdd }
|
|
171
|
+
);
|
|
172
|
+
|
|
122
173
|
// Option A — callback
|
|
123
174
|
const unsubscribe = thread.onMessage((data) => {
|
|
124
175
|
console.log('Result from thread:', data);
|
|
@@ -262,10 +313,12 @@ type ThreadHandle = {
|
|
|
262
313
|
readonly id: number;
|
|
263
314
|
readonly name: string;
|
|
264
315
|
run(task: ThreadTask, params?: unknown): void;
|
|
265
|
-
/** Callback variant — fires on every message. Returns unsubscribe fn. */
|
|
316
|
+
/** Callback variant — fires on every successful message. Returns unsubscribe fn. */
|
|
266
317
|
onMessage(handler: (data: unknown) => void): () => void;
|
|
267
|
-
/** Promise variant — resolves on
|
|
318
|
+
/** Promise variant — resolves on success, rejects on thread error. */
|
|
268
319
|
onMessage(): Promise<unknown>;
|
|
320
|
+
/** Subscribe to errors thrown inside this thread. Returns unsubscribe fn. */
|
|
321
|
+
onError(handler: (error: ThreadError) => void): () => void;
|
|
269
322
|
destroy(): void;
|
|
270
323
|
};
|
|
271
324
|
```
|
|
@@ -275,12 +328,26 @@ type ThreadHandle = {
|
|
|
275
328
|
| `id` | Numeric ID assigned by the native layer. |
|
|
276
329
|
| `name` | Display name provided at creation (or the default `RNThread-<id>`). |
|
|
277
330
|
| `run(task, params?)` | Execute `task` on this thread. `params` is passed as the first argument to the function. Can be called multiple times. |
|
|
278
|
-
| `onMessage(handler)` | Subscribe to `resolveThreadMessage` output from **this thread only**. Returns an unsubscribe function. |
|
|
279
|
-
| `onMessage()` | Returns a `Promise` that resolves with the next message from **this thread only**,
|
|
331
|
+
| `onMessage(handler)` | Subscribe to `resolveThreadMessage` output from **this thread only**. Error messages are filtered out. Returns an unsubscribe function. |
|
|
332
|
+
| `onMessage()` | Returns a `Promise` that resolves with the next message from **this thread only**, or **rejects** with an `Error` if the thread threw. Auto-unsubscribes. |
|
|
333
|
+
| `onError(handler)` | Subscribe to uncaught exceptions from **this thread only**. The handler receives a `ThreadError` with `message` and `stack`. Returns an unsubscribe function. |
|
|
280
334
|
| `destroy()` | Shut down the thread and remove it from the registry. Equivalent to calling `destroyThread(handle.id)`. |
|
|
281
335
|
|
|
282
336
|
---
|
|
283
337
|
|
|
338
|
+
### `ThreadError`
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
type ThreadError = {
|
|
342
|
+
message: string;
|
|
343
|
+
stack: string;
|
|
344
|
+
};
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Received by `ThreadHandle.onError` when a thread throws an uncaught exception. The `message` is the error's `.message` and `stack` is the `.stack` trace from the thread engine.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
284
351
|
### `ThreadInfo`
|
|
285
352
|
|
|
286
353
|
```ts
|
|
@@ -398,35 +465,87 @@ Because this library must *serialise* functions to strings and send them to a se
|
|
|
398
465
|
|
|
399
466
|
### The solution
|
|
400
467
|
|
|
401
|
-
The included Babel plugin runs at **compile time** — before Hermes touches the code — and
|
|
468
|
+
The included Babel plugin runs at **compile time** — before Hermes touches the code — and transforms both the task function and function-valued params.
|
|
469
|
+
|
|
470
|
+
#### Task function (first argument)
|
|
471
|
+
|
|
472
|
+
Arrow functions and function expressions are replaced with an ES5-downleveled string literal wrapped as an IIFE:
|
|
402
473
|
|
|
403
474
|
```js
|
|
404
475
|
// Input (your source)
|
|
405
476
|
thread.run((args) => {
|
|
406
|
-
resolveThreadMessage(args.
|
|
407
|
-
}, {
|
|
477
|
+
resolveThreadMessage(`${args.num} is great`);
|
|
478
|
+
}, { num: 42 });
|
|
408
479
|
|
|
409
480
|
// Output (what Hermes compiles)
|
|
410
|
-
thread.run("((args)
|
|
481
|
+
thread.run("((function (args) {\n resolveThreadMessage(\"\".concat(args.num, \" is great\"));\n}))(__params__)", { num: 42 });
|
|
411
482
|
```
|
|
412
483
|
|
|
413
|
-
|
|
484
|
+
#### Function params (second argument)
|
|
485
|
+
|
|
486
|
+
Functions passed inside the params object are detected, extracted, and tagged with `{ __rnThreadFn: "<source>" }`. The runtime serializer emits the source directly into the thread code.
|
|
487
|
+
|
|
488
|
+
```js
|
|
489
|
+
// Input
|
|
490
|
+
const b = 3;
|
|
491
|
+
const add = (x) => x + b;
|
|
492
|
+
function multiply(a) {
|
|
493
|
+
return add(a) * 2;
|
|
494
|
+
}
|
|
495
|
+
thread.run(fn, { multiply });
|
|
496
|
+
|
|
497
|
+
// Output — transitive closures are captured in a self-contained IIFE
|
|
498
|
+
thread.run(fn, {
|
|
499
|
+
multiply: {
|
|
500
|
+
__rnThreadFn: "(function(){ var b = 3;\nvar add = function(x) { return x + b; };\nreturn function multiply(a) { return add(a) * 2; };})()"
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
#### Cross-module imports
|
|
506
|
+
|
|
507
|
+
Functions imported from relative paths are resolved from disk, parsed, and inlined:
|
|
508
|
+
|
|
509
|
+
```js
|
|
510
|
+
// utils.ts
|
|
511
|
+
export function checkEvenOdd(num: number): string {
|
|
512
|
+
return num % 2 === 0 ? 'Even' : 'Odd';
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// App.tsx
|
|
516
|
+
import { checkEvenOdd } from './utils';
|
|
517
|
+
thread.run(fn, { checkEvenOdd });
|
|
518
|
+
// → checkEvenOdd is inlined with TypeScript stripped and ES5-downleveled
|
|
519
|
+
```
|
|
414
520
|
|
|
415
521
|
### Supported call sites
|
|
416
522
|
|
|
417
|
-
| Pattern |
|
|
523
|
+
| Pattern | Task transformed | Params transformed |
|
|
524
|
+
|---|---|---|
|
|
525
|
+
| `runOnJS(() => { ... }, { fn })` | Yes | Yes |
|
|
526
|
+
| `runOnNewJS(() => { ... }, { fn })` | Yes | Yes |
|
|
527
|
+
| `anyHandle.run(() => { ... }, { fn })` | Yes | Yes |
|
|
528
|
+
| Raw code string `run("...", { fn })` | No (already a string) | Yes |
|
|
529
|
+
|
|
530
|
+
### What the plugin captures in params
|
|
531
|
+
|
|
532
|
+
| Value type | Captured |
|
|
418
533
|
|---|---|
|
|
419
|
-
|
|
|
420
|
-
|
|
|
421
|
-
| `
|
|
422
|
-
|
|
|
534
|
+
| Inline arrow / function expression | Yes |
|
|
535
|
+
| Reference to local `function` declaration | Yes |
|
|
536
|
+
| Reference to local `const fn = () => ...` | Yes |
|
|
537
|
+
| Imported function (`import { fn } from './mod'`) | Yes (relative paths only) |
|
|
538
|
+
| Closed-over `const`/`let`/`var` with literal init | Yes (transitively) |
|
|
539
|
+
| Closed-over function references | Yes (transitively) |
|
|
540
|
+
| Runtime-computed values, `Map`, `Set`, classes | No — pass as plain params |
|
|
423
541
|
|
|
424
542
|
### Limitations
|
|
425
543
|
|
|
426
|
-
-
|
|
427
|
-
-
|
|
544
|
+
- **Captured closures must be statically resolvable**: only variables initialized with literals and functions (local or imported) are captured. Runtime-computed values (e.g. `const x = fetchValue()`) must be passed explicitly as params.
|
|
545
|
+
- **Cross-module resolution** only follows **relative imports** (e.g. `'./utils'`). Package imports (e.g. `'lodash'`) are not resolved.
|
|
428
546
|
- Thread function bodies must be **ASCII-safe**: Rhino (Android) does not support non-ASCII identifier characters in source mode.
|
|
429
|
-
-
|
|
547
|
+
- `undefined`, `Map`, `Set`, and class instances are not serialisable as param values — use plain objects, arrays, strings, numbers, booleans, or `null`.
|
|
548
|
+
- Thread functions run in an **isolated JS engine** with no access to the React tree, native modules, or the main thread's global scope.
|
|
430
549
|
|
|
431
550
|
---
|
|
432
551
|
|
|
@@ -434,9 +553,11 @@ The second `params` argument is left untouched; only the first (function) argume
|
|
|
434
553
|
|
|
435
554
|
| Constraint | Reason |
|
|
436
555
|
|---|---|
|
|
437
|
-
|
|
|
438
|
-
|
|
|
556
|
+
| Thread functions run in isolation | They execute in a completely separate JS engine |
|
|
557
|
+
| Function params must be statically resolvable | The Babel plugin extracts source at compile time |
|
|
558
|
+
| Non-function `params` must be JSON-serialisable | Serialised via `JSON.stringify` at runtime |
|
|
439
559
|
| `resolveThreadMessage` payload must be JSON-serialisable | Transported as a JSON string over the bridge |
|
|
560
|
+
| Cross-module resolution is relative-only | The plugin reads files from disk using the import path |
|
|
440
561
|
| Function body must be ASCII-safe | Rhino parser limitation |
|
|
441
562
|
| New Architecture required | TurboModule / Codegen only; no bridge fallback |
|
|
442
563
|
|
|
@@ -1,19 +1,339 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const nodePath = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
3
5
|
const TOP_LEVEL_API = new Set(['runOnJS', 'runOnNewJS']);
|
|
4
6
|
const METHOD_API = new Set(['run']);
|
|
7
|
+
const SKIP_KEYS = new Set(['type', 'start', 'end', 'loc', 'leadingComments', 'trailingComments', 'innerComments', 'extra', 'range']);
|
|
5
8
|
module.exports = function reactNativeThreadPlugin({
|
|
6
|
-
types: t
|
|
9
|
+
types: t,
|
|
10
|
+
...babel
|
|
7
11
|
}) {
|
|
12
|
+
const parser = babel.parser && babel.parser || require('@babel/parser');
|
|
13
|
+
|
|
14
|
+
// ── Cross-module import resolution ─────────────────────────────
|
|
15
|
+
|
|
16
|
+
const RESOLVE_EXTS = ['.ts', '.tsx', '.js', '.jsx', ''];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Given a relative import source (e.g. './Utility') and the
|
|
20
|
+
* filename of the importing file, try to resolve, read, parse,
|
|
21
|
+
* and extract the source of the named export `exportName`.
|
|
22
|
+
*
|
|
23
|
+
* Returns the raw function source string or null.
|
|
24
|
+
*/
|
|
25
|
+
function resolveImportedFnSource(importSource, exportName, state) {
|
|
26
|
+
const currentFile = state.filename || state.file.opts.filename;
|
|
27
|
+
if (!currentFile || !importSource.startsWith('.')) return null;
|
|
28
|
+
const dir = nodePath.dirname(currentFile);
|
|
29
|
+
let resolvedFile = null;
|
|
30
|
+
for (const ext of RESOLVE_EXTS) {
|
|
31
|
+
const candidate = nodePath.resolve(dir, importSource + ext);
|
|
32
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
|
|
33
|
+
resolvedFile = candidate;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!resolvedFile) {
|
|
38
|
+
// Try as directory with index file
|
|
39
|
+
for (const ext of RESOLVE_EXTS) {
|
|
40
|
+
const candidate = nodePath.resolve(dir, importSource, 'index' + ext);
|
|
41
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
|
|
42
|
+
resolvedFile = candidate;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!resolvedFile) return null;
|
|
48
|
+
let source;
|
|
49
|
+
try {
|
|
50
|
+
source = fs.readFileSync(resolvedFile, 'utf8');
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
let ast;
|
|
55
|
+
try {
|
|
56
|
+
ast = parser.parse(source, {
|
|
57
|
+
sourceType: 'module',
|
|
58
|
+
plugins: ['typescript', 'jsx']
|
|
59
|
+
});
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Walk top-level statements to find the exported function
|
|
65
|
+
for (const stmt of ast.program.body) {
|
|
66
|
+
// export function foo() { ... }
|
|
67
|
+
if (t.isExportNamedDeclaration(stmt) && stmt.declaration) {
|
|
68
|
+
if (t.isFunctionDeclaration(stmt.declaration) && stmt.declaration.id && stmt.declaration.id.name === exportName) {
|
|
69
|
+
const raw = source.slice(stmt.declaration.start, stmt.declaration.end);
|
|
70
|
+
return transpileForThread(raw, {
|
|
71
|
+
filename: resolvedFile
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// export const foo = () => { ... }
|
|
75
|
+
if (t.isVariableDeclaration(stmt.declaration)) {
|
|
76
|
+
for (const decl of stmt.declaration.declarations) {
|
|
77
|
+
if (t.isVariableDeclarator(decl) && t.isIdentifier(decl.id) && decl.id.name === exportName && decl.init && (t.isFunctionExpression(decl.init) || t.isArrowFunctionExpression(decl.init))) {
|
|
78
|
+
const raw = source.slice(decl.init.start, decl.init.end);
|
|
79
|
+
return transpileForThread(raw, {
|
|
80
|
+
filename: resolvedFile
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ── AST helpers ────────────────────────────────────────────────
|
|
91
|
+
|
|
92
|
+
/** Collect all identifiers that appear in reference position inside `node`. */
|
|
93
|
+
function collectReferencedIds(node) {
|
|
94
|
+
const ids = new Set();
|
|
95
|
+
function walk(n, skipId) {
|
|
96
|
+
if (!n || typeof n !== 'object') return;
|
|
97
|
+
if (Array.isArray(n)) {
|
|
98
|
+
n.forEach(el => walk(el, false));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (!n.type) return;
|
|
102
|
+
if (t.isIdentifier(n) && !skipId) {
|
|
103
|
+
ids.add(n.name);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (t.isMemberExpression(n)) {
|
|
107
|
+
walk(n.object, false);
|
|
108
|
+
if (n.computed) walk(n.property, false);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (t.isObjectProperty(n)) {
|
|
112
|
+
if (n.computed) walk(n.key, false);
|
|
113
|
+
walk(n.value, false);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (t.isFunctionExpression(n) || t.isArrowFunctionExpression(n) || t.isFunctionDeclaration(n)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
for (const key of Object.keys(n)) {
|
|
120
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
121
|
+
walk(n[key], false);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
walk(node, false);
|
|
125
|
+
return ids;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Collect names declared locally inside a function (params + body). */
|
|
129
|
+
function collectLocalNames(fnNode) {
|
|
130
|
+
const names = new Set();
|
|
131
|
+
if (fnNode.params) {
|
|
132
|
+
for (const p of fnNode.params) {
|
|
133
|
+
if (t.isIdentifier(p)) names.add(p.name);
|
|
134
|
+
if (t.isAssignmentPattern(p) && t.isIdentifier(p.left)) names.add(p.left.name);
|
|
135
|
+
if (t.isRestElement(p) && t.isIdentifier(p.argument)) names.add(p.argument.name);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (fnNode.id && t.isIdentifier(fnNode.id)) names.add(fnNode.id.name);
|
|
139
|
+
function walk(n) {
|
|
140
|
+
if (!n || typeof n !== 'object') return;
|
|
141
|
+
if (Array.isArray(n)) {
|
|
142
|
+
n.forEach(walk);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (!n.type) return;
|
|
146
|
+
if (t.isVariableDeclarator(n) && t.isIdentifier(n.id)) names.add(n.id.name);
|
|
147
|
+
if (t.isFunctionDeclaration(n) && n.id) {
|
|
148
|
+
names.add(n.id.name);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (t.isFunctionExpression(n) || t.isArrowFunctionExpression(n)) return;
|
|
152
|
+
for (const key of Object.keys(n)) {
|
|
153
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
154
|
+
walk(n[key]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (fnNode.body) walk(fnNode.body);
|
|
158
|
+
return names;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* For each free variable in `fnNode`, try to resolve it to a
|
|
163
|
+
* compile-time value (literal or function) via scope bindings.
|
|
164
|
+
* Handles transitive closures: if a captured function itself has
|
|
165
|
+
* free variables, those are captured too.
|
|
166
|
+
*
|
|
167
|
+
* Returns an array of source strings like `"var b = 3;"` or
|
|
168
|
+
* `"var add = (x) => x + b;"`.
|
|
169
|
+
*/
|
|
170
|
+
function getCaptureDecls(fnNode, scope, state) {
|
|
171
|
+
const captures = [];
|
|
172
|
+
const seen = new Set();
|
|
173
|
+
function capture(targetFnNode) {
|
|
174
|
+
const referenced = collectReferencedIds(targetFnNode.body);
|
|
175
|
+
const locals = collectLocalNames(targetFnNode);
|
|
176
|
+
for (const name of referenced) {
|
|
177
|
+
if (locals.has(name) || seen.has(name)) continue;
|
|
178
|
+
seen.add(name);
|
|
179
|
+
const binding = scope.getBinding(name);
|
|
180
|
+
if (!binding) continue;
|
|
181
|
+
const bNode = binding.path.node;
|
|
182
|
+
|
|
183
|
+
// const/let/var x = <literal>
|
|
184
|
+
if (t.isVariableDeclarator(bNode) && bNode.init && t.isLiteral(bNode.init)) {
|
|
185
|
+
const initSrc = state.file.code.slice(bNode.init.start, bNode.init.end);
|
|
186
|
+
captures.push('var ' + name + ' = ' + initSrc + ';');
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// const/let/var x = <arrow / function expression>
|
|
191
|
+
if (t.isVariableDeclarator(bNode) && bNode.init && (t.isFunctionExpression(bNode.init) || t.isArrowFunctionExpression(bNode.init))) {
|
|
192
|
+
// Recursively capture the inner function's free vars first
|
|
193
|
+
capture(bNode.init);
|
|
194
|
+
const initSrc = state.file.code.slice(bNode.init.start, bNode.init.end);
|
|
195
|
+
captures.push('var ' + name + ' = ' + transpileForThread(initSrc, state) + ';');
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// function declaration
|
|
200
|
+
if (t.isFunctionDeclaration(bNode)) {
|
|
201
|
+
capture(bNode);
|
|
202
|
+
const fnSrc = state.file.code.slice(bNode.start, bNode.end);
|
|
203
|
+
captures.push(transpileForThread(fnSrc, state));
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
capture(fnNode);
|
|
209
|
+
return captures;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ── Core transform helpers ─────────────────────────────────────
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Transpile extracted source for the thread engine. Always downlevels
|
|
216
|
+
* to ES5 (for Rhino). Also strips TypeScript when the host file is TS.
|
|
217
|
+
*/
|
|
218
|
+
function transpileForThread(code, state) {
|
|
219
|
+
try {
|
|
220
|
+
const babelCore = require('@babel/core');
|
|
221
|
+
const fn = state.filename || state.file.opts && state.file.opts.filename || '';
|
|
222
|
+
const isTS = /\.tsx?$/.test(fn);
|
|
223
|
+
const plugins = isTS ? [['@babel/plugin-transform-typescript', {
|
|
224
|
+
isTSX: true
|
|
225
|
+
}]] : [];
|
|
226
|
+
const result = babelCore.transformSync(code, {
|
|
227
|
+
presets: [['@babel/preset-env', {
|
|
228
|
+
targets: {
|
|
229
|
+
ie: '11'
|
|
230
|
+
},
|
|
231
|
+
modules: false
|
|
232
|
+
}]],
|
|
233
|
+
plugins,
|
|
234
|
+
configFile: false,
|
|
235
|
+
babelrc: false,
|
|
236
|
+
filename: isTS ? 'thread.tsx' : 'thread.js'
|
|
237
|
+
});
|
|
238
|
+
return (result && result.code || code).replace(/;\s*$/, '');
|
|
239
|
+
} catch {
|
|
240
|
+
return code;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
8
243
|
function maybeTransformArg(callPath, state, argNode, index) {
|
|
9
244
|
if (!t.isArrowFunctionExpression(argNode) && !t.isFunctionExpression(argNode)) {
|
|
10
245
|
return;
|
|
11
246
|
}
|
|
12
247
|
const originalCode = state.file.code;
|
|
13
|
-
const fnSource = originalCode.slice(argNode.start, argNode.end);
|
|
248
|
+
const fnSource = transpileForThread(originalCode.slice(argNode.start, argNode.end), state);
|
|
14
249
|
const iife = `(${fnSource})(__params__)`;
|
|
15
250
|
callPath.node.arguments[index] = t.stringLiteral(iife);
|
|
16
251
|
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Resolve a node to its function source **and** any captured free-variable
|
|
255
|
+
* declarations. Returns the ready-to-eval source string, or null.
|
|
256
|
+
*/
|
|
257
|
+
function extractFnSource(node, callPath, state) {
|
|
258
|
+
let fnNode = null;
|
|
259
|
+
let fnSource = null;
|
|
260
|
+
let isImported = false;
|
|
261
|
+
if (t.isFunctionExpression(node) || t.isArrowFunctionExpression(node)) {
|
|
262
|
+
fnNode = node;
|
|
263
|
+
fnSource = state.file.code.slice(node.start, node.end);
|
|
264
|
+
} else if (t.isIdentifier(node)) {
|
|
265
|
+
const binding = callPath.scope.getBinding(node.name);
|
|
266
|
+
if (!binding) return null;
|
|
267
|
+
const bNode = binding.path.node;
|
|
268
|
+
if (t.isFunctionDeclaration(bNode)) {
|
|
269
|
+
fnNode = bNode;
|
|
270
|
+
fnSource = state.file.code.slice(bNode.start, bNode.end);
|
|
271
|
+
} else if (t.isVariableDeclarator(bNode) && bNode.init) {
|
|
272
|
+
if (t.isFunctionExpression(bNode.init) || t.isArrowFunctionExpression(bNode.init)) {
|
|
273
|
+
fnNode = bNode.init;
|
|
274
|
+
fnSource = state.file.code.slice(bNode.init.start, bNode.init.end);
|
|
275
|
+
}
|
|
276
|
+
} else if (t.isImportSpecifier(bNode) || t.isImportDefaultSpecifier(bNode)) {
|
|
277
|
+
// Cross-module import: resolve the source file and extract the function
|
|
278
|
+
const importDecl = binding.path.parentPath.node;
|
|
279
|
+
const importSource = importDecl.source.value;
|
|
280
|
+
const exportName = t.isImportSpecifier(bNode) && bNode.imported ? t.isIdentifier(bNode.imported) ? bNode.imported.name : bNode.imported.value : 'default';
|
|
281
|
+
const imported = resolveImportedFnSource(importSource, exportName, state);
|
|
282
|
+
if (imported) {
|
|
283
|
+
fnSource = imported;
|
|
284
|
+
isImported = true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (!fnSource) return null;
|
|
289
|
+
|
|
290
|
+
// For imported functions we already have the full source (no local AST node
|
|
291
|
+
// to walk for captures — the function must be self-contained or only depend
|
|
292
|
+
// on its own module's scope which was already inlined).
|
|
293
|
+
if (isImported) return fnSource;
|
|
294
|
+
if (!fnNode) return null;
|
|
295
|
+
fnSource = transpileForThread(fnSource, state);
|
|
296
|
+
const captures = getCaptureDecls(fnNode, callPath.scope, state);
|
|
297
|
+
if (captures.length > 0) {
|
|
298
|
+
fnSource = '(function(){' + captures.join('\n') + '\nreturn ' + fnSource + ';})()';
|
|
299
|
+
}
|
|
300
|
+
return fnSource;
|
|
301
|
+
}
|
|
302
|
+
function tagFnValue(source) {
|
|
303
|
+
return t.objectExpression([t.objectProperty(t.identifier('__rnThreadFn'), t.stringLiteral(source))]);
|
|
304
|
+
}
|
|
305
|
+
function maybeTransformParams(callPath, state, paramsNode) {
|
|
306
|
+
if (!t.isObjectExpression(paramsNode)) return;
|
|
307
|
+
for (const prop of paramsNode.properties) {
|
|
308
|
+
if (!t.isObjectProperty(prop)) continue;
|
|
309
|
+
const fnSrc = extractFnSource(prop.value, callPath, state);
|
|
310
|
+
if (fnSrc) {
|
|
311
|
+
prop.value = tagFnValue(fnSrc);
|
|
312
|
+
prop.shorthand = false;
|
|
313
|
+
} else if (t.isObjectExpression(prop.value)) {
|
|
314
|
+
maybeTransformParams(callPath, state, prop.value);
|
|
315
|
+
} else if (t.isArrayExpression(prop.value)) {
|
|
316
|
+
maybeTransformArrayParams(callPath, state, prop.value);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function maybeTransformArrayParams(callPath, state, arrNode) {
|
|
321
|
+
for (let i = 0; i < arrNode.elements.length; i++) {
|
|
322
|
+
const el = arrNode.elements[i];
|
|
323
|
+
if (!el) continue;
|
|
324
|
+
const fnSrc = extractFnSource(el, callPath, state);
|
|
325
|
+
if (fnSrc) {
|
|
326
|
+
arrNode.elements[i] = tagFnValue(fnSrc);
|
|
327
|
+
} else if (t.isObjectExpression(el)) {
|
|
328
|
+
maybeTransformParams(callPath, state, el);
|
|
329
|
+
} else if (t.isArrayExpression(el)) {
|
|
330
|
+
maybeTransformArrayParams(callPath, state, el);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ── Visitor ────────────────────────────────────────────────────
|
|
336
|
+
|
|
17
337
|
return {
|
|
18
338
|
name: 'react-native-thread',
|
|
19
339
|
visitor: {
|
|
@@ -26,12 +346,18 @@ module.exports = function reactNativeThreadPlugin({
|
|
|
26
346
|
if (args.length >= 1) {
|
|
27
347
|
maybeTransformArg(path, state, args[0], 0);
|
|
28
348
|
}
|
|
349
|
+
if (args.length >= 2) {
|
|
350
|
+
maybeTransformParams(path, state, args[1]);
|
|
351
|
+
}
|
|
29
352
|
return;
|
|
30
353
|
}
|
|
31
354
|
if (t.isMemberExpression(callee) && !callee.computed && t.isIdentifier(callee.property) && METHOD_API.has(callee.property.name)) {
|
|
32
355
|
if (args.length >= 1) {
|
|
33
356
|
maybeTransformArg(path, state, args[0], 0);
|
|
34
357
|
}
|
|
358
|
+
if (args.length >= 2) {
|
|
359
|
+
maybeTransformParams(path, state, args[1]);
|
|
360
|
+
}
|
|
35
361
|
}
|
|
36
362
|
}
|
|
37
363
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TOP_LEVEL_API","Set","METHOD_API","module","exports","reactNativeThreadPlugin","types","t","maybeTransformArg","callPath","state","argNode","index","isArrowFunctionExpression","isFunctionExpression","originalCode","file","code","fnSource","slice","start","end","iife","node","arguments","stringLiteral","name","visitor","CallExpression","path","callee","args","isIdentifier","has","length","isMemberExpression","computed","property"],"sourceRoot":"../../src","sources":["babel-plugin.js"],"mappings":"AAAA,YAAY;;AAEZ,MAAMA,aAAa,GAAG,IAAIC,GAAG,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AAExD,MAAMC,UAAU,GAAG,IAAID,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AAEnCE,MAAM,CAACC,OAAO,GAAG,SAASC,uBAAuBA,CAAC;EAAEC,KAAK,EAAEC;AAAE,CAAC,EAAE;EAC9D,SAASC,iBAAiBA,CAACC,QAAQ,EAAEC,KAAK,EAAEC,OAAO,EAAEC,KAAK,EAAE;IAC1D,IACE,CAACL,CAAC,CAACM,yBAAyB,CAACF,OAAO,CAAC,IACrC,CAACJ,CAAC,CAACO,oBAAoB,CAACH,OAAO,CAAC,EAChC;MACA;IACF;IAEA,MAAMI,YAAY,GAAGL,KAAK,CAACM,IAAI,CAACC,IAAI;IACpC,MAAMC,QAAQ,GAAGH,YAAY,CAACI,KAAK,CAACR,OAAO,CAACS,KAAK,EAAET,OAAO,CAACU,GAAG,CAAC;IAC/D,MAAMC,IAAI,GAAG,IAAIJ,QAAQ,eAAe;IAExCT,QAAQ,CAACc,IAAI,CAACC,SAAS,CAACZ,KAAK,CAAC,GAAGL,CAAC,CAACkB,aAAa,CAACH,IAAI,CAAC;EACxD;EAEA,OAAO;IACLI,IAAI,EAAE,qBAAqB;IAC3BC,OAAO,EAAE;MACPC,cAAcA,CAACC,IAAI,EAAEnB,KAAK,EAAE;QAC1B,MAAM;UAAEoB,MAAM;UAAEN,SAAS,EAAEO;QAAK,CAAC,GAAGF,IAAI,CAACN,IAAI;QAE7C,IAAIhB,CAAC,CAACyB,YAAY,CAACF,MAAM,CAAC,IAAI9B,aAAa,CAACiC,GAAG,CAACH,MAAM,CAACJ,IAAI,CAAC,EAAE;UAC5D,IAAIK,IAAI,CAACG,MAAM,IAAI,CAAC,EAAE;YACpB1B,iBAAiB,CAACqB,IAAI,EAAEnB,KAAK,EAAEqB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;UAC5C;UACA;QACF;QAEA,IACExB,CAAC,CAAC4B,kBAAkB,CAACL,MAAM,CAAC,IAC5B,CAACA,MAAM,CAACM,QAAQ,IAChB7B,CAAC,CAACyB,YAAY,CAACF,MAAM,CAACO,QAAQ,CAAC,IAC/BnC,UAAU,CAAC+B,GAAG,CAACH,MAAM,CAACO,QAAQ,CAACX,IAAI,CAAC,EACpC;UACA,IAAIK,IAAI,CAACG,MAAM,IAAI,CAAC,EAAE;YACpB1B,iBAAiB,CAACqB,IAAI,EAAEnB,KAAK,EAAEqB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;UAC5C;QACF;MACF;IACF;EACF,CAAC;AACH,CAAC","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["nodePath","require","fs","TOP_LEVEL_API","Set","METHOD_API","SKIP_KEYS","module","exports","reactNativeThreadPlugin","types","t","babel","parser","RESOLVE_EXTS","resolveImportedFnSource","importSource","exportName","state","currentFile","filename","file","opts","startsWith","dir","dirname","resolvedFile","ext","candidate","resolve","existsSync","statSync","isFile","source","readFileSync","ast","parse","sourceType","plugins","stmt","program","body","isExportNamedDeclaration","declaration","isFunctionDeclaration","id","name","raw","slice","start","end","transpileForThread","isVariableDeclaration","decl","declarations","isVariableDeclarator","isIdentifier","init","isFunctionExpression","isArrowFunctionExpression","collectReferencedIds","node","ids","walk","n","skipId","Array","isArray","forEach","el","type","add","isMemberExpression","object","computed","property","isObjectProperty","key","value","Object","keys","has","collectLocalNames","fnNode","names","params","p","isAssignmentPattern","left","isRestElement","argument","getCaptureDecls","scope","captures","seen","capture","targetFnNode","referenced","locals","binding","getBinding","bNode","path","isLiteral","initSrc","code","push","fnSrc","babelCore","fn","isTS","test","isTSX","result","transformSync","presets","targets","ie","modules","configFile","babelrc","replace","maybeTransformArg","callPath","argNode","index","originalCode","fnSource","iife","arguments","stringLiteral","extractFnSource","isImported","isImportSpecifier","isImportDefaultSpecifier","importDecl","parentPath","imported","length","join","tagFnValue","objectExpression","objectProperty","identifier","maybeTransformParams","paramsNode","isObjectExpression","prop","properties","shorthand","isArrayExpression","maybeTransformArrayParams","arrNode","i","elements","visitor","CallExpression","callee","args"],"sourceRoot":"../../src","sources":["babel-plugin.js"],"mappings":"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","ignoreList":[]}
|