261 lines
8.4 KiB
JavaScript
261 lines
8.4 KiB
JavaScript
/**
|
|
* 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.
|
|
*
|
|
* strict-local
|
|
* @format
|
|
*/
|
|
'use strict';
|
|
|
|
var _objectSpread2 = require("@babel/runtime/helpers/interopRequireDefault")(require("@babel/runtime/helpers/objectSpread"));
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* Wrapper API that is an amalgam of the `RelayModernRecord` API and
|
|
* `MutableRecordSource` interface, implementing copy-on-write semantics for
|
|
* records in a record source. If a `backup` is supplied, the mutator will
|
|
* ensure that the backup contains sufficient information to revert all
|
|
* modifications by publishing the backup.
|
|
*
|
|
* Modifications are applied to fresh copies of records with optional backups
|
|
* created:
|
|
* - Records in `base` are never modified.
|
|
* - Modifications cause a fresh version of a record to be created in `sink`.
|
|
* These sink records contain only modified fields.
|
|
* - If a `backup` is supplied, any modifications to a record will cause the
|
|
* sink version of the record to be added to the backup.
|
|
* - Creation of a record causes a sentinel object to be added to the backup
|
|
* so that the new record can be removed from the store by publishing the
|
|
* backup.
|
|
*/
|
|
var RelayRecordSourceMutator =
|
|
/*#__PURE__*/
|
|
function () {
|
|
function RelayRecordSourceMutator(base, sink, backup) {
|
|
this._backup = backup;
|
|
this._base = base;
|
|
this._sink = sink;
|
|
this.__sources = [sink, base];
|
|
}
|
|
|
|
var _proto = RelayRecordSourceMutator.prototype;
|
|
|
|
_proto._createBackupRecord = function _createBackupRecord(dataID) {
|
|
var backup = this._backup;
|
|
|
|
if (backup && !backup.has(dataID)) {
|
|
var baseRecord = this._base.get(dataID);
|
|
|
|
if (baseRecord != null) {
|
|
backup.set(dataID, baseRecord);
|
|
} else if (baseRecord === null) {
|
|
backup["delete"](dataID);
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto._setSentinelFieldsInBackupRecord = function _setSentinelFieldsInBackupRecord(dataID, record) {
|
|
var backup = this._backup;
|
|
|
|
if (backup) {
|
|
var backupRecord = backup.get(dataID);
|
|
|
|
if (backupRecord && backupRecord !== require("./RelayStoreUtils").UNPUBLISH_RECORD_SENTINEL) {
|
|
var copy = null;
|
|
|
|
for (var key in record) {
|
|
if (record.hasOwnProperty(key)) {
|
|
if (!(key in backupRecord)) {
|
|
copy = copy || (0, _objectSpread2["default"])({}, backupRecord);
|
|
copy[key] = require("./RelayStoreUtils").UNPUBLISH_FIELD_SENTINEL;
|
|
}
|
|
}
|
|
}
|
|
|
|
backup.set(dataID, copy || backupRecord);
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto._setSentinelFieldInBackupRecord = function _setSentinelFieldInBackupRecord(dataID, storageKey) {
|
|
var backup = this._backup;
|
|
|
|
if (backup) {
|
|
var backupRecord = backup.get(dataID);
|
|
|
|
if (backupRecord && backupRecord !== require("./RelayStoreUtils").UNPUBLISH_RECORD_SENTINEL && !(storageKey in backupRecord)) {
|
|
var copy = (0, _objectSpread2["default"])({}, backupRecord);
|
|
|
|
require("./RelayModernRecord").setValue(copy, storageKey, require("./RelayStoreUtils").UNPUBLISH_FIELD_SENTINEL);
|
|
|
|
backup.set(dataID, copy);
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto._getSinkRecord = function _getSinkRecord(dataID) {
|
|
var sinkRecord = this._sink.get(dataID);
|
|
|
|
if (!sinkRecord) {
|
|
var baseRecord = this._base.get(dataID);
|
|
|
|
!baseRecord ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'RelayRecordSourceMutator: Cannot modify non-existent record `%s`.', dataID) : require("fbjs/lib/invariant")(false) : void 0;
|
|
sinkRecord = require("./RelayModernRecord").create(dataID, require("./RelayModernRecord").getType(baseRecord));
|
|
|
|
this._sink.set(dataID, sinkRecord);
|
|
}
|
|
|
|
return sinkRecord;
|
|
};
|
|
|
|
_proto.copyFields = function copyFields(sourceID, sinkID) {
|
|
var sinkSource = this._sink.get(sourceID);
|
|
|
|
var baseSource = this._base.get(sourceID);
|
|
|
|
!(sinkSource || baseSource) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'RelayRecordSourceMutator#copyFields(): Cannot copy fields from ' + 'non-existent record `%s`.', sourceID) : require("fbjs/lib/invariant")(false) : void 0;
|
|
|
|
this._createBackupRecord(sinkID);
|
|
|
|
var sink = this._getSinkRecord(sinkID);
|
|
|
|
if (baseSource) {
|
|
require("./RelayModernRecord").copyFields(baseSource, sink);
|
|
}
|
|
|
|
if (sinkSource) {
|
|
require("./RelayModernRecord").copyFields(sinkSource, sink);
|
|
}
|
|
|
|
this._setSentinelFieldsInBackupRecord(sinkID, sink);
|
|
};
|
|
|
|
_proto.copyFieldsFromRecord = function copyFieldsFromRecord(record, sinkID) {
|
|
this.copyFields(require("./RelayModernRecord").getDataID(record), sinkID);
|
|
|
|
var sink = this._getSinkRecord(sinkID);
|
|
|
|
require("./RelayModernRecord").copyFields(record, sink);
|
|
|
|
this._setSentinelFieldsInBackupRecord(sinkID, sink);
|
|
};
|
|
|
|
_proto.create = function create(dataID, typeName) {
|
|
!(this._base.getStatus(dataID) !== require("./RelayRecordState").EXISTENT && this._sink.getStatus(dataID) !== require("./RelayRecordState").EXISTENT) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'RelayRecordSourceMutator#create(): Cannot create a record with id ' + '`%s`, this record already exists.', dataID) : require("fbjs/lib/invariant")(false) : void 0;
|
|
|
|
if (this._backup) {
|
|
this._backup.set(dataID, require("./RelayStoreUtils").UNPUBLISH_RECORD_SENTINEL);
|
|
}
|
|
|
|
var record = require("./RelayModernRecord").create(dataID, typeName);
|
|
|
|
this._sink.set(dataID, record);
|
|
};
|
|
|
|
_proto["delete"] = function _delete(dataID) {
|
|
this._createBackupRecord(dataID);
|
|
|
|
this._sink["delete"](dataID);
|
|
};
|
|
|
|
_proto.getStatus = function getStatus(dataID) {
|
|
return this._sink.has(dataID) ? this._sink.getStatus(dataID) : this._base.getStatus(dataID);
|
|
};
|
|
|
|
_proto.getType = function getType(dataID) {
|
|
for (var ii = 0; ii < this.__sources.length; ii++) {
|
|
var record = this.__sources[ii].get(dataID);
|
|
|
|
if (record) {
|
|
return require("./RelayModernRecord").getType(record);
|
|
} else if (record === null) {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto.getValue = function getValue(dataID, storageKey) {
|
|
for (var ii = 0; ii < this.__sources.length; ii++) {
|
|
var record = this.__sources[ii].get(dataID);
|
|
|
|
if (record) {
|
|
var value = require("./RelayModernRecord").getValue(record, storageKey);
|
|
|
|
if (value !== undefined) {
|
|
return value;
|
|
}
|
|
} else if (record === null) {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto.setValue = function setValue(dataID, storageKey, value) {
|
|
this._createBackupRecord(dataID);
|
|
|
|
var sinkRecord = this._getSinkRecord(dataID);
|
|
|
|
require("./RelayModernRecord").setValue(sinkRecord, storageKey, value);
|
|
|
|
this._setSentinelFieldInBackupRecord(dataID, storageKey);
|
|
};
|
|
|
|
_proto.getLinkedRecordID = function getLinkedRecordID(dataID, storageKey) {
|
|
for (var ii = 0; ii < this.__sources.length; ii++) {
|
|
var record = this.__sources[ii].get(dataID);
|
|
|
|
if (record) {
|
|
var linkedID = require("./RelayModernRecord").getLinkedRecordID(record, storageKey);
|
|
|
|
if (linkedID !== undefined) {
|
|
return linkedID;
|
|
}
|
|
} else if (record === null) {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto.setLinkedRecordID = function setLinkedRecordID(dataID, storageKey, linkedID) {
|
|
this._createBackupRecord(dataID);
|
|
|
|
var sinkRecord = this._getSinkRecord(dataID);
|
|
|
|
require("./RelayModernRecord").setLinkedRecordID(sinkRecord, storageKey, linkedID);
|
|
|
|
this._setSentinelFieldInBackupRecord(dataID, storageKey);
|
|
};
|
|
|
|
_proto.getLinkedRecordIDs = function getLinkedRecordIDs(dataID, storageKey) {
|
|
for (var ii = 0; ii < this.__sources.length; ii++) {
|
|
var record = this.__sources[ii].get(dataID);
|
|
|
|
if (record) {
|
|
var linkedIDs = require("./RelayModernRecord").getLinkedRecordIDs(record, storageKey);
|
|
|
|
if (linkedIDs !== undefined) {
|
|
return linkedIDs;
|
|
}
|
|
} else if (record === null) {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto.setLinkedRecordIDs = function setLinkedRecordIDs(dataID, storageKey, linkedIDs) {
|
|
this._createBackupRecord(dataID);
|
|
|
|
var sinkRecord = this._getSinkRecord(dataID);
|
|
|
|
require("./RelayModernRecord").setLinkedRecordIDs(sinkRecord, storageKey, linkedIDs);
|
|
|
|
this._setSentinelFieldInBackupRecord(dataID, storageKey);
|
|
};
|
|
|
|
return RelayRecordSourceMutator;
|
|
}();
|
|
|
|
module.exports = RelayRecordSourceMutator; |