Update the Delta/HMR format

Summary:
Makes the delta bundle data structures more consistent.

The changes are as follows:
* There are now two types of JSON bundles that can be downloaded from the delta endpoint. Base bundles (`Bundle` type), and Delta bundles (`DeltaBundle` type).
* The `reset` boolean is renamed to `base`.
* `pre` and `post` properties are now strings.
* Only `Bundle` can define `pre` and `post` properties.
* The `delta` property is renamed to `modules`.
* Deleted modules are now listed inside of the `deleted` property, which is only defined by `DeltaBundle`.

Reviewed By: mjesun

Differential Revision: D10446831

fbshipit-source-id: 40e229a2811d48950f0bad8dd341ece189089e9b
This commit is contained in:
Alexandre Kirszenberg
2018-10-29 08:54:17 -07:00
committed by Facebook Github Bot
parent bb93abf5ca
commit 1eedf05651
4 changed files with 88 additions and 81 deletions

View File

@@ -25,7 +25,7 @@ import okio.BufferedSource;
public abstract class BundleDeltaClient {
private static final String METRO_DELTA_ID_HEADER = "X-Metro-Delta-ID";
@Nullable private String mDeltaId;
@Nullable private String mRevisionId;
public enum ClientType {
NONE,
@@ -54,46 +54,45 @@ public abstract class BundleDeltaClient {
BufferedSource body,
File outputFile) throws IOException;
final public String extendUrlForDelta(String bundleURL) {
return mDeltaId != null ? bundleURL + "&deltaBundleId=" + mDeltaId : bundleURL;
final public synchronized String extendUrlForDelta(String bundleURL) {
return mRevisionId != null ? bundleURL + "&revisionId=" + mRevisionId : bundleURL;
}
public void reset() {
mDeltaId = null;
public synchronized void reset() {
mRevisionId = null;
}
public Pair<Boolean, NativeDeltaClient> processDelta(
public synchronized Pair<Boolean, NativeDeltaClient> processDelta(
Headers headers,
BufferedSource body,
File outputFile) throws IOException {
mDeltaId = headers.get(METRO_DELTA_ID_HEADER);
mRevisionId = headers.get(METRO_DELTA_ID_HEADER);
return processDelta(body, outputFile);
}
private static class BundleDeltaJavaClient extends BundleDeltaClient {
final LinkedHashMap<Number, byte[]> mPreModules = new LinkedHashMap<Number, byte[]>();
final LinkedHashMap<Number, byte[]> mDeltaModules = new LinkedHashMap<Number, byte[]>();
final LinkedHashMap<Number, byte[]> mPostModules = new LinkedHashMap<Number, byte[]>();
byte[] mPreCode;
byte[] mPostCode;
final LinkedHashMap<Number, byte[]> mModules = new LinkedHashMap<Number, byte[]>();
@Override
public boolean canHandle(ClientType type) {
return type == ClientType.DEV_SUPPORT;
}
public void reset() {
public synchronized void reset() {
super.reset();
mDeltaModules.clear();
mPreModules.clear();
mPostModules.clear();
mPreCode = null;
mPostCode = null;
mModules.clear();
}
@Override
public synchronized Pair<Boolean, NativeDeltaClient> processDelta(
BufferedSource body,
File outputFile) throws IOException {
JsonReader jsonReader = new JsonReader(new InputStreamReader(body.inputStream()));
jsonReader.beginObject();
int numChangedModules = 0;
@@ -101,11 +100,13 @@ public abstract class BundleDeltaClient {
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
if (name.equals("pre")) {
numChangedModules += patchDelta(jsonReader, mPreModules);
mPreCode = jsonReader.nextString().getBytes();
} else if (name.equals("post")) {
numChangedModules += patchDelta(jsonReader, mPostModules);
} else if (name.equals("delta")) {
numChangedModules += patchDelta(jsonReader, mDeltaModules);
mPostCode = jsonReader.nextString().getBytes();
} else if (name.equals("modules")) {
numChangedModules += setModules(jsonReader, mModules);
} else if (name.equals("deleted")) {
numChangedModules += removeModules(jsonReader, mModules);
} else {
jsonReader.skipValue();
}
@@ -123,20 +124,16 @@ public abstract class BundleDeltaClient {
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
try {
for (byte[] code : mPreModules.values()) {
fileOutputStream.write(mPreCode);
fileOutputStream.write('\n');
for (byte[] code : mModules.values()) {
fileOutputStream.write(code);
fileOutputStream.write('\n');
}
for (byte[] code : mDeltaModules.values()) {
fileOutputStream.write(code);
fileOutputStream.write('\n');
}
for (byte[] code : mPostModules.values()) {
fileOutputStream.write(code);
fileOutputStream.write('\n');
}
fileOutputStream.write(mPostCode);
fileOutputStream.write('\n');
} finally {
fileOutputStream.flush();
fileOutputStream.close();
@@ -145,7 +142,7 @@ public abstract class BundleDeltaClient {
return Pair.create(Boolean.TRUE, null);
}
private static int patchDelta(JsonReader jsonReader, LinkedHashMap<Number, byte[]> map)
private static int setModules(JsonReader jsonReader, LinkedHashMap<Number, byte[]> map)
throws IOException {
jsonReader.beginArray();
@@ -155,12 +152,7 @@ public abstract class BundleDeltaClient {
int moduleId = jsonReader.nextInt();
if (jsonReader.peek() == JsonToken.NULL) {
jsonReader.skipValue();
map.remove(moduleId);
} else {
map.put(moduleId, jsonReader.nextString().getBytes());
}
map.put(moduleId, jsonReader.nextString().getBytes());
jsonReader.endArray();
numModules++;
@@ -170,6 +162,24 @@ public abstract class BundleDeltaClient {
return numModules;
}
private static int removeModules(JsonReader jsonReader, LinkedHashMap<Number, byte[]> map)
throws IOException {
jsonReader.beginArray();
int numModules = 0;
while (jsonReader.hasNext()) {
int moduleId = jsonReader.nextInt();
map.remove(moduleId);
numModules++;
}
jsonReader.endArray();
return numModules;
}
}
private static class BundleDeltaNativeClient extends BundleDeltaClient {