@orbit/record-cache
Version:
Orbit base classes used to access and maintain a set of records.
99 lines • 17.3 kB
JavaScript
import { SyncOperationProcessor } from '../sync-operation-processor';
import { getInverseRelationship, getInverseRelationships, getAllInverseRelationships, getInverseRelationshipRemovalOps } from './utils/cache-integrity-utils';
/**
* An operation processor that ensures that a cache's data is consistent and
* doesn't contain any dead references.
*
* This is achieved by maintaining a mapping of reverse relationships for each
* record. When a record is removed, any references to it can also be identified
* and removed.
*/
export class SyncCacheIntegrityProcessor extends SyncOperationProcessor {
after(operation) {
switch (operation.op) {
case 'replaceRelatedRecord':
this.removeInverseRelationship(operation.record, operation.relationship, this.accessor.getRelatedRecordSync(operation.record, operation.relationship));
return [];
case 'replaceRelatedRecords':
this.removeInverseRelationships(operation.record, operation.relationship, this.accessor.getRelatedRecordsSync(operation.record, operation.relationship));
return [];
case 'removeFromRelatedRecords':
this.removeInverseRelationship(operation.record, operation.relationship, operation.relatedRecord);
return [];
case 'removeRecord':
this.removeAllInverseRelationships(operation.record);
return [];
case 'updateRecord':
this.removeAllInverseRelationships(operation.record);
return [];
default:
return [];
}
}
finally(operation) {
switch (operation.op) {
case 'replaceRelatedRecord':
this.addInverseRelationship(operation.record, operation.relationship, operation.relatedRecord);
return [];
case 'replaceRelatedRecords':
this.addInverseRelationships(operation.record, operation.relationship, operation.relatedRecords);
return [];
case 'addToRelatedRecords':
this.addInverseRelationship(operation.record, operation.relationship, operation.relatedRecord);
return [];
case 'addRecord':
this.addAllInverseRelationships(operation.record);
return [];
case 'updateRecord':
this.addAllInverseRelationships(operation.record);
return [];
case 'removeRecord':
return this.clearInverseRelationshipOps(operation.record);
default:
return [];
}
}
addInverseRelationship(record, relationship, relatedRecord) {
let inverseRelationship = getInverseRelationship(this.accessor.schema, record, relationship, relatedRecord);
if (inverseRelationship) {
this.accessor.addInverseRelationshipsSync([inverseRelationship]);
}
}
addInverseRelationships(record, relationship, relatedRecords) {
let inverseRelationships = getInverseRelationships(this.accessor.schema, record, relationship, relatedRecords);
if (inverseRelationships) {
this.accessor.addInverseRelationshipsSync(inverseRelationships);
}
}
addAllInverseRelationships(record) {
let inverseRelationships = getAllInverseRelationships(this.accessor.schema, record);
if (inverseRelationships.length > 0) {
this.accessor.addInverseRelationshipsSync(inverseRelationships);
}
}
removeInverseRelationship(record, relationship, relatedRecord) {
let inverseRelationship = getInverseRelationship(this.accessor.schema, record, relationship, relatedRecord);
if (inverseRelationship) {
this.accessor.removeInverseRelationshipsSync([inverseRelationship]);
}
}
removeInverseRelationships(record, relationship, relatedRecords) {
let inverseRelationships = getInverseRelationships(this.accessor.schema, record, relationship, relatedRecords);
if (inverseRelationships.length > 0) {
this.accessor.removeInverseRelationshipsSync(inverseRelationships);
}
}
removeAllInverseRelationships(record) {
const currentRecord = this.accessor.getRecordSync(record);
if (currentRecord) {
const inverseRelationships = getAllInverseRelationships(this.accessor.schema, currentRecord);
if (inverseRelationships.length > 0) {
this.accessor.removeInverseRelationshipsSync(inverseRelationships);
}
}
}
clearInverseRelationshipOps(record) {
return getInverseRelationshipRemovalOps(this.accessor.schema, this.accessor.getInverseRelationshipsSync(record));
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1jYWNoZS1pbnRlZ3JpdHktcHJvY2Vzc29yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL29wZXJhdGlvbi1wcm9jZXNzb3JzL3N5bmMtY2FjaGUtaW50ZWdyaXR5LXByb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLHVCQUF1QixFQUN2QiwwQkFBMEIsRUFDMUIsZ0NBQWdDLEVBQ2pDLE1BQU0sK0JBQStCLENBQUM7QUFFdkM7Ozs7Ozs7R0FPRztBQUNILE1BQU0sT0FBTywyQkFBNEIsU0FBUSxzQkFBc0I7SUFDckUsS0FBSyxDQUFDLFNBQTBCO1FBQzlCLFFBQVEsU0FBUyxDQUFDLEVBQUUsRUFBRTtZQUNwQixLQUFLLHNCQUFzQjtnQkFDekIsSUFBSSxDQUFDLHlCQUF5QixDQUM1QixTQUFTLENBQUMsTUFBTSxFQUNoQixTQUFTLENBQUMsWUFBWSxFQUN0QixJQUFJLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUNoQyxTQUFTLENBQUMsTUFBTSxFQUNoQixTQUFTLENBQUMsWUFBWSxDQUN2QixDQUNGLENBQUM7Z0JBQ0YsT0FBTyxFQUFFLENBQUM7WUFFWixLQUFLLHVCQUF1QjtnQkFDMUIsSUFBSSxDQUFDLDBCQUEwQixDQUM3QixTQUFTLENBQUMsTUFBTSxFQUNoQixTQUFTLENBQUMsWUFBWSxFQUN0QixJQUFJLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUNqQyxTQUFTLENBQUMsTUFBTSxFQUNoQixTQUFTLENBQUMsWUFBWSxDQUN2QixDQUNGLENBQUM7Z0JBQ0YsT0FBTyxFQUFFLENBQUM7WUFFWixLQUFLLDBCQUEwQjtnQkFDN0IsSUFBSSxDQUFDLHlCQUF5QixDQUM1QixTQUFTLENBQUMsTUFBTSxFQUNoQixTQUFTLENBQUMsWUFBWSxFQUN0QixTQUFTLENBQUMs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O0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBJbml0aWFsaXplZFJlY29yZCxcbiAgUmVjb3JkSWRlbnRpdHksXG4gIFJlY29yZE9wZXJhdGlvblxufSBmcm9tICdAb3JiaXQvcmVjb3Jkcyc7XG5pbXBvcnQgeyBTeW5jT3BlcmF0aW9uUHJvY2Vzc29yIH0gZnJvbSAnLi4vc3luYy1vcGVyYXRpb24tcHJvY2Vzc29yJztcbmltcG9ydCB7XG4gIGdldEludmVyc2VSZWxhdGlvbnNoaXAsXG4gIGdldEludmVyc2VSZWxhdGlvbnNoaXBzLFxuICBnZXRBbGxJbnZlcnNlUmVsYXRpb25zaGlwcyxcbiAgZ2V0SW52ZXJzZVJlbGF0aW9uc2hpcFJlbW92YWxPcHNcbn0gZnJvbSAnLi91dGlscy9jYWNoZS1pbnRlZ3JpdHktdXRpbHMnO1xuXG4vKipcbiAqIEFuIG9wZXJhdGlvbiBwcm9jZXNzb3IgdGhhdCBlbnN1cmVzIHRoYXQgYSBjYWNoZSdzIGRhdGEgaXMgY29uc2lzdGVudCBhbmRcbiAqIGRvZXNuJ3QgY29udGFpbiBhbnkgZGVhZCByZWZlcmVuY2VzLlxuICpcbiAqIFRoaXMgaXMgYWNoaWV2ZWQgYnkgbWFpbnRhaW5pbmcgYSBtYXBwaW5nIG9mIHJldmVyc2UgcmVsYXRpb25zaGlwcyBmb3IgZWFjaFxuICogcmVjb3JkLiBXaGVuIGEgcmVjb3JkIGlzIHJlbW92ZWQsIGFueSByZWZlcmVuY2VzIHRvIGl0IGNhbiBhbHNvIGJlIGlkZW50aWZpZWRcbiAqIGFuZCByZW1vdmVkLlxuICovXG5leHBvcnQgY2xhc3MgU3luY0NhY2hlSW50ZWdyaXR5UHJvY2Vzc29yIGV4dGVuZHMgU3luY09wZXJhdGlvblByb2Nlc3NvciB7XG4gIGFmdGVyKG9wZXJhdGlvbjogUmVjb3JkT3BlcmF0aW9uKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICAgIHN3aXRjaCAob3BlcmF0aW9uLm9wKSB7XG4gICAgICBjYXNlICdyZXBsYWNlUmVsYXRlZFJlY29yZCc6XG4gICAgICAgIHRoaXMucmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcChcbiAgICAgICAgICBvcGVyYXRpb24ucmVjb3JkLFxuICAgICAgICAgIG9wZXJhdGlvbi5yZWxhdGlvbnNoaXAsXG4gICAgICAgICAgdGhpcy5hY2Nlc3Nvci5nZXRSZWxhdGVkUmVjb3JkU3luYyhcbiAgICAgICAgICAgIG9wZXJhdGlvbi5yZWNvcmQsXG4gICAgICAgICAgICBvcGVyYXRpb24ucmVsYXRpb25zaGlwXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW107XG5cbiAgICAgIGNhc2UgJ3JlcGxhY2VSZWxhdGVkUmVjb3Jkcyc6XG4gICAgICAgIHRoaXMucmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcHMoXG4gICAgICAgICAgb3BlcmF0aW9uLnJlY29yZCxcbiAgICAgICAgICBvcGVyYXRpb24ucmVsYXRpb25zaGlwLFxuICAgICAgICAgIHRoaXMuYWNjZXNzb3IuZ2V0UmVsYXRlZFJlY29yZHNTeW5jKFxuICAgICAgICAgICAgb3BlcmF0aW9uLnJlY29yZCxcbiAgICAgICAgICAgIG9wZXJhdGlvbi5yZWxhdGlvbnNoaXBcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBbXTtcblxuICAgICAgY2FzZSAncmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzJzpcbiAgICAgICAgdGhpcy5yZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwKFxuICAgICAgICAgIG9wZXJhdGlvbi5yZWNvcmQsXG4gICAgICAgICAgb3BlcmF0aW9uLnJlbGF0aW9uc2hpcCxcbiAgICAgICAgICBvcGVyYXRpb24ucmVsYXRlZFJlY29yZFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW107XG5cbiAgICAgIGNhc2UgJ3JlbW92ZVJlY29yZCc6XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsSW52ZXJzZVJlbGF0aW9uc2hpcHMob3BlcmF0aW9uLnJlY29yZCk7XG4gICAgICAgIHJldHVybiBbXTtcblxuICAgICAgY2FzZSAndXBkYXRlUmVjb3JkJzpcbiAgICAgICAgdGhpcy5yZW1vdmVBbGxJbnZlcnNlUmVsYXRpb25zaGlwcyhvcGVyYXRpb24ucmVjb3JkKTtcbiAgICAgICAgcmV0dXJuIFtdO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICB9XG5cbiAgZmluYWxseShvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvbik6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgICBzd2l0Y2ggKG9wZXJhdGlvbi5vcCkge1xuICAgICAgY2FzZSAncmVwbGFjZVJlbGF0ZWRSZWNvcmQnOlxuICAgICAgICB0aGlzLmFkZEludmVyc2VSZWxhdGlvbnNoaXAoXG4gICAgICAgICAgb3BlcmF0aW9uLnJlY29yZCxcbiAgICAgICAgICBvcGVyYXRpb24ucmVsYXRpb25zaGlwLFxuICAgICAgICAgIG9wZXJhdGlvbi5yZWxhdGVkUmVjb3JkXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBbXTtcblxuICAgICAgY2FzZSAncmVwbGFjZVJlbGF0ZWRSZWNvcmRzJzpcbiAgICAgICAgdGhpcy5hZGRJbnZlcnNlUmVsYXRpb25zaGlwcyhcbiAgICAgICAgICBvcGVyYXRpb24ucmVjb3JkLFxuICAgICAgICAgIG9wZXJhdGlvbi5yZWxhdGlvbnNoaXAsXG4gICAgICAgICAgb3BlcmF0aW9uLnJlbGF0ZWRSZWNvcmRzXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBbXTtcblxuICAgICAgY2FzZSAnYWRkVG9SZWxhdGVkUmVjb3Jkcyc6XG4gICAgICAgIHRoaXMuYWRkSW52ZXJzZVJlbGF0aW9uc2hpcChcbiAgICAgICAgICBvcGVyYXRpb24ucmVjb3JkLFxuICAgICAgICAgIG9wZXJhdGlvbi5yZWxhdGlvbnNoaXAsXG4gICAgICAgICAgb3BlcmF0aW9uLnJlbGF0ZWRSZWNvcmRcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIFtdO1xuXG4gICAgICBjYXNlICdhZGRSZWNvcmQnOlxuICAgICAgICB0aGlzLmFkZEFsbEludmVyc2VSZWxhdGlvbnNoaXBzKG9wZXJhdGlvbi5yZWNvcmQpO1xuICAgICAgICByZXR1cm4gW107XG5cbiAgICAgIGNhc2UgJ3VwZGF0ZVJlY29yZCc6XG4gICAgICAgIHRoaXMuYWRkQWxsSW52ZXJzZVJlbGF0aW9uc2hpcHMob3BlcmF0aW9uLnJlY29yZCk7XG4gICAgICAgIHJldHVybiBbXTtcblxuICAgICAgY2FzZSAncmVtb3ZlUmVjb3JkJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xlYXJJbnZlcnNlUmVsYXRpb25zaGlwT3BzKG9wZXJhdGlvbi5yZWNvcmQpO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFkZEludmVyc2VSZWxhdGlvbnNoaXAoXG4gICAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgICByZWxhdGVkUmVjb3JkOiBSZWNvcmRJZGVudGl0eSB8IG51bGxcbiAgKTogdm9pZCB7XG4gICAgbGV0IGludmVyc2VSZWxhdGlvbnNoaXAgPSBnZXRJbnZlcnNlUmVsYXRpb25zaGlwKFxuICAgICAgdGhpcy5hY2Nlc3Nvci5zY2hlbWEsXG4gICAgICByZWNvcmQsXG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWxhdGVkUmVjb3JkXG4gICAgKTtcbiAgICBpZiAoaW52ZXJzZVJlbGF0aW9uc2hpcCkge1xuICAgICAgdGhpcy5hY2Nlc3Nvci5hZGRJbnZlcnNlUmVsYXRpb25zaGlwc1N5bmMoW2ludmVyc2VSZWxhdGlvbnNoaXBdKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHMoXG4gICAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgICByZWxhdGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXVxuICApOiB2b2lkIHtcbiAgICBsZXQgaW52ZXJzZVJlbGF0aW9uc2hpcHMgPSBnZXRJbnZlcnNlUmVsYXRpb25zaGlwcyhcbiAgICAgIHRoaXMuYWNjZXNzb3Iuc2NoZW1hLFxuICAgICAgcmVjb3JkLFxuICAgICAgcmVsYXRpb25zaGlwLFxuICAgICAgcmVsYXRlZFJlY29yZHNcbiAgICApO1xuICAgIGlmIChpbnZlcnNlUmVsYXRpb25zaGlwcykge1xuICAgICAgdGhpcy5hY2Nlc3Nvci5hZGRJbnZlcnNlUmVsYXRpb25zaGlwc1N5bmMoaW52ZXJzZVJlbGF0aW9uc2hpcHMpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhZGRBbGxJbnZlcnNlUmVsYXRpb25zaGlwcyhyZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkKTogdm9pZCB7XG4gICAgbGV0IGludmVyc2VSZWxhdGlvbnNoaXBzID0gZ2V0QWxsSW52ZXJzZVJlbGF0aW9uc2hpcHMoXG4gICAgICB0aGlzLmFjY2Vzc29yLnNjaGVtYSxcbiAgICAgIHJlY29yZFxuICAgICk7XG4gICAgaWYgKGludmVyc2VSZWxhdGlvbnNoaXBzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYWNjZXNzb3IuYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKGludmVyc2VSZWxhdGlvbnNoaXBzKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcChcbiAgICByZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICAgIHJlbGF0aW9uc2hpcDogc3RyaW5nLFxuICAgIHJlbGF0ZWRSZWNvcmQ/OiBSZWNvcmRJZGVudGl0eSB8IG51bGxcbiAgKTogdm9pZCB7XG4gICAgbGV0IGludmVyc2VSZWxhdGlvbnNoaXAgPSBnZXRJbnZlcnNlUmVsYXRpb25zaGlwKFxuICAgICAgdGhpcy5hY2Nlc3Nvci5zY2hlbWEsXG4gICAgICByZWNvcmQsXG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWxhdGVkUmVjb3JkXG4gICAgKTtcbiAgICBpZiAoaW52ZXJzZVJlbGF0aW9uc2hpcCkge1xuICAgICAgdGhpcy5hY2Nlc3Nvci5yZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwc1N5bmMoW2ludmVyc2VSZWxhdGlvbnNoaXBdKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcHMoXG4gICAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgICByZWxhdGVkUmVjb3Jkcz86IFJlY29yZElkZW50aXR5W11cbiAgKTogdm9pZCB7XG4gICAgbGV0IGludmVyc2VSZWxhdGlvbnNoaXBzID0gZ2V0SW52ZXJzZVJlbGF0aW9uc2hpcHMoXG4gICAgICB0aGlzLmFjY2Vzc29yLnNjaGVtYSxcbiAgICAgIHJlY29yZCxcbiAgICAgIHJlbGF0aW9uc2hpcCxcbiAgICAgIHJlbGF0ZWRSZWNvcmRzXG4gICAgKTtcbiAgICBpZiAoaW52ZXJzZVJlbGF0aW9uc2hpcHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5hY2Nlc3Nvci5yZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwc1N5bmMoaW52ZXJzZVJlbGF0aW9uc2hpcHMpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCByZW1vdmVBbGxJbnZlcnNlUmVsYXRpb25zaGlwcyhyZWNvcmQ6IFJlY29yZElkZW50aXR5KTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudFJlY29yZCA9IHRoaXMuYWNjZXNzb3IuZ2V0UmVjb3JkU3luYyhyZWNvcmQpO1xuICAgIGlmIChjdXJyZW50UmVjb3JkKSB7XG4gICAgICBjb25zdCBpbnZlcnNlUmVsYXRpb25zaGlwcyA9IGdldEFsbEludmVyc2VSZWxhdGlvbnNoaXBzKFxuICAgICAgICB0aGlzLmFjY2Vzc29yLnNjaGVtYSxcbiAgICAgICAgY3VycmVudFJlY29yZFxuICAgICAgKTtcbiAgICAgIGlmIChpbnZlcnNlUmVsYXRpb25zaGlwcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuYWNjZXNzb3IucmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKGludmVyc2VSZWxhdGlvbnNoaXBzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYXJJbnZlcnNlUmVsYXRpb25zaGlwT3BzKFxuICAgIHJlY29yZDogUmVjb3JkSWRlbnRpdHlcbiAgKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICAgIHJldHVybiBnZXRJbnZlcnNlUmVsYXRpb25zaGlwUmVtb3ZhbE9wcyhcbiAgICAgIHRoaXMuYWNjZXNzb3Iuc2NoZW1hLFxuICAgICAgdGhpcy5hY2Nlc3Nvci5nZXRJbnZlcnNlUmVsYXRpb25zaGlwc1N5bmMocmVjb3JkKVxuICAgICk7XG4gIH1cbn1cbiJdfQ==