2018-10-31 01:35:03 -07:00
|
|
|
// Copyright (c) Facebook, Inc. and its affiliates.
|
|
|
|
//
|
|
|
|
// This source code is licensed under the MIT license found in the
|
|
|
|
// LICENSE file in the root directory of this source tree.
|
|
|
|
|
2018-05-03 08:38:01 -07:00
|
|
|
#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) {
|
2018-10-29 08:54:17 -07:00
|
|
|
startupCode << section->getString() << '\n';
|
2018-05-03 08:38:01 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return startupCode.str();
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
DeltaClient: split DeltaBundle's modules into added and modified
Summary:
The reasoning behind this change is that right now, having both added and modified modules inside of a single `modules` field doesn't allow for basic operations like combining two deltas.
For instance, say I have three different bundle revisions: A, B and C.
Module 42 was added in B, and then removed in C.
A->B = `{modules: [42, "..."], deleted: []}`
B->C = `{modules: [], deleted: [42]}`
A->C = `{modules: [], deleted: []}`
However, were we to compute A->C as the combination of A->B and B->C, it would result in `{modules: [], deleted: [42]}` because we have no way of knowing that module 42 was only just added in B.
This means that the `deleted` field of delta X->Y might eventually contain module ids that were never present in revision X, because they were added and then removed between revisions X and Y.
The last time I changed the delta format, we had a few bug reports pop out from people who had desync issues between their version of React Native and their version of Metro. As such, I've tried to make this change backwards compatible in at least one direction (new RN, old Metro). However, this will still break if someone is using a newer version of Metro and an older version of RN. I created T37123645 to follow up on this.
Reviewed By: rafeca, fromcelticpark
Differential Revision: D13156514
fbshipit-source-id: 4a4ee3b6cc0cdff5dca7368a46d7bf663769e281
2018-11-28 02:48:51 -08:00
|
|
|
void JSDeltaBundleClient::patchModules(const folly::dynamic *modules) {
|
|
|
|
for (const folly::dynamic pair : *modules) {
|
|
|
|
auto id = pair[0].getInt();
|
|
|
|
auto module = pair[1];
|
|
|
|
modules_.emplace(id, module.getString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-03 08:38:01 -07:00
|
|
|
void JSDeltaBundleClient::patch(const folly::dynamic& delta) {
|
2018-10-29 08:54:17 -07:00
|
|
|
auto const base = delta.get_ptr("base");
|
|
|
|
|
|
|
|
if (base != nullptr && base->asBool()) {
|
2018-05-03 08:38:01 -07:00
|
|
|
clear();
|
|
|
|
|
2018-10-29 08:54:17 -07:00
|
|
|
auto const pre = delta.get_ptr("pre");
|
|
|
|
auto const post = delta.get_ptr("post");
|
2018-05-03 08:38:01 -07:00
|
|
|
|
|
|
|
startupCode_ = startupCode(pre, post);
|
DeltaClient: split DeltaBundle's modules into added and modified
Summary:
The reasoning behind this change is that right now, having both added and modified modules inside of a single `modules` field doesn't allow for basic operations like combining two deltas.
For instance, say I have three different bundle revisions: A, B and C.
Module 42 was added in B, and then removed in C.
A->B = `{modules: [42, "..."], deleted: []}`
B->C = `{modules: [], deleted: [42]}`
A->C = `{modules: [], deleted: []}`
However, were we to compute A->C as the combination of A->B and B->C, it would result in `{modules: [], deleted: [42]}` because we have no way of knowing that module 42 was only just added in B.
This means that the `deleted` field of delta X->Y might eventually contain module ids that were never present in revision X, because they were added and then removed between revisions X and Y.
The last time I changed the delta format, we had a few bug reports pop out from people who had desync issues between their version of React Native and their version of Metro. As such, I've tried to make this change backwards compatible in at least one direction (new RN, old Metro). However, this will still break if someone is using a newer version of Metro and an older version of RN. I created T37123645 to follow up on this.
Reviewed By: rafeca, fromcelticpark
Differential Revision: D13156514
fbshipit-source-id: 4a4ee3b6cc0cdff5dca7368a46d7bf663769e281
2018-11-28 02:48:51 -08:00
|
|
|
|
|
|
|
const folly::dynamic *modules = delta.get_ptr("modules");
|
|
|
|
if (modules != nullptr) {
|
|
|
|
patchModules(modules);
|
|
|
|
}
|
2018-10-29 08:54:17 -07:00
|
|
|
} else {
|
|
|
|
const folly::dynamic *deleted = delta.get_ptr("deleted");
|
|
|
|
if (deleted != nullptr) {
|
|
|
|
for (const folly::dynamic id : *deleted) {
|
|
|
|
modules_.erase(id.getInt());
|
|
|
|
}
|
|
|
|
}
|
2018-05-03 08:38:01 -07:00
|
|
|
|
DeltaClient: split DeltaBundle's modules into added and modified
Summary:
The reasoning behind this change is that right now, having both added and modified modules inside of a single `modules` field doesn't allow for basic operations like combining two deltas.
For instance, say I have three different bundle revisions: A, B and C.
Module 42 was added in B, and then removed in C.
A->B = `{modules: [42, "..."], deleted: []}`
B->C = `{modules: [], deleted: [42]}`
A->C = `{modules: [], deleted: []}`
However, were we to compute A->C as the combination of A->B and B->C, it would result in `{modules: [], deleted: [42]}` because we have no way of knowing that module 42 was only just added in B.
This means that the `deleted` field of delta X->Y might eventually contain module ids that were never present in revision X, because they were added and then removed between revisions X and Y.
The last time I changed the delta format, we had a few bug reports pop out from people who had desync issues between their version of React Native and their version of Metro. As such, I've tried to make this change backwards compatible in at least one direction (new RN, old Metro). However, this will still break if someone is using a newer version of Metro and an older version of RN. I created T37123645 to follow up on this.
Reviewed By: rafeca, fromcelticpark
Differential Revision: D13156514
fbshipit-source-id: 4a4ee3b6cc0cdff5dca7368a46d7bf663769e281
2018-11-28 02:48:51 -08:00
|
|
|
// TODO T37123645 This is deprecated but necessary in order to support older
|
|
|
|
// versions of the Metro server.
|
|
|
|
const folly::dynamic *modules = delta.get_ptr("modules");
|
|
|
|
if (modules != nullptr) {
|
|
|
|
patchModules(modules);
|
|
|
|
}
|
|
|
|
|
|
|
|
const folly::dynamic *added = delta.get_ptr("added");
|
|
|
|
if (added != nullptr) {
|
|
|
|
patchModules(added);
|
|
|
|
}
|
|
|
|
|
|
|
|
const folly::dynamic *modified = delta.get_ptr("modified");
|
|
|
|
if (modified != nullptr) {
|
|
|
|
patchModules(modified);
|
2018-05-03 08:38:01 -07:00
|
|
|
}
|
|
|
|
}
|
DeltaClient: split DeltaBundle's modules into added and modified
Summary:
The reasoning behind this change is that right now, having both added and modified modules inside of a single `modules` field doesn't allow for basic operations like combining two deltas.
For instance, say I have three different bundle revisions: A, B and C.
Module 42 was added in B, and then removed in C.
A->B = `{modules: [42, "..."], deleted: []}`
B->C = `{modules: [], deleted: [42]}`
A->C = `{modules: [], deleted: []}`
However, were we to compute A->C as the combination of A->B and B->C, it would result in `{modules: [], deleted: [42]}` because we have no way of knowing that module 42 was only just added in B.
This means that the `deleted` field of delta X->Y might eventually contain module ids that were never present in revision X, because they were added and then removed between revisions X and Y.
The last time I changed the delta format, we had a few bug reports pop out from people who had desync issues between their version of React Native and their version of Metro. As such, I've tried to make this change backwards compatible in at least one direction (new RN, old Metro). However, this will still break if someone is using a newer version of Metro and an older version of RN. I created T37123645 to follow up on this.
Reviewed By: rafeca, fromcelticpark
Differential Revision: D13156514
fbshipit-source-id: 4a4ee3b6cc0cdff5dca7368a46d7bf663769e281
2018-11-28 02:48:51 -08:00
|
|
|
|
2018-05-03 08:38:01 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|