react-native 0.88.0-rc.0 → 0.88.0-rc.2
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/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Renderer/implementations/ReactFabric-dev.js +3056 -1531
- package/Libraries/Renderer/implementations/ReactFabric-prod.js +2239 -1011
- package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2451 -1124
- package/React/Base/RCTVersion.m +1 -1
- package/React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +3 -4
- package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +8 -0
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +7 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +11 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +12 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Canary_Android.kt +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +15 -1
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +4 -1
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +5 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +6 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +74 -56
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +4 -2
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +5 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +10 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSCanary.h +5 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +2 -1
- package/ReactCommon/react/nativemodule/core/iostests/RCTTurboModuleTests.mm +18 -65
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.h +1 -2
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm +1 -2
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h +2 -9
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +33 -71
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +6 -1
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +3 -1
- package/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm +8 -19
- package/package.json +16 -13
- package/scripts/codegen/generate-artifacts-executor/generateRCTThirdPartyComponents.js +18 -4
- package/scripts/setup-apple-spm.js +82 -4
- package/scripts/spm/autolinking-plugins.js +8 -5
- package/scripts/spm/expand-spm-dependencies.js +217 -156
- package/scripts/spm/generate-spm-autolinking.js +114 -88
- package/scripts/spm/generate-spm-xcodeproj.js +67 -22
- package/scripts/spm/ios-deployment-target.js +378 -0
- package/scripts/spm/read-podspec.js +156 -8
- package/scripts/spm/scaffold-package-swift.js +272 -105
- package/scripts/spm/spm-pbxproj.js +36 -21
- package/scripts/spm/spm-types.js +25 -8
- package/scripts/spm/spm-utils.js +26 -0
- package/scripts/spm/swiftpm-config.js +245 -0
- package/scripts/spm/sync-spm-autolinking.js +11 -2
- package/sdks/hermes-engine/version.properties +1 -1
- package/src/private/featureflags/ReactNativeFeatureFlags.js +10 -5
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +2 -1
- package/src/private/webapis/dom/nodes/ReactNativeElement.js +6 -4
- package/src/private/webapis/dom/nodes/ReadOnlyText.js +6 -4
- package/src/react-private-interface.js +4 -0
- package/src/react-private-interface.js.flow +2 -0
- package/types_generated/Libraries/ReactNative/FabricUIManager.d.ts +47 -0
- package/types_generated/src/react-private-interface.d.ts +4 -1
- package/React/Base/RCTArrayBuffer.h +0 -64
- package/React/Base/RCTArrayBuffer.mm +0 -127
|
@@ -7,10 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
#import <XCTest/XCTest.h>
|
|
9
9
|
|
|
10
|
-
#import <React/RCTArrayBuffer.h>
|
|
11
10
|
#import <ReactCommon/RCTTurboModule.h>
|
|
12
11
|
#import <hermes/hermes.h>
|
|
13
|
-
#import <jsi/decorator.h>
|
|
14
12
|
#import <react/featureflags/ReactNativeFeatureFlags.h>
|
|
15
13
|
#import <react/featureflags/ReactNativeFeatureFlagsDefaults.h>
|
|
16
14
|
|
|
@@ -94,39 +92,6 @@ class TestMutableBuffer : public facebook::jsi::MutableBuffer {
|
|
|
94
92
|
std::vector<uint8_t> bytes_;
|
|
95
93
|
};
|
|
96
94
|
|
|
97
|
-
// `jsi::Runtime::tryGetMutableBuffer` is optional — the Hermes branch linked into apps returns
|
|
98
|
-
// nullptr for every ArrayBuffer — so decorate the runtime to answer it for the buffers created
|
|
99
|
-
// through it. That keeps the coverage of the native-backed path independent of the engine.
|
|
100
|
-
// The registry is weak, so the only owners of a backing store remain the JS ArrayBuffer and
|
|
101
|
-
// whatever the conversion retains.
|
|
102
|
-
class MutableBufferAwareRuntime final : public facebook::jsi::RuntimeDecorator<facebook::jsi::Runtime> {
|
|
103
|
-
public:
|
|
104
|
-
explicit MutableBufferAwareRuntime(facebook::jsi::Runtime &plain) : RuntimeDecorator(plain) {}
|
|
105
|
-
|
|
106
|
-
facebook::jsi::ArrayBuffer createArrayBuffer(std::shared_ptr<facebook::jsi::MutableBuffer> buffer) override
|
|
107
|
-
{
|
|
108
|
-
auto arrayBuffer = RuntimeDecorator::createArrayBuffer(buffer);
|
|
109
|
-
buffers_.push_back(buffer);
|
|
110
|
-
return arrayBuffer;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
std::shared_ptr<facebook::jsi::MutableBuffer> tryGetMutableBuffer(
|
|
114
|
-
const facebook::jsi::ArrayBuffer &arrayBuffer) override
|
|
115
|
-
{
|
|
116
|
-
uint8_t *data = arrayBuffer.data(*this);
|
|
117
|
-
for (const auto &weakBuffer : buffers_) {
|
|
118
|
-
auto buffer = weakBuffer.lock();
|
|
119
|
-
if (buffer != nullptr && buffer->data() == data) {
|
|
120
|
-
return buffer;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return nullptr;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private:
|
|
127
|
-
std::vector<std::weak_ptr<facebook::jsi::MutableBuffer>> buffers_;
|
|
128
|
-
};
|
|
129
|
-
|
|
130
95
|
class StubNativeMethodCallInvoker : public NativeMethodCallInvoker {
|
|
131
96
|
public:
|
|
132
97
|
void invokeAsync(const std::string &methodName, NativeMethodCallFunc &&func) noexcept override
|
|
@@ -354,46 +319,34 @@ class ExceptionCapturingNativeMethodCallInvoker : public NativeMethodCallInvoker
|
|
|
354
319
|
XCTAssertNotNil(original.callStackSymbols);
|
|
355
320
|
}
|
|
356
321
|
|
|
357
|
-
// A
|
|
358
|
-
// the
|
|
359
|
-
|
|
322
|
+
// A JS ArrayBuffer converts to an NSMutableData that owns an independent copy of
|
|
323
|
+
// the bytes — NSMutableData cannot alias a foreign buffer, so the result stays
|
|
324
|
+
// valid and is safe to mutate after the source buffer is gone. This covers the
|
|
325
|
+
// ArrayBuffer-backed-by-native-MutableBuffer case, which is the one that could in
|
|
326
|
+
// principle have been aliased zero-copy.
|
|
327
|
+
- (void)testArrayBufferConvertsToIndependentNSMutableData
|
|
360
328
|
{
|
|
361
329
|
constexpr size_t kBufferSize = 64 * 1024;
|
|
362
330
|
|
|
363
331
|
auto hermesRuntime = facebook::hermes::makeHermesRuntime();
|
|
364
|
-
|
|
332
|
+
facebook::jsi::Runtime *rt = hermesRuntime.get();
|
|
365
333
|
|
|
366
334
|
auto buffer = std::make_shared<TestMutableBuffer>(kBufferSize);
|
|
367
335
|
*buffer->data() = 0xAB;
|
|
368
|
-
const uint8_t *sourceBytes = buffer->data();
|
|
369
|
-
|
|
370
|
-
RCTArrayBuffer *converted = nil;
|
|
371
|
-
{
|
|
372
|
-
facebook::jsi::ArrayBuffer arrayBuffer(runtime, buffer);
|
|
373
|
-
const long ownersBeforeConversion = buffer.use_count();
|
|
374
|
-
|
|
375
|
-
id result = TurboModuleConvertUtils::convertJSIValueToObjCObject(
|
|
376
|
-
runtime, facebook::jsi::Value(runtime, arrayBuffer), nullptr, NO, NO);
|
|
377
|
-
XCTAssertTrue([result isKindOfClass:[RCTArrayBuffer class]]);
|
|
378
|
-
converted = (RCTArrayBuffer *)result;
|
|
379
|
-
|
|
380
|
-
XCTAssertEqual(
|
|
381
|
-
buffer.use_count(), ownersBeforeConversion + 1, @"The RCTArrayBuffer must retain the backing MutableBuffer");
|
|
382
|
-
}
|
|
383
336
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
337
|
+
facebook::jsi::ArrayBuffer arrayBuffer(*rt, buffer);
|
|
338
|
+
id converted =
|
|
339
|
+
TurboModuleConvertUtils::convertJSIValueToObjCObject(*rt, facebook::jsi::Value(*rt, arrayBuffer), nullptr);
|
|
387
340
|
|
|
388
|
-
|
|
389
|
-
*
|
|
390
|
-
XCTAssertEqual(
|
|
391
|
-
*static_cast<uint8_t *>(
|
|
392
|
-
XCTAssertEqual(*buffer->data(), 0xEF);
|
|
341
|
+
XCTAssertTrue([converted isKindOfClass:[NSMutableData class]]);
|
|
342
|
+
NSMutableData *data = (NSMutableData *)converted;
|
|
343
|
+
XCTAssertEqual(data.length, (NSUInteger)kBufferSize);
|
|
344
|
+
XCTAssertEqual(*static_cast<const uint8_t *>(data.bytes), 0xAB);
|
|
393
345
|
|
|
394
|
-
//
|
|
395
|
-
|
|
396
|
-
|
|
346
|
+
// Independent copy: mutating the NSMutableData must not write through to the
|
|
347
|
+
// source MutableBuffer.
|
|
348
|
+
*static_cast<uint8_t *>(data.mutableBytes) = 0xCD;
|
|
349
|
+
XCTAssertEqual(*buffer->data(), 0xAB, @"NSMutableData must not alias the source buffer");
|
|
397
350
|
}
|
|
398
351
|
|
|
399
352
|
@end
|
package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.h
CHANGED
|
@@ -75,8 +75,7 @@ class JSI_EXPORT ObjCInteropTurboModule : public ObjCTurboModule {
|
|
|
75
75
|
const jsi::Value &arg,
|
|
76
76
|
size_t i,
|
|
77
77
|
NSInvocation *inv,
|
|
78
|
-
NSMutableArray *retainedObjectsForInvocation
|
|
79
|
-
bool mustCopyBytes) override;
|
|
78
|
+
NSMutableArray *retainedObjectsForInvocation) override;
|
|
80
79
|
|
|
81
80
|
private:
|
|
82
81
|
std::vector<MethodDescriptor> methodDescriptors_;
|
package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm
CHANGED
|
@@ -363,8 +363,7 @@ void ObjCInteropTurboModule::setInvocationArg(
|
|
|
363
363
|
const jsi::Value &jsiArg,
|
|
364
364
|
size_t index,
|
|
365
365
|
NSInvocation *inv,
|
|
366
|
-
NSMutableArray *retainedObjectsForInvocation
|
|
367
|
-
[[maybe_unused]] bool mustCopyBytes)
|
|
366
|
+
NSMutableArray *retainedObjectsForInvocation)
|
|
368
367
|
{
|
|
369
368
|
NSString *methodName = @(methodNameCStr);
|
|
370
369
|
std::string methodJsSignature = name_ + "." + methodNameCStr + "()";
|
|
@@ -35,8 +35,7 @@ id convertJSIValueToObjCObject(
|
|
|
35
35
|
jsi::Runtime &runtime,
|
|
36
36
|
const jsi::Value &value,
|
|
37
37
|
const std::shared_ptr<CallInvoker> &jsInvoker,
|
|
38
|
-
BOOL useNSNull = NO
|
|
39
|
-
BOOL mustCopyBytes = YES);
|
|
38
|
+
BOOL useNSNull = NO);
|
|
40
39
|
} // namespace TurboModuleConvertUtils
|
|
41
40
|
|
|
42
41
|
template <>
|
|
@@ -114,9 +113,6 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule {
|
|
|
114
113
|
* ObjCInteropTurboModule relies heavily on RCTConvert to convert arguments from JavaScript values to Objective C
|
|
115
114
|
* values. ObjCTurboModule tries to minimize reliance on RCTConvert: RCTConvert uses the RCT_EXPORT_METHOD macros,
|
|
116
115
|
* which we want to remove long term from React Native.
|
|
117
|
-
*
|
|
118
|
-
* mustCopyBytes says whether the invocation may outlive the JS call, in which case ArrayBuffer arguments must be
|
|
119
|
-
* copied rather than aliased.
|
|
120
116
|
*/
|
|
121
117
|
virtual void setInvocationArg(
|
|
122
118
|
jsi::Runtime &runtime,
|
|
@@ -125,8 +121,7 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule {
|
|
|
125
121
|
const jsi::Value &arg,
|
|
126
122
|
size_t i,
|
|
127
123
|
NSInvocation *inv,
|
|
128
|
-
NSMutableArray *retainedObjectsForInvocation
|
|
129
|
-
bool mustCopyBytes);
|
|
124
|
+
NSMutableArray *retainedObjectsForInvocation);
|
|
130
125
|
|
|
131
126
|
private:
|
|
132
127
|
// Does the NativeModule dispatch async methods to the JS thread?
|
|
@@ -142,13 +137,11 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule {
|
|
|
142
137
|
NSDictionary<NSString *, NSArray<NSString *> *> *methodArgumentTypeNames_;
|
|
143
138
|
|
|
144
139
|
bool isMethodSync(TurboModuleMethodValueKind returnType);
|
|
145
|
-
bool mustCopyJSHeapArrayBufferBytes(TurboModuleMethodValueKind returnType);
|
|
146
140
|
BOOL hasMethodArgConversionSelector(NSString *methodName, size_t argIndex);
|
|
147
141
|
SEL getMethodArgConversionSelector(NSString *methodName, size_t argIndex);
|
|
148
142
|
NSInvocation *createMethodInvocation(
|
|
149
143
|
jsi::Runtime &runtime,
|
|
150
144
|
bool isSync,
|
|
151
|
-
bool mustCopyBytes,
|
|
152
145
|
const char *methodName,
|
|
153
146
|
SEL selector,
|
|
154
147
|
const jsi::Value *args,
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
#import "RCTTurboModule.h"
|
|
9
9
|
|
|
10
|
-
#import <React/RCTArrayBuffer.h>
|
|
11
10
|
#import <React/RCTBridgeModule.h>
|
|
12
11
|
#import <React/RCTConvert.h>
|
|
13
12
|
#import <React/RCTCxxConvert.h>
|
|
@@ -90,43 +89,35 @@ static std::vector<jsi::Value> convertNSArrayToStdVector(jsi::Runtime &runtime,
|
|
|
90
89
|
return result;
|
|
91
90
|
}
|
|
92
91
|
|
|
93
|
-
static jsi::ArrayBuffer
|
|
92
|
+
static jsi::ArrayBuffer convertNSMutableDataToJSIArrayBuffer(jsi::Runtime &runtime, NSMutableData *value)
|
|
94
93
|
{
|
|
95
|
-
class
|
|
94
|
+
class NSMutableDataBuffer final : public jsi::MutableBuffer {
|
|
96
95
|
public:
|
|
97
|
-
explicit
|
|
98
|
-
: buffer_(buffer), data_(static_cast<uint8_t *>(buffer.mutableBytes)), size_(buffer.length)
|
|
99
|
-
{
|
|
100
|
-
}
|
|
96
|
+
explicit NSMutableDataBuffer(NSMutableData *data) : data_(data) {}
|
|
101
97
|
|
|
102
98
|
size_t size() const override
|
|
103
99
|
{
|
|
104
|
-
return
|
|
100
|
+
return data_.length;
|
|
105
101
|
}
|
|
106
102
|
|
|
107
103
|
uint8_t *data() override
|
|
108
104
|
{
|
|
109
|
-
return data_;
|
|
105
|
+
return static_cast<uint8_t *>(data_.mutableBytes);
|
|
110
106
|
}
|
|
111
107
|
|
|
112
108
|
private:
|
|
113
|
-
|
|
114
|
-
[[maybe_unused]] RCTArrayBuffer *buffer_;
|
|
115
|
-
uint8_t *data_;
|
|
116
|
-
size_t size_;
|
|
109
|
+
NSMutableData *data_;
|
|
117
110
|
};
|
|
118
111
|
|
|
119
|
-
// nil would yield a NULL pointer
|
|
112
|
+
// A nil NSMutableData would silently yield a NULL `mutableBytes` pointer
|
|
113
|
+
// (ObjC nil-messaging) and corrupt the resulting ArrayBuffer. Substitute a
|
|
114
|
+
// fresh empty NSMutableData so the wrapped pointer is always well-defined.
|
|
120
115
|
if (value == nil) {
|
|
121
|
-
RCTLogWarn(@"
|
|
122
|
-
value = [
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (!value.isOwningBytes) {
|
|
126
|
-
value = [RCTArrayBuffer arrayBufferWithCopiedBytes:value.mutableBytes length:value.length];
|
|
116
|
+
RCTLogWarn(@"convertNSMutableDataToJSIArrayBuffer: received nil NSMutableData; returning empty ArrayBuffer");
|
|
117
|
+
value = [NSMutableData data];
|
|
127
118
|
}
|
|
128
|
-
|
|
129
|
-
return {runtime, std::
|
|
119
|
+
auto buffer = std::make_shared<NSMutableDataBuffer>(value);
|
|
120
|
+
return {runtime, std::move(buffer)};
|
|
130
121
|
}
|
|
131
122
|
|
|
132
123
|
jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value)
|
|
@@ -142,8 +133,8 @@ jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value)
|
|
|
142
133
|
return convertNSDictionaryToJSIObject(runtime, (NSDictionary *)value);
|
|
143
134
|
} else if ([value isKindOfClass:[NSArray class]]) {
|
|
144
135
|
return convertNSArrayToJSIArray(runtime, (NSArray *)value);
|
|
145
|
-
} else if ([value isKindOfClass:[
|
|
146
|
-
return
|
|
136
|
+
} else if ([value isKindOfClass:[NSMutableData class]]) {
|
|
137
|
+
return convertNSMutableDataToJSIArrayBuffer(runtime, (NSMutableData *)value);
|
|
147
138
|
} else if (value == (id)kCFNull) {
|
|
148
139
|
return jsi::Value::null();
|
|
149
140
|
}
|
|
@@ -210,41 +201,23 @@ convertJSIFunctionToCallback(jsi::Runtime &rt, jsi::Function &&function, const s
|
|
|
210
201
|
};
|
|
211
202
|
}
|
|
212
203
|
|
|
213
|
-
//
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
|
|
219
|
-
|
|
204
|
+
// Copy the ArrayBuffer's bytes into an NSMutableData. A zero-copy wrap is not
|
|
205
|
+
// possible here: NSMutableData needs its own resizable backing store and cannot
|
|
206
|
+
// alias a foreign buffer (even via initWithBytesNoCopy:length:deallocator:, which
|
|
207
|
+
// copies eagerly for the mutable subclass). Copying also makes the result safe to
|
|
208
|
+
// retain in a block, store, or dispatch to another thread, regardless of whether
|
|
209
|
+
// the bytes were owned by JS (valid only for this callstack) or by a native
|
|
210
|
+
// MutableBuffer (which the JS ArrayBuffer may GC concurrently).
|
|
211
|
+
static NSMutableData *convertJSIArrayBufferToNSMutableData(jsi::Runtime &rt, const jsi::ArrayBuffer &value)
|
|
220
212
|
{
|
|
221
|
-
|
|
222
|
-
auto keepAlive = std::move(nativeBuffer);
|
|
223
|
-
return [RCTArrayBuffer arrayBufferWithOwnedBytes:keepAlive->data()
|
|
224
|
-
length:keepAlive->size()
|
|
225
|
-
cleanup:^{
|
|
226
|
-
(void)keepAlive;
|
|
227
|
-
}];
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
void *bytes = arrayBuffer.data(rt);
|
|
231
|
-
size_t size = arrayBuffer.size(rt);
|
|
232
|
-
|
|
233
|
-
// The bytes belong to the JS heap -> async call.
|
|
234
|
-
if (mustCopyBytes) {
|
|
235
|
-
return [RCTArrayBuffer arrayBufferWithCopiedBytes:bytes length:size];
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// The bytes belong to the JS heap -> sync call.
|
|
239
|
-
return [RCTArrayBuffer arrayBufferWithUnownedBytes:bytes length:size];
|
|
213
|
+
return [NSMutableData dataWithBytes:value.data(rt) length:value.size(rt)];
|
|
240
214
|
}
|
|
241
215
|
|
|
242
216
|
id convertJSIValueToObjCObject(
|
|
243
217
|
jsi::Runtime &runtime,
|
|
244
218
|
const jsi::Value &value,
|
|
245
219
|
const std::shared_ptr<CallInvoker> &jsInvoker,
|
|
246
|
-
BOOL useNSNull
|
|
247
|
-
BOOL mustCopyBytes)
|
|
220
|
+
BOOL useNSNull)
|
|
248
221
|
{
|
|
249
222
|
if (value.isUndefined() || (value.isNull() && !useNSNull)) {
|
|
250
223
|
return nil;
|
|
@@ -270,7 +243,7 @@ id convertJSIValueToObjCObject(
|
|
|
270
243
|
return convertJSIFunctionToCallback(runtime, o.getFunction(runtime), jsInvoker);
|
|
271
244
|
}
|
|
272
245
|
if (o.isArrayBuffer(runtime)) {
|
|
273
|
-
return
|
|
246
|
+
return convertJSIArrayBufferToNSMutableData(runtime, o.getArrayBuffer(runtime));
|
|
274
247
|
}
|
|
275
248
|
return convertJSIObjectToNSDictionary(runtime, o, jsInvoker, useNSNull);
|
|
276
249
|
}
|
|
@@ -629,11 +602,11 @@ jsi::Value ObjCTurboModule::convertReturnIdToJSIValue(
|
|
|
629
602
|
break;
|
|
630
603
|
}
|
|
631
604
|
case ArrayBufferKind: {
|
|
632
|
-
if (result != nil && ![result isKindOfClass:[
|
|
633
|
-
RCTLogError(@"convertReturnIdToJSIValue: expected
|
|
605
|
+
if (result != nil && ![result isKindOfClass:[NSMutableData class]]) {
|
|
606
|
+
RCTLogError(@"convertReturnIdToJSIValue: expected NSMutableData for ArrayBufferKind, got %@", [result class]);
|
|
634
607
|
break;
|
|
635
608
|
}
|
|
636
|
-
returnValue =
|
|
609
|
+
returnValue = convertNSMutableDataToJSIArrayBuffer(runtime, (NSMutableData *)result);
|
|
637
610
|
break;
|
|
638
611
|
}
|
|
639
612
|
case FunctionKind:
|
|
@@ -710,8 +683,7 @@ void ObjCTurboModule::setInvocationArg(
|
|
|
710
683
|
const jsi::Value &arg,
|
|
711
684
|
size_t i,
|
|
712
685
|
NSInvocation *inv,
|
|
713
|
-
NSMutableArray *retainedObjectsForInvocation
|
|
714
|
-
bool mustCopyBytes)
|
|
686
|
+
NSMutableArray *retainedObjectsForInvocation)
|
|
715
687
|
{
|
|
716
688
|
if (arg.isBool()) {
|
|
717
689
|
bool v = arg.getBool();
|
|
@@ -754,15 +726,13 @@ void ObjCTurboModule::setInvocationArg(
|
|
|
754
726
|
* Convert arg to ObjC objects.
|
|
755
727
|
*/
|
|
756
728
|
BOOL enableModuleArgumentNSNullConversionIOS = ReactNativeFeatureFlags::enableModuleArgumentNSNullConversionIOS();
|
|
757
|
-
id objCArg =
|
|
758
|
-
convertJSIValueToObjCObject(runtime, arg, jsInvoker_, enableModuleArgumentNSNullConversionIOS, mustCopyBytes);
|
|
729
|
+
id objCArg = convertJSIValueToObjCObject(runtime, arg, jsInvoker_, enableModuleArgumentNSNullConversionIOS);
|
|
759
730
|
|
|
760
731
|
// A JS `null` in argument position must reach ObjC as `nil`; only nulls nested inside arrays and
|
|
761
732
|
// dictionaries are preserved as `kCFNull`. Skipping `setArgument:` leaves the slot zeroed.
|
|
762
733
|
if (enableModuleArgumentNSNullConversionIOS && objCArg == (id)kCFNull) {
|
|
763
734
|
return;
|
|
764
735
|
}
|
|
765
|
-
|
|
766
736
|
if (objCArg != nullptr) {
|
|
767
737
|
NSString *methodNameNSString = @(methodName);
|
|
768
738
|
|
|
@@ -823,7 +793,6 @@ void ObjCTurboModule::setInvocationArg(
|
|
|
823
793
|
NSInvocation *ObjCTurboModule::createMethodInvocation(
|
|
824
794
|
jsi::Runtime &runtime,
|
|
825
795
|
bool isSync,
|
|
826
|
-
bool mustCopyBytes,
|
|
827
796
|
const char *methodName,
|
|
828
797
|
SEL selector,
|
|
829
798
|
const jsi::Value *args,
|
|
@@ -852,7 +821,7 @@ NSInvocation *ObjCTurboModule::createMethodInvocation(
|
|
|
852
821
|
for (size_t i = 0; i < count; i++) {
|
|
853
822
|
const jsi::Value &arg = args[i];
|
|
854
823
|
const std::string objCArgType = [methodSignature getArgumentTypeAtIndex:i + 2];
|
|
855
|
-
setInvocationArg(runtime, methodName, objCArgType, arg, i, inv, retainedObjectsForInvocation
|
|
824
|
+
setInvocationArg(runtime, methodName, objCArgType, arg, i, inv, retainedObjectsForInvocation);
|
|
856
825
|
}
|
|
857
826
|
|
|
858
827
|
if (isSync) {
|
|
@@ -873,12 +842,6 @@ bool ObjCTurboModule::isMethodSync(TurboModuleMethodValueKind returnType)
|
|
|
873
842
|
return returnType != VoidKind && returnType != PromiseKind;
|
|
874
843
|
}
|
|
875
844
|
|
|
876
|
-
bool ObjCTurboModule::mustCopyJSHeapArrayBufferBytes(TurboModuleMethodValueKind returnType)
|
|
877
|
-
{
|
|
878
|
-
// Void always dispatches via invokeAsync and promise may.
|
|
879
|
-
return returnType == VoidKind || returnType == PromiseKind;
|
|
880
|
-
}
|
|
881
|
-
|
|
882
845
|
ObjCTurboModule::ObjCTurboModule(const InitParams ¶ms)
|
|
883
846
|
: TurboModule(params.moduleName, params.jsInvoker),
|
|
884
847
|
instance_(params.instance),
|
|
@@ -899,7 +862,6 @@ jsi::Value ObjCTurboModule::invokeObjCMethod(
|
|
|
899
862
|
const char *methodName = methodNameStr.c_str();
|
|
900
863
|
|
|
901
864
|
bool isSyncInvocation = isMethodSync(returnType);
|
|
902
|
-
bool mustCopyBytes = mustCopyJSHeapArrayBufferBytes(returnType);
|
|
903
865
|
|
|
904
866
|
if (isSyncInvocation) {
|
|
905
867
|
TurboModulePerfLogger::syncMethodCallStart(moduleName, methodName);
|
|
@@ -909,7 +871,7 @@ jsi::Value ObjCTurboModule::invokeObjCMethod(
|
|
|
909
871
|
|
|
910
872
|
NSMutableArray *retainedObjectsForInvocation = [NSMutableArray arrayWithCapacity:count + 2];
|
|
911
873
|
NSInvocation *inv = createMethodInvocation(
|
|
912
|
-
runtime, isSyncInvocation,
|
|
874
|
+
runtime, isSyncInvocation, methodName, selector, args, count, retainedObjectsForInvocation);
|
|
913
875
|
|
|
914
876
|
jsi::Value returnValue = jsi::Value::undefined();
|
|
915
877
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<909f4afa6f96b4e77577432e4d98ba76>>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -199,6 +199,11 @@ bool NativeReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetCha
|
|
|
199
199
|
return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges();
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
bool NativeReactNativeFeatureFlags::enableImperativeEvents(
|
|
203
|
+
jsi::Runtime& /*runtime*/) {
|
|
204
|
+
return ReactNativeFeatureFlags::enableImperativeEvents();
|
|
205
|
+
}
|
|
206
|
+
|
|
202
207
|
bool NativeReactNativeFeatureFlags::enableImperativeFocus(
|
|
203
208
|
jsi::Runtime& /*runtime*/) {
|
|
204
209
|
return ReactNativeFeatureFlags::enableImperativeFocus();
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<88f2554b7033d38f5b275eac1d52ae6e>>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -100,6 +100,8 @@ class NativeReactNativeFeatureFlags
|
|
|
100
100
|
|
|
101
101
|
bool enableImmediateUpdateModeForContentOffsetChanges(jsi::Runtime& runtime);
|
|
102
102
|
|
|
103
|
+
bool enableImperativeEvents(jsi::Runtime& runtime);
|
|
104
|
+
|
|
103
105
|
bool enableImperativeFocus(jsi::Runtime& runtime);
|
|
104
106
|
|
|
105
107
|
bool enableInteropViewManagerClassLookUpOptimizationIOS(jsi::Runtime& runtime);
|
package/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
#import "RCTSampleTurboModule.h"
|
|
9
|
-
|
|
10
|
-
#import <React/RCTArrayBuffer.h>
|
|
11
9
|
#import "RCTSampleTurboModulePlugin.h"
|
|
12
10
|
|
|
13
11
|
#import <React/RCTAssert.h>
|
|
@@ -16,8 +14,6 @@
|
|
|
16
14
|
#import <ReactCommon/RCTTurboModuleWithJSIBindings.h>
|
|
17
15
|
#import <UIKit/UIKit.h>
|
|
18
16
|
|
|
19
|
-
#include <span>
|
|
20
|
-
|
|
21
17
|
using namespace facebook::react;
|
|
22
18
|
|
|
23
19
|
@interface RCTSampleTurboModule () <RCTTurboModuleWithJSIBindings, RCTInitializing>
|
|
@@ -149,27 +145,20 @@ RCT_EXPORT_MODULE()
|
|
|
149
145
|
};
|
|
150
146
|
}
|
|
151
147
|
|
|
152
|
-
//
|
|
153
|
-
|
|
148
|
+
// Arguments arrive as an immutable NSData, but an ArrayBuffer return must be
|
|
149
|
+
// NSMutableData: it is handed to JS as a jsi::MutableBuffer, whose data() is
|
|
150
|
+
// non-const. Echoing the argument back therefore needs a mutable copy.
|
|
151
|
+
- (NSMutableData *)getArrayBuffer:(NSData *)buffer
|
|
154
152
|
{
|
|
155
|
-
|
|
156
|
-
if (bytes == nullptr) {
|
|
157
|
-
return buffer;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
std::span<uint8_t> byteSpan(bytes, static_cast<size_t>(buffer.length));
|
|
161
|
-
for (auto &byte : byteSpan) {
|
|
162
|
-
byte = static_cast<uint8_t>(byte * 2);
|
|
163
|
-
}
|
|
164
|
-
return buffer;
|
|
153
|
+
return [buffer mutableCopy];
|
|
165
154
|
}
|
|
166
155
|
|
|
167
|
-
- (
|
|
156
|
+
- (NSMutableData *)createNativeBuffer:(double)size
|
|
168
157
|
{
|
|
169
|
-
return [
|
|
158
|
+
return [NSMutableData dataWithLength:(NSUInteger)size];
|
|
170
159
|
}
|
|
171
160
|
|
|
172
|
-
- (void)processAsyncBuffer:(
|
|
161
|
+
- (void)processAsyncBuffer:(NSData *)payload
|
|
173
162
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
174
163
|
reject:(RCTPromiseRejectBlock)reject
|
|
175
164
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native",
|
|
3
|
-
"version": "0.88.0-rc.
|
|
3
|
+
"version": "0.88.0-rc.2",
|
|
4
4
|
"description": "A framework for building native apps using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,10 @@
|
|
|
34
34
|
"default": "./index.js"
|
|
35
35
|
},
|
|
36
36
|
"./Libraries/*": {
|
|
37
|
-
"react-native-legacy-deep-imports":
|
|
37
|
+
"react-native-legacy-deep-imports": [
|
|
38
|
+
"./types_DEPRECATED/Libraries/*.d.ts",
|
|
39
|
+
"./Libraries/*.d.ts"
|
|
40
|
+
],
|
|
38
41
|
"types": null,
|
|
39
42
|
"default": "./Libraries/*.js"
|
|
40
43
|
},
|
|
@@ -143,7 +146,7 @@
|
|
|
143
146
|
},
|
|
144
147
|
"peerDependencies": {
|
|
145
148
|
"@types/react": "^19.1.1",
|
|
146
|
-
"react": "^19.
|
|
149
|
+
"react": "^19.3.0"
|
|
147
150
|
},
|
|
148
151
|
"peerDependenciesMeta": {
|
|
149
152
|
"@types/react": {
|
|
@@ -151,29 +154,29 @@
|
|
|
151
154
|
}
|
|
152
155
|
},
|
|
153
156
|
"dependencies": {
|
|
154
|
-
"@react-native/asset-utils": "0.88.0-rc.
|
|
155
|
-
"@react-native/codegen": "0.88.0-rc.
|
|
156
|
-
"@react-native/community-cli-plugin": "0.88.0-rc.
|
|
157
|
-
"@react-native/gradle-plugin": "0.88.0-rc.
|
|
158
|
-
"@react-native/normalize-colors": "0.88.0-rc.
|
|
159
|
-
"@react-native/virtualized-lists": "0.88.0-rc.
|
|
157
|
+
"@react-native/asset-utils": "0.88.0-rc.2",
|
|
158
|
+
"@react-native/codegen": "0.88.0-rc.2",
|
|
159
|
+
"@react-native/community-cli-plugin": "0.88.0-rc.2",
|
|
160
|
+
"@react-native/gradle-plugin": "0.88.0-rc.2",
|
|
161
|
+
"@react-native/normalize-colors": "0.88.0-rc.2",
|
|
162
|
+
"@react-native/virtualized-lists": "0.88.0-rc.2",
|
|
160
163
|
"anser": "^1.4.9",
|
|
161
164
|
"ansi-regex": "^5.0.0",
|
|
162
165
|
"flow-parser": "0.327.0",
|
|
163
166
|
"base64-js": "^1.5.1",
|
|
164
167
|
"flow-enums-runtime": "^0.0.6",
|
|
165
|
-
"hermes-compiler": "260318099.0.
|
|
168
|
+
"hermes-compiler": "260318099.0.3",
|
|
166
169
|
"invariant": "^2.2.4",
|
|
167
170
|
"memoize-one": "^5.0.0",
|
|
168
|
-
"metro-runtime": "^0.87.
|
|
169
|
-
"metro-source-map": "^0.87.
|
|
171
|
+
"metro-runtime": "^0.87.1",
|
|
172
|
+
"metro-source-map": "^0.87.1",
|
|
170
173
|
"nullthrows": "^1.1.1",
|
|
171
174
|
"pretty-format": "^29.7.0",
|
|
172
175
|
"promise": "^8.3.0",
|
|
173
176
|
"react-devtools-core": "^6.1.5",
|
|
174
177
|
"react-refresh": "^0.14.0",
|
|
175
178
|
"regenerator-runtime": "^0.13.2",
|
|
176
|
-
"scheduler": "0.
|
|
179
|
+
"scheduler": "0.28.0",
|
|
177
180
|
"semver": "^7.1.3",
|
|
178
181
|
"stacktrace-parser": "^0.1.10",
|
|
179
182
|
"tinyglobby": "^0.2.15",
|
|
@@ -177,10 +177,24 @@ function findFilesWithExtension(
|
|
|
177
177
|
return null;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
// A library's own sources never live in its dependencies, and crawling them
|
|
181
|
+
// is what makes this walk explode on large projects.
|
|
182
|
+
if (file === 'node_modules') {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!fs.existsSync(absolutePath)) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// `lstatSync` does not resolve symlinks: following them can loop forever,
|
|
191
|
+
// e.g. workspace packages that link into each other under pnpm.
|
|
192
|
+
const stats = fs.lstatSync(absolutePath);
|
|
193
|
+
if (stats.isSymbolicLink()) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (stats.isDirectory()) {
|
|
184
198
|
files.push(...findFilesWithExtension(absolutePath, extension));
|
|
185
199
|
} else if (file.endsWith(extension)) {
|
|
186
200
|
files.push(absolutePath);
|