UNPKG

@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
"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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