diff --git a/lib/dist.js b/lib/dist.js index 3d1d0bc..4862b59 100644 --- a/lib/dist.js +++ b/lib/dist.js @@ -86,21 +86,21 @@ module.exports = } // Exporting classes - module.exports.EventStoreConnection = __webpack_require__(6); - module.exports.UserCredentials = __webpack_require__(65); + module.exports.EventStoreConnection = __webpack_require__(7); + module.exports.UserCredentials = __webpack_require__(66); module.exports.EventData = EventData; - module.exports.PersistentSubscriptionSettings = __webpack_require__(66); - module.exports.SystemConsumerStrategies = __webpack_require__(52); + module.exports.PersistentSubscriptionSettings = __webpack_require__(67); + module.exports.SystemConsumerStrategies = __webpack_require__(53); // Exporting errors - module.exports.WrongExpectedVersionError = __webpack_require__(34); - module.exports.StreamDeletedError = __webpack_require__(35); - module.exports.AccessDeniedError = __webpack_require__(36); + module.exports.WrongExpectedVersionError = __webpack_require__(35); + module.exports.StreamDeletedError = __webpack_require__(36); + module.exports.AccessDeniedError = __webpack_require__(37); // Exporting enums/constants module.exports.expectedVersion = expectedVersion; module.exports.positions = positions; - module.exports.systemMetadata = __webpack_require__(67); + module.exports.systemMetadata = __webpack_require__(68); module.exports.eventReadStatus = results.EventReadStatus; - module.exports.sliceReadStatus = __webpack_require__(47); + module.exports.sliceReadStatus = __webpack_require__(48); // Helper functions module.exports.createConnection = module.exports.EventStoreConnection.create; module.exports.createEventData = eventDataFactory; @@ -160,46 +160,42 @@ module.exports = var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var ensure = __webpack_require__(5); - - function toNumber(obj) { - if (typeof obj === 'number') - return obj; - if (typeof obj !== 'object') - throw new TypeError(util.format("'%s' is not a number.", obj)); - if (!obj.hasOwnProperty('low') || !obj.hasOwnProperty('high') || !obj.hasOwnProperty('unsigned')) - throw new Error("Invalid number."); - return (obj.low + (obj.high * 0xffffffff)); - } + var Long = __webpack_require__(5); + var ensure = __webpack_require__(6); /** - * @param {!number} commitPosition - * @param {!number} preparePosition + * @param {!number|!Long} commitPosition + * @param {!number|!Long} preparePosition * @constructor - * @property {!number} commitPosition - * @property {!number} preparePosition + * @property {!Long} commitPosition + * @property {!Long} preparePosition */ function Position(commitPosition, preparePosition) { + ensure.notNull(commitPosition, "commitPosition"); + ensure.notNull(preparePosition, "preparePosition"); + commitPosition = Long.fromValue(commitPosition); + preparePosition = Long.fromValue(preparePosition); + Object.defineProperties(this, { commitPosition: { - enumerable: true, value: toNumber(commitPosition) + enumerable: true, value: commitPosition }, preparePosition: { - enumerable: true, value: toNumber(preparePosition) + enumerable: true, value: preparePosition } }); } Position.prototype.compareTo = function(other) { - if (this.commitPosition < other.commitPosition || (this.commitPosition === other.commitPosition && this.preparePosition < other.preparePosition)) + if (this.commitPosition.lt(other.commitPosition) || (this.commitPosition.eq(other.commitPosition)&& this.preparePosition.lt(other.preparePosition))) return -1; - if (this.commitPosition > other.commitPosition || (this.commitPosition === other.commitPosition && this.preparePosition > other.preparePosition)) + if (this.commitPosition.gt(other.commitPosition) || (this.commitPosition.eq(other.commitPosition) && this.preparePosition.gt(other.preparePosition))) return 1; return 0; }; Position.prototype.toString = function() { - return util.format("%d/%d", this.commitPosition, this.preparePosition); + return [this.commitPosition.toString(), this.preparePosition.toString()].join("/"); }; @@ -229,8 +225,8 @@ module.exports = eventNumber: {enumerable: true, value: ev.event_number}, eventType: {enumerable: true, value: ev.event_type}, //Javascript doesn't have .Net precision for time, so we use created_epoch for created - created: {enumerable: true, value: new Date(ev.created_epoch || 0)}, - createdEpoch: {enumerable: true, value: ev.created_epoch ? toNumber(ev.created_epoch) : 0}, + created: {enumerable: true, value: new Date(ev.created_epoch ? ev.created_epoch.toInt() : 0)}, + createdEpoch: {enumerable: true, value: ev.created_epoch ? ev.created_epoch.toInt() : 0}, data: {enumerable: true, value: ev.data ? ev.data.toBuffer() : new Buffer(0)}, metadata: {enumerable: true, value: ev.metadata ? ev.metadata.toBuffer() : new Buffer(0)}, isJson: {enumerable: true, value: ev.data_content_type == 1} @@ -498,7 +494,6 @@ module.exports = // Exports Constructors module.exports.Position = Position; - module.exports.toNumber = toNumber; module.exports.ResolvedEvent = ResolvedEvent; module.exports.EventReadStatus = EventReadStatus; module.exports.EventReadResult = EventReadResult; @@ -523,6 +518,12 @@ module.exports = /***/ }, /* 5 */ +/***/ function(module, exports) { + + module.exports = require("long"); + +/***/ }, +/* 6 */ /***/ function(module, exports) { module.exports.notNullOrEmpty = function(value, name) { @@ -546,12 +547,12 @@ module.exports = if (!Array.isArray(value)) throw new TypeError(name + " should be an array."); if (!value.every(function(x) { return x instanceof expectedType; })) - throw new TypeError([name, " should be an array of ", expectedType, "."].join("")); + throw new TypeError([name, " should be an array of ", expectedType.name, "."].join("")); }; module.exports.isTypeOf = function(expectedType, value, name) { if (!(value instanceof expectedType)) - throw new TypeError([name, " should be of type '", expectedType, "'."].join("")); + throw new TypeError([name, " should be of type '", expectedType.name, "'."].join("")); }; module.exports.positive = function(value, name) { @@ -565,12 +566,12 @@ module.exports = }; /***/ }, -/* 6 */ +/* 7 */ /***/ function(module, exports, __webpack_require__) { - var EventStoreNodeConnection = __webpack_require__(7); - var StaticEndpointDiscoverer = __webpack_require__(63); - var NoopLogger = __webpack_require__(64); + var EventStoreNodeConnection = __webpack_require__(8); + var StaticEndpointDiscoverer = __webpack_require__(64); + var NoopLogger = __webpack_require__(65); var defaultConnectionSettings = { log: new NoopLogger(), @@ -625,39 +626,39 @@ module.exports = }; /***/ }, -/* 7 */ +/* 8 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var EventEmitter = __webpack_require__(8).EventEmitter; - var ensure = __webpack_require__(5); + var EventEmitter = __webpack_require__(9).EventEmitter; + var ensure = __webpack_require__(6); - var messages = __webpack_require__(9); - var EventStoreConnectionLogicHandler = __webpack_require__(10); + var messages = __webpack_require__(10); + var EventStoreConnectionLogicHandler = __webpack_require__(11); - var DeleteStreamOperation = __webpack_require__(33); - var AppendToStreamOperation = __webpack_require__(38); - var StartTransactionOperation = __webpack_require__(39); - var TransactionalWriteOperation = __webpack_require__(41); - var CommitTransactionOperation = __webpack_require__(42); - var ReadEventOperation = __webpack_require__(43); - var ReadStreamEventsForwardOperation = __webpack_require__(44); - var ReadStreamEventsBackwardOperation = __webpack_require__(48); - var ReadAllEventsForwardOperation = __webpack_require__(49); - var ReadAllEventsBackwardOperation = __webpack_require__(50); - var CreatePersistentSubscriptionOperation = __webpack_require__(51); - var UpdatePersistentSubscriptionOperation = __webpack_require__(53); - var DeletePersistentSubscriptionOperation = __webpack_require__(54); + var DeleteStreamOperation = __webpack_require__(34); + var AppendToStreamOperation = __webpack_require__(39); + var StartTransactionOperation = __webpack_require__(40); + var TransactionalWriteOperation = __webpack_require__(42); + var CommitTransactionOperation = __webpack_require__(43); + var ReadEventOperation = __webpack_require__(44); + var ReadStreamEventsForwardOperation = __webpack_require__(45); + var ReadStreamEventsBackwardOperation = __webpack_require__(49); + var ReadAllEventsForwardOperation = __webpack_require__(50); + var ReadAllEventsBackwardOperation = __webpack_require__(51); + var CreatePersistentSubscriptionOperation = __webpack_require__(52); + var UpdatePersistentSubscriptionOperation = __webpack_require__(54); + var DeletePersistentSubscriptionOperation = __webpack_require__(55); - var EventStoreTransaction = __webpack_require__(40); - var EventStoreStreamCatchUpSubscription = __webpack_require__(55); - var EventStoreAllCatchUpSubscription = __webpack_require__(57); - var EventStorePersistentSubscription = __webpack_require__(58); + var EventStoreTransaction = __webpack_require__(41); + var EventStoreStreamCatchUpSubscription = __webpack_require__(56); + var EventStoreAllCatchUpSubscription = __webpack_require__(58); + var EventStorePersistentSubscription = __webpack_require__(59); var results = __webpack_require__(3); - var systemStreams = __webpack_require__(61); - var systemEventTypes = __webpack_require__(62); + var systemStreams = __webpack_require__(62); + var systemEventTypes = __webpack_require__(63); var EventData = __webpack_require__(1); const MaxReadSize = 4096; @@ -782,7 +783,10 @@ module.exports = * @returns {Promise.} */ EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedVersion, userCredentials) { - //TODO validations + ensure.notNullOrEmpty(stream, "stream"); + ensure.isInteger(expectedVersion, "expectedVersion"); + userCredentials = userCredentials || null; + var self = this; return new Promise(function(resolve, reject) { function cb(err, result) { @@ -790,7 +794,7 @@ module.exports = resolve(result); } var operation = new StartTransactionOperation(self._settings.log, cb, self._settings.requireMaster, stream, - expectedVersion, self, userCredentials || null); + expectedVersion, self, userCredentials); self._enqueueOperation(operation); }); }; @@ -802,11 +806,16 @@ module.exports = * @returns {EventStoreTransaction} */ EventStoreNodeConnection.prototype.continueTransaction = function(transactionId, userCredentials) { - //TODO validations + ensure.nonNegative(transactionId, "transactionId"); + return new EventStoreTransaction(transactionId, userCredentials, this); }; EventStoreNodeConnection.prototype.transactionalWrite = function(transaction, events, userCredentials) { + ensure.isTypeOf(EventStoreTransaction, transaction, "transaction"); + ensure.isArrayOf(EventData, events, "events"); + userCredentials = userCredentials || null; + var self = this; return new Promise(function(resolve, reject) { function cb(err) { @@ -820,6 +829,8 @@ module.exports = }; EventStoreNodeConnection.prototype.commitTransaction = function(transaction, userCredentials) { + ensure.isTypeOf(EventStoreTransaction, transaction, "transaction"); + var self = this; return new Promise(function(resolve, reject) { function cb(err, result) { @@ -1278,17 +1289,17 @@ module.exports = /***/ }, -/* 8 */ +/* 9 */ /***/ function(module, exports) { module.exports = require("events"); /***/ }, -/* 9 */ +/* 10 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var ensure = __webpack_require__(5); + var ensure = __webpack_require__(6); function Message() { } @@ -1398,25 +1409,25 @@ module.exports = /***/ }, -/* 10 */ +/* 11 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var EventEmitter = __webpack_require__(8).EventEmitter; + var EventEmitter = __webpack_require__(9).EventEmitter; - var SimpleQueuedHandler = __webpack_require__(11); - var TcpPackageConnection = __webpack_require__(12); - var OperationsManager = __webpack_require__(20); - var SubscriptionsManager = __webpack_require__(22); - var VolatileSubscriptionOperation = __webpack_require__(24); - var ConnectToPersistentSubscriptionOperation = __webpack_require__(31); - var messages = __webpack_require__(9); + var SimpleQueuedHandler = __webpack_require__(12); + var TcpPackageConnection = __webpack_require__(13); + var OperationsManager = __webpack_require__(21); + var SubscriptionsManager = __webpack_require__(23); + var VolatileSubscriptionOperation = __webpack_require__(25); + var ConnectToPersistentSubscriptionOperation = __webpack_require__(32); + var messages = __webpack_require__(10); - var TcpPackage = __webpack_require__(17); - var TcpCommand = __webpack_require__(19); - var TcpFlags = __webpack_require__(18); - var InspectionDecision = __webpack_require__(26); + var TcpPackage = __webpack_require__(18); + var TcpCommand = __webpack_require__(20); + var TcpFlags = __webpack_require__(19); + var InspectionDecision = __webpack_require__(27); const ConnectionState = { Init: 'init', @@ -2079,7 +2090,7 @@ module.exports = module.exports = EventStoreConnectionLogicHandler; /***/ }, -/* 11 */ +/* 12 */ /***/ function(module, exports) { function typeName(t) { @@ -2125,16 +2136,16 @@ module.exports = module.exports = SimpleQueuedHandler; /***/ }, -/* 12 */ +/* 13 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var LengthPrefixMessageFramer = __webpack_require__(13); - var TcpConnection = __webpack_require__(15); - var TcpPackage = __webpack_require__(17); - var TcpCommand = __webpack_require__(19); + var LengthPrefixMessageFramer = __webpack_require__(14); + var TcpConnection = __webpack_require__(16); + var TcpPackage = __webpack_require__(18); + var TcpCommand = __webpack_require__(20); /** * @param log @@ -2283,10 +2294,10 @@ module.exports = module.exports = TcpPackageConnection; /***/ }, -/* 13 */ +/* 14 */ /***/ function(module, exports, __webpack_require__) { - var createBufferSegment = __webpack_require__(14); + var createBufferSegment = __webpack_require__(15); const HeaderLength = 4; @@ -2361,7 +2372,7 @@ module.exports = /***/ }, -/* 14 */ +/* 15 */ /***/ function(module, exports) { /** @@ -2398,11 +2409,11 @@ module.exports = }; /***/ }, -/* 15 */ +/* 16 */ /***/ function(module, exports, __webpack_require__) { - var net = __webpack_require__(16); - var createBufferSegment = __webpack_require__(14); + var net = __webpack_require__(17); + var createBufferSegment = __webpack_require__(15); const MaxSendPacketSize = 64 * 1000; @@ -2556,19 +2567,19 @@ module.exports = module.exports = TcpConnection; /***/ }, -/* 16 */ +/* 17 */ /***/ function(module, exports) { module.exports = require("net"); /***/ }, -/* 17 */ +/* 18 */ /***/ function(module, exports, __webpack_require__) { var uuid = __webpack_require__(2); - var createBufferSegment = __webpack_require__(14); - var TcpFlags = __webpack_require__(18); + var createBufferSegment = __webpack_require__(15); + var TcpFlags = __webpack_require__(19); const CommandOffset = 0; const FlagsOffset = CommandOffset + 1; @@ -2653,7 +2664,7 @@ module.exports = module.exports = TcpPackage; /***/ }, -/* 18 */ +/* 19 */ /***/ function(module, exports) { const TcpFlags = { @@ -2665,7 +2676,7 @@ module.exports = /***/ }, -/* 19 */ +/* 20 */ /***/ function(module, exports) { const TcpCommand = { @@ -2757,14 +2768,14 @@ module.exports = /***/ }, -/* 20 */ +/* 21 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var Hash = __webpack_require__(21); - var TcpCommand = __webpack_require__(19); + var Hash = __webpack_require__(22); + var TcpCommand = __webpack_require__(20); /** * @param {string} connectionName @@ -2934,7 +2945,7 @@ module.exports = /***/ }, -/* 21 */ +/* 22 */ /***/ function(module, exports) { /** @@ -2981,14 +2992,14 @@ module.exports = /***/ }, -/* 22 */ +/* 23 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var Hash = __webpack_require__(21); + var Hash = __webpack_require__(22); - var SubscriptionDropReason = __webpack_require__(23); + var SubscriptionDropReason = __webpack_require__(24); function SubscriptionsManager(connectionName, settings) { //Ensure.NotNull(connectionName, "connectionName"); @@ -3157,7 +3168,7 @@ module.exports = module.exports = SubscriptionsManager; /***/ }, -/* 23 */ +/* 24 */ /***/ function(module, exports) { const SubscriptionDropReason = { @@ -3178,21 +3189,21 @@ module.exports = module.exports = SubscriptionDropReason; /***/ }, -/* 24 */ +/* 25 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var SubscriptionOperation = __webpack_require__(25); - var ClientMessage = __webpack_require__(28); - var TcpPackage = __webpack_require__(17); - var TcpCommand = __webpack_require__(19); - var TcpFlags = __webpack_require__(18); - var BufferSegment = __webpack_require__(14); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); + var SubscriptionOperation = __webpack_require__(26); + var ClientMessage = __webpack_require__(29); + var TcpPackage = __webpack_require__(18); + var TcpCommand = __webpack_require__(20); + var TcpFlags = __webpack_require__(19); + var BufferSegment = __webpack_require__(15); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); var results = __webpack_require__(3); - var VolatileEventStoreSubscription = __webpack_require__(29); + var VolatileEventStoreSubscription = __webpack_require__(30); function VolatileSubscriptionOperation( log, cb, streamId, resolveLinkTos, userCredentials, eventAppeared, @@ -3238,21 +3249,21 @@ module.exports = module.exports = VolatileSubscriptionOperation; /***/ }, -/* 25 */ +/* 26 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var TcpFlags = __webpack_require__(18); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); - var ClientMessage = __webpack_require__(28); - var TcpPackage = __webpack_require__(17); - var BufferSegment = __webpack_require__(14); + var TcpCommand = __webpack_require__(20); + var TcpFlags = __webpack_require__(19); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); + var ClientMessage = __webpack_require__(29); + var TcpPackage = __webpack_require__(18); + var BufferSegment = __webpack_require__(15); var results = __webpack_require__(3); - var SubscriptionDropReason = __webpack_require__(23); + var SubscriptionDropReason = __webpack_require__(24); //TODO: nodify eventAppeared and subscriptionDropped, should be emit on subscription function SubscriptionOperation( @@ -3513,7 +3524,7 @@ module.exports = module.exports = SubscriptionOperation; /***/ }, -/* 26 */ +/* 27 */ /***/ function(module, exports) { var InspectionDecision = { @@ -3527,7 +3538,7 @@ module.exports = module.exports = InspectionDecision; /***/ }, -/* 27 */ +/* 28 */ /***/ function(module, exports) { function InspectionResult(decision, description, tcpEndPoint, secureTcpEndPoint) { @@ -3541,18 +3552,18 @@ module.exports = /***/ }, -/* 28 */ +/* 29 */ /***/ function(module, exports) { module.exports = require("../src/messages/clientMessage"); /***/ }, -/* 29 */ +/* 30 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var EventStoreSubsription = __webpack_require__(30); + var EventStoreSubsription = __webpack_require__(31); /** * @param {SubscriptionOperation} subscriptionOperation @@ -3577,7 +3588,7 @@ module.exports = /***/ }, -/* 30 */ +/* 31 */ /***/ function(module, exports) { /*** @@ -3627,24 +3638,24 @@ module.exports = /***/ }, -/* 31 */ +/* 32 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var SubscriptionOperation = __webpack_require__(25); - var ClientMessage = __webpack_require__(28); - var TcpCommand = __webpack_require__(19); - var TcpFlags = __webpack_require__(18); - var TcpPackage = __webpack_require__(17); - var createBufferSegment = __webpack_require__(14); - var InspectionResult = __webpack_require__(27); - var InspectionDecision = __webpack_require__(26); + var SubscriptionOperation = __webpack_require__(26); + var ClientMessage = __webpack_require__(29); + var TcpCommand = __webpack_require__(20); + var TcpFlags = __webpack_require__(19); + var TcpPackage = __webpack_require__(18); + var createBufferSegment = __webpack_require__(15); + var InspectionResult = __webpack_require__(28); + var InspectionDecision = __webpack_require__(27); var results = __webpack_require__(3); - var SubscriptionDropReason = __webpack_require__(23); - var PersistentEventStoreSubscription = __webpack_require__(32); - var ensure = __webpack_require__(5); + var SubscriptionDropReason = __webpack_require__(24); + var PersistentEventStoreSubscription = __webpack_require__(33); + var ensure = __webpack_require__(6); function ConnectToPersistentSubscriptionOperation( log, cb, groupName, bufferSize, streamId, userCredentials, eventAppeared, subscriptionDropped, @@ -3755,12 +3766,12 @@ module.exports = /***/ }, -/* 32 */ +/* 33 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var EventStoreSubscription = __webpack_require__(30); + var EventStoreSubscription = __webpack_require__(31); function PersistentEventStoreSubscription(subscriptionOperation, streamId, lastCommitPosition, lastEventNumber) { @@ -3786,22 +3797,22 @@ module.exports = /***/ }, -/* 33 */ +/* 34 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); - var ClientMessage = __webpack_require__(28); + var TcpCommand = __webpack_require__(20); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); + var ClientMessage = __webpack_require__(29); var results = __webpack_require__(3); - var WrongExpectedVersionError = __webpack_require__(34); - var StreamDeletedError = __webpack_require__(35); - var AccessDeniedError = __webpack_require__(36); + var WrongExpectedVersionError = __webpack_require__(35); + var StreamDeletedError = __webpack_require__(36); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function DeleteStreamOperation(log, cb, requireMaster, stream, expectedVersion, hardDelete, userCredentials) { @@ -3859,69 +3870,99 @@ module.exports = module.exports = DeleteStreamOperation; /***/ }, -/* 34 */ +/* 35 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); + var Long = __webpack_require__(5); - function WrongExpectedVersionError(action, stream, expectedVersion) { + function WrongExpectedVersionError(action, streamOrTransactionId, expectedVersion) { Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; - this.message = util.format("%s failed due to WrongExpectedVersion. Stream: %s Expected version: %d.", action, stream, expectedVersion); this.action = action; - this.stream = stream; - this.expectedVersion = expectedVersion; + if (typeof streamOrTransactionId === 'string') { + this.message = util.format("%s failed due to WrongExpectedVersion. Stream: %s Expected version: %d.", action, streamOrTransactionId, expectedVersion); + this.stream = streamOrTransactionId; + this.expectedVersion = expectedVersion; + return; + } + if (Long.isLong(streamOrTransactionId)) { + this.message = util.format("%s transaction failed due to WrongExpectedVersion. Transaction Id: %s.", action, streamOrTransactionId); + this.transactionId = streamOrTransactionId; + return; + } + throw new TypeError("second argument must be a stream name or a transaction Id."); } util.inherits(WrongExpectedVersionError, Error); module.exports = WrongExpectedVersionError; /***/ }, -/* 35 */ +/* 36 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); + var Long = __webpack_require__(5); - function StreamDeletedError(stream) { + function StreamDeletedError(streamOrTransactionId) { Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; - this.message = util.format("Event stream '%s' is deleted.", stream); - this.stream = stream; + if (typeof streamOrTransactionId === 'string') { + this.message = util.format("Event stream '%s' is deleted.", streamOrTransactionId); + this.stream = streamOrTransactionId; + return; + } + if (Long.isLong(streamOrTransactionId)) { + this.message = util.format("Stream is deleted for transaction %s.", streamOrTransactionId); + this.transactionId = streamOrTransactionId; + return; + } + throw new TypeError("second argument must be a stream name or transaction Id."); } util.inherits(StreamDeletedError, Error); module.exports = StreamDeletedError; /***/ }, -/* 36 */ +/* 37 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); + var Long = __webpack_require__(5); - function AccessDeniedError(action, stream) { + function AccessDeniedError(action, streamOrTransactionId) { Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; - this.message = util.format("%s access denied for stream '%s'.", action, stream); this.action = action; - this.stream = stream; + if (typeof streamOrTransactionId === 'string') { + this.message = util.format("%s access denied for stream '%s'.", action, streamOrTransactionId); + this.stream = streamOrTransactionId; + return; + } + if (Long.isLong(streamOrTransactionId)) { + this.message = util.format("%s access denied for transaction %s.", action, streamOrTransactionId); + this.transactionId = streamOrTransactionId; + return; + } + throw new TypeError("second argument must be a stream name or transaction Id."); } util.inherits(AccessDeniedError, Error); module.exports = AccessDeniedError; /***/ }, -/* 37 */ +/* 38 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var TcpPackage = __webpack_require__(17); - var TcpCommand = __webpack_require__(19); - var TcpFlags = __webpack_require__(18); - var InspectionDecision = __webpack_require__(26); - var ClientMessage = __webpack_require__(28); - var InspectionResult = __webpack_require__(27); - var createBufferSegment = __webpack_require__(14); + var TcpPackage = __webpack_require__(18); + var TcpCommand = __webpack_require__(20); + var TcpFlags = __webpack_require__(19); + var InspectionDecision = __webpack_require__(27); + var ClientMessage = __webpack_require__(29); + var InspectionResult = __webpack_require__(28); + var createBufferSegment = __webpack_require__(15); function OperationBase(log, cb, requestCommand, responseCommand, userCredentials) { this.log = log; @@ -4064,23 +4105,23 @@ module.exports = /***/ }, -/* 38 */ +/* 39 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); - var ClientMessage = __webpack_require__(28); + var TcpCommand = __webpack_require__(20); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); + var ClientMessage = __webpack_require__(29); var WriteResult = __webpack_require__(3).WriteResult; var Position = __webpack_require__(3).Position; - var WrongExpectedVersionError = __webpack_require__(34); - var StreamDeletedError = __webpack_require__(35); - var AccessDeniedError = __webpack_require__(36); + var WrongExpectedVersionError = __webpack_require__(35); + var StreamDeletedError = __webpack_require__(36); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function AppendToStreamOperation(log, cb, requireMaster, stream, expectedVersion, events, userCredentials) { OperationBase.call(this, log, cb, TcpCommand.WriteEvents, TcpCommand.WriteEventsCompleted, userCredentials); @@ -4152,20 +4193,22 @@ module.exports = /***/ }, -/* 39 */ +/* 40 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); - var ClientMessage = __webpack_require__(28); - var EventStoreTransaction = __webpack_require__(40); + var TcpCommand = __webpack_require__(20); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); + var ClientMessage = __webpack_require__(29); + var EventStoreTransaction = __webpack_require__(41); var results = __webpack_require__(3); - - var OperationBase = __webpack_require__(37); + var AccessDeniedError = __webpack_require__(37); + var WrongExpectedVersionError = __webpack_require__(35); + var StreamDeletedError = __webpack_require__(36); + var OperationBase = __webpack_require__(38); function StartTransactionOperation(log, cb, requireMaster, stream, expectedVersion, parentConnection, userCredentials) { OperationBase.call(this, log, cb, TcpCommand.TransactionStart, TcpCommand.TransactionStartCompleted, userCredentials); @@ -4195,17 +4238,16 @@ module.exports = case ClientMessage.OperationResult.ForwardTimeout: return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); case ClientMessage.OperationResult.WrongExpectedVersion: - var err = util.format("Start transaction failed due to WrongExpectedVersion. Stream: %s, Expected version: %d.", this._stream, this._expectedVersion); - this.fail(new Error(err)); + this.fail(new WrongExpectedVersionError("Start transaction", this._stream, this._expectedVersion)); return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion"); case ClientMessage.OperationResult.StreamDeleted: - this.fail(new Error("Stream deleted: " + this._stream)); + this.fail(new StreamDeletedError(this._stream)); return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted"); case ClientMessage.OperationResult.InvalidTransaction: this.fail(new Error("Invalid transaction.")); return new InspectionResult(InspectionDecision.EndOperation, "InvalidTransaction"); case ClientMessage.OperationResult.AccessDenied: - this.fail(new Error(util.format("Write access denied for stream '%s'.", this._stream))); + this.fail(new AccessDeniedError("Write", this._stream)); return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); default: throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); @@ -4213,7 +4255,7 @@ module.exports = }; StartTransactionOperation.prototype._transformResponse = function(response) { - return new EventStoreTransaction(results.toNumber(response.transaction_id), this.userCredentials, this._parentConnection); + return new EventStoreTransaction(response.transaction_id, this.userCredentials, this._parentConnection); }; StartTransactionOperation.prototype.toString = function() { @@ -4224,7 +4266,7 @@ module.exports = /***/ }, -/* 40 */ +/* 41 */ /***/ function(module, exports) { /** @@ -4241,12 +4283,13 @@ module.exports = this._isCommitted = false; this._isRolledBack = false; + + Object.defineProperties(this, { + transactionId: { + enumerable: true, get: function() { return this._transactionId; } + } + }); } - Object.defineProperty(EventStoreTransaction.prototype, 'transactionId', { - get: function() { - return this._transactionId; - } - }); /** * Commit (async) @@ -4261,13 +4304,13 @@ module.exports = /** * Write events (async) - * @param {Array.} events + * @param {EventData|EventData[]} eventOrEvents * @returns {Promise} */ - EventStoreTransaction.prototype.write = function(events) { + EventStoreTransaction.prototype.write = function(eventOrEvents) { if (this._isRolledBack) throw new Error("can't write to a rolledback transaction"); if (this._isCommitted) throw new Error("Transaction is already committed"); - if (!Array.isArray(events)) throw new Error("events must be an array."); + var events = Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents]; return this._connection.transactionalWrite(this, events); }; @@ -4282,18 +4325,19 @@ module.exports = module.exports = EventStoreTransaction; /***/ }, -/* 41 */ +/* 42 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); - var ClientMessage = __webpack_require__(28); + var TcpCommand = __webpack_require__(20); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); + var ClientMessage = __webpack_require__(29); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function TransactionalWriteOperation(log, cb, requireMaster, transactionId, events, userCredentials) { @@ -4330,7 +4374,7 @@ module.exports = case ClientMessage.OperationResult.ForwardTimeout: return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); case ClientMessage.OperationResult.AccessDenied: - this.fail(new Error("Write access denied.")); + this.fail(new AccessDeniedError("Write", "trx:" + this._transactionId)); return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); default: throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); @@ -4350,19 +4394,22 @@ module.exports = /***/ }, -/* 42 */ +/* 43 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); - var ClientMessage = __webpack_require__(28); + var TcpCommand = __webpack_require__(20); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); + var ClientMessage = __webpack_require__(29); var results = __webpack_require__(3); + var WrongExpectedVersionError = __webpack_require__(35); + var StreamDeletedError = __webpack_require__(36); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function CommitTransactionOperation(log, cb, requireMaster, transactionId, userCredentials) { @@ -4391,17 +4438,16 @@ module.exports = case ClientMessage.OperationResult.ForwardTimeout: return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); case ClientMessage.OperationResult.WrongExpectedVersion: - var err = util.format("Commit transaction failed due to WrongExpectedVersion. TransactionID: %d.", this._transactionId); - this.fail(new Error(err)); + this.fail(new WrongExpectedVersionError("Commit", this._transactionId)); return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion"); case ClientMessage.OperationResult.StreamDeleted: - this.fail(new Error("Stream deleted.")); + this.fail(new StreamDeletedError(this._transactionId)); return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted"); case ClientMessage.OperationResult.InvalidTransaction: this.fail(new Error("Invalid transaction.")); return new InspectionResult(InspectionDecision.EndOperation, "InvalidTransaction"); case ClientMessage.OperationResult.AccessDenied: - this.fail(new Error("Write access denied.")); + this.fail(new AccessDeniedError("Write", this._transactionId)); return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); default: throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); @@ -4420,19 +4466,19 @@ module.exports = module.exports = CommitTransactionOperation; /***/ }, -/* 43 */ +/* 44 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var TcpCommand = __webpack_require__(19); - var ClientMessage = __webpack_require__(28); - var InspectionResult = __webpack_require__(27); - var InspectionDecision = __webpack_require__(26); + var TcpCommand = __webpack_require__(20); + var ClientMessage = __webpack_require__(29); + var InspectionResult = __webpack_require__(28); + var InspectionDecision = __webpack_require__(27); var results = __webpack_require__(3); - var AccessDeniedError = __webpack_require__(36); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function ReadEventOperation(log, cb, stream, eventNumber, resolveLinkTos, requireMaster, userCredentials) { OperationBase.call(this, log, cb, TcpCommand.ReadEvent, TcpCommand.ReadEventCompleted, userCredentials); @@ -4506,22 +4552,22 @@ module.exports = /***/ }, -/* 44 */ +/* 45 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var ClientMessage = __webpack_require__(28); - var ReadDirection = __webpack_require__(45); - var StatusCode = __webpack_require__(46); - var InspectionResult = __webpack_require__(27); - var InspectionDecision = __webpack_require__(26); + var TcpCommand = __webpack_require__(20); + var ClientMessage = __webpack_require__(29); + var ReadDirection = __webpack_require__(46); + var StatusCode = __webpack_require__(47); + var InspectionResult = __webpack_require__(28); + var InspectionDecision = __webpack_require__(27); var results = __webpack_require__(3); - var AccessDeniedError = __webpack_require__(36); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function ReadStreamEventsForwardOperation( log, cb, stream, fromEventNumber, maxCount, resolveLinkTos, requireMaster, userCredentials @@ -4586,7 +4632,7 @@ module.exports = /***/ }, -/* 45 */ +/* 46 */ /***/ function(module, exports) { const ReadDirection = { @@ -4598,11 +4644,11 @@ module.exports = /***/ }, -/* 46 */ +/* 47 */ /***/ function(module, exports, __webpack_require__) { - var ClientMessage = __webpack_require__(28); - var SliceReadStatus = __webpack_require__(47); + var ClientMessage = __webpack_require__(29); + var SliceReadStatus = __webpack_require__(48); module.exports = {}; @@ -4620,7 +4666,7 @@ module.exports = }; /***/ }, -/* 47 */ +/* 48 */ /***/ function(module, exports) { const SliceReadStatus = { @@ -4633,22 +4679,22 @@ module.exports = /***/ }, -/* 48 */ +/* 49 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var ClientMessage = __webpack_require__(28); - var ReadDirection = __webpack_require__(45); - var StatusCode = __webpack_require__(46); - var InspectionResult = __webpack_require__(27); - var InspectionDecision = __webpack_require__(26); + var TcpCommand = __webpack_require__(20); + var ClientMessage = __webpack_require__(29); + var ReadDirection = __webpack_require__(46); + var StatusCode = __webpack_require__(47); + var InspectionResult = __webpack_require__(28); + var InspectionDecision = __webpack_require__(27); var results = __webpack_require__(3); - var AccessDeniedError = __webpack_require__(36); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function ReadStreamEventsBackwardOperation( log, cb, stream, fromEventNumber, maxCount, resolveLinkTos, requireMaster, userCredentials @@ -4713,21 +4759,21 @@ module.exports = /***/ }, -/* 49 */ +/* 50 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var ClientMessage = __webpack_require__(28); - var ReadDirection = __webpack_require__(45); - var InspectionResult = __webpack_require__(27); - var InspectionDecision = __webpack_require__(26); + var TcpCommand = __webpack_require__(20); + var ClientMessage = __webpack_require__(29); + var ReadDirection = __webpack_require__(46); + var InspectionResult = __webpack_require__(28); + var InspectionDecision = __webpack_require__(27); var results = __webpack_require__(3); - var AccessDeniedError = __webpack_require__(36); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function ReadAllEventsForwardOperation( log, cb, position, maxCount, resolveLinkTos, requireMaster, userCredentials @@ -4781,21 +4827,21 @@ module.exports = /***/ }, -/* 50 */ +/* 51 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var TcpCommand = __webpack_require__(19); - var ClientMessage = __webpack_require__(28); - var ReadDirection = __webpack_require__(45); - var InspectionResult = __webpack_require__(27); - var InspectionDecision = __webpack_require__(26); + var TcpCommand = __webpack_require__(20); + var ClientMessage = __webpack_require__(29); + var ReadDirection = __webpack_require__(46); + var InspectionResult = __webpack_require__(28); + var InspectionDecision = __webpack_require__(27); var results = __webpack_require__(3); - var AccessDeniedError = __webpack_require__(36); + var AccessDeniedError = __webpack_require__(37); - var OperationBase = __webpack_require__(37); + var OperationBase = __webpack_require__(38); function ReadAllEventsBackwardOperation( log, cb, position, maxCount, resolveLinkTos, requireMaster, userCredentials @@ -4849,19 +4895,19 @@ module.exports = /***/ }, -/* 51 */ +/* 52 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var ensure = __webpack_require__(5); - var OperationBase = __webpack_require__(37); - var TcpCommand = __webpack_require__(19); - var ClientMessage = __webpack_require__(28); - var SystemConsumerStrategies = __webpack_require__(52); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); + var ensure = __webpack_require__(6); + var OperationBase = __webpack_require__(38); + var TcpCommand = __webpack_require__(20); + var ClientMessage = __webpack_require__(29); + var SystemConsumerStrategies = __webpack_require__(53); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); var results = __webpack_require__(3); @@ -4929,7 +4975,7 @@ module.exports = /***/ }, -/* 52 */ +/* 53 */ /***/ function(module, exports) { const SystemConsumerStrategies = { @@ -4942,19 +4988,19 @@ module.exports = /***/ }, -/* 53 */ +/* 54 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var ensure = __webpack_require__(5); - var OperationBase = __webpack_require__(37); - var TcpCommand = __webpack_require__(19); - var ClientMessage = __webpack_require__(28); - var SystemConsumerStrategies = __webpack_require__(52); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); + var ensure = __webpack_require__(6); + var OperationBase = __webpack_require__(38); + var TcpCommand = __webpack_require__(20); + var ClientMessage = __webpack_require__(29); + var SystemConsumerStrategies = __webpack_require__(53); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); var results = __webpack_require__(3); @@ -5022,18 +5068,18 @@ module.exports = /***/ }, -/* 54 */ +/* 55 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); var uuid = __webpack_require__(2); - var ensure = __webpack_require__(5); - var OperationBase = __webpack_require__(37); - var TcpCommand = __webpack_require__(19); - var ClientMessage = __webpack_require__(28); - var InspectionDecision = __webpack_require__(26); - var InspectionResult = __webpack_require__(27); + var ensure = __webpack_require__(6); + var OperationBase = __webpack_require__(38); + var TcpCommand = __webpack_require__(20); + var ClientMessage = __webpack_require__(29); + var InspectionDecision = __webpack_require__(27); + var InspectionResult = __webpack_require__(28); var results = __webpack_require__(3); @@ -5083,13 +5129,13 @@ module.exports = /***/ }, -/* 55 */ +/* 56 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var EventStoreCatchUpSubscription = __webpack_require__(56); - var SliceReadStatus = __webpack_require__(47); + var EventStoreCatchUpSubscription = __webpack_require__(57); + var SliceReadStatus = __webpack_require__(48); function EventStoreStreamCatchUpSubscription( connection, log, streamId, fromEventNumberExclusive, resolveLinkTos, userCredentials, @@ -5181,12 +5227,12 @@ module.exports = /***/ }, -/* 56 */ +/* 57 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var SubscriptionDropReason = __webpack_require__(23); + var SubscriptionDropReason = __webpack_require__(24); var results = __webpack_require__(3); const DefaultReadBatchSize = 500; @@ -5439,12 +5485,12 @@ module.exports = module.exports = EventStoreCatchUpSubscription; /***/ }, -/* 57 */ +/* 58 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var EventStoreCatchUpSubscription = __webpack_require__(56); + var EventStoreCatchUpSubscription = __webpack_require__(57); var results = __webpack_require__(3); @@ -5529,13 +5575,13 @@ module.exports = /***/ }, -/* 58 */ +/* 59 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var EventStorePersistentSubscriptionBase = __webpack_require__(59); - var messages = __webpack_require__(9); + var EventStorePersistentSubscriptionBase = __webpack_require__(60); + var messages = __webpack_require__(10); function EventStorePersistentSubscription( subscriptionId, streamId, eventAppeared, subscriptionDropped, userCredentials, log, verboseLogging, settings, @@ -5569,13 +5615,13 @@ module.exports = module.exports = EventStorePersistentSubscription; /***/ }, -/* 59 */ +/* 60 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(4); - var ensure = __webpack_require__(5); - var PersistentSubscriptionNakEventAction = __webpack_require__(60); - var SubscriptionDropReason = __webpack_require__(23); + var ensure = __webpack_require__(6); + var PersistentSubscriptionNakEventAction = __webpack_require__(61); + var SubscriptionDropReason = __webpack_require__(24); function DropSubscriptionEvent() {} @@ -5742,7 +5788,7 @@ module.exports = /***/ }, -/* 60 */ +/* 61 */ /***/ function(module, exports) { const PersistentSubscriptionNakEventAction = { @@ -5762,7 +5808,7 @@ module.exports = /***/ }, -/* 61 */ +/* 62 */ /***/ function(module, exports) { module.exports.metastreamOf = function(stream) { @@ -5773,7 +5819,7 @@ module.exports = }; /***/ }, -/* 62 */ +/* 63 */ /***/ function(module, exports) { const SystemEventTypes = { @@ -5784,7 +5830,7 @@ module.exports = /***/ }, -/* 63 */ +/* 64 */ /***/ function(module, exports) { function StaticEndpointDiscoverer(tcpEndPoint, useSsl) { @@ -5801,7 +5847,7 @@ module.exports = module.exports = StaticEndpointDiscoverer; /***/ }, -/* 64 */ +/* 65 */ /***/ function(module, exports) { function NoopLogger() { @@ -5813,10 +5859,10 @@ module.exports = module.exports = NoopLogger; /***/ }, -/* 65 */ +/* 66 */ /***/ function(module, exports, __webpack_require__) { - var ensure = __webpack_require__(5); + var ensure = __webpack_require__(6); /** * @param {string} username @@ -5838,10 +5884,10 @@ module.exports = module.exports = UserCredentials; /***/ }, -/* 66 */ +/* 67 */ /***/ function(module, exports, __webpack_require__) { - var SystemConsumerStrategies = __webpack_require__(52); + var SystemConsumerStrategies = __webpack_require__(53); function PersistentSubscriptionSettings( resolveLinkTos, startFrom, extraStatistics, messageTimeout, @@ -5869,7 +5915,7 @@ module.exports = }; /***/ }, -/* 67 */ +/* 68 */ /***/ function(module, exports) { const SystemMetadata = { diff --git a/src/clientOperations/commitTransactionOperation.js b/src/clientOperations/commitTransactionOperation.js index 7c5f3dc..1024bb4 100644 --- a/src/clientOperations/commitTransactionOperation.js +++ b/src/clientOperations/commitTransactionOperation.js @@ -6,6 +6,9 @@ var InspectionDecision = require('../systemData/inspectionDecision'); var InspectionResult = require('./../systemData/inspectionResult'); var ClientMessage = require('../messages/clientMessage'); var results = require('../results'); +var WrongExpectedVersionError = require('../errors/wrongExpectedVersionError'); +var StreamDeletedError = require('../errors/streamDeletedError'); +var AccessDeniedError = require('../errors/accessDeniedError'); var OperationBase = require('../clientOperations/operationBase'); @@ -36,17 +39,16 @@ CommitTransactionOperation.prototype._inspectResponse = function(response) { case ClientMessage.OperationResult.ForwardTimeout: return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); case ClientMessage.OperationResult.WrongExpectedVersion: - var err = util.format("Commit transaction failed due to WrongExpectedVersion. TransactionID: %d.", this._transactionId); - this.fail(new Error(err)); + this.fail(new WrongExpectedVersionError("Commit", this._transactionId)); return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion"); case ClientMessage.OperationResult.StreamDeleted: - this.fail(new Error("Stream deleted.")); + this.fail(new StreamDeletedError(this._transactionId)); return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted"); case ClientMessage.OperationResult.InvalidTransaction: this.fail(new Error("Invalid transaction.")); return new InspectionResult(InspectionDecision.EndOperation, "InvalidTransaction"); case ClientMessage.OperationResult.AccessDenied: - this.fail(new Error("Write access denied.")); + this.fail(new AccessDeniedError("Write", this._transactionId)); return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); default: throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); diff --git a/src/clientOperations/startTransactionOperation.js b/src/clientOperations/startTransactionOperation.js index 57b4173..4119e84 100644 --- a/src/clientOperations/startTransactionOperation.js +++ b/src/clientOperations/startTransactionOperation.js @@ -7,7 +7,9 @@ var InspectionResult = require('./../systemData/inspectionResult'); var ClientMessage = require('../messages/clientMessage'); var EventStoreTransaction = require('../eventStoreTransaction'); var results = require('../results'); - +var AccessDeniedError = require('../errors/accessDeniedError'); +var WrongExpectedVersionError = require('../errors/wrongExpectedVersionError'); +var StreamDeletedError = require('../errors/streamDeletedError'); var OperationBase = require('../clientOperations/operationBase'); function StartTransactionOperation(log, cb, requireMaster, stream, expectedVersion, parentConnection, userCredentials) { @@ -38,17 +40,16 @@ StartTransactionOperation.prototype._inspectResponse = function(response) { case ClientMessage.OperationResult.ForwardTimeout: return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); case ClientMessage.OperationResult.WrongExpectedVersion: - var err = util.format("Start transaction failed due to WrongExpectedVersion. Stream: %s, Expected version: %d.", this._stream, this._expectedVersion); - this.fail(new Error(err)); + this.fail(new WrongExpectedVersionError("Start transaction", this._stream, this._expectedVersion)); return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion"); case ClientMessage.OperationResult.StreamDeleted: - this.fail(new Error("Stream deleted: " + this._stream)); + this.fail(new StreamDeletedError(this._stream)); return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted"); case ClientMessage.OperationResult.InvalidTransaction: this.fail(new Error("Invalid transaction.")); return new InspectionResult(InspectionDecision.EndOperation, "InvalidTransaction"); case ClientMessage.OperationResult.AccessDenied: - this.fail(new Error(util.format("Write access denied for stream '%s'.", this._stream))); + this.fail(new AccessDeniedError("Write", this._stream)); return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); default: throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); diff --git a/src/clientOperations/transactionalWriteOperation.js b/src/clientOperations/transactionalWriteOperation.js index 9848220..dcb4761 100644 --- a/src/clientOperations/transactionalWriteOperation.js +++ b/src/clientOperations/transactionalWriteOperation.js @@ -5,6 +5,7 @@ var TcpCommand = require('../systemData/tcpCommand'); var InspectionDecision = require('../systemData/inspectionDecision'); var InspectionResult = require('./../systemData/inspectionResult'); var ClientMessage = require('../messages/clientMessage'); +var AccessDeniedError = require('../errors/accessDeniedError'); var OperationBase = require('../clientOperations/operationBase'); @@ -43,7 +44,7 @@ TransactionalWriteOperation.prototype._inspectResponse = function(response) { case ClientMessage.OperationResult.ForwardTimeout: return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); case ClientMessage.OperationResult.AccessDenied: - this.fail(new Error("Write access denied.")); + this.fail(new AccessDeniedError("Write", "trx:" + this._transactionId)); return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); default: throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); diff --git a/src/common/utils/ensure.js b/src/common/utils/ensure.js index a68027e..deab3d7 100644 --- a/src/common/utils/ensure.js +++ b/src/common/utils/ensure.js @@ -19,12 +19,12 @@ module.exports.isArrayOf = function(expectedType, value, name) { if (!Array.isArray(value)) throw new TypeError(name + " should be an array."); if (!value.every(function(x) { return x instanceof expectedType; })) - throw new TypeError([name, " should be an array of ", expectedType, "."].join("")); + throw new TypeError([name, " should be an array of ", expectedType.name, "."].join("")); }; module.exports.isTypeOf = function(expectedType, value, name) { if (!(value instanceof expectedType)) - throw new TypeError([name, " should be of type '", expectedType, "'."].join("")); + throw new TypeError([name, " should be of type '", expectedType.name, "'."].join("")); }; module.exports.positive = function(value, name) { diff --git a/src/errors/accessDeniedError.js b/src/errors/accessDeniedError.js index d8d2beb..f66eaa8 100644 --- a/src/errors/accessDeniedError.js +++ b/src/errors/accessDeniedError.js @@ -1,11 +1,21 @@ var util = require('util'); +var Long = require('long'); -function AccessDeniedError(action, stream) { +function AccessDeniedError(action, streamOrTransactionId) { Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; - this.message = util.format("%s access denied for stream '%s'.", action, stream); this.action = action; - this.stream = stream; + if (typeof streamOrTransactionId === 'string') { + this.message = util.format("%s access denied for stream '%s'.", action, streamOrTransactionId); + this.stream = streamOrTransactionId; + return; + } + if (Long.isLong(streamOrTransactionId)) { + this.message = util.format("%s access denied for transaction %s.", action, streamOrTransactionId); + this.transactionId = streamOrTransactionId; + return; + } + throw new TypeError("second argument must be a stream name or transaction Id."); } util.inherits(AccessDeniedError, Error); diff --git a/src/errors/streamDeletedError.js b/src/errors/streamDeletedError.js index f7c1fcd..fc476cc 100644 --- a/src/errors/streamDeletedError.js +++ b/src/errors/streamDeletedError.js @@ -1,10 +1,20 @@ var util = require('util'); +var Long = require('long'); -function StreamDeletedError(stream) { +function StreamDeletedError(streamOrTransactionId) { Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; - this.message = util.format("Event stream '%s' is deleted.", stream); - this.stream = stream; + if (typeof streamOrTransactionId === 'string') { + this.message = util.format("Event stream '%s' is deleted.", streamOrTransactionId); + this.stream = streamOrTransactionId; + return; + } + if (Long.isLong(streamOrTransactionId)) { + this.message = util.format("Stream is deleted for transaction %s.", streamOrTransactionId); + this.transactionId = streamOrTransactionId; + return; + } + throw new TypeError("second argument must be a stream name or transaction Id."); } util.inherits(StreamDeletedError, Error); diff --git a/src/errors/wrongExpectedVersionError.js b/src/errors/wrongExpectedVersionError.js index a8ce711..96e0bd4 100644 --- a/src/errors/wrongExpectedVersionError.js +++ b/src/errors/wrongExpectedVersionError.js @@ -1,12 +1,22 @@ var util = require('util'); +var Long = require('long'); -function WrongExpectedVersionError(action, stream, expectedVersion) { +function WrongExpectedVersionError(action, streamOrTransactionId, expectedVersion) { Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; - this.message = util.format("%s failed due to WrongExpectedVersion. Stream: %s Expected version: %d.", action, stream, expectedVersion); this.action = action; - this.stream = stream; - this.expectedVersion = expectedVersion; + if (typeof streamOrTransactionId === 'string') { + this.message = util.format("%s failed due to WrongExpectedVersion. Stream: %s Expected version: %d.", action, streamOrTransactionId, expectedVersion); + this.stream = streamOrTransactionId; + this.expectedVersion = expectedVersion; + return; + } + if (Long.isLong(streamOrTransactionId)) { + this.message = util.format("%s transaction failed due to WrongExpectedVersion. Transaction Id: %s.", action, streamOrTransactionId); + this.transactionId = streamOrTransactionId; + return; + } + throw new TypeError("second argument must be a stream name or a transaction Id."); } util.inherits(WrongExpectedVersionError, Error); diff --git a/src/eventStoreNodeConnection.js b/src/eventStoreNodeConnection.js index 1f11d48..8405f74 100644 --- a/src/eventStoreNodeConnection.js +++ b/src/eventStoreNodeConnection.js @@ -152,7 +152,10 @@ EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVer * @returns {Promise.} */ EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedVersion, userCredentials) { - //TODO validations + ensure.notNullOrEmpty(stream, "stream"); + ensure.isInteger(expectedVersion, "expectedVersion"); + userCredentials = userCredentials || null; + var self = this; return new Promise(function(resolve, reject) { function cb(err, result) { @@ -160,7 +163,7 @@ EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedV resolve(result); } var operation = new StartTransactionOperation(self._settings.log, cb, self._settings.requireMaster, stream, - expectedVersion, self, userCredentials || null); + expectedVersion, self, userCredentials); self._enqueueOperation(operation); }); }; @@ -172,11 +175,16 @@ EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedV * @returns {EventStoreTransaction} */ EventStoreNodeConnection.prototype.continueTransaction = function(transactionId, userCredentials) { - //TODO validations + ensure.nonNegative(transactionId, "transactionId"); + return new EventStoreTransaction(transactionId, userCredentials, this); }; EventStoreNodeConnection.prototype.transactionalWrite = function(transaction, events, userCredentials) { + ensure.isTypeOf(EventStoreTransaction, transaction, "transaction"); + ensure.isArrayOf(EventData, events, "events"); + userCredentials = userCredentials || null; + var self = this; return new Promise(function(resolve, reject) { function cb(err) { @@ -190,6 +198,8 @@ EventStoreNodeConnection.prototype.transactionalWrite = function(transaction, ev }; EventStoreNodeConnection.prototype.commitTransaction = function(transaction, userCredentials) { + ensure.isTypeOf(EventStoreTransaction, transaction, "transaction"); + var self = this; return new Promise(function(resolve, reject) { function cb(err, result) { diff --git a/src/eventStoreTransaction.js b/src/eventStoreTransaction.js index 388b494..f2857c3 100644 --- a/src/eventStoreTransaction.js +++ b/src/eventStoreTransaction.js @@ -33,13 +33,13 @@ EventStoreTransaction.prototype.commit = function() { /** * Write events (async) - * @param {Array.} events + * @param {EventData|EventData[]} eventOrEvents * @returns {Promise} */ -EventStoreTransaction.prototype.write = function(events) { +EventStoreTransaction.prototype.write = function(eventOrEvents) { if (this._isRolledBack) throw new Error("can't write to a rolledback transaction"); if (this._isCommitted) throw new Error("Transaction is already committed"); - if (!Array.isArray(events)) throw new Error("events must be an array."); + var events = Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents]; return this._connection.transactionalWrite(this, events); }; diff --git a/test/client_test.js b/test/client_test.js index 4507c9e..76007ec 100644 --- a/test/client_test.js +++ b/test/client_test.js @@ -67,7 +67,7 @@ module.exports = { .catch(function (err) { test.done(err); }); - },*/ + }, 'Test Commit Two Events Using Transaction': function(test) { this.conn.startTransaction(testStreamName, client.expectedVersion.any) .then(function(trx) { @@ -90,7 +90,6 @@ module.exports = { test.done(err); }); }, - /* 'Test Read One Event': function(test) { this.conn.readEvent(testStreamName, 0) .then(function(result) { @@ -231,14 +230,15 @@ module.exports = { function liveProcessingStarted() { liveProcessing = true; var events = [createRandomEvent()]; - self.conn.appendToStream('test', client.expectedVersion.any, events); + self.conn.appendToStream(testStreamName, client.expectedVersion.any, events); } function subscriptionDropped(connection, reason, error) { test.ok(liveEvents.length === 1, "Expecting 1 live event, got " + liveEvents.length); - test.ok(catchUpEvents.length > 1, "Expecting at least 1 catchUp event, got " + catchUpEvents.length); + test.ok(catchUpEvents.length >= 1, "Expecting at least 1 catchUp event, got " + catchUpEvents.length); test.done(error); } - var subscription = this.conn.subscribeToStreamFrom('test', null, false, eventAppeared, liveProcessingStarted, subscriptionDropped); + //this.conn.appendToStream() + var subscription = this.conn.subscribeToStreamFrom(testStreamName, null, false, eventAppeared, liveProcessingStarted, subscriptionDropped); }, 'Test Subscribe to All From': function(test) { var self = this; diff --git a/test/transactions_test.js b/test/transactions_test.js new file mode 100644 index 0000000..0c6b84f --- /dev/null +++ b/test/transactions_test.js @@ -0,0 +1,185 @@ +var uuid = require('uuid'); +var Long = require('long'); +var client = require('../src/client'); + +module.exports = { + setUp: function(cb) { + cb(); + }, + 'Start A Transaction Happy Path': function(test) { + this.conn.startTransaction(this.testStreamName, client.expectedVersion.noStream) + .then(function(trx) { + test.ok(Long.isLong(trx.transactionId), "trx.transactionId should be a Long."); + test.done(); + }) + .catch(test.done); + }, + /* + 'Start A Transaction With Wrong Expected Version': function(test) { + this.conn.startTransaction(this.testStreamName, 10) + .then(function(trx) { + test.fail("Start Transaction with wrong expected version succeeded."); + test.done(); + }) + .catch(function(err) { + var isWrongExpectedVersion = err instanceof client.WrongExpectedVersionError; + if (isWrongExpectedVersion) return test.done(); + test.done(err); + }); + }, + 'Start A Transaction With Deleted Stream': function(test) { + var self = this; + this.conn.deleteStream(this.testStreamName, client.expectedVersion.emptyStream) + .then(function() { + return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any); + }) + .then(function(trx) { + test.fail("Start Transaction with deleted stream succeeded."); + test.done(); + }) + .catch(function(err) { + var isStreamDeleted = err instanceof client.StreamDeletedError; + test.ok(isStreamDeleted, "Expected StreamDeletedError got " + err.constructor.name); + if (isStreamDeleted) return test.done(); + test.done(err); + }); + }, + */ + 'Start A Transaction With No Access': function(test) { + var self = this; + var metadata = {$acl: {$w: "$admins"}}; + this.conn.setStreamMetadataRaw(this.testStreamName, -1, metadata) + .then(function() { + return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any); + }) + .then(function(trx) { + test.fail("Start Transaction with no access succeeded."); + test.done(); + }) + .catch(function(err) { + var isAccessDenied = err instanceof client.AccessDeniedError; + test.ok(isAccessDenied, "Expected AccessDeniedError got " + err.constructor.name); + if (isAccessDenied) return test.done(); + test.done(err); + }); + }, + 'Continue A Transaction Happy Path': function(test) { + var self = this; + this.conn.startTransaction(this.testStreamName, client.expectedVersion.emptyStream) + .then(function(trx) { + return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random()}, null, 'anEvent')) + .then(function () { + return self.conn.continueTransaction(trx.transactionId); + }); + }) + .then(function(trx) { + return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random()}, null, 'anEvent')) + .then(function() { + return trx.commit(); + }) + .then(function() { + test.done(); + }); + }) + .catch(test.done); + }, + 'Write/Commit Transaction Happy Path': function(test) { + var self = this; + this.conn.startTransaction(this.testStreamName, client.expectedVersion.emptyStream) + .then(function(trx) { + self.events = []; + for(var i = 0; i < 15; i++) { + var event = {a: uuid.v4(), b: Math.random()}; + self.events.push(client.createJsonEventData(uuid.v4(), event, null, 'anEvent')); + } + return trx.write(self.events) + .then(function() { + var events = []; + for(var j = 0; j < 9; j++) { + var event = {a: Math.random(), b: uuid.v4()}; + events.push(client.createJsonEventData(uuid.v4(), event, null, 'anotherEvent')); + } + Array.prototype.push.apply(self.events, events); + trx.write(events); + }) + .then(function() { + return trx.commit(); + }); + }) + .then(function(result) { + test.ok(result.logPosition, "Missing result.logPosition"); + test.areEqual("result.nextExpectedVersion", result.nextExpectedVersion, self.events.length-1); + test.done(); + }) + .catch(test.done); + }, + 'Write/Commit Transaction With Wrong Expected Version': function(test) { + this.conn.startTransaction(this.testStreamName, 10) + .then(function(trx) { + return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent')) + .then(function() { + return trx.commit(); + }); + }) + .then(function() { + test.fail("Commit on transaction with wrong expected version succeeded."); + test.done(); + }) + .catch(function(err) { + var isWrongExpectedVersion = err instanceof client.WrongExpectedVersionError; + test.ok(isWrongExpectedVersion, "Expected WrongExpectedVersionError, but got " + err.constructor.name); + if (isWrongExpectedVersion) return test.done(); + test.done(err); + }); + }, + 'Write/Commit Transaction With Deleted Stream': function(test) { + var self = this; + this.conn.deleteStream(this.testStreamName, client.expectedVersion.emptyStream, true) + .then(function() { + return self.conn.startTransaction(self.testStreamName, client.expectedVersion.any); + }) + .then(function(trx) { + return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent')) + .then(function() { + return trx.commit(); + }); + }) + .then(function() { + test.fail("Commit on transaction on deleted stream succeeded."); + test.done(); + }) + .catch(function(err) { + var isStreamDeleted = err instanceof client.StreamDeletedError; + test.ok(isStreamDeleted, "Expected StreamDeletedError, but got " + err.constructor.name); + if (isStreamDeleted) return test.done(); + test.done(err); + }); + }, + 'Write/Commit Transaction With No Write Access': function(test) { + var self = this; + this.conn.startTransaction(this.testStreamName, client.expectedVersion.any) + .then(function(trx) { + var metadata = {$acl: {$w: "$admins"}}; + return self.conn.setStreamMetadataRaw(self.testStreamName, -1, metadata) + .then(function () { + return trx.write(client.createJsonEventData(uuid.v4(), {a: Math.random(), b: uuid.v4()}, null, 'anEvent')) + .then(function () { + return trx.commit(); + }); + }) + }) + .then(function() { + test.fail("Commit on transaction on deleted stream succeeded."); + test.done(); + }) + .catch(function(err) { + var isAccessDenied = err instanceof client.AccessDeniedError; + test.ok(isAccessDenied, "Expected AccessDeniedError, but got " + err.constructor.name); + if (isAccessDenied) return test.done(); + test.done(err); + }); + } +}; + +require('./common/base_test').init(module.exports); +