react-native-windows 0.67.0-preview.5 → 0.67.1
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 +167 -5
- package/CHANGELOG.md +71 -5
- package/Libraries/Components/Keyboard/Keyboard.js +2 -2
- package/Libraries/Components/Pressable/Pressable.windows.js +33 -0
- package/Libraries/Core/ReactNativeVersion.js +3 -3
- package/Libraries/Pressability/HoverState.js +4 -0
- package/Microsoft.ReactNative/JsiApi.cpp +3 -3
- package/Microsoft.ReactNative/JsiApi.h +4 -4
- package/Microsoft.ReactNative/Modules/CreateModules.cpp +2 -2
- package/Microsoft.ReactNative/Modules/PaperUIManagerModule.cpp +1 -1
- package/Microsoft.ReactNative/ReactHost/ReactContext.h +2 -2
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +1 -1
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
- package/Microsoft.ReactNative.Cxx/NativeModules.h +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +2 -2
- package/Shared/ChakraRuntimeHolder.cpp +4 -0
- package/Shared/ChakraRuntimeHolder.h +2 -1
- package/Shared/DevSettings.h +3 -5
- package/Shared/HermesRuntimeHolder.cpp +4 -0
- package/Shared/HermesRuntimeHolder.h +2 -1
- package/Shared/IWebSocketResource.h +6 -6
- package/Shared/InspectorPackagerConnection.cpp +2 -3
- package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +6 -2
- package/Shared/JSI/NapiJsiV8RuntimeHolder.h +2 -1
- package/Shared/JSI/RuntimeHolder.h +5 -4
- package/Shared/Modules/WebSocketModule.cpp +133 -120
- package/Shared/Modules/WebSocketModule.h +22 -12
- package/Shared/OInstance.cpp +17 -4
- package/Shared/V8JSIRuntimeHolder.cpp +4 -0
- package/Shared/V8JSIRuntimeHolder.h +2 -1
- package/Shared/WinRTWebSocketResource.cpp +55 -46
- package/Shared/WinRTWebSocketResource.h +2 -9
- package/jest/preprocessor.js +7 -75
- package/package.json +8 -8
- package/template/shared-app/proj/NuGet.Config +2 -0
|
@@ -96,7 +96,11 @@ void NapiJsiV8RuntimeHolder::InitRuntime() noexcept {
|
|
|
96
96
|
m_ownThreadId = std::this_thread::get_id();
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
#pragma region
|
|
99
|
+
#pragma region Microsoft::JSI::RuntimeHolderLazyInit
|
|
100
|
+
|
|
101
|
+
facebook::react::JSIEngineOverride NapiJsiV8RuntimeHolder::getRuntimeType() noexcept {
|
|
102
|
+
return facebook::react::JSIEngineOverride::V8NodeApi;
|
|
103
|
+
}
|
|
100
104
|
|
|
101
105
|
shared_ptr<Runtime> NapiJsiV8RuntimeHolder::getRuntime() noexcept /*override*/
|
|
102
106
|
{
|
|
@@ -112,6 +116,6 @@ shared_ptr<Runtime> NapiJsiV8RuntimeHolder::getRuntime() noexcept /*override*/
|
|
|
112
116
|
return m_runtime;
|
|
113
117
|
}
|
|
114
118
|
|
|
115
|
-
#pragma endregion
|
|
119
|
+
#pragma endregion Microsoft::JSI::RuntimeHolderLazyInit
|
|
116
120
|
|
|
117
121
|
} // namespace Microsoft::JSI
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
namespace Microsoft::JSI {
|
|
12
12
|
|
|
13
|
-
class NapiJsiV8RuntimeHolder : public
|
|
13
|
+
class NapiJsiV8RuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
|
|
14
14
|
public:
|
|
15
15
|
std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept override;
|
|
16
|
+
facebook::react::JSIEngineOverride getRuntimeType() noexcept override;
|
|
16
17
|
|
|
17
18
|
NapiJsiV8RuntimeHolder(
|
|
18
19
|
std::shared_ptr<facebook::react::DevSettings> devSettings,
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
#include <jsi/jsi.h>
|
|
4
4
|
#include <memory>
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
#include <DevSettings.h>
|
|
7
|
+
|
|
8
|
+
namespace Microsoft::JSI {
|
|
8
9
|
|
|
9
10
|
// An instance of this interface is expected to
|
|
10
11
|
// a. lazily create a JSI Runtime on the first call to getRuntime
|
|
@@ -15,7 +16,7 @@ namespace jsi {
|
|
|
15
16
|
|
|
16
17
|
struct RuntimeHolderLazyInit {
|
|
17
18
|
virtual std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept = 0;
|
|
19
|
+
virtual facebook::react::JSIEngineOverride getRuntimeType() noexcept = 0;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
|
-
} // namespace
|
|
21
|
-
} // namespace facebook
|
|
22
|
+
} // namespace Microsoft::JSI
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
#include <iomanip>
|
|
15
15
|
|
|
16
16
|
using namespace facebook::xplat;
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
using facebook::react::Instance;
|
|
19
|
+
using folly::dynamic;
|
|
18
20
|
|
|
19
21
|
using Microsoft::Common::Unicode::Utf16ToUtf8;
|
|
20
22
|
using Microsoft::Common::Unicode::Utf8ToUtf16;
|
|
@@ -24,17 +26,111 @@ using std::string;
|
|
|
24
26
|
using std::weak_ptr;
|
|
25
27
|
|
|
26
28
|
namespace {
|
|
29
|
+
using Microsoft::React::IWebSocketResource;
|
|
30
|
+
using Microsoft::React::WebSocketModule;
|
|
31
|
+
|
|
27
32
|
constexpr char moduleName[] = "WebSocketModule";
|
|
33
|
+
|
|
34
|
+
static void SendEvent(weak_ptr<Instance> weakInstance, string &&eventName, dynamic &&args) {
|
|
35
|
+
if (auto instance = weakInstance.lock()) {
|
|
36
|
+
instance->callJSFunction("RCTDeviceEventEmitter", "emit", dynamic::array(std::move(eventName), std::move(args)));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static shared_ptr<IWebSocketResource>
|
|
41
|
+
GetOrCreateWebSocket(int64_t id, string &&url, weak_ptr<WebSocketModule::SharedState> weakState) {
|
|
42
|
+
auto state = weakState.lock();
|
|
43
|
+
if (!state) {
|
|
44
|
+
return nullptr;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
auto itr = state->ResourceMap.find(id);
|
|
48
|
+
if (itr == state->ResourceMap.end()) {
|
|
49
|
+
if (!state->Module) {
|
|
50
|
+
return nullptr;
|
|
51
|
+
}
|
|
52
|
+
auto weakInstance = state->Module->getInstance();
|
|
53
|
+
|
|
54
|
+
shared_ptr<IWebSocketResource> ws;
|
|
55
|
+
try {
|
|
56
|
+
ws = state->ResourceFactory(std::move(url));
|
|
57
|
+
} catch (const winrt::hresult_error &e) {
|
|
58
|
+
std::stringstream ss;
|
|
59
|
+
ss << "[" << std::hex << std::showbase << std::setw(8) << static_cast<uint32_t>(e.code()) << "] "
|
|
60
|
+
<< winrt::to_string(e.message());
|
|
61
|
+
|
|
62
|
+
SendEvent(weakInstance, "webSocketFailed", dynamic::object("id", id)("message", std::move(ss.str())));
|
|
63
|
+
|
|
64
|
+
return nullptr;
|
|
65
|
+
} catch (const std::exception &e) {
|
|
66
|
+
SendEvent(weakInstance, "webSocketFailed", dynamic::object("id", id)("message", e.what()));
|
|
67
|
+
|
|
68
|
+
return nullptr;
|
|
69
|
+
} catch (...) {
|
|
70
|
+
SendEvent(
|
|
71
|
+
weakInstance,
|
|
72
|
+
"webSocketFailed",
|
|
73
|
+
dynamic::object("id", id)("message", "Unidentified error creating IWebSocketResource"));
|
|
74
|
+
|
|
75
|
+
return nullptr;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ws->SetOnError([id, weakInstance](const IWebSocketResource::Error &err) {
|
|
79
|
+
auto strongInstance = weakInstance.lock();
|
|
80
|
+
if (!strongInstance)
|
|
81
|
+
return;
|
|
82
|
+
|
|
83
|
+
auto errorObj = dynamic::object("id", id)("message", err.Message);
|
|
84
|
+
SendEvent(weakInstance, "websocketFailed", std::move(errorObj));
|
|
85
|
+
});
|
|
86
|
+
ws->SetOnConnect([id, weakInstance]() {
|
|
87
|
+
auto strongInstance = weakInstance.lock();
|
|
88
|
+
if (!strongInstance)
|
|
89
|
+
return;
|
|
90
|
+
|
|
91
|
+
auto args = dynamic::object("id", id);
|
|
92
|
+
SendEvent(weakInstance, "websocketOpen", std::move(args));
|
|
93
|
+
});
|
|
94
|
+
ws->SetOnMessage([id, weakInstance](size_t length, const string &message, bool isBinary) {
|
|
95
|
+
auto strongInstance = weakInstance.lock();
|
|
96
|
+
if (!strongInstance)
|
|
97
|
+
return;
|
|
98
|
+
|
|
99
|
+
auto args = dynamic::object("id", id)("data", message)("type", isBinary ? "binary" : "text");
|
|
100
|
+
SendEvent(weakInstance, "websocketMessage", std::move(args));
|
|
101
|
+
});
|
|
102
|
+
ws->SetOnClose([id, weakInstance](IWebSocketResource::CloseCode code, const string &reason) {
|
|
103
|
+
auto strongInstance = weakInstance.lock();
|
|
104
|
+
if (!strongInstance)
|
|
105
|
+
return;
|
|
106
|
+
|
|
107
|
+
auto args = dynamic::object("id", id)("code", static_cast<uint16_t>(code))("reason", reason);
|
|
108
|
+
SendEvent(weakInstance, "websocketClosed", std::move(args));
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
state->ResourceMap.emplace(id, ws);
|
|
112
|
+
return ws;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return itr->second;
|
|
116
|
+
}
|
|
117
|
+
|
|
28
118
|
} // anonymous namespace
|
|
29
119
|
|
|
30
120
|
namespace Microsoft::React {
|
|
31
121
|
|
|
32
|
-
WebSocketModule::WebSocketModule()
|
|
33
|
-
|
|
122
|
+
WebSocketModule::WebSocketModule() : m_sharedState{std::make_shared<SharedState>()} {
|
|
123
|
+
m_sharedState->ResourceFactory = [](string &&url) { return IWebSocketResource::Make(); };
|
|
124
|
+
m_sharedState->Module = this;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
WebSocketModule::~WebSocketModule() noexcept /*override*/ {
|
|
128
|
+
m_sharedState->Module = nullptr;
|
|
129
|
+
}
|
|
34
130
|
|
|
35
131
|
void WebSocketModule::SetResourceFactory(
|
|
36
132
|
std::function<shared_ptr<IWebSocketResource>(const string &)> &&resourceFactory) {
|
|
37
|
-
|
|
133
|
+
m_sharedState->ResourceFactory = std::move(resourceFactory);
|
|
38
134
|
}
|
|
39
135
|
|
|
40
136
|
string WebSocketModule::getName() {
|
|
@@ -50,9 +146,9 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
|
|
|
50
146
|
{
|
|
51
147
|
return
|
|
52
148
|
{
|
|
53
|
-
|
|
149
|
+
{
|
|
54
150
|
"connect",
|
|
55
|
-
[
|
|
151
|
+
[weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // const string& url, dynamic protocols, dynamic options, int64_t id
|
|
56
152
|
{
|
|
57
153
|
IWebSocketResource::Protocols protocols;
|
|
58
154
|
dynamic protocolsDynamic = jsArgAsDynamic(args, 1);
|
|
@@ -75,20 +171,21 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
|
|
|
75
171
|
}
|
|
76
172
|
}
|
|
77
173
|
|
|
78
|
-
weak_ptr weakWs =
|
|
174
|
+
weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 3), jsArgAsString(args, 0), weakState);
|
|
79
175
|
if (auto sharedWs = weakWs.lock())
|
|
80
176
|
{
|
|
81
|
-
sharedWs->Connect(protocols, options);
|
|
177
|
+
sharedWs->Connect(jsArgAsString(args, 0), protocols, options);
|
|
82
178
|
}
|
|
83
|
-
}
|
|
84
|
-
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
{
|
|
85
182
|
"close",
|
|
86
|
-
[
|
|
183
|
+
[weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // [int64_t code, string reason,] int64_t id
|
|
87
184
|
{
|
|
88
185
|
// See react-native\Libraries\WebSocket\WebSocket.js:_close
|
|
89
186
|
if (args.size() == 3) // WebSocketModule.close(statusCode, closeReason, this._socketId);
|
|
90
187
|
{
|
|
91
|
-
weak_ptr weakWs =
|
|
188
|
+
weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 2), {}, weakState);
|
|
92
189
|
if (auto sharedWs = weakWs.lock())
|
|
93
190
|
{
|
|
94
191
|
sharedWs->Close(static_cast<IWebSocketResource::CloseCode>(jsArgAsInt(args, 0)), jsArgAsString(args, 1));
|
|
@@ -96,7 +193,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
|
|
|
96
193
|
}
|
|
97
194
|
else if (args.size() == 1) // WebSocketModule.close(this._socketId);
|
|
98
195
|
{
|
|
99
|
-
weak_ptr weakWs =
|
|
196
|
+
weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 0), {}, weakState);
|
|
100
197
|
if (auto sharedWs = weakWs.lock())
|
|
101
198
|
{
|
|
102
199
|
sharedWs->Close(IWebSocketResource::CloseCode::Normal, {});
|
|
@@ -104,137 +201,53 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
|
|
|
104
201
|
}
|
|
105
202
|
else
|
|
106
203
|
{
|
|
107
|
-
auto
|
|
108
|
-
|
|
204
|
+
auto state = weakState.lock();
|
|
205
|
+
if (state && state->Module) {
|
|
206
|
+
auto errorObj = dynamic::object("id", -1)("message", "Incorrect number of parameters");
|
|
207
|
+
SendEvent(state->Module->getInstance(), "websocketFailed", std::move(errorObj));
|
|
208
|
+
}
|
|
109
209
|
}
|
|
110
|
-
}
|
|
111
|
-
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
{
|
|
112
213
|
"send",
|
|
113
|
-
[
|
|
214
|
+
[weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // const string& message, int64_t id
|
|
114
215
|
{
|
|
115
|
-
weak_ptr weakWs =
|
|
216
|
+
weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 1), {}, weakState);
|
|
116
217
|
if (auto sharedWs = weakWs.lock())
|
|
117
218
|
{
|
|
118
219
|
sharedWs->Send(jsArgAsString(args, 0));
|
|
119
220
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
{
|
|
122
224
|
"sendBinary",
|
|
123
|
-
[
|
|
225
|
+
[weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // const string& base64String, int64_t id
|
|
124
226
|
{
|
|
125
|
-
weak_ptr weakWs =
|
|
227
|
+
weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 1), {}, weakState);
|
|
126
228
|
if (auto sharedWs = weakWs.lock())
|
|
127
229
|
{
|
|
128
230
|
sharedWs->SendBinary(jsArgAsString(args, 0));
|
|
129
231
|
}
|
|
130
|
-
}
|
|
131
|
-
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
{
|
|
132
235
|
"ping",
|
|
133
|
-
[
|
|
236
|
+
[weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // int64_t id
|
|
134
237
|
{
|
|
135
|
-
weak_ptr weakWs =
|
|
238
|
+
weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 0), {}, weakState);
|
|
136
239
|
if (auto sharedWs = weakWs.lock())
|
|
137
240
|
{
|
|
138
241
|
sharedWs->Ping();
|
|
139
242
|
}
|
|
140
|
-
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
141
245
|
};
|
|
142
246
|
} // getMethods
|
|
143
247
|
// clang-format on
|
|
144
248
|
|
|
145
|
-
#pragma region private members
|
|
146
|
-
|
|
147
|
-
void WebSocketModule::SendEvent(string &&eventName, dynamic &&args) {
|
|
148
|
-
auto weakInstance = this->getInstance();
|
|
149
|
-
if (auto instance = weakInstance.lock()) {
|
|
150
|
-
instance->callJSFunction("RCTDeviceEventEmitter", "emit", dynamic::array(std::move(eventName), std::move(args)));
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// clang-format off
|
|
155
|
-
shared_ptr<IWebSocketResource> WebSocketModule::GetOrCreateWebSocket(int64_t id, string&& url)
|
|
156
|
-
{
|
|
157
|
-
auto itr = m_webSockets.find(id);
|
|
158
|
-
if (itr == m_webSockets.end())
|
|
159
|
-
{
|
|
160
|
-
shared_ptr<IWebSocketResource> ws;
|
|
161
|
-
try
|
|
162
|
-
{
|
|
163
|
-
ws = m_resourceFactory(std::move(url));
|
|
164
|
-
}
|
|
165
|
-
catch (const winrt::hresult_error& e)
|
|
166
|
-
{
|
|
167
|
-
std::stringstream ss;
|
|
168
|
-
ss << "[" << std::hex << std::showbase << std::setw(8) << static_cast<uint32_t>(e.code()) << "] " <<
|
|
169
|
-
winrt::to_string(e.message());
|
|
170
|
-
|
|
171
|
-
SendEvent("webSocketFailed", dynamic::object("id", id)("message", std::move(ss.str())));
|
|
172
|
-
|
|
173
|
-
return nullptr;
|
|
174
|
-
}
|
|
175
|
-
catch (const std::exception& e)
|
|
176
|
-
{
|
|
177
|
-
SendEvent("webSocketFailed", dynamic::object("id", id)("message", e.what()));
|
|
178
|
-
|
|
179
|
-
return nullptr;
|
|
180
|
-
}
|
|
181
|
-
catch (...)
|
|
182
|
-
{
|
|
183
|
-
SendEvent("webSocketFailed", dynamic::object("id", id)("message", "Unidentified error creating IWebSocketResource"));
|
|
184
|
-
|
|
185
|
-
return nullptr;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
auto weakInstance = this->getInstance();
|
|
189
|
-
ws->SetOnError([this, id, weakInstance](const IWebSocketResource::Error& err)
|
|
190
|
-
{
|
|
191
|
-
auto strongInstance = weakInstance.lock();
|
|
192
|
-
if (!strongInstance)
|
|
193
|
-
return;
|
|
194
|
-
|
|
195
|
-
auto errorObj = dynamic::object("id", id)("message", err.Message);
|
|
196
|
-
this->SendEvent("websocketFailed", std::move(errorObj));
|
|
197
|
-
});
|
|
198
|
-
ws->SetOnConnect([this, id, weakInstance]()
|
|
199
|
-
{
|
|
200
|
-
auto strongInstance = weakInstance.lock();
|
|
201
|
-
if (!strongInstance)
|
|
202
|
-
return;
|
|
203
|
-
|
|
204
|
-
auto args = dynamic::object("id", id);
|
|
205
|
-
this->SendEvent("websocketOpen", std::move(args));
|
|
206
|
-
});
|
|
207
|
-
ws->SetOnMessage([this, id, weakInstance](size_t length, const string& message, bool isBinary)
|
|
208
|
-
{
|
|
209
|
-
auto strongInstance = weakInstance.lock();
|
|
210
|
-
if (!strongInstance)
|
|
211
|
-
return;
|
|
212
|
-
|
|
213
|
-
auto args = dynamic::object("id", id)("data", message)("type", isBinary ? "binary" : "text");
|
|
214
|
-
this->SendEvent("websocketMessage", std::move(args));
|
|
215
|
-
});
|
|
216
|
-
ws->SetOnClose([this, id, weakInstance](IWebSocketResource::CloseCode code, const string& reason)
|
|
217
|
-
{
|
|
218
|
-
auto strongInstance = weakInstance.lock();
|
|
219
|
-
if (!strongInstance)
|
|
220
|
-
return;
|
|
221
|
-
|
|
222
|
-
auto args = dynamic::object("id", id)("code", static_cast<uint16_t>(code))("reason", reason);
|
|
223
|
-
this->SendEvent("websocketClosed", std::move(args));
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
m_webSockets.emplace(id, ws);
|
|
227
|
-
return ws;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return itr->second;
|
|
231
|
-
}
|
|
232
|
-
// clang-format on
|
|
233
|
-
|
|
234
|
-
#pragma endregion private members
|
|
235
|
-
|
|
236
249
|
/*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateWebSocketModule() noexcept {
|
|
237
|
-
return make_unique<WebSocketModule>();
|
|
250
|
+
return std::make_unique<WebSocketModule>();
|
|
238
251
|
}
|
|
239
252
|
|
|
240
253
|
} // namespace Microsoft::React
|
|
@@ -18,6 +18,26 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
|
|
|
18
18
|
|
|
19
19
|
WebSocketModule();
|
|
20
20
|
|
|
21
|
+
~WebSocketModule() noexcept override;
|
|
22
|
+
|
|
23
|
+
struct SharedState {
|
|
24
|
+
/// <summary>
|
|
25
|
+
/// Keeps <c>IWebSocketResource</c> instances identified by <c>id</c>.
|
|
26
|
+
/// As defined in WebSocket.js.
|
|
27
|
+
/// </summary>
|
|
28
|
+
std::map<int64_t, std::shared_ptr<IWebSocketResource>> ResourceMap{};
|
|
29
|
+
|
|
30
|
+
/// <summary>
|
|
31
|
+
/// Generates IWebSocketResource instances, defaulting to IWebSocketResource::Make.
|
|
32
|
+
/// </summary>
|
|
33
|
+
std::function<std::shared_ptr<IWebSocketResource>(std::string &&)> ResourceFactory;
|
|
34
|
+
|
|
35
|
+
/// <summary>
|
|
36
|
+
/// Keeps a raw reference to the module object to lazily retrieve the React Instance as needed.
|
|
37
|
+
/// </summary>
|
|
38
|
+
CxxModule *Module{nullptr};
|
|
39
|
+
};
|
|
40
|
+
|
|
21
41
|
#pragma region CxxModule overrides
|
|
22
42
|
|
|
23
43
|
/// <summary>
|
|
@@ -41,16 +61,6 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
|
|
|
41
61
|
void SetResourceFactory(std::function<std::shared_ptr<IWebSocketResource>(const std::string &)> &&resourceFactory);
|
|
42
62
|
|
|
43
63
|
private:
|
|
44
|
-
/// <summary>
|
|
45
|
-
/// Notifies an event to the current React Instance.
|
|
46
|
-
/// </summary>
|
|
47
|
-
void SendEvent(std::string &&eventName, folly::dynamic &¶meters);
|
|
48
|
-
|
|
49
|
-
/// <summary>
|
|
50
|
-
/// Creates or retrieves a raw <c>IWebSocketResource</c> pointer.
|
|
51
|
-
/// </summary>
|
|
52
|
-
std::shared_ptr<IWebSocketResource> GetOrCreateWebSocket(std::int64_t id, std::string &&url = {});
|
|
53
|
-
|
|
54
64
|
/// <summary>
|
|
55
65
|
/// Keeps <c>IWebSocketResource</c> instances identified by <c>id</c>.
|
|
56
66
|
/// As defined in WebSocket.js.
|
|
@@ -58,9 +68,9 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
|
|
|
58
68
|
std::map<int64_t, std::shared_ptr<IWebSocketResource>> m_webSockets;
|
|
59
69
|
|
|
60
70
|
/// <summary>
|
|
61
|
-
///
|
|
71
|
+
/// Keeps members that can be accessed threads other than this module's owner accessible.
|
|
62
72
|
/// </summary>
|
|
63
|
-
std::
|
|
73
|
+
std::shared_ptr<SharedState> m_sharedState;
|
|
64
74
|
};
|
|
65
75
|
|
|
66
76
|
} // namespace Microsoft::React
|
package/Shared/OInstance.cpp
CHANGED
|
@@ -193,7 +193,7 @@ class OJSIExecutorFactory : public JSExecutorFactory {
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
OJSIExecutorFactory(
|
|
196
|
-
std::shared_ptr<
|
|
196
|
+
std::shared_ptr<Microsoft::JSI::RuntimeHolderLazyInit> runtimeHolder,
|
|
197
197
|
NativeLoggingHook loggingHook,
|
|
198
198
|
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry,
|
|
199
199
|
bool isProfilingEnabled,
|
|
@@ -205,7 +205,7 @@ class OJSIExecutorFactory : public JSExecutorFactory {
|
|
|
205
205
|
isProfilingEnabled_{isProfilingEnabled} {}
|
|
206
206
|
|
|
207
207
|
private:
|
|
208
|
-
std::shared_ptr<
|
|
208
|
+
std::shared_ptr<Microsoft::JSI::RuntimeHolderLazyInit> runtimeHolder_;
|
|
209
209
|
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry_;
|
|
210
210
|
std::shared_ptr<CallInvoker> jsCallInvoker_;
|
|
211
211
|
NativeLoggingHook loggingHook_;
|
|
@@ -278,6 +278,20 @@ void InstanceImpl::SetInError() noexcept {
|
|
|
278
278
|
m_isInError = true;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
namespace {
|
|
282
|
+
bool shouldStartHermesInspector(DevSettings &devSettings) {
|
|
283
|
+
bool isHermes =
|
|
284
|
+
((devSettings.jsiEngineOverride == JSIEngineOverride::Hermes) ||
|
|
285
|
+
(devSettings.jsiEngineOverride == JSIEngineOverride::Default && devSettings.jsiRuntimeHolder &&
|
|
286
|
+
devSettings.jsiRuntimeHolder->getRuntimeType() == facebook::react::JSIEngineOverride::Hermes));
|
|
287
|
+
|
|
288
|
+
if (isHermes && devSettings.useDirectDebugger && !devSettings.useWebDebugger)
|
|
289
|
+
return true;
|
|
290
|
+
else
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
} // namespace
|
|
294
|
+
|
|
281
295
|
InstanceImpl::InstanceImpl(
|
|
282
296
|
std::shared_ptr<Instance> &&instance,
|
|
283
297
|
std::string &&jsBundleBasePath,
|
|
@@ -305,8 +319,7 @@ InstanceImpl::InstanceImpl(
|
|
|
305
319
|
facebook::react::tracing::initializeETW();
|
|
306
320
|
#endif
|
|
307
321
|
|
|
308
|
-
if (m_devSettings
|
|
309
|
-
!m_devSettings->useWebDebugger) {
|
|
322
|
+
if (shouldStartHermesInspector(*m_devSettings)) {
|
|
310
323
|
m_devManager->StartInspector(m_devSettings->sourceBundleHost, m_devSettings->sourceBundlePort);
|
|
311
324
|
}
|
|
312
325
|
|
|
@@ -31,6 +31,10 @@ class TaskRunnerAdapter : public v8runtime::JSITaskRunner {
|
|
|
31
31
|
std::shared_ptr<facebook::react::MessageQueueThread> jsQueue_;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
facebook::react::JSIEngineOverride V8JSIRuntimeHolder::getRuntimeType() noexcept {
|
|
35
|
+
return facebook::react::JSIEngineOverride::V8;
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
std::shared_ptr<facebook::jsi::Runtime> V8JSIRuntimeHolder::getRuntime() noexcept {
|
|
35
39
|
std::call_once(once_flag_, [this]() { initRuntime(); });
|
|
36
40
|
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
namespace facebook {
|
|
14
14
|
namespace react {
|
|
15
15
|
|
|
16
|
-
class V8JSIRuntimeHolder : public
|
|
16
|
+
class V8JSIRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
|
|
17
17
|
public:
|
|
18
18
|
std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept override;
|
|
19
|
+
facebook::react::JSIEngineOverride getRuntimeType() noexcept override;
|
|
19
20
|
|
|
20
21
|
V8JSIRuntimeHolder(
|
|
21
22
|
std::shared_ptr<facebook::react::DevSettings> devSettings,
|
|
@@ -90,29 +90,21 @@ namespace Microsoft::React {
|
|
|
90
90
|
// private
|
|
91
91
|
WinRTWebSocketResource::WinRTWebSocketResource(
|
|
92
92
|
IMessageWebSocket &&socket,
|
|
93
|
-
Uri &&uri,
|
|
94
93
|
vector<ChainValidationResult> &&certExceptions)
|
|
95
|
-
: WinRTWebSocketResource(
|
|
96
|
-
std::move(socket),
|
|
97
|
-
DataWriter{socket.OutputStream()},
|
|
98
|
-
std::move(uri),
|
|
99
|
-
std::move(certExceptions)) {}
|
|
94
|
+
: WinRTWebSocketResource(std::move(socket), DataWriter{socket.OutputStream()}, std::move(certExceptions)) {}
|
|
100
95
|
|
|
101
96
|
WinRTWebSocketResource::WinRTWebSocketResource(
|
|
102
97
|
IMessageWebSocket &&socket,
|
|
103
98
|
IDataWriter &&writer,
|
|
104
|
-
Uri &&uri,
|
|
105
99
|
vector<ChainValidationResult> &&certExceptions)
|
|
106
|
-
:
|
|
107
|
-
m_socket.MessageReceived({this, &WinRTWebSocketResource::OnMessageReceived});
|
|
108
|
-
|
|
100
|
+
: m_socket{std::move(socket)}, m_writer{std::move(writer)} {
|
|
109
101
|
for (const auto &certException : certExceptions) {
|
|
110
102
|
m_socket.Control().IgnorableServerCertificateErrors().Append(certException);
|
|
111
103
|
}
|
|
112
104
|
}
|
|
113
105
|
|
|
114
|
-
WinRTWebSocketResource::WinRTWebSocketResource(
|
|
115
|
-
: WinRTWebSocketResource(MessageWebSocket{},
|
|
106
|
+
WinRTWebSocketResource::WinRTWebSocketResource(vector<ChainValidationResult> &&certExceptions)
|
|
107
|
+
: WinRTWebSocketResource(MessageWebSocket{}, std::move(certExceptions)) {}
|
|
116
108
|
|
|
117
109
|
WinRTWebSocketResource::~WinRTWebSocketResource() noexcept /*override*/
|
|
118
110
|
{
|
|
@@ -123,13 +115,14 @@ WinRTWebSocketResource::~WinRTWebSocketResource() noexcept /*override*/
|
|
|
123
115
|
|
|
124
116
|
#pragma region Private members
|
|
125
117
|
|
|
126
|
-
IAsyncAction WinRTWebSocketResource::PerformConnect() noexcept {
|
|
118
|
+
IAsyncAction WinRTWebSocketResource::PerformConnect(Uri &&uri) noexcept {
|
|
127
119
|
auto self = shared_from_this();
|
|
120
|
+
auto coUri = std::move(uri);
|
|
128
121
|
|
|
129
122
|
co_await resume_background();
|
|
130
123
|
|
|
131
124
|
try {
|
|
132
|
-
auto async = self->m_socket.ConnectAsync(
|
|
125
|
+
auto async = self->m_socket.ConnectAsync(coUri);
|
|
133
126
|
|
|
134
127
|
co_await lessthrow_await_adapter<IAsyncAction>{async};
|
|
135
128
|
|
|
@@ -293,36 +286,6 @@ fire_and_forget WinRTWebSocketResource::PerformClose() noexcept {
|
|
|
293
286
|
m_closePerformed.Set();
|
|
294
287
|
}
|
|
295
288
|
|
|
296
|
-
void WinRTWebSocketResource::OnMessageReceived(
|
|
297
|
-
IWebSocket const &sender,
|
|
298
|
-
IMessageWebSocketMessageReceivedEventArgs const &args) {
|
|
299
|
-
try {
|
|
300
|
-
string response;
|
|
301
|
-
IDataReader reader = args.GetDataReader();
|
|
302
|
-
auto len = reader.UnconsumedBufferLength();
|
|
303
|
-
if (args.MessageType() == SocketMessageType::Utf8) {
|
|
304
|
-
reader.UnicodeEncoding(UnicodeEncoding::Utf8);
|
|
305
|
-
vector<uint8_t> data(len);
|
|
306
|
-
reader.ReadBytes(data);
|
|
307
|
-
|
|
308
|
-
response = string(CheckedReinterpretCast<char *>(data.data()), data.size());
|
|
309
|
-
} else {
|
|
310
|
-
auto buffer = reader.ReadBuffer(len);
|
|
311
|
-
winrt::hstring data = CryptographicBuffer::EncodeToBase64String(buffer);
|
|
312
|
-
|
|
313
|
-
response = winrt::to_string(std::wstring_view(data));
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (m_readHandler) {
|
|
317
|
-
m_readHandler(response.length(), response, args.MessageType() == SocketMessageType::Binary);
|
|
318
|
-
}
|
|
319
|
-
} catch (hresult_error const &e) {
|
|
320
|
-
if (m_errorHandler) {
|
|
321
|
-
m_errorHandler({HResultToString(e), ErrorType::Receive});
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
289
|
void WinRTWebSocketResource::Synchronize() noexcept {
|
|
327
290
|
// Ensure sequence of other operations
|
|
328
291
|
if (m_connectRequested) {
|
|
@@ -334,7 +297,36 @@ void WinRTWebSocketResource::Synchronize() noexcept {
|
|
|
334
297
|
|
|
335
298
|
#pragma region IWebSocketResource
|
|
336
299
|
|
|
337
|
-
void WinRTWebSocketResource::Connect(const Protocols &protocols, const Options &options) noexcept {
|
|
300
|
+
void WinRTWebSocketResource::Connect(string &&url, const Protocols &protocols, const Options &options) noexcept {
|
|
301
|
+
m_socket.MessageReceived(
|
|
302
|
+
[self = shared_from_this()](IWebSocket const &sender, IMessageWebSocketMessageReceivedEventArgs const &args) {
|
|
303
|
+
try {
|
|
304
|
+
string response;
|
|
305
|
+
IDataReader reader = args.GetDataReader();
|
|
306
|
+
auto len = reader.UnconsumedBufferLength();
|
|
307
|
+
if (args.MessageType() == SocketMessageType::Utf8) {
|
|
308
|
+
reader.UnicodeEncoding(UnicodeEncoding::Utf8);
|
|
309
|
+
vector<uint8_t> data(len);
|
|
310
|
+
reader.ReadBytes(data);
|
|
311
|
+
|
|
312
|
+
response = string(CheckedReinterpretCast<char *>(data.data()), data.size());
|
|
313
|
+
} else {
|
|
314
|
+
auto buffer = reader.ReadBuffer(len);
|
|
315
|
+
winrt::hstring data = CryptographicBuffer::EncodeToBase64String(buffer);
|
|
316
|
+
|
|
317
|
+
response = winrt::to_string(std::wstring_view(data));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (self->m_readHandler) {
|
|
321
|
+
self->m_readHandler(response.length(), response, args.MessageType() == SocketMessageType::Binary);
|
|
322
|
+
}
|
|
323
|
+
} catch (hresult_error const &e) {
|
|
324
|
+
if (self->m_errorHandler) {
|
|
325
|
+
self->m_errorHandler({HResultToString(e), ErrorType::Receive});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
338
330
|
m_readyState = ReadyState::Connecting;
|
|
339
331
|
|
|
340
332
|
for (const auto &header : options) {
|
|
@@ -348,7 +340,24 @@ void WinRTWebSocketResource::Connect(const Protocols &protocols, const Options &
|
|
|
348
340
|
}
|
|
349
341
|
|
|
350
342
|
m_connectRequested = true;
|
|
351
|
-
|
|
343
|
+
|
|
344
|
+
Uri uri{nullptr};
|
|
345
|
+
try {
|
|
346
|
+
uri = Uri{winrt::to_hstring(url)};
|
|
347
|
+
} catch (hresult_error const &e) {
|
|
348
|
+
if (m_errorHandler) {
|
|
349
|
+
m_errorHandler({HResultToString(e), ErrorType::Connection});
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Abort - Mark connection as concluded.
|
|
353
|
+
SetEvent(m_connectPerformed.get());
|
|
354
|
+
m_connectPerformedPromise.set_value();
|
|
355
|
+
m_connectRequested = false;
|
|
356
|
+
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
PerformConnect(std::move(uri));
|
|
352
361
|
}
|
|
353
362
|
|
|
354
363
|
void WinRTWebSocketResource::Ping() noexcept {
|