mirror of
https://github.com/status-im/react-native.git
synced 2025-02-03 21:24:31 +00:00
Add native delta client for Metro
Summary: Adds C++ delta client that keeps modules in memory, and can be used as a RAM bundle. For now, this client expects a `folly::dynamic` object as payload for patches, i.e. the JSON response retrieved from Metro needs to be parsed with `folly::parseJson` by the caller. In the future, we will replace JSON with a streaming friendly binary format. Reviewed By: fromcelticpark Differential Revision: D7845136 fbshipit-source-id: f003f98a2607c8354c427a7e60e01e19e20295b1
This commit is contained in:
parent
e8662a2123
commit
4d931d529e
@ -82,7 +82,7 @@ JSModulesUnbundle::Module JniJSModulesUnbundle::getModule(uint32_t moduleId) con
|
||||
buffer = static_cast<const char *>(AAsset_getBuffer(asset.get()));
|
||||
}
|
||||
if (buffer == nullptr) {
|
||||
throw ModuleNotFound("Module not found: " + sourceUrl);
|
||||
throw ModuleNotFound(moduleId);
|
||||
}
|
||||
return {sourceUrl, std::string(buffer, AAsset_getLength(asset.get()))};
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ LOCAL_SRC_FILES := \
|
||||
JSCSamplingProfiler.cpp \
|
||||
JSCTracing.cpp \
|
||||
JSCUtils.cpp \
|
||||
JSDeltaBundleClient.cpp \
|
||||
JSExecutor.cpp \
|
||||
JSIndexedRAMBundle.cpp \
|
||||
MethodCall.cpp \
|
||||
|
@ -92,6 +92,7 @@ CXXREACT_PUBLIC_HEADERS = [
|
||||
"JSCExecutor.h",
|
||||
"JSCNativeModules.h",
|
||||
"JSCUtils.h",
|
||||
"JSDeltaBundleClient.h",
|
||||
"JSIndexedRAMBundle.h",
|
||||
"JSModulesUnbundle.h",
|
||||
"MessageQueueThread.h",
|
||||
|
72
ReactCommon/cxxreact/JSDeltaBundleClient.cpp
Normal file
72
ReactCommon/cxxreact/JSDeltaBundleClient.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include "JSDeltaBundleClient.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <folly/Memory.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
namespace {
|
||||
std::string startupCode(const folly::dynamic *pre, const folly::dynamic *post) {
|
||||
std::ostringstream startupCode;
|
||||
|
||||
for (auto section : {pre, post}) {
|
||||
if (section != nullptr) {
|
||||
for (folly::dynamic pair : *section) {
|
||||
startupCode << pair[1].getString() << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return startupCode.str();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void JSDeltaBundleClient::patch(const folly::dynamic& delta) {
|
||||
auto const reset = delta.get_ptr("reset");
|
||||
if (reset != nullptr && reset->asBool()) {
|
||||
clear();
|
||||
}
|
||||
|
||||
auto const pre = delta.get_ptr("pre");
|
||||
auto const post = delta.get_ptr("post");
|
||||
|
||||
if ((pre != nullptr && pre->size() > 0) || (post != nullptr && post->size() > 0)) {
|
||||
startupCode_ = startupCode(pre, post);
|
||||
}
|
||||
|
||||
const folly::dynamic *modules = delta.get_ptr("delta");
|
||||
if (modules != nullptr) {
|
||||
for (const folly::dynamic pair : *modules) {
|
||||
auto id = pair[0].getInt();
|
||||
auto module = pair[1];
|
||||
if (module.isNull()) {
|
||||
modules_.erase(id);
|
||||
} else {
|
||||
modules_.emplace(id, module.getString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSModulesUnbundle::Module JSDeltaBundleClient::getModule(uint32_t moduleId) const {
|
||||
auto search = modules_.find(moduleId);
|
||||
if (search != modules_.end()) {
|
||||
return {folly::to<std::string>(search->first, ".js"), search->second};
|
||||
}
|
||||
|
||||
throw JSModulesUnbundle::ModuleNotFound(moduleId);
|
||||
}
|
||||
|
||||
std::unique_ptr<const JSBigString> JSDeltaBundleClient::getStartupCode() const {
|
||||
return folly::make_unique<JSBigStdString>(startupCode_);
|
||||
}
|
||||
|
||||
void JSDeltaBundleClient::clear() {
|
||||
modules_.clear();
|
||||
startupCode_.clear();
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
42
ReactCommon/cxxreact/JSDeltaBundleClient.h
Normal file
42
ReactCommon/cxxreact/JSDeltaBundleClient.h
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <cxxreact/JSBigString.h>
|
||||
#include <cxxreact/JSModulesUnbundle.h>
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class JSDeltaBundleClient {
|
||||
public:
|
||||
void patch(const folly::dynamic& delta);
|
||||
JSModulesUnbundle::Module getModule(uint32_t moduleId) const;
|
||||
std::unique_ptr<const JSBigString> getStartupCode() const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
std::unordered_map<uint32_t, std::string> modules_;
|
||||
std::string startupCode_;
|
||||
};
|
||||
|
||||
class JSDeltaBundleClientRAMBundle : public JSModulesUnbundle {
|
||||
public:
|
||||
JSDeltaBundleClientRAMBundle(
|
||||
std::shared_ptr<const JSDeltaBundleClient> client) : client_(client) {}
|
||||
|
||||
Module getModule(uint32_t moduleId) const override {
|
||||
return client_->getModule(moduleId);
|
||||
}
|
||||
private:
|
||||
const std::shared_ptr<const JSDeltaBundleClient> client_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
@ -6,6 +6,7 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <folly/Conv.h>
|
||||
#include <jschelpers/noncopyable.h>
|
||||
|
||||
namespace facebook {
|
||||
@ -21,7 +22,10 @@ class JSModulesUnbundle : noncopyable {
|
||||
*/
|
||||
public:
|
||||
class ModuleNotFound : public std::out_of_range {
|
||||
public:
|
||||
using std::out_of_range::out_of_range;
|
||||
ModuleNotFound(uint32_t moduleId) : std::out_of_range::out_of_range(
|
||||
folly::to<std::string>("Module not found: ", moduleId)) {}
|
||||
};
|
||||
struct Module {
|
||||
std::string name;
|
||||
|
Loading…
x
Reference in New Issue
Block a user