mirror: add typename support to `UpdateResult`s (#1664)
Summary: The internal `UpdateResult` structure now lists IDs of objects whose typename has been queried. This list is expected to be empty for now. Test Plan: Unit tests added. wchargin-branch: mirror-typename-updateresult
This commit is contained in:
parent
477243fc2c
commit
5c937d8604
|
@ -735,7 +735,9 @@ export class Mirror {
|
||||||
queryResult: UpdateResult
|
queryResult: UpdateResult
|
||||||
): void {
|
): void {
|
||||||
for (const topLevelKey of Object.keys(queryResult)) {
|
for (const topLevelKey of Object.keys(queryResult)) {
|
||||||
if (topLevelKey.startsWith(_FIELD_PREFIXES.OWN_DATA)) {
|
if (topLevelKey.startsWith(_FIELD_PREFIXES.TYPENAMES)) {
|
||||||
|
throw new Error("Typename update results not yet supported");
|
||||||
|
} else if (topLevelKey.startsWith(_FIELD_PREFIXES.OWN_DATA)) {
|
||||||
const rawValue: OwnDataUpdateResult | NodeConnectionsUpdateResult =
|
const rawValue: OwnDataUpdateResult | NodeConnectionsUpdateResult =
|
||||||
queryResult[topLevelKey];
|
queryResult[topLevelKey];
|
||||||
const updateRecord: OwnDataUpdateResult = (rawValue: any);
|
const updateRecord: OwnDataUpdateResult = (rawValue: any);
|
||||||
|
@ -2092,6 +2094,16 @@ type NestedFieldResult = {
|
||||||
+[Schema.Fieldname]: PrimitiveResult | NodeFieldResult,
|
+[Schema.Fieldname]: PrimitiveResult | NodeFieldResult,
|
||||||
} | null;
|
} | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result describing only the typename of a set of nodes. Used when we
|
||||||
|
* only have references to nodes via unfaithful fields.
|
||||||
|
*/
|
||||||
|
type TypenamesUpdateResult = $ReadOnlyArray<{|
|
||||||
|
+__typename: Schema.Typename,
|
||||||
|
+id: Schema.ObjectId,
|
||||||
|
|}>;
|
||||||
|
export type _TypenamesUpdateResult = TypenamesUpdateResult; // for tests
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result describing own-data for many nodes of a given type. Whether a
|
* Result describing own-data for many nodes of a given type. Whether a
|
||||||
* value is a `PrimitiveResult` or a `NodeFieldResult` is determined by
|
* value is a `PrimitiveResult` or a `NodeFieldResult` is determined by
|
||||||
|
@ -2107,6 +2119,7 @@ type OwnDataUpdateResult = $ReadOnlyArray<{
|
||||||
| NodeFieldResult
|
| NodeFieldResult
|
||||||
| NestedFieldResult,
|
| NestedFieldResult,
|
||||||
}>;
|
}>;
|
||||||
|
export type _OwnDataUpdateResult = OwnDataUpdateResult; // for tests
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result describing new elements for connections on a single node.
|
* Result describing new elements for connections on a single node.
|
||||||
|
@ -2117,12 +2130,13 @@ type NodeConnectionsUpdateResult = {
|
||||||
+id: Schema.ObjectId,
|
+id: Schema.ObjectId,
|
||||||
+[connectionFieldname: Schema.Fieldname]: ConnectionFieldResult,
|
+[connectionFieldname: Schema.Fieldname]: ConnectionFieldResult,
|
||||||
};
|
};
|
||||||
|
export type _NodeConnectionsUpdateResult = NodeConnectionsUpdateResult; // for tests
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result describing both own-data updates and connection updates. Each
|
* Result describing all kinds of updates. Each key's prefix determines
|
||||||
* key's prefix determines what type of results the corresponding value
|
* what type of results the corresponding value represents (see
|
||||||
* represents (see constants below). No field prefix is a prefix of
|
* constants below). No field prefix is a prefix of another, so this
|
||||||
* another, so this characterization is complete.
|
* characterization is complete.
|
||||||
*
|
*
|
||||||
* This type would be exact but for facebook/flow#2977, et al.
|
* This type would be exact but for facebook/flow#2977, et al.
|
||||||
*
|
*
|
||||||
|
@ -2131,10 +2145,19 @@ type NodeConnectionsUpdateResult = {
|
||||||
type UpdateResult = {
|
type UpdateResult = {
|
||||||
// The prefix of each key determines what type of results the value
|
// The prefix of each key determines what type of results the value
|
||||||
// represents. See constants below.
|
// represents. See constants below.
|
||||||
+[string]: OwnDataUpdateResult | NodeConnectionsUpdateResult,
|
+[string]:
|
||||||
|
| TypenamesUpdateResult
|
||||||
|
| OwnDataUpdateResult
|
||||||
|
| NodeConnectionsUpdateResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const _FIELD_PREFIXES = deepFreeze({
|
export const _FIELD_PREFIXES = deepFreeze({
|
||||||
|
/**
|
||||||
|
* A key of an `UpdateResult` has this prefix if and only if the
|
||||||
|
* corresponding value represents `TypenamesUpdateResult`s.
|
||||||
|
*/
|
||||||
|
TYPENAMES: "typenames_",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A key of an `UpdateResult` has this prefix if and only if the
|
* A key of an `UpdateResult` has this prefix if and only if the
|
||||||
* corresponding value represents `OwnDataUpdateResult`s.
|
* corresponding value represents `OwnDataUpdateResult`s.
|
||||||
|
|
|
@ -13,6 +13,8 @@ import {
|
||||||
_inTransaction,
|
_inTransaction,
|
||||||
_makeSingleUpdateFunction,
|
_makeSingleUpdateFunction,
|
||||||
Mirror,
|
Mirror,
|
||||||
|
type _OwnDataUpdateResult,
|
||||||
|
type _TypenamesUpdateResult,
|
||||||
} from "./mirror";
|
} from "./mirror";
|
||||||
import stringify from "json-stable-stringify";
|
import stringify from "json-stable-stringify";
|
||||||
|
|
||||||
|
@ -799,6 +801,20 @@ describe("graphql/mirror", () => {
|
||||||
}).toThrow('Bad key in query result: "wat_0"');
|
}).toThrow('Bad key in query result: "wat_0"');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("throws if given a key with typename results", () => {
|
||||||
|
const db = new Database(":memory:");
|
||||||
|
const mirror = new Mirror(db, buildGithubSchema());
|
||||||
|
const updateId = mirror._createUpdate(new Date(123));
|
||||||
|
const result = {
|
||||||
|
typenames_0: ([
|
||||||
|
{id: "issue:#1", __typename: "Issue"},
|
||||||
|
]: _TypenamesUpdateResult),
|
||||||
|
};
|
||||||
|
expect(() => {
|
||||||
|
mirror._nontransactionallyUpdateData(updateId, result);
|
||||||
|
}).toThrow("Typename update results not yet supported");
|
||||||
|
});
|
||||||
|
|
||||||
// We test the happy path lightly, because it just delegates to
|
// We test the happy path lightly, because it just delegates to
|
||||||
// other methods, which are themselves tested. This test is
|
// other methods, which are themselves tested. This test is
|
||||||
// sufficient to effect full coverage.
|
// sufficient to effect full coverage.
|
||||||
|
@ -810,14 +826,14 @@ describe("graphql/mirror", () => {
|
||||||
mirror.registerObject({typename: "Issue", id: "issue:#1"});
|
mirror.registerObject({typename: "Issue", id: "issue:#1"});
|
||||||
mirror.registerObject({typename: "Issue", id: "issue:#2"});
|
mirror.registerObject({typename: "Issue", id: "issue:#2"});
|
||||||
const result = {
|
const result = {
|
||||||
owndata_0: [
|
owndata_0: ([
|
||||||
{
|
{
|
||||||
__typename: "Repository",
|
__typename: "Repository",
|
||||||
id: "repo:foo/bar",
|
id: "repo:foo/bar",
|
||||||
url: "url://foo/bar",
|
url: "url://foo/bar",
|
||||||
},
|
},
|
||||||
],
|
]: _OwnDataUpdateResult),
|
||||||
owndata_1: [
|
owndata_1: ([
|
||||||
{
|
{
|
||||||
__typename: "Issue",
|
__typename: "Issue",
|
||||||
id: "issue:#1",
|
id: "issue:#1",
|
||||||
|
@ -846,7 +862,7 @@ describe("graphql/mirror", () => {
|
||||||
id: "user:alice",
|
id: "user:alice",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
]: _OwnDataUpdateResult),
|
||||||
node_0: {
|
node_0: {
|
||||||
id: "repo:foo/bar",
|
id: "repo:foo/bar",
|
||||||
issues: {
|
issues: {
|
||||||
|
@ -3797,13 +3813,13 @@ describe("graphql/mirror", () => {
|
||||||
const rowid = mirror._logRequest(query, queryParameters, new Date(123));
|
const rowid = mirror._logRequest(query, queryParameters, new Date(123));
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
owndata_0: [
|
owndata_0: ([
|
||||||
{
|
{
|
||||||
__typename: "Repository",
|
__typename: "Repository",
|
||||||
id: "repo:foo/bar",
|
id: "repo:foo/bar",
|
||||||
url: "url://foo/bar",
|
url: "url://foo/bar",
|
||||||
},
|
},
|
||||||
],
|
]: _OwnDataUpdateResult),
|
||||||
};
|
};
|
||||||
|
|
||||||
mirror._logResponse(rowid, response, new Date(456));
|
mirror._logResponse(rowid, response, new Date(456));
|
||||||
|
|
Loading…
Reference in New Issue