@dolittle/sdk.projections
Version:
Dolittle is a decentralized, distributed, event-driven microservice platform built to harness the power of events.
170 lines • 21.2 kB
JavaScript
"use strict";
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectionStore = void 0;
const operators_1 = require("rxjs/operators");
const rudiments_1 = require("@dolittle/rudiments");
const sdk_artifacts_1 = require("@dolittle/sdk.artifacts");
const sdk_events_1 = require("@dolittle/sdk.events");
const sdk_protobuf_1 = require("@dolittle/sdk.protobuf");
const sdk_resilience_1 = require("@dolittle/sdk.resilience");
const sdk_services_1 = require("@dolittle/sdk.services");
const Store_pb_1 = require("@dolittle/contracts/Runtime/Projections/Store_pb");
const Key_1 = require("../Key");
const ProjectionId_1 = require("../ProjectionId");
const ProjectionsToSDKConverter_1 = require("./Converters/ProjectionsToSDKConverter");
const FailedToGetProjection_1 = require("./FailedToGetProjection");
const FailedToGetProjectionState_1 = require("./FailedToGetProjectionState");
const IProjectionStore_1 = require("./IProjectionStore");
const ReceivedDuplicateProjectionKeys_1 = require("./ReceivedDuplicateProjectionKeys");
const WrongKeyReceivedFromRuntime_1 = require("./WrongKeyReceivedFromRuntime");
const ProjectionOf_1 = require("./ProjectionOf");
const ScopedProjectionId_1 = require("./ScopedProjectionId");
/**
* Represents an implementation of {@link IProjectionStore}.
*/
class ProjectionStore extends IProjectionStore_1.IProjectionStore {
/**
* Initialises a new instance of the {@link ProjectionStore} class.
* @param {ProjectionsClient} _projectionsClient - The projections client to use to get projection states.
* @param {ExecutionContext} _executionContext - The execution context of the client.
* @param {IProjectionReadModelTypes} _readModelTypes - All the types associated with projections.
* @param {Logger} _logger - The logger to use for logging.
*/
constructor(_projectionsClient, _executionContext, _readModelTypes, _logger) {
super();
this._projectionsClient = _projectionsClient;
this._executionContext = _executionContext;
this._readModelTypes = _readModelTypes;
this._logger = _logger;
this._converter = new ProjectionsToSDKConverter_1.ProjectionsToSDKConverter();
}
of(type, maybeProjection, maybeScope) {
if (maybeProjection === undefined) {
return new ProjectionOf_1.ProjectionOf(type, this, this._readModelTypes.getFor(type));
}
const scopeId = maybeScope !== null && maybeScope !== void 0 ? maybeScope : sdk_events_1.ScopeId.default;
return new ProjectionOf_1.ProjectionOf(type, this, new ScopedProjectionId_1.ScopedProjectionId(ProjectionId_1.ProjectionId.from(maybeProjection), sdk_events_1.ScopeId.from(scopeId)));
}
get(typeOrKey, keyOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope, maybeCancellation) {
return this.getStateInternal(typeOrKey, keyOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope, maybeCancellation).then(_ => _.state);
}
getAll(typeOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope, maybeCancellation) {
const type = typeof typeOrProjection === 'function'
? typeOrProjection
: undefined;
const [projection, scope] = this.getProjectionAndScopeForAll(type, typeOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope);
const cancellation = this.getCancellationFrom(maybeCancellationOrProjectionOrScope, maybeCancellationOrScope, maybeCancellation);
this._logger.debug(`Getting all states from projection ${projection} in scope ${scope}`);
const request = new Store_pb_1.GetAllRequest();
request.setCallcontext(sdk_protobuf_1.ExecutionContexts.toCallContext(this._executionContext));
request.setProjectionid(sdk_protobuf_1.Guids.toProtobuf(projection.value));
request.setScopeid(sdk_protobuf_1.Guids.toProtobuf(scope.value));
return (0, sdk_services_1.reactiveServerStream)(this._projectionsClient, this._projectionsClient.getAllInBatches, request, cancellation)
.pipe((0, operators_1.map)(response => {
this.throwIfHasFailure(response, projection, scope);
return this._converter.convertAll(type, response.getStatesList());
}), (0, operators_1.reduce)((all, batch, index) => {
this._logger.debug(`Received batch ${index} with ${batch.size} states from projection ${projection} in scope ${scope}`);
for (const [key, state] of batch) {
if (all.has(key)) {
throw new ReceivedDuplicateProjectionKeys_1.ReceivedDuplicateProjectionKeys(projection, scope, key);
}
all.set(key, state);
}
return all;
}, new sdk_artifacts_1.ComplexValueMap(Key_1.Key, key => [key.value], 1)), (0, operators_1.map)(map => Array.from(map.values()).map(_ => _.state))).toPromise();
}
getState(typeOrKey, keyOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope, maybeCancellation) {
return this.getStateInternal(typeOrKey, keyOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope, maybeCancellation);
}
getStateInternal(typeOrKey, keyOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope, maybeCancellation) {
const type = typeof typeOrKey === 'function'
? typeOrKey
: undefined;
const key = this.getKeyFrom(typeOrKey, keyOrProjection);
const [projection, scope] = this.getProjectionAndScopeForOne(type, keyOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope);
const cancellation = this.getCancellationFrom(maybeCancellationOrProjectionOrScope, maybeCancellationOrScope, maybeCancellation);
this._logger.debug(`Getting one state from projection ${projection} in scope ${scope} with key ${key}`);
const request = new Store_pb_1.GetOneRequest();
request.setCallcontext(sdk_protobuf_1.ExecutionContexts.toCallContext(this._executionContext));
request.setKey(key.value);
request.setProjectionid(sdk_protobuf_1.Guids.toProtobuf(projection.value));
request.setScopeid(sdk_protobuf_1.Guids.toProtobuf(scope.value));
return (0, sdk_services_1.reactiveUnary)(this._projectionsClient, this._projectionsClient.getOne, request, cancellation)
.pipe((0, operators_1.map)(response => {
this.throwIfHasFailure(response, projection, scope, key);
this.throwIfNoState(response, projection, scope, key);
this.throwIfWrongKeyReceived(response.getState(), projection, scope, key);
return this._converter.convert(type, response.getState());
})).toPromise();
}
getKeyFrom(typeOrKey, keyOrProjection) {
if (typeof typeOrKey === 'function') {
return Key_1.Key.from(keyOrProjection);
}
return Key_1.Key.from(typeOrKey);
}
getProjectionAndScopeForOne(type, keyOrProjection, maybeProjectionOrCancellationOrScope, maybeCancellationOrScope) {
if (type === undefined) {
if (maybeProjectionOrCancellationOrScope !== undefined && !(maybeProjectionOrCancellationOrScope instanceof sdk_resilience_1.Cancellation)) {
return [ProjectionId_1.ProjectionId.from(keyOrProjection), sdk_events_1.ScopeId.from(maybeProjectionOrCancellationOrScope)];
}
return [ProjectionId_1.ProjectionId.from(keyOrProjection), sdk_events_1.ScopeId.default];
}
else if (maybeProjectionOrCancellationOrScope instanceof ProjectionId_1.ProjectionId || maybeProjectionOrCancellationOrScope instanceof rudiments_1.Guid || typeof maybeProjectionOrCancellationOrScope === 'string') {
if (maybeCancellationOrScope !== undefined && !(maybeCancellationOrScope instanceof sdk_resilience_1.Cancellation)) {
return [ProjectionId_1.ProjectionId.from(maybeProjectionOrCancellationOrScope), sdk_events_1.ScopeId.from(maybeCancellationOrScope)];
}
return [ProjectionId_1.ProjectionId.from(maybeProjectionOrCancellationOrScope), sdk_events_1.ScopeId.default];
}
const projection = this._readModelTypes.getFor(type);
return [projection.projectionId, projection.scopeId];
}
getProjectionAndScopeForAll(type, typeOrProjection, maybeCancellationOrProjectionOrScope, maybeCancellationOrScope) {
if (typeOrProjection instanceof ProjectionId_1.ProjectionId || typeOrProjection instanceof rudiments_1.Guid || typeof typeOrProjection === 'string') {
if (maybeCancellationOrProjectionOrScope !== undefined && !(maybeCancellationOrProjectionOrScope instanceof sdk_resilience_1.Cancellation)) {
return [ProjectionId_1.ProjectionId.from(typeOrProjection), sdk_events_1.ScopeId.from(maybeCancellationOrProjectionOrScope)];
}
return [ProjectionId_1.ProjectionId.from(typeOrProjection), sdk_events_1.ScopeId.default];
}
else if (maybeCancellationOrProjectionOrScope instanceof ProjectionId_1.ProjectionId || maybeCancellationOrProjectionOrScope instanceof rudiments_1.Guid || typeof maybeCancellationOrProjectionOrScope === 'string') {
if (maybeCancellationOrScope !== undefined && !(maybeCancellationOrScope instanceof sdk_resilience_1.Cancellation)) {
return [ProjectionId_1.ProjectionId.from(maybeCancellationOrProjectionOrScope), sdk_events_1.ScopeId.from(maybeCancellationOrScope)];
}
return [ProjectionId_1.ProjectionId.from(maybeCancellationOrProjectionOrScope), sdk_events_1.ScopeId.default];
}
const projection = this._readModelTypes.getFor(type);
return [projection.projectionId, projection.scopeId];
}
getCancellationFrom(maybeProjectionOrCancellationOrScope, maybeCancellationOrScope, maybeCancellation) {
if (maybeProjectionOrCancellationOrScope instanceof sdk_resilience_1.Cancellation) {
return maybeProjectionOrCancellationOrScope;
}
else if (maybeCancellationOrScope instanceof sdk_resilience_1.Cancellation) {
return maybeCancellationOrScope;
}
else if (maybeCancellation instanceof sdk_resilience_1.Cancellation) {
return maybeCancellation;
}
return sdk_resilience_1.Cancellation.default;
}
throwIfHasFailure(response, projection, scope, key) {
if (response.hasFailure()) {
throw new FailedToGetProjection_1.FailedToGetProjection(projection, scope, key, sdk_protobuf_1.Failures.toSDK(response.getFailure()));
}
}
throwIfNoState(response, projection, scope, key) {
if (!response.hasState()) {
throw new FailedToGetProjectionState_1.FailedToGetProjectionState(projection, scope, key);
}
}
throwIfWrongKeyReceived(state, projection, scope, key) {
if (state.getKey() !== key.value) {
throw new WrongKeyReceivedFromRuntime_1.WrongKeyReceivedFromRuntime(projection, scope, key, state.getKey());
}
}
}
exports.ProjectionStore = ProjectionStore;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJvamVjdGlvblN0b3JlLmpzIiwic291cmNlUm9vdCI6Ii4uLyIsInNvdXJjZXMiOlsiU3RvcmUvUHJvamVjdGlvblN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0MscUdBQXFHOzs7QUFFckcsOENBQTZDO0FBRTdDLG1EQUEyQztBQUUzQywyREFBMEQ7QUFDMUQscURBQStDO0FBRS9DLHlEQUE0RTtBQUM1RSw2REFBd0Q7QUFDeEQseURBQTZFO0FBSTdFLCtFQUFnSTtBQUVoSSxnQ0FBNkI7QUFDN0Isa0RBQStDO0FBRS9DLHNGQUFtRjtBQUVuRixtRUFBZ0U7QUFDaEUsNkVBQTBFO0FBRTFFLHlEQUFzRDtBQUN0RCx1RkFBb0Y7QUFFcEYsK0VBQTRFO0FBRTVFLGlEQUE4QztBQUM5Qyw2REFBMEQ7QUFFMUQ7O0dBRUc7QUFDSCxNQUFhLGVBQWdCLFNBQVEsbUNBQWdCO0lBR2pEOzs7Ozs7T0FNRztJQUNILFlBQ3FCLGtCQUFxQyxFQUNyQyxpQkFBbUMsRUFDbkMsZUFBMEMsRUFDMUMsT0FBZTtRQUNoQyxLQUFLLEVBQUUsQ0FBQztRQUpTLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBbUI7UUFDckMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUNuQyxvQkFBZSxHQUFmLGVBQWUsQ0FBMkI7UUFDMUMsWUFBTyxHQUFQLE9BQU8sQ0FBUTtRQWI1QixlQUFVLEdBQTZCLElBQUkscURBQXlCLEVBQUUsQ0FBQztJQWUvRSxDQUFDO0lBTUQsRUFBRSxDQUFjLElBQThCLEVBQUUsZUFBOEMsRUFBRSxVQUFvQztRQUNoSSxJQUFJLGVBQWUsS0FBSyxTQUFTLEVBQUU7WUFDL0IsT0FBTyxJQUFJLDJCQUFZLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1NBQzFFO1FBRUQsTUFBTSxPQUFPLEdBQUcsVUFBVSxhQUFWLFVBQVUsY0FBVixV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