You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BridgeJS: Optimize numeric array bridging with bulk TypedArray transfer
Use bulk TypedArray memory copy instead of element-by-element stack
serialization for numeric arrays ([Int], [UInt8], [Float], [Double],
etc.). TypeScript types remain number[]/bigint[] — no API change.
Swift->JS: withUnsafeBufferPointer passes (ptr, count, kind) to
swift_js_push_typed_array which copies bytes into a JS TypedArray,
then Array.from() converts to number[] for the caller.
JS->Swift: retains the array as a TypedArray in the JS heap, passes
(id, count) as WASM params, Swift allocates via
Array(unsafeUninitializedCapacity:) and calls back to JS to bulk copy.
Non-numeric arrays (String, structs, classes, enums) are unaffected
and continue using the existing element-by-element stack protocol.
## Decision 1: Internal optimization, not API change (per Yuta's feedback)
4
+
5
+
**Context:** Original implementation used `BridgeType.typedArray(TypedArrayKind)` with config and `@JS(typedArray:)` to change `[UInt8]` → `Uint8Array` in TypeScript. Yuta's feedback: "we can solve performance and API independently without introducing config."
6
+
7
+
**Decision:** Remove `BridgeType.typedArray`, config, and `@JS(typedArray:)`. Instead, optimize the internal transfer mechanism for `BridgeType.array(elementType)` when elementType is numeric. TS type stays `number[]` / `bigint[]`.
8
+
9
+
## Decision 2: Array.from(TypedArray) conversion is acceptable
10
+
11
+
**Context:** Bulk transfer produces a TypedArray view, but the user expects `number[]`. Converting via `Array.from()` adds a pure JS loop.
12
+
13
+
**Decision:**`Array.from()` for 1000 elements is <1µs in V8. Current element-by-element is ~20µs of WASM boundary crossing overhead. Still a ~20× improvement. Acceptable trade-off.
14
+
15
+
## Decision 3: JSTypedArray<T> as BridgeJS type is separate work
16
+
17
+
**Context:** Yuta said "for those who want raw TypedArray in JS side, use JSTypedArray rather than Swift.Array."
18
+
19
+
**Decision:** JSTypedArray<T> BridgeJS support is a separate PR. This PR focuses only on the internal performance optimization for `[T]`.
20
+
21
+
## Decision 4: Zero-copy view for internal transfer
22
+
23
+
**Context:** The TypedArray view created for `Array.from()` is consumed immediately in the same synchronous JS call. It never escapes to the user.
24
+
25
+
**Decision:** Use `new TypedArray(memory.buffer, ptr, count)` (zero-copy view) for the internal transfer, NOT `.slice()`. This is safe because the view is consumed by `Array.from()` before any WASM call can trigger `memory.grow()`. Same pattern as `swjs_decode_string` which uses `.subarray()` for `TextDecoder.decode()`.
Rework typed array bridging per Yuta's feedback: internal performance optimization only, no API change. `[UInt8]` stays `number[]` in TS, but uses bulk TypedArray transfer internally.
5
+
6
+
## Key Files
7
+
-`DECISIONS.md` — design rationale
8
+
- Branch: `krodak/typed-array` (will be force-pushed after rework)
0 commit comments