react-native-windows 0.66.13 → 0.66.16

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/CHANGELOG.json CHANGED
@@ -2,7 +2,52 @@
2
2
  "name": "react-native-windows",
3
3
  "entries": [
4
4
  {
5
- "date": "Thu, 24 Feb 2022 16:39:54 GMT",
5
+ "date": "Mon, 04 Apr 2022 15:12:52 GMT",
6
+ "tag": "react-native-windows_v0.66.16",
7
+ "version": "0.66.16",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "comment": "MustBeNoExceptVoidFunctor should depend on the template type parameter to avoid being evaluated too early (#9609)",
12
+ "author": "asklar@microsoft.com",
13
+ "commit": "aab0df703cec0f9e69b185d13a59d976fa62a873",
14
+ "package": "react-native-windows"
15
+ }
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "date": "Mon, 14 Mar 2022 15:13:42 GMT",
21
+ "tag": "react-native-windows_v0.66.15",
22
+ "version": "0.66.15",
23
+ "comments": {
24
+ "patch": [
25
+ {
26
+ "comment": "Safe re-entrancy for EnsureHermesLoaded",
27
+ "author": "tudor.mihai@microsoft.com",
28
+ "commit": "7c9bdabed0af6a90c72ea1840efa5b6f00200627",
29
+ "package": "react-native-windows"
30
+ }
31
+ ]
32
+ }
33
+ },
34
+ {
35
+ "date": "Mon, 28 Feb 2022 16:14:18 GMT",
36
+ "tag": "react-native-windows_v0.66.14",
37
+ "version": "0.66.14",
38
+ "comments": {
39
+ "patch": [
40
+ {
41
+ "comment": "Enable TurboModule Promise completion from any thread (#9595)",
42
+ "author": "vmorozov@microsoft.com",
43
+ "commit": "789933a1a3828cdd9cf5ee191689d35b31e134fe",
44
+ "package": "react-native-windows"
45
+ }
46
+ ]
47
+ }
48
+ },
49
+ {
50
+ "date": "Thu, 24 Feb 2022 16:40:08 GMT",
6
51
  "tag": "react-native-windows_v0.66.13",
7
52
  "version": "0.66.13",
8
53
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,17 +1,41 @@
1
1
  # Change Log - react-native-windows
2
2
 
3
- This log was last generated on Thu, 24 Feb 2022 16:39:54 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 04 Apr 2022 15:12:52 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## 0.66.13
7
+ ## 0.66.16
8
8
 
9
- Thu, 24 Feb 2022 16:39:54 GMT
9
+ Mon, 04 Apr 2022 15:12:52 GMT
10
10
 
11
11
  ### Patches
12
12
 
13
- - Crash when getting Platform.osVersion on Windows 8.1 (30809111+acoates-ms@users.noreply.github.com)
13
+ - MustBeNoExceptVoidFunctor should depend on the template type parameter to avoid being evaluated too early (#9609) (asklar@microsoft.com)
14
14
 
15
+ ## 0.66.15
16
+
17
+ Mon, 14 Mar 2022 15:13:42 GMT
18
+
19
+ ### Patches
20
+
21
+ - Safe re-entrancy for EnsureHermesLoaded (tudor.mihai@microsoft.com)
22
+
23
+ ## 0.66.14
24
+
25
+ Mon, 28 Feb 2022 16:14:18 GMT
26
+
27
+ ### Patches
28
+
29
+ - Enable TurboModule Promise completion from any thread (#9595) (vmorozov@microsoft.com)
30
+
31
+ ## 0.66.13
32
+
33
+ Thu, 24 Feb 2022 16:40:08 GMT
34
+
35
+ ### Patches
36
+
37
+ - Crash when getting Platform.osVersion on Windows 8.1 (30809111+acoates-ms@users.noreply.github.com)
38
+
15
39
  ## 0.66.12
16
40
 
17
41
  Mon, 21 Feb 2022 16:09:42 GMT
@@ -0,0 +1,101 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+ #include "JSDispatcherWriter.h"
6
+ #include <JSI/JSIDynamic.h>
7
+ #include <crash/verifyElseCrash.h>
8
+
9
+ namespace winrt::Microsoft::ReactNative {
10
+
11
+ //===========================================================================
12
+ // JSDispatcherWriter implementation
13
+ //===========================================================================
14
+
15
+ JSDispatcherWriter::JSDispatcherWriter(
16
+ IReactDispatcher const &jsDispatcher,
17
+ facebook::jsi::Runtime &jsiRuntime) noexcept
18
+ : m_jsDispatcher(jsDispatcher), m_jsiRuntime(jsiRuntime) {}
19
+
20
+ void JSDispatcherWriter::WithResultArgs(
21
+ Mso::Functor<void(facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t argCount)>
22
+ handler) noexcept {
23
+ if (m_jsDispatcher.HasThreadAccess()) {
24
+ VerifyElseCrash(!m_dynamicWriter);
25
+ const facebook::jsi::Value *args{nullptr};
26
+ size_t argCount{0};
27
+ m_jsiWriter->AccessResultAsArgs(args, argCount);
28
+ handler(m_jsiRuntime, args, argCount);
29
+ } else {
30
+ VerifyElseCrash(!m_jsiWriter);
31
+ folly::dynamic dynValue = m_dynamicWriter->TakeValue();
32
+ m_jsDispatcher.Post([handler, dynValue, &runtime = m_jsiRuntime]() {
33
+ VerifyElseCrash(dynValue.isArray());
34
+ std::vector<facebook::jsi::Value> args;
35
+ args.reserve(dynValue.size());
36
+ for (auto const &item : dynValue) {
37
+ args.emplace_back(facebook::jsi::valueFromDynamic(runtime, item));
38
+ }
39
+ handler(runtime, args.data(), args.size());
40
+ });
41
+ }
42
+ }
43
+
44
+ void JSDispatcherWriter::WriteNull() noexcept {
45
+ GetWriter().WriteNull();
46
+ }
47
+
48
+ void JSDispatcherWriter::WriteBoolean(bool value) noexcept {
49
+ GetWriter().WriteBoolean(value);
50
+ }
51
+
52
+ void JSDispatcherWriter::WriteInt64(int64_t value) noexcept {
53
+ GetWriter().WriteInt64(value);
54
+ }
55
+
56
+ void JSDispatcherWriter::WriteDouble(double value) noexcept {
57
+ GetWriter().WriteDouble(value);
58
+ }
59
+
60
+ void JSDispatcherWriter::WriteString(const winrt::hstring &value) noexcept {
61
+ GetWriter().WriteString(value);
62
+ }
63
+
64
+ void JSDispatcherWriter::WriteObjectBegin() noexcept {
65
+ GetWriter().WriteObjectBegin();
66
+ }
67
+
68
+ void JSDispatcherWriter::WritePropertyName(const winrt::hstring &name) noexcept {
69
+ GetWriter().WritePropertyName(name);
70
+ }
71
+
72
+ void JSDispatcherWriter::WriteObjectEnd() noexcept {
73
+ GetWriter().WriteObjectEnd();
74
+ }
75
+
76
+ void JSDispatcherWriter::WriteArrayBegin() noexcept {
77
+ GetWriter().WriteArrayBegin();
78
+ }
79
+
80
+ void JSDispatcherWriter::WriteArrayEnd() noexcept {
81
+ GetWriter().WriteArrayEnd();
82
+ }
83
+
84
+ IJSValueWriter JSDispatcherWriter::GetWriter() noexcept {
85
+ if (m_jsDispatcher.HasThreadAccess()) {
86
+ VerifyElseCrash(!m_dynamicWriter);
87
+ if (!m_jsiWriter) {
88
+ m_jsiWriter = winrt::make_self<JsiWriter>(m_jsiRuntime);
89
+ m_writer = m_jsiWriter.as<IJSValueWriter>();
90
+ }
91
+ } else {
92
+ VerifyElseCrash(!m_jsiWriter);
93
+ if (!m_dynamicWriter) {
94
+ m_dynamicWriter = winrt::make_self<DynamicWriter>();
95
+ m_writer = m_dynamicWriter.as<IJSValueWriter>();
96
+ }
97
+ }
98
+ return m_writer;
99
+ }
100
+
101
+ } // namespace winrt::Microsoft::ReactNative
@@ -0,0 +1,44 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ #pragma once
4
+
5
+ #include <functional/functor.h>
6
+ #include "DynamicWriter.h"
7
+ #include "JsiWriter.h"
8
+ #include "folly/dynamic.h"
9
+ #include "winrt/Microsoft.ReactNative.h"
10
+
11
+ namespace winrt::Microsoft::ReactNative {
12
+
13
+ // IJSValueWriter to ensure that JsiWriter is always used from JSDispatcher.
14
+ // In case if writing is done outside of JSDispatcher, it uses DynamicWriter to create
15
+ // folly::dynamic which then is written to JsiWriter in JSDispatcher.
16
+ struct JSDispatcherWriter : winrt::implements<JSDispatcherWriter, IJSValueWriter> {
17
+ JSDispatcherWriter(IReactDispatcher const &jsDispatcher, facebook::jsi::Runtime &jsiRuntime) noexcept;
18
+ void WithResultArgs(Mso::Functor<void(facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t argCount)>
19
+ handler) noexcept;
20
+
21
+ public: // IJSValueWriter
22
+ void WriteNull() noexcept;
23
+ void WriteBoolean(bool value) noexcept;
24
+ void WriteInt64(int64_t value) noexcept;
25
+ void WriteDouble(double value) noexcept;
26
+ void WriteString(const winrt::hstring &value) noexcept;
27
+ void WriteObjectBegin() noexcept;
28
+ void WritePropertyName(const winrt::hstring &name) noexcept;
29
+ void WriteObjectEnd() noexcept;
30
+ void WriteArrayBegin() noexcept;
31
+ void WriteArrayEnd() noexcept;
32
+
33
+ private:
34
+ IJSValueWriter GetWriter() noexcept;
35
+
36
+ private:
37
+ IReactDispatcher m_jsDispatcher;
38
+ facebook::jsi::Runtime &m_jsiRuntime;
39
+ winrt::com_ptr<DynamicWriter> m_dynamicWriter;
40
+ winrt::com_ptr<JsiWriter> m_jsiWriter;
41
+ IJSValueWriter m_writer;
42
+ };
43
+
44
+ } // namespace winrt::Microsoft::ReactNative
@@ -61,7 +61,7 @@ void JsiWriter::WriteDouble(double value) noexcept {
61
61
  }
62
62
 
63
63
  void JsiWriter::WriteString(const winrt::hstring &value) noexcept {
64
- WriteValue({m_runtime, facebook::jsi::String::createFromUtf8(m_runtime, winrt::to_string(value))});
64
+ WriteValue({facebook::jsi::String::createFromUtf8(m_runtime, winrt::to_string(value))});
65
65
  }
66
66
 
67
67
  void JsiWriter::WriteObjectBegin() noexcept {
@@ -163,16 +163,4 @@ void JsiWriter::Push(Container &&container) noexcept {
163
163
  m_containers.push_back(std::move(container));
164
164
  }
165
165
 
166
- /*static*/ facebook::jsi::Value JsiWriter::ToJsiValue(
167
- facebook::jsi::Runtime &runtime,
168
- JSValueArgWriter const &argWriter) noexcept {
169
- if (argWriter) {
170
- IJSValueWriter jsiWriter = winrt::make<JsiWriter>(runtime);
171
- argWriter(jsiWriter);
172
- return jsiWriter.as<JsiWriter>()->MoveResult();
173
- }
174
-
175
- return {};
176
- }
177
-
178
166
  } // namespace winrt::Microsoft::ReactNative
@@ -35,9 +35,6 @@ struct JsiWriter : winrt::implements<JsiWriter, IJSValueWriter> {
35
35
  void WriteArrayBegin() noexcept;
36
36
  void WriteArrayEnd() noexcept;
37
37
 
38
- public:
39
- static facebook::jsi::Value ToJsiValue(facebook::jsi::Runtime &runtime, JSValueArgWriter const &argWriter) noexcept;
40
-
41
38
  private:
42
39
  enum class ContainerState {
43
40
  AcceptValueAndFinish,
@@ -192,6 +192,9 @@
192
192
  <ClInclude Include="DynamicWriter.h">
193
193
  <DependentUpon>IJSValueWriter.idl</DependentUpon>
194
194
  </ClInclude>
195
+ <ClInclude Include="JSDispatcherWriter.h">
196
+ <DependentUpon>IJSValueWriter.idl</DependentUpon>
197
+ </ClInclude>
195
198
  <ClInclude Include="GlyphViewManager.h" />
196
199
  <ClInclude Include="HResult.h" />
197
200
  <ClInclude Include="IReactDispatcher.h">
@@ -508,6 +511,9 @@
508
511
  <ClCompile Include="DynamicWriter.cpp">
509
512
  <DependentUpon>IJSValueWriter.idl</DependentUpon>
510
513
  </ClCompile>
514
+ <ClCompile Include="JSDispatcherWriter.cpp">
515
+ <DependentUpon>IJSValueWriter.idl</DependentUpon>
516
+ </ClCompile>
511
517
  <ClCompile Include="GlyphViewManager.cpp" />
512
518
  <ClCompile Include="IReactDispatcher.cpp">
513
519
  <DependentUpon>IReactDispatcher.idl</DependentUpon>
@@ -7,6 +7,7 @@
7
7
  #include "pch.h"
8
8
  #include "TurboModulesProvider.h"
9
9
  #include <ReactCommon/TurboModuleUtils.h>
10
+ #include "JSDispatcherWriter.h"
10
11
  #include "JsiApi.h"
11
12
  #include "JsiReader.h"
12
13
  #include "JsiWriter.h"
@@ -58,7 +59,7 @@ struct TurboModuleBuilder : winrt::implements<TurboModuleBuilder, IReactModuleBu
58
59
  std::unordered_map<std::string, TurboModuleMethodInfo> m_methods;
59
60
  std::unordered_map<std::string, SyncMethodDelegate> m_syncMethods;
60
61
  std::vector<ConstantProviderDelegate> m_constantProviders;
61
- bool m_constantsEvaluated = false;
62
+ bool m_constantsEvaluated{false};
62
63
 
63
64
  private:
64
65
  void EnsureMemberNotSet(const std::string &key, bool checkingMethod) noexcept {
@@ -82,11 +83,13 @@ class TurboModuleImpl : public facebook::react::TurboModule {
82
83
  TurboModuleImpl(
83
84
  const IReactContext &reactContext,
84
85
  const std::string &name,
85
- std::shared_ptr<facebook::react::CallInvoker> jsInvoker,
86
- ReactModuleProvider reactModuleProvider)
87
- : facebook::react::TurboModule(name, jsInvoker), m_moduleBuilder(winrt::make<TurboModuleBuilder>(reactContext)) {
88
- providedModule = reactModuleProvider(m_moduleBuilder);
89
- if (auto hostObject = providedModule.try_as<IJsiHostObject>()) {
86
+ const std::shared_ptr<facebook::react::CallInvoker> &jsInvoker,
87
+ const ReactModuleProvider &reactModuleProvider)
88
+ : facebook::react::TurboModule(name, jsInvoker),
89
+ m_reactContext(reactContext),
90
+ m_moduleBuilder(winrt::make<TurboModuleBuilder>(reactContext)),
91
+ m_providedModule(reactModuleProvider(m_moduleBuilder)) {
92
+ if (auto hostObject = m_providedModule.try_as<IJsiHostObject>()) {
90
93
  m_hostObjectWrapper = std::make_shared<implementation::HostObjectWrapper>(hostObject);
91
94
  }
92
95
  }
@@ -96,12 +99,13 @@ class TurboModuleImpl : public facebook::react::TurboModule {
96
99
  return m_hostObjectWrapper->getPropertyNames(rt);
97
100
  }
98
101
 
99
- std::vector<facebook::jsi::PropNameID> props;
100
- auto tmb = m_moduleBuilder.as<TurboModuleBuilder>();
101
- for (auto &it : tmb->m_methods) {
102
- props.push_back(facebook::jsi::PropNameID::forAscii(rt, it.first));
102
+ auto turboModuleBuilder = m_moduleBuilder.as<TurboModuleBuilder>();
103
+ std::vector<facebook::jsi::PropNameID> propertyNames;
104
+ propertyNames.reserve(turboModuleBuilder->m_methods.size());
105
+ for (auto &methodInfo : turboModuleBuilder->m_methods) {
106
+ propertyNames.push_back(facebook::jsi::PropNameID::forAscii(rt, methodInfo.first));
103
107
  }
104
- return props;
108
+ return propertyNames;
105
109
  };
106
110
 
107
111
  facebook::jsi::Value get(facebook::jsi::Runtime &runtime, const facebook::jsi::PropNameID &propName) override {
@@ -110,25 +114,25 @@ class TurboModuleImpl : public facebook::react::TurboModule {
110
114
  }
111
115
 
112
116
  // it is not safe to assume that "runtime" never changes, so members are not cached here
113
- auto tmb = m_moduleBuilder.as<TurboModuleBuilder>();
114
- auto key = propName.utf8(runtime);
117
+ auto moduleBuilder = m_moduleBuilder.as<TurboModuleBuilder>();
118
+ std::string key = propName.utf8(runtime);
115
119
 
116
- if (key == "getConstants" && tmb->m_constantProviders.size() > 0) {
120
+ if (key == "getConstants" && !moduleBuilder->m_constantProviders.empty()) {
117
121
  // try to find getConstants if there is any constant
118
122
  return facebook::jsi::Function::createFromHostFunction(
119
123
  runtime,
120
124
  propName,
121
125
  0,
122
- [&runtime, tmb](
126
+ [moduleBuilder](
123
127
  facebook::jsi::Runtime &rt,
124
128
  const facebook::jsi::Value &thisVal,
125
129
  const facebook::jsi::Value *args,
126
130
  size_t count) {
127
131
  // collect all constants to an object
128
- auto writer = winrt::make<JsiWriter>(runtime);
132
+ auto writer = winrt::make<JsiWriter>(rt);
129
133
  writer.WriteObjectBegin();
130
- for (auto cp : tmb->m_constantProviders) {
131
- cp(writer);
134
+ for (auto constantProvider : moduleBuilder->m_constantProviders) {
135
+ constantProvider(writer);
132
136
  }
133
137
  writer.WriteObjectEnd();
134
138
  return writer.as<JsiWriter>()->MoveResult();
@@ -137,150 +141,134 @@ class TurboModuleImpl : public facebook::react::TurboModule {
137
141
 
138
142
  {
139
143
  // try to find a Method
140
- auto it = tmb->m_methods.find(key);
141
- if (it != tmb->m_methods.end()) {
142
- return facebook::jsi::Function::createFromHostFunction(
143
- runtime,
144
- propName,
145
- 0,
146
- [&runtime, method = it->second](
147
- facebook::jsi::Runtime &rt,
148
- const facebook::jsi::Value &thisVal,
149
- const facebook::jsi::Value *args,
150
- size_t count) {
151
- // prepare input arguments
152
- size_t serializableArgumentCount = count;
153
- switch (method.ReturnType) {
154
- case MethodReturnType::Callback:
155
- VerifyElseCrash(count >= 1);
156
- VerifyElseCrash(args[count - 1].isObject() && args[count - 1].asObject(runtime).isFunction(runtime));
157
- serializableArgumentCount -= 1;
158
- break;
159
- case MethodReturnType::TwoCallbacks:
160
- VerifyElseCrash(count >= 2);
161
- VerifyElseCrash(args[count - 1].isObject() && args[count - 1].asObject(runtime).isFunction(runtime));
162
- VerifyElseCrash(args[count - 2].isObject() && args[count - 2].asObject(runtime).isFunction(runtime));
163
- serializableArgumentCount -= 2;
164
- break;
165
- case MethodReturnType::Void:
166
- case MethodReturnType::Promise:
167
- // handled below
168
- break;
169
- }
170
- auto argReader = winrt::make<JsiReader>(runtime, args, serializableArgumentCount);
171
-
172
- // prepare output value
173
- // TODO: it is no reason to pass a argWriter just to receive [undefined] for void, should be optimized
174
- auto argWriter = winrt::make<JsiWriter>(runtime);
175
-
176
- // call the function
177
- switch (method.ReturnType) {
178
- case MethodReturnType::Void: {
179
- method.Method(argReader, argWriter, nullptr, nullptr);
144
+ auto it = moduleBuilder->m_methods.find(key);
145
+ if (it != moduleBuilder->m_methods.end()) {
146
+ TurboModuleMethodInfo methodInfo = it->second;
147
+ switch (methodInfo.ReturnType) {
148
+ case MethodReturnType::Void:
149
+ return facebook::jsi::Function::createFromHostFunction(
150
+ runtime,
151
+ propName,
152
+ 0,
153
+ [methodInfo](
154
+ facebook::jsi::Runtime &rt,
155
+ const facebook::jsi::Value & /*thisVal*/,
156
+ const facebook::jsi::Value *args,
157
+ size_t argCount) {
158
+ methodInfo.Method(winrt::make<JsiReader>(rt, args, argCount), nullptr, nullptr, nullptr);
159
+ return facebook::jsi::Value::undefined();
160
+ });
161
+ case MethodReturnType::Callback:
162
+ return facebook::jsi::Function::createFromHostFunction(
163
+ runtime,
164
+ propName,
165
+ 0,
166
+ [jsDispatcher = m_reactContext.JSDispatcher(), methodInfo](
167
+ facebook::jsi::Runtime &rt,
168
+ const facebook::jsi::Value & /*thisVal*/,
169
+ const facebook::jsi::Value *args,
170
+ size_t argCount) {
171
+ VerifyElseCrash(argCount > 0);
172
+ methodInfo.Method(
173
+ winrt::make<JsiReader>(rt, args, argCount - 1),
174
+ winrt::make<JSDispatcherWriter>(jsDispatcher, rt),
175
+ MakeCallback(rt, {rt, args[argCount - 1]}),
176
+ nullptr);
177
+ return facebook::jsi::Value::undefined();
178
+ });
179
+ case MethodReturnType::TwoCallbacks:
180
+ return facebook::jsi::Function::createFromHostFunction(
181
+ runtime,
182
+ propName,
183
+ 0,
184
+ [jsDispatcher = m_reactContext.JSDispatcher(), methodInfo](
185
+ facebook::jsi::Runtime &rt,
186
+ const facebook::jsi::Value & /*thisVal*/,
187
+ const facebook::jsi::Value *args,
188
+ size_t argCount) {
189
+ VerifyElseCrash(argCount > 1);
190
+ methodInfo.Method(
191
+ winrt::make<JsiReader>(rt, args, argCount - 2),
192
+ winrt::make<JSDispatcherWriter>(jsDispatcher, rt),
193
+ MakeCallback(rt, {rt, args[argCount - 2]}),
194
+ MakeCallback(rt, {rt, args[argCount - 1]}));
180
195
  return facebook::jsi::Value::undefined();
181
- }
182
- case MethodReturnType::Promise: {
196
+ });
197
+ case MethodReturnType::Promise:
198
+ return facebook::jsi::Function::createFromHostFunction(
199
+ runtime,
200
+ propName,
201
+ 0,
202
+ [jsDispatcher = m_reactContext.JSDispatcher(), methodInfo](
203
+ facebook::jsi::Runtime &rt,
204
+ const facebook::jsi::Value & /*thisVal*/,
205
+ const facebook::jsi::Value *args,
206
+ size_t count) {
207
+ auto argReader = winrt::make<JsiReader>(rt, args, count);
208
+ auto argWriter = winrt::make<JSDispatcherWriter>(jsDispatcher, rt);
183
209
  return facebook::react::createPromiseAsJSIValue(
184
- runtime, [=](facebook::jsi::Runtime &runtime, std::shared_ptr<facebook::react::Promise> promise) {
185
- method.Method(
210
+ rt,
211
+ [methodInfo, argReader, argWriter](
212
+ facebook::jsi::Runtime &runtime, std::shared_ptr<facebook::react::Promise> promise) {
213
+ methodInfo.Method(
186
214
  argReader,
187
215
  argWriter,
188
- [promise, &runtime](const IJSValueWriter &writer) {
189
- auto result = writer.as<JsiWriter>()->MoveResult();
190
- if (result.isObject()) {
191
- auto resultArrayObject = result.getObject(runtime);
192
- VerifyElseCrash(resultArrayObject.isArray(runtime));
193
- auto resultArray = resultArrayObject.getArray(runtime);
194
- VerifyElseCrash(resultArray.length(runtime) == 1);
195
- auto resultItem = resultArray.getValueAtIndex(runtime, 0);
196
- promise->resolve(resultItem);
197
- } else {
198
- VerifyElseCrash(false);
199
- }
216
+ [promise](const IJSValueWriter &writer) {
217
+ writer.as<JSDispatcherWriter>()->WithResultArgs([promise](
218
+ facebook::jsi::Runtime &runtime,
219
+ facebook::jsi::Value const *args,
220
+ size_t argCount) {
221
+ VerifyElseCrash(argCount == 1);
222
+ promise->resolve(args[0]);
223
+ });
200
224
  },
201
- [promise, &runtime](const IJSValueWriter &writer) {
202
- auto result = writer.as<JsiWriter>()->MoveResult();
203
- if (result.isString()) {
204
- promise->reject(result.getString(runtime).utf8(runtime));
205
- } else if (result.isObject()) {
206
- auto errorArrayObject = result.getObject(runtime);
207
- VerifyElseCrash(errorArrayObject.isArray(runtime));
208
- auto errorArray = errorArrayObject.getArray(runtime);
209
- VerifyElseCrash(errorArray.length(runtime) == 1);
210
- auto errorObjectValue = errorArray.getValueAtIndex(runtime, 0);
211
- VerifyElseCrash(errorObjectValue.isObject());
212
- auto errorObject = errorObjectValue.getObject(runtime);
213
- VerifyElseCrash(errorObject.hasProperty(runtime, "message"));
214
- auto errorMessage = errorObject.getProperty(runtime, "message");
215
- VerifyElseCrash(errorMessage.isString());
216
- promise->reject(errorMessage.getString(runtime).utf8(runtime));
217
- } else {
218
- VerifyElseCrash(false);
219
- }
225
+ [promise](const IJSValueWriter &writer) {
226
+ writer.as<JSDispatcherWriter>()->WithResultArgs([promise](
227
+ facebook::jsi::Runtime &runtime,
228
+ facebook::jsi::Value const *args,
229
+ size_t argCount) {
230
+ VerifyElseCrash(argCount == 1);
231
+ // To match the Android and iOS TurboModule behavior we create the Error object for
232
+ // the Promise rejection the same way as in updateErrorWithErrorData method.
233
+ // See react-native/Libraries/BatchedBridge/NativeModules.js for details.
234
+ auto error = runtime.global()
235
+ .getPropertyAsFunction(runtime, "Error")
236
+ .callAsConstructor(runtime, {});
237
+ auto &errorData = args[0];
238
+ if (errorData.isObject()) {
239
+ runtime.global()
240
+ .getPropertyAsObject(runtime, "Object")
241
+ .getPropertyAsFunction(runtime, "assign")
242
+ .call(runtime, error, errorData.getObject(runtime));
243
+ }
244
+ promise->reject_.call(runtime, error);
245
+ });
220
246
  });
221
247
  });
222
- }
223
- case MethodReturnType::Callback:
224
- case MethodReturnType::TwoCallbacks: {
225
- facebook::jsi::Value resolveFunction;
226
- facebook::jsi::Value rejectFunction;
227
- if (method.ReturnType == MethodReturnType::Callback) {
228
- resolveFunction = {runtime, args[count - 1]};
229
- } else {
230
- resolveFunction = {runtime, args[count - 2]};
231
- rejectFunction = {runtime, args[count - 1]};
232
- }
233
-
234
- auto makeCallback =
235
- [&runtime](const facebook::jsi::Value &callbackValue) noexcept -> MethodResultCallback {
236
- // workaround: xcode doesn't accept a captured value with only rvalue copy constructor
237
- auto functionObject =
238
- std::make_shared<facebook::jsi::Function>(callbackValue.asObject(runtime).asFunction(runtime));
239
- return [&runtime, callbackFunction = functionObject](const IJSValueWriter &writer) noexcept {
240
- const facebook::jsi::Value *resultArgs = nullptr;
241
- size_t resultCount = 0;
242
- writer.as<JsiWriter>()->AccessResultAsArgs(resultArgs, resultCount);
243
- callbackFunction->call(runtime, resultArgs, resultCount);
244
- };
245
- };
246
-
247
- method.Method(
248
- argReader,
249
- argWriter,
250
- makeCallback(resolveFunction),
251
- (method.ReturnType == MethodReturnType::Callback ? nullptr : makeCallback(rejectFunction)));
252
- return facebook::jsi::Value::undefined();
253
- }
254
- default:
255
- VerifyElseCrash(false);
256
- }
257
- });
248
+ });
249
+ default:
250
+ VerifyElseCrash(false);
251
+ }
258
252
  }
259
253
  }
260
254
 
261
255
  {
262
256
  // try to find a SyncMethod
263
- auto it = tmb->m_syncMethods.find(key);
264
- if (it != tmb->m_syncMethods.end()) {
257
+ auto it = moduleBuilder->m_syncMethods.find(key);
258
+ if (it != moduleBuilder->m_syncMethods.end()) {
265
259
  return facebook::jsi::Function::createFromHostFunction(
266
260
  runtime,
267
261
  propName,
268
262
  0,
269
- [&runtime, method = it->second](
263
+ [method = it->second](
270
264
  facebook::jsi::Runtime &rt,
271
265
  const facebook::jsi::Value &thisVal,
272
266
  const facebook::jsi::Value *args,
273
267
  size_t count) {
274
- // prepare input arguments
275
- auto argReader = winrt::make<JsiReader>(runtime, args, count);
276
-
277
- // prepare output value
278
- auto writer = winrt::make<JsiWriter>(runtime);
279
-
280
- // call the function
281
- method(argReader, writer);
282
-
283
- return writer.as<JsiWriter>()->MoveResult();
268
+ auto argReader = winrt::make<JsiReader>(rt, args, count);
269
+ auto argWriter = winrt::make<JsiWriter>(rt);
270
+ method(argReader, argWriter);
271
+ return argWriter.as<JsiWriter>()->MoveResult();
284
272
  });
285
273
  }
286
274
  }
@@ -299,17 +287,30 @@ class TurboModuleImpl : public facebook::react::TurboModule {
299
287
  }
300
288
 
301
289
  private:
290
+ static MethodResultCallback MakeCallback(facebook::jsi::Runtime &runtime, facebook::jsi::Value callback) noexcept {
291
+ auto sharedCallback =
292
+ std::make_shared<facebook::jsi::Function>(std::move(callback).asObject(runtime).asFunction(runtime));
293
+ return [sharedCallback = std::move(sharedCallback)](const IJSValueWriter &writer) noexcept {
294
+ writer.as<JSDispatcherWriter>()->WithResultArgs(
295
+ [sharedCallback](facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t count) {
296
+ sharedCallback->call(rt, args, count);
297
+ });
298
+ };
299
+ }
300
+
301
+ private:
302
+ IReactContext m_reactContext;
302
303
  IReactModuleBuilder m_moduleBuilder;
303
- IInspectable providedModule;
304
+ IInspectable m_providedModule;
304
305
  std::shared_ptr<implementation::HostObjectWrapper> m_hostObjectWrapper;
305
306
  };
306
307
 
307
308
  /*-------------------------------------------------------------------------------
308
309
  TurboModulesProvider
309
310
  -------------------------------------------------------------------------------*/
310
- TurboModulesProvider::TurboModulePtr TurboModulesProvider::getModule(
311
+ std::shared_ptr<facebook::react::TurboModule> TurboModulesProvider::getModule(
311
312
  const std::string &moduleName,
312
- const CallInvokerPtr &callInvoker) noexcept {
313
+ const std::shared_ptr<facebook::react::CallInvoker> &callInvoker) noexcept {
313
314
  // fail if the expected turbo module has not been registered
314
315
  auto it = m_moduleProviders.find(moduleName);
315
316
  if (it == m_moduleProviders.end()) {
@@ -13,16 +13,11 @@
13
13
  namespace winrt::Microsoft::ReactNative {
14
14
 
15
15
  class TurboModulesProvider final : public facebook::react::TurboModuleRegistry {
16
- private:
17
- using TurboModule = facebook::react::TurboModule;
18
- using CallInvoker = facebook::react::CallInvoker;
19
-
20
- using TurboModulePtr = std::shared_ptr<TurboModule>;
21
- using CallInvokerPtr = std::shared_ptr<CallInvoker>;
22
-
23
- public:
24
- virtual TurboModulePtr getModule(const std::string &moduleName, const CallInvokerPtr &callInvoker) noexcept override;
25
- virtual std::vector<std::string> getEagerInitModuleNames() noexcept override;
16
+ public: // TurboModuleRegistry implementation
17
+ std::shared_ptr<facebook::react::TurboModule> getModule(
18
+ const std::string &moduleName,
19
+ const std::shared_ptr<facebook::react::CallInvoker> &callInvoker) noexcept override;
20
+ std::vector<std::string> getEagerInitModuleNames() noexcept override;
26
21
 
27
22
  public:
28
23
  void SetReactContext(const IReactContext &reactContext) noexcept;
@@ -3,9 +3,7 @@
3
3
 
4
4
  #include "pch.h"
5
5
 
6
- #include <DynamicReader.h>
7
6
  #include <JSValueWriter.h>
8
- #include <JsiWriter.h>
9
7
  #include <Views/SIPEventHandler.h>
10
8
  #include <Views/ShadowNodeBase.h>
11
9
  #include "Impl/ScrollViewUWPImplementation.h"
@@ -723,9 +723,14 @@ inline DispatchTaskImpl<TInvoke, TOnCancel>::~DispatchTaskImpl() noexcept {
723
723
  }
724
724
  }
725
725
 
726
+ namespace details {
727
+ template <typename>
728
+ constexpr bool always_false = false;
729
+ }
730
+
726
731
  template <typename T>
727
732
  inline void MustBeNoExceptVoidFunctor() {
728
- static_assert(false, __FUNCTION__ ": not a noexcept callable functor returning void");
733
+ static_assert(details::always_false<T>, __FUNCTION__ ": not a noexcept callable functor returning void");
729
734
  }
730
735
 
731
736
  template <typename TInvoke, typename TOnCancel>
@@ -39,8 +39,12 @@ constexpr const char *dumpSampledTraceToFileSymbol =
39
39
  "?dumpSampledTraceToFile@HermesRuntime@hermes@facebook@@SAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z";
40
40
  #endif
41
41
 
42
+ static std::once_flag s_hermesLoading;
43
+
42
44
  static void EnsureHermesLoaded() noexcept {
43
- if (!s_hermesModule) {
45
+ std::call_once(s_hermesLoading, []() {
46
+ VerifyElseCrashSz(!s_hermesModule, "Invalid state: \"hermes.dll\" being loaded again.");
47
+
44
48
  s_hermesModule = LoadLibrary(L"hermes.dll");
45
49
  VerifyElseCrashSz(s_hermesModule, "Could not load \"hermes.dll\"");
46
50
 
@@ -59,7 +63,7 @@ static void EnsureHermesLoaded() noexcept {
59
63
  s_dumpSampledTraceToFile = reinterpret_cast<decltype(s_dumpSampledTraceToFile)>(
60
64
  GetProcAddress(s_hermesModule, dumpSampledTraceToFileSymbol));
61
65
  VerifyElseCrash(s_dumpSampledTraceToFile);
62
- }
66
+ });
63
67
  }
64
68
 
65
69
  std::unique_ptr<facebook::hermes::HermesRuntime> makeHermesRuntime(const hermes::vm::RuntimeConfig &runtimeConfig) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.66.13",
3
+ "version": "0.66.16",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",