Skip to content

Commit

Permalink
Change some Flow types to prepare for tracking field errors
Browse files Browse the repository at this point in the history
Reviewed By: alunyov

Differential Revision: D48451400

fbshipit-source-id: 1ce4a3f1691276207186baf4bcf4ef935b3065b9
  • Loading branch information
Ryan Holdren authored and facebook-github-bot committed Aug 28, 2023
1 parent f63e7c6 commit 7945157
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 28 deletions.
49 changes: 35 additions & 14 deletions packages/relay-runtime/store/RelayModernRecord.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,17 @@ const areEqual = require('areEqual');
const invariant = require('invariant');
const warning = require('warning');

type StorageKey = string;

export type RecordJSON = {
[StorageKey]: mixed,
...
};

/*
* An individual cached graph object.
*/
export opaque type Record = {[key: string]: mixed, ...};
export opaque type Record = RecordJSON;

/**
* @public
Expand Down Expand Up @@ -129,10 +136,12 @@ function create(dataID: DataID, typeName: string): Record {
/**
* @public
*
* Convert an object to a record.
* Convert the JSON representation of a record into a record.
*/
function fromObject(object: {[key: string]: mixed, ...}): Record {
return object;
function fromObject<TMaybe: ?empty = empty>(
json: RecordJSON | TMaybe,
): Record | TMaybe {
return json;
}

/**
Expand All @@ -149,7 +158,7 @@ function getDataID(record: Record): DataID {
*
* Get the fields of a record.
*/
function getFields(record: Record): Array<string> {
function getFields(record: Record): Array<StorageKey> {
return Object.keys(record);
}

Expand All @@ -167,7 +176,7 @@ function getType(record: Record): string {
*
* Get a scalar (non-link) field value.
*/
function getValue(record: Record, storageKey: string): mixed {
function getValue(record: Record, storageKey: StorageKey): mixed {
const value = record[storageKey];
if (value && typeof value === 'object') {
invariant(
Expand All @@ -189,7 +198,7 @@ function getValue(record: Record, storageKey: string): mixed {
*
* Check if a record has a value for the given field.
*/
function hasValue(record: Record, storageKey: string): boolean {
function hasValue(record: Record, storageKey: StorageKey): boolean {
return storageKey in record;
}

Expand All @@ -199,7 +208,7 @@ function hasValue(record: Record, storageKey: string): boolean {
* Get the value of a field as a reference to another record. Throws if the
* field has a different type.
*/
function getLinkedRecordID(record: Record, storageKey: string): ?DataID {
function getLinkedRecordID(record: Record, storageKey: StorageKey): ?DataID {
const maybeLink = record[storageKey];
if (maybeLink == null) {
return maybeLink;
Expand Down Expand Up @@ -231,7 +240,7 @@ function getLinkedRecordID(record: Record, storageKey: string): ?DataID {
*/
function getLinkedRecordIDs(
record: Record,
storageKey: string,
storageKey: StorageKey,
): ?Array<?DataID> {
const links = record[storageKey];
if (links == null) {
Expand Down Expand Up @@ -367,7 +376,7 @@ function freeze(record: Record): void {
*
* Set the value of a storageKey to a scalar.
*/
function setValue(record: Record, storageKey: string, value: mixed): void {
function setValue(record: Record, storageKey: StorageKey, value: mixed): void {
if (__DEV__) {
const prevID = getDataID(record);
if (storageKey === ID_KEY) {
Expand Down Expand Up @@ -406,7 +415,7 @@ function setValue(record: Record, storageKey: string, value: mixed): void {
*/
function setLinkedRecordID(
record: Record,
storageKey: string,
storageKey: StorageKey,
linkedID: DataID,
): void {
// See perf note above for why we aren't using computed property access.
Expand All @@ -422,7 +431,7 @@ function setLinkedRecordID(
*/
function setLinkedRecordIDs(
record: Record,
storageKey: string,
storageKey: StorageKey,
linkedIDs: Array<?DataID>,
): void {
// See perf note above for why we aren't using computed property access.
Expand All @@ -438,7 +447,7 @@ function setLinkedRecordIDs(
*/
function setActorLinkedRecordID(
record: Record,
storageKey: string,
storageKey: StorageKey,
actorIdentifier: ActorIdentifier,
linkedID: DataID,
): void {
Expand All @@ -456,7 +465,7 @@ function setActorLinkedRecordID(
*/
function getActorLinkedRecordID(
record: Record,
storageKey: string,
storageKey: StorageKey,
): ?[ActorIdentifier, DataID] {
const link = record[storageKey];
if (link == null) {
Expand Down Expand Up @@ -526,6 +535,17 @@ function getResolverLinkedRecordIDs(
});
}

/**
* @public
*
* Convert a record to JSON.
*/
function toJSON<TMaybe: ?empty = empty>(
record: Record | TMaybe,
): RecordJSON | TMaybe {
return record;
}

module.exports = {
clone,
copyFields,
Expand All @@ -549,4 +569,5 @@ module.exports = {
setActorLinkedRecordID,
getResolverLinkedRecordID,
getResolverLinkedRecordIDs,
toJSON,
};
5 changes: 3 additions & 2 deletions packages/relay-runtime/store/RelayOptimisticRecordSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
'use strict';

import type {DataID} from '../util/RelayRuntimeTypes';
import type {RecordJSON} from './RelayModernRecord';
import type {RecordState} from './RelayRecordState';
import type {
MutableRecordSource,
Expand Down Expand Up @@ -101,14 +102,14 @@ class RelayOptimisticRecordSource implements MutableRecordSource {
return Object.keys(this.toJSON()).length;
}

toJSON(): {[DataID]: ?Record} {
toJSON(): {[DataID]: ?RecordJSON} {
const merged = {...this._base.toJSON()};
this._sink.getRecordIDs().forEach(dataID => {
const record = this.get(dataID);
if (record === undefined) {
delete merged[dataID];
} else {
merged[dataID] = record;
merged[dataID] = RelayModernRecord.toJSON<null | void>(record);
}
});
return merged;
Expand Down
4 changes: 2 additions & 2 deletions packages/relay-runtime/store/RelayReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ class RelayReader {
const fragmentRef = {};
this._createFragmentPointer(
field.fragmentSpread,
RelayModernRecord.fromObject({
RelayModernRecord.fromObject<>({
__id: dataID,
}),
fragmentRef,
Expand Down Expand Up @@ -991,7 +991,7 @@ class RelayReader {
record,
fieldData,
);
return RelayModernRecord.fromObject(fieldData);
return RelayModernRecord.fromObject<>(fieldData);
}

// Has three possible return values:
Expand Down
14 changes: 7 additions & 7 deletions packages/relay-runtime/store/RelayRecordSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
'use strict';

import type {DataID} from '../util/RelayRuntimeTypes';
import type {RecordJSON} from './RelayModernRecord';
import type {RecordState} from './RelayRecordState';
import type {MutableRecordSource, Record} from './RelayStoreTypes';

Expand All @@ -23,7 +24,7 @@ const {EXISTENT, NONEXISTENT, UNKNOWN} = RelayRecordState;
/**
* A collection of records keyed by id.
*/
type RecordObjectMap = {[DataID]: ?{[key: string]: mixed}};
type RecordObjectMap = {[DataID]: ?RecordJSON};

/**
* An implementation of the `MutableRecordSource` interface (defined in
Expand All @@ -37,8 +38,7 @@ class RelayRecordSource implements MutableRecordSource {
if (records != null) {
Object.keys(records).forEach(key => {
const object = records[key];
const record =
object == null ? object : RelayModernRecord.fromObject(object);
const record = RelayModernRecord.fromObject<null | void>(object);
this._records.set(key, record);
});
}
Expand Down Expand Up @@ -87,10 +87,10 @@ class RelayRecordSource implements MutableRecordSource {
return this._records.size;
}

toJSON(): {[DataID]: ?Record, ...} {
const obj: {[DataID]: ?Record} = {};
for (const [key, value] of this._records) {
obj[key] = value;
toJSON(): {[DataID]: ?RecordJSON} {
const obj: {[DataID]: ?RecordJSON} = {};
for (const [key, record] of this._records) {
obj[key] = RelayModernRecord.toJSON<null | void>(record);
}
return obj;
}
Expand Down
7 changes: 5 additions & 2 deletions packages/relay-runtime/store/RelayStoreTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ import type {
UpdatableQuery,
Variables,
} from '../util/RelayRuntimeTypes';
import type {Record as RelayModernRecord} from './RelayModernRecord';
import type {
Record as RelayModernRecord,
RecordJSON,
} from './RelayModernRecord';
import type {InvalidationState} from './RelayModernStore';
import type RelayOperationTracker from './RelayOperationTracker';
import type {RecordState} from './RelayRecordState';
Expand Down Expand Up @@ -242,7 +245,7 @@ export interface RecordSource {
getStatus(dataID: DataID): RecordState;
has(dataID: DataID): boolean;
size(): number;
toJSON(): {[DataID]: ?Record, ...};
toJSON(): {[DataID]: ?RecordJSON};
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('RelayModernRecord', () => {
});

describe('fromObject()', () => {
it('returns the given object', () => {
it('returns the given JSON object', () => {
const object = {};
const record = RelayModernRecord.fromObject(object);
expect(record).toBe(object);
Expand Down

0 comments on commit 7945157

Please sign in to comment.