diff --git a/.gitignore b/.gitignore index d29af16..f55f145 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,6 @@ node_modules .node_repl_history # InteliJ -.idea \ No newline at end of file +.idea + +lib/ \ No newline at end of file diff --git a/index.js b/index.js index 0c3f304..3997974 100644 --- a/index.js +++ b/index.js @@ -3,9 +3,4 @@ * see README.md for more details * see LICENSE for license info */ -/** - * TODO: - * library is heavy on number of files so it could have negative impact on load time - * we need a compiled (single file) version of the library - */ module.exports = require('./lib/dist.js'); diff --git a/lib/dist.js b/lib/dist.js deleted file mode 100644 index 4862b59..0000000 --- a/lib/dist.js +++ /dev/null @@ -1,5939 +0,0 @@ -module.exports = -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; - -/******/ // The require function -/******/ function __webpack_require__(moduleId) { - -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; - -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ exports: {}, -/******/ id: moduleId, -/******/ loaded: false -/******/ }; - -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - -/******/ // Flag the module as loaded -/******/ module.loaded = true; - -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } - - -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; - -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; - -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; - -/******/ // Load entry module and return exports -/******/ return __webpack_require__(0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports, __webpack_require__) { - - var EventData = __webpack_require__(1); - var results = __webpack_require__(3); - - const expectedVersion = { - any: -2, - noStream: -1, - emptyStream: -1 - }; - const positions = { - start: new results.Position(0, 0), - end: new results.Position(-1, -1) - }; - - /** - * @param {string} eventId - * @param {object} event - * @param {object} [metadata] - * @param {string} [type] - * @returns {EventData} - */ - function jsonEventDataFactory(eventId, event, metadata, type) { - if (!event || typeof event !== 'object') throw new TypeError("data must be an object."); - - var eventBuf = new Buffer(JSON.stringify(event)); - var metaBuf = metadata ? new Buffer(JSON.stringify(metadata)) : null; - return new EventData(eventId, type || event.constructor.name, true, eventBuf, metaBuf); - } - - /** - * @param {string} eventId - * @param {string} type - * @param {boolean} isJson - * @param {Buffer} data - * @param {Buffer} [metadata] - * @returns {EventData} - */ - function eventDataFactory(eventId, type, isJson, data, metadata) { - return new EventData(eventId, type, isJson, data, metadata); - } - - // Exporting classes - module.exports.EventStoreConnection = __webpack_require__(7); - module.exports.UserCredentials = __webpack_require__(66); - module.exports.EventData = EventData; - module.exports.PersistentSubscriptionSettings = __webpack_require__(67); - module.exports.SystemConsumerStrategies = __webpack_require__(53); - // Exporting errors - 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__(68); - module.exports.eventReadStatus = results.EventReadStatus; - module.exports.sliceReadStatus = __webpack_require__(48); - // Helper functions - module.exports.createConnection = module.exports.EventStoreConnection.create; - module.exports.createEventData = eventDataFactory; - module.exports.createJsonEventData = jsonEventDataFactory; - -/***/ }, -/* 1 */ -/***/ function(module, exports, __webpack_require__) { - - var uuid = __webpack_require__(2); - - function isValidId(id) { - if (typeof id !== 'string') return false; - var buf = uuid.parse(id); - var valid = false; - for(var i=0;i} - */ - EventStoreNodeConnection.prototype.deleteStream = function(stream, expectedVersion, hardDelete, userCredentials) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.isInteger(expectedVersion, "expectedVersion"); - hardDelete = !!hardDelete; - userCredentials = userCredentials || null; - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - - var deleteStreamOperation = new DeleteStreamOperation( - self._settings.log, cb, self._settings.requireMaster, stream, expectedVersion, hardDelete, userCredentials); - self._enqueueOperation(deleteStreamOperation); - }); - }; - - /** - * Append events to a stream (async) - * @param {string} stream The name of the stream to which to append. - * @param {number} expectedVersion The version at which we currently expect the stream to be in order that an optimistic concurrency check can be performed. - * @param {EventData[]|EventData} events The event(s) to append. - * @param {UserCredentials} [userCredentials] User credentials - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.appendToStream = function(stream, expectedVersion, events, userCredentials) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.isInteger(expectedVersion, "expectedVersion"); - if (!Array.isArray(events)) - events = [events]; - ensure.isArrayOf(EventData, events, "events"); - userCredentials = userCredentials || null; - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var operation = new AppendToStreamOperation(self._settings.log, cb, self._settings.requireMaster, stream, - expectedVersion, events, userCredentials); - self._enqueueOperation(operation); - }); - }; - - /** - * Start a transaction (async) - * @param {string} stream - * @param {number} expectedVersion - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.startTransaction = function(stream, expectedVersion, userCredentials) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.isInteger(expectedVersion, "expectedVersion"); - userCredentials = userCredentials || null; - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var operation = new StartTransactionOperation(self._settings.log, cb, self._settings.requireMaster, stream, - expectedVersion, self, userCredentials); - self._enqueueOperation(operation); - }); - }; - - /** - * Continue a transaction - * @param {number} transactionId - * @param {UserCredentials} userCredentials - * @returns {EventStoreTransaction} - */ - EventStoreNodeConnection.prototype.continueTransaction = function(transactionId, userCredentials) { - 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) { - if (err) return reject(err); - resolve(); - } - var operation = new TransactionalWriteOperation(self._settings.log, cb, self._settings.requireMaster, - transaction.transactionId, events, userCredentials); - self._enqueueOperation(operation); - }); - }; - - EventStoreNodeConnection.prototype.commitTransaction = function(transaction, userCredentials) { - ensure.isTypeOf(EventStoreTransaction, transaction, "transaction"); - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var operation = new CommitTransactionOperation(self._settings.log, cb, self._settings.requireMaster, - transaction.transactionId, userCredentials); - self._enqueueOperation(operation); - }); - }; - - /** - * Read a single event (async) - * @param {string} stream - * @param {number} eventNumber - * @param {boolean} [resolveLinkTos] - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.readEvent = function(stream, eventNumber, resolveLinkTos, userCredentials) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.isInteger(eventNumber, "eventNumber"); - if (eventNumber < -1) throw new Error("eventNumber out of range."); - resolveLinkTos = !!resolveLinkTos; - userCredentials = userCredentials || null; - - if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be an non-empty string."); - if (typeof eventNumber !== 'number' || eventNumber % 1 !== 0) throw new TypeError("eventNumber must be an integer."); - if (eventNumber < -1) throw new Error("eventNumber out of range."); - if (resolveLinkTos && typeof resolveLinkTos !== 'boolean') throw new TypeError("resolveLinkTos must be a boolean."); - - var self = this; - return new Promise(function(resolve, reject){ - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var operation = new ReadEventOperation(self._settings.log, cb, stream, eventNumber, resolveLinkTos, - self._settings.requireMaster, userCredentials); - self._enqueueOperation(operation); - }); - }; - - /** - * Reading a specific stream forwards (async) - * @param {string} stream - * @param {number} start - * @param {number} count - * @param {boolean} [resolveLinkTos] - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.readStreamEventsForward = function( - stream, start, count, resolveLinkTos, userCredentials - ) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.isInteger(start, "start"); - ensure.nonNegative(start, "start"); - ensure.isInteger(count, "count"); - ensure.positive(count, "count"); - if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize)); - resolveLinkTos = !!resolveLinkTos; - userCredentials = userCredentials || null; - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var operation = new ReadStreamEventsForwardOperation(self._settings.log, cb, stream, start, count, - resolveLinkTos, self._settings.requireMaster, userCredentials); - self._enqueueOperation(operation); - }); - }; - - /** - * Reading a specific stream backwards (async) - * @param {string} stream - * @param {number} start - * @param {number} count - * @param {boolean} [resolveLinkTos] - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.readStreamEventsBackward = function( - stream, start, count, resolveLinkTos, userCredentials - ) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.isInteger(start, "start"); - ensure.isInteger(count, "count"); - ensure.positive(count, "count"); - if (count > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize)); - resolveLinkTos = !!resolveLinkTos; - userCredentials = userCredentials || null; - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var operation = new ReadStreamEventsBackwardOperation(self._settings.log, cb, stream, start, count, - resolveLinkTos, self._settings.requireMaster, userCredentials); - self._enqueueOperation(operation); - }); - }; - - /** - * Reading all events forwards (async) - * @param {Position} position - * @param {number} maxCount - * @param {boolean} [resolveLinkTos] - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.readAllEventsForward = function( - position, maxCount, resolveLinkTos, userCredentials - ) { - ensure.isTypeOf(results.Position, position, "position"); - ensure.isInteger(maxCount, "maxCount"); - ensure.positive(maxCount, "maxCount"); - if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize)); - resolveLinkTos = !!resolveLinkTos; - userCredentials = userCredentials || null; - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var operation = new ReadAllEventsForwardOperation(self._settings.log, cb, position, maxCount, - resolveLinkTos, self._settings.requireMaster, userCredentials); - self._enqueueOperation(operation); - }); - }; - - /** - * Reading all events backwards (async) - * @param {Position} position - * @param {number} maxCount - * @param {boolean} [resolveLinkTos] - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.readAllEventsBackward = function( - position, maxCount, resolveLinkTos, userCredentials - ) { - ensure.isTypeOf(results.Position, position, "position"); - ensure.isInteger(maxCount, "maxCount"); - ensure.positive(maxCount, "maxCount"); - if (maxCount > MaxReadSize) throw new Error(util.format("Count should be less than %d. For larger reads you should page.", MaxReadSize)); - resolveLinkTos = !!resolveLinkTos; - userCredentials = userCredentials || null; - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var operation = new ReadAllEventsBackwardOperation(self._settings.log, cb, position, maxCount, - resolveLinkTos || false, self._settings.requireMaster, userCredentials || null); - self._enqueueOperation(operation); - }); - }; - - /** - * Subscribe to a stream (async) - * @param {!string} stream - * @param {!boolean} resolveLinkTos - * @param {function} eventAppeared - * @param {function} [subscriptionDropped] - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.subscribeToStream = function( - stream, resolveLinkTos, eventAppeared, subscriptionDropped, userCredentials - ) { - if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be a non-empty string."); - if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function."); - - var self = this; - return new Promise(function(resolve,reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - self._handler.enqueueMessage( - new messages.StartSubscriptionMessage( - cb, stream, !!resolveLinkTos, userCredentials || null, eventAppeared, subscriptionDropped || null, - self._settings.maxRetries, self._settings.operationTimeout)); - }); - }; - - /** - * @param {!string} stream - * @param {?number} lastCheckpoint - * @param {!boolean} resolveLinkTos - * @param {!function} eventAppeared - * @param {function} [liveProcessingStarted] - * @param {function} [subscriptionDropped] - * @param {UserCredentials} [userCredentials] - * @param {!number} [readBatchSize] - * @returns {EventStoreStreamCatchUpSubscription} - */ - EventStoreNodeConnection.prototype.subscribeToStreamFrom = function( - stream, lastCheckpoint, resolveLinkTos, eventAppeared, liveProcessingStarted, subscriptionDropped, - userCredentials, readBatchSize - ) { - if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be a non-empty string."); - if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function."); - - var catchUpSubscription = - new EventStoreStreamCatchUpSubscription(this, this._settings.log, stream, lastCheckpoint, - resolveLinkTos, userCredentials || null, eventAppeared, - liveProcessingStarted || null, subscriptionDropped || null, this._settings.verboseLogging, - readBatchSize); - catchUpSubscription.start(); - return catchUpSubscription; - }; - - /** - * Subscribe to all (async) - * @param {!boolean} resolveLinkTos - * @param {!function} eventAppeared - * @param {function} [subscriptionDropped] - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.subscribeToAll = function( - resolveLinkTos, eventAppeared, subscriptionDropped, userCredentials - ) { - if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function."); - - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - self._handler.enqueueMessage( - new messages.StartSubscriptionMessage( - cb, '', resolveLinkTos, userCredentials || null, eventAppeared, subscriptionDropped || null, - self._settings.maxRetries, self._settings.operationTimeout)); - }); - }; - - /** - * Subscribe to all from - * @param {?Position} lastCheckpoint - * @param {!boolean} resolveLinkTos - * @param {!function} eventAppeared - * @param {function} [liveProcessingStarted] - * @param {function} [subscriptionDropped] - * @param {UserCredentials} [userCredentials] - * @param {!number} [readBatchSize] - * @returns {EventStoreAllCatchUpSubscription} - */ - EventStoreNodeConnection.prototype.subscribeToAllFrom = function( - lastCheckpoint, resolveLinkTos, eventAppeared, liveProcessingStarted, subscriptionDropped, - userCredentials, readBatchSize - ) { - if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function."); - - var catchUpSubscription = - new EventStoreAllCatchUpSubscription(this, this._settings.log, lastCheckpoint, resolveLinkTos, - userCredentials || null, eventAppeared, liveProcessingStarted || null, - subscriptionDropped || null, this._settings.verboseLogging, readBatchSize || 500); - catchUpSubscription.start(); - return catchUpSubscription; - }; - - /** - * Subscribe to a persistent subscription - * @param {string} stream - * @param {string} groupName - * @param {function} eventAppeared - * @param {function} [subscriptionDropped] - * @param {UserCredentials} [userCredentials] - * @param {number} [bufferSize] - * @param {boolean} [autoAck] - */ - EventStoreNodeConnection.prototype.connectToPersistentSubscription = function( - stream, groupName, eventAppeared, subscriptionDropped, userCredentials, bufferSize, autoAck - ) { - ensure.notNullOrEmpty(groupName, "groupName"); - ensure.notNullOrEmpty(stream, "stream"); - ensure.notNull(eventAppeared, "eventAppeared"); - - subscriptionDropped = subscriptionDropped || null; - userCredentials = userCredentials || null; - bufferSize = bufferSize === undefined ? 10 : bufferSize; - autoAck = autoAck === undefined ? true : !!autoAck; - - var subscription = new EventStorePersistentSubscription( - groupName, stream, eventAppeared, subscriptionDropped, userCredentials, this._settings.log, - this._settings.verboseLogging, this._settings, this._handler, bufferSize, autoAck); - subscription.start(); - - return subscription; - }; - - /** - * @param {string} stream - * @param {string} groupName - * @param {PersistentSubscriptionSettings} settings - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.createPersistentSubscription = function(stream, groupName, settings, userCredentials) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.notNullOrEmpty(groupName, "groupName"); - ensure.notNull(settings, "settings"); - - var self = this; - return new Promise(function(resolve, reject){ - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - self._enqueueOperation( - new CreatePersistentSubscriptionOperation(self._settings.log, cb, stream, groupName, settings, userCredentials || null)); - }); - }; - - /** - * @param {string} stream - * @param {string} groupName - * @param {string} settings - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.updatePersistentSubscription = function(stream, groupName, settings, userCredentials) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.notNullOrEmpty(groupName, "groupName"); - ensure.notNull(settings, "settings"); - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - self._enqueueOperation( - new UpdatePersistentSubscriptionOperation(self._settings.log, cb, stream, groupName, settings, userCredentials || null)); - }); - }; - - /** - * @param {string} stream - * @param {string} groupName - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.deletePersistentSubscription = function(stream, groupName, userCredentials) { - ensure.notNullOrEmpty(stream, "stream"); - ensure.notNullOrEmpty(groupName, "groupName"); - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - self._enqueueOperation( - new DeletePersistentSubscriptionOperation(self._settings.log, cb, stream, groupName, userCredentials || null)); - }); - }; - - EventStoreNodeConnection.prototype.setStreamMetadata = function() { - //TODO: set stream metadata (non-raw) - throw new Error("Not implemented."); - }; - - /** - * Set stream metadata with raw object (async) - * @param {string} stream - * @param {number} expectedMetastreamVersion - * @param {object} metadata - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.setStreamMetadataRaw = function( - stream, expectedMetastreamVersion, metadata, userCredentials - ) { - ensure.notNullOrEmpty(stream, "stream"); - if (systemStreams.isMetastream(stream)) - throw new Error(util.format("Setting metadata for metastream '%s' is not supported.", stream)); - var self = this; - return new Promise(function(resolve, reject) { - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - var data = metadata ? new Buffer(JSON.stringify(metadata)) : null; - var metaevent = new EventData(uuid.v4(), systemEventTypes.StreamMetadata, true, data, null); - self._enqueueOperation( - new AppendToStreamOperation(self._settings.log, cb, self._settings.requireMaster, - systemStreams.metastreamOf(stream), expectedMetastreamVersion, - [metaevent], userCredentials)); - }); - }; - - EventStoreNodeConnection.prototype.getStreamMetadata = function(stream, userCredentials) { - //TODO: get stream metadata (non-raw) - throw new Error("Not implemented."); - }; - - /** - * Get stream metadata as raw object (async) - * @param {string} stream - * @param {UserCredentials} [userCredentials] - * @returns {Promise.} - */ - EventStoreNodeConnection.prototype.getStreamMetadataRaw = function(stream, userCredentials) { - return this.readEvent(systemStreams.metastreamOf(stream), -1, false, userCredentials) - .then(function(res) { - switch(res.status) { - case results.EventReadStatus.Success: - if (res.event === null) throw new Error("Event is null while operation result is Success."); - var evnt = res.event.originalEvent; - var version = evnt ? evnt.eventNumber : -1; - var data = evnt ? JSON.parse(evnt.data.toString()) : null; - return new results.RawStreamMetadataResult(stream, false, version, data); - case results.EventReadStatus.NotFound: - case results.EventReadStatus.NoStream: - return new results.RawStreamMetadataResult(stream, false, -1, null); - case results.EventReadStatus.StreamDeleted: - return new results.RawStreamMetadataResult(stream, true, 0x7fffffff, null); - default: - throw new Error(util.format("Unexpected ReadEventResult: %s.", res.status)); - } - }); - }; - - EventStoreNodeConnection.prototype.setSystemSettings = function() { - //TODO: set system settings - throw new Error("Not implemented."); - }; - - EventStoreNodeConnection.prototype._enqueueOperation = function(operation) { - var self = this; - var message = new messages.StartOperationMessage(operation, self._settings.maxRetries, self._settings.operationTimeout); - function tryEnqueue() { - if (self._handler.totalOperationCount >= self._settings.maxQueueSize) { - setImmediate(tryEnqueue); - return; - } - self._handler.enqueueMessage(message); - } - setImmediate(tryEnqueue) - }; - - module.exports = EventStoreNodeConnection; - - -/***/ }, -/* 9 */ -/***/ function(module, exports) { - - module.exports = require("events"); - -/***/ }, -/* 10 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var ensure = __webpack_require__(6); - - function Message() { - } - Message.prototype.toString = function() { - return this.constructor.name; - }; - - function StartConnectionMessage(cb, endpointDiscoverer) { - this.cb = cb; - this.endpointDiscoverer = endpointDiscoverer; - } - util.inherits(StartConnectionMessage, Message); - - function CloseConnectionMessage(reason, error) { - this.reason = reason; - this.error = error; - } - util.inherits(CloseConnectionMessage, Message); - - function StartOperationMessage(operation, maxRetries, timeout) { - this.operation = operation; - this.maxRetries = maxRetries; - this.timeout = timeout; - } - util.inherits(StartOperationMessage, Message); - - function StartSubscriptionMessage( - cb, streamId, resolveLinkTos, userCredentials, eventAppeared, subscriptionDropped, maxRetries, timeout - ) { - this.cb = cb; - this.streamId = streamId; - this.resolveLinkTos = resolveLinkTos; - this.userCredentials = userCredentials; - this.eventAppeared = eventAppeared; - this.subscriptionDropped = subscriptionDropped; - this.maxRetries = maxRetries; - this.timeout = timeout; - } - util.inherits(StartSubscriptionMessage, Message); - - /** - * @constructor - * @property {object} endPoints - * @property {object} endPoints.secureTcpEndPoint - * @property {object} endPoints.tcpEndPoint - */ - function EstablishTcpConnectionMessage(endPoints) { - this.endPoints = endPoints; - } - util.inherits(EstablishTcpConnectionMessage, Message); - - function HandleTcpPackageMessage(connection, pkg) { - this.connection = connection; - this.package = pkg; - } - util.inherits(HandleTcpPackageMessage, Message); - - function TcpConnectionErrorMessage(connection, error) { - this.connection = connection; - this.error = error; - } - util.inherits(TcpConnectionErrorMessage, Message); - - function TcpConnectionEstablishedMessage(connection) { - this.connection = connection; - } - util.inherits(TcpConnectionEstablishedMessage, Message); - - function TcpConnectionClosedMessage(connection, error) { - this.connection = connection; - this.error = error; - } - util.inherits(TcpConnectionClosedMessage, Message); - - function TimerTickMessage() {} - util.inherits(TimerTickMessage, Message); - - function StartPersistentSubscriptionMessage( - cb, subscriptionId, streamId, bufferSize, userCredentials, eventAppeared, subscriptionDropped, - maxRetries, operationTimeout - ) { - this.cb = cb; - this.subscriptionId = subscriptionId; - this.streamId = streamId; - this.bufferSize = bufferSize; - this.userCredentials = userCredentials; - this.eventAppeared = eventAppeared; - this.subscriptionDropped = subscriptionDropped; - this.maxRetries = maxRetries; - this.timeout = operationTimeout; - } - util.inherits(StartPersistentSubscriptionMessage, Message); - - module.exports = { - StartConnectionMessage: StartConnectionMessage, - CloseConnectionMessage: CloseConnectionMessage, - StartOperationMessage: StartOperationMessage, - StartSubscriptionMessage: StartSubscriptionMessage, - EstablishTcpConnectionMessage: EstablishTcpConnectionMessage, - HandleTcpPackageMessage: HandleTcpPackageMessage, - TcpConnectionErrorMessage: TcpConnectionErrorMessage, - TcpConnectionEstablishedMessage: TcpConnectionEstablishedMessage, - TcpConnectionClosedMessage: TcpConnectionClosedMessage, - TimerTickMessage: TimerTickMessage, - StartPersistentSubscriptionMessage: StartPersistentSubscriptionMessage - }; - - -/***/ }, -/* 11 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - var EventEmitter = __webpack_require__(9).EventEmitter; - - 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__(18); - var TcpCommand = __webpack_require__(20); - var TcpFlags = __webpack_require__(19); - var InspectionDecision = __webpack_require__(27); - - const ConnectionState = { - Init: 'init', - Connecting: 'connecting', - Connected: 'connected', - Closed: 'closed' - }; - - const ConnectingPhase = { - Invalid: 'invalid', - Reconnecting: 'reconnecting', - EndPointDiscovery: 'endpointDiscovery', - ConnectionEstablishing: 'connectionEstablishing', - Authentication: 'authentication', - Connected: 'connected' - }; - - const TimerPeriod = 200; - const TimerTickMessage = new messages.TimerTickMessage(); - const EmptyGuid = '00000000-0000-0000-0000-000000000000'; - - /** - * @param {EventStoreNodeConnection} esConnection - * @param {Object} settings - * @constructor - * @property {Number} totalOperationCount - */ - function EventStoreConnectionLogicHandler(esConnection, settings) { - this._esConnection = esConnection; - this._settings = settings; - this._queue = new SimpleQueuedHandler(); - this._state = ConnectionState.Init; - this._connectingPhase = ConnectingPhase.Invalid; - this._endpointDiscoverer = null; - this._connection = null; - this._wasConnected = false; - this._packageNumber = 0; - this._authInfo = null; - this._lastTimeoutsTimeStamp = 0; - - this._operations = new OperationsManager(esConnection.connectionName, settings); - this._subscriptions = new SubscriptionsManager(esConnection.connectionName, settings); - - var self = this; - this._queue.registerHandler(messages.StartConnectionMessage, function(msg) { - self._startConnection(msg.cb, msg.endpointDiscoverer); - }); - this._queue.registerHandler(messages.CloseConnectionMessage, function(msg) { - self._closeConnection(msg.reason, msg.error); - }); - - this._queue.registerHandler(messages.StartOperationMessage, function(msg) { - self._startOperation(msg.operation, msg.maxRetries, msg.timeout); - }); - this._queue.registerHandler(messages.StartSubscriptionMessage, function(msg) { - self._startSubscription(msg); - }); - this._queue.registerHandler(messages.StartPersistentSubscriptionMessage, function(msg) { - self._startPersistentSubscription(msg); - }); - - this._queue.registerHandler(messages.EstablishTcpConnectionMessage, function(msg) { - self._establishTcpConnection(msg.endPoints); - }); - this._queue.registerHandler(messages.TcpConnectionEstablishedMessage, function(msg) { - self._tcpConnectionEstablished(msg.connection); - }); - this._queue.registerHandler(messages.TcpConnectionErrorMessage, function(msg) { - self._tcpConnectionError(msg.connection, msg.error); - }); - this._queue.registerHandler(messages.TcpConnectionClosedMessage, function(msg) { - self._tcpConnectionClosed(msg.connection, msg.error); - }); - this._queue.registerHandler(messages.HandleTcpPackageMessage, function(msg) { - self._handleTcpPackage(msg.connection, msg.package); - }); - - this._queue.registerHandler(messages.TimerTickMessage, function(msg) { - self._timerTick(); - }); - - this._timer = setInterval(function() { - self.enqueueMessage(TimerTickMessage); - }, TimerPeriod); - } - util.inherits(EventStoreConnectionLogicHandler, EventEmitter); - - Object.defineProperty(EventStoreConnectionLogicHandler.prototype, 'totalOperationCount', { - get: function() { - return this._operations.totalOperationCount; - } - }); - - EventStoreConnectionLogicHandler.prototype.enqueueMessage = function(msg) { - if (this._settings.verboseLogging && msg !== TimerTickMessage) this._logDebug("enqueuing message %s.", msg); - this._queue.enqueueMessage(msg); - }; - - EventStoreConnectionLogicHandler.prototype._discoverEndpoint = function(cb) { - this._logDebug('DiscoverEndpoint'); - - if (this._state !== ConnectionState.Connecting) return; - if (this._connectingPhase !== ConnectingPhase.Reconnecting) return; - - this._connectingPhase = ConnectingPhase.EndPointDiscovery; - - cb = cb || function() {}; - - var self = this; - this._endpointDiscoverer.discover(this._connection !== null ? this._connection.remoteEndPoint : null) - .then(function(nodeEndpoints){ - self.enqueueMessage(new messages.EstablishTcpConnectionMessage(nodeEndpoints)); - cb(); - }) - .catch(function(err) { - self.enqueueMessage(new messages.CloseConnectionMessage("Failed to resolve TCP end point to which to connect.", err)); - cb(new Error("Couldn't resolve target end point: " + err.message)); - }); - }; - - /** - * @param {Function} cb - * @param {StaticEndpointDiscoverer} endpointDiscoverer - * @private - */ - EventStoreConnectionLogicHandler.prototype._startConnection = function(cb, endpointDiscoverer) { - this._logDebug('StartConnection'); - - switch(this._state) { - case ConnectionState.Init: - this._endpointDiscoverer = endpointDiscoverer; - this._state = ConnectionState.Connecting; - this._connectingPhase = ConnectingPhase.Reconnecting; - this._discoverEndpoint(cb); - break; - case ConnectionState.Connecting: - case ConnectionState.Connected: - return cb(new Error(['EventStoreConnection', this._esConnection.connectionName, 'is already active.'].join(' '))); - case ConnectionState.Closed: - return cb(new Error(['EventStoreConnection', this._esConnection.connectionName, 'is closed.'].join(' '))); - default: - return cb(new Error(['Unknown state:', this._state].join(' '))); - } - }; - - /** - * @param {string} reason - * @param {Error} [error] - * @private - */ - EventStoreConnectionLogicHandler.prototype._closeConnection = function(reason, error) { - if (this._state == ConnectionState.Closed) { - this._logDebug("CloseConnection IGNORED because is ESConnection is CLOSED, reason %s, error %s.", reason, error ? error.stack : ''); - return; - } - - this._logDebug("CloseConnection, reason %s, error %s.", reason, error ? error.stack : ''); - - this._state = ConnectionState.Closed; - - clearInterval(this._timer); - this._operations.cleanUp(); - this._subscriptions.cleanUp(); - this._closeTcpConnection(reason); - - this._logInfo("Closed. Reason: %s", reason); - - if (error) - this.emit('error', error); - - this.emit('closed', reason); - }; - - EventStoreConnectionLogicHandler.prototype._closeTcpConnection = function(reason) { - if (!this._connection) { - this._logDebug("CloseTcpConnection IGNORED because _connection == null"); - return; - } - - this._logDebug("CloseTcpConnection"); - this._connection.close(reason); - this._tcpConnectionClosed(this._connection); - this._connection = null; - }; - - var _nextSeqNo = -1; - function createOperationItem(operation, maxRetries, timeout) { - var operationItem = { - seqNo: _nextSeqNo++, - operation: operation, - maxRetries: maxRetries, - timeout: timeout, - createdTime: Date.now(), - correlationId: uuid.v4(), - retryCount: 0, - lastUpdated: Date.now() - }; - operationItem.toString = (function() { - return util.format("Operation %s (%s): %s, retry count: %d, created: %s, last updated: %s", - this.operation.constructor.name, this.correlationId, this.operation, this.retryCount, - new Date(this.createdTime).toISOString().substr(11,12), - new Date(this.lastUpdated).toISOString().substr(11,12)); - }).bind(operationItem); - return operationItem; - } - - EventStoreConnectionLogicHandler.prototype._startOperation = function(operation, maxRetries, timeout) { - switch(this._state) { - case ConnectionState.Init: - operation.fail(new Error("EventStoreConnection '" + this._esConnection.connectionName + "' is not active.")); - break; - case ConnectionState.Connecting: - this._logDebug("StartOperation enqueue %s, %s, %d, %d.", operation.constructor.name, operation, maxRetries, timeout); - this._operations.enqueueOperation(createOperationItem(operation, maxRetries, timeout)); - break; - case ConnectionState.Connected: - this._logDebug("StartOperation schedule %s, %s, %d, %d.", operation.constructor.name, operation, maxRetries, timeout); - this._operations.scheduleOperation(createOperationItem(operation, maxRetries, timeout), this._connection); - break; - case ConnectionState.Closed: - operation.fail(new Error("EventStoreConnection '" + this._esConnection.connectionName + "' is closed.")); - break; - default: - throw new Error("Unknown state: " + this._state + '.'); - } - }; - - function createSubscriptionItem(operation, maxRetries, timeout) { - var subscriptionItem = { - operation: operation, - maxRetries: maxRetries, - timeout: timeout, - createdTime: Date.now(), - correlationId: uuid.v4(), - retryCount: 0, - lastUpdated: Date.now(), - isSubscribed: false - }; - subscriptionItem.toString = (function(){ - return util.format("Subscription %s (%s): %s, is subscribed: %s, retry count: %d, created: %s, last updated: %s", - this.operation.constructor.name, this.correlationId, this.operation, this.isSubscribed, this.retryCount, - new Date(this.createdTime).toISOString().substr(11,12), - new Date(this.lastUpdated).toISOString().substr(11,12)); - }).bind(subscriptionItem); - return subscriptionItem; - } - - EventStoreConnectionLogicHandler.prototype._startSubscription = function(msg) { - switch (this._state) - { - case ConnectionState.Init: - msg.cb(new Error(util.format("EventStoreConnection '%s' is not active.", this._esConnection.connectionName))); - break; - case ConnectionState.Connecting: - case ConnectionState.Connected: - var self = this; - var operation = new VolatileSubscriptionOperation(this._settings.log, msg.cb, msg.streamId, msg.resolveLinkTos, - msg.userCredentials, msg.eventAppeared, msg.subscriptionDropped, - this._settings.verboseLogging, function() { return self._connection }); - this._logDebug("StartSubscription %s %s, %s, %d, %d.", - this._state === ConnectionState.Connected ? "fire" : "enqueue", - operation.constructor.name, operation, msg.maxRetries, msg.timeout); - var subscription = createSubscriptionItem(operation, msg.maxRetries, msg.timeout); - if (this._state === ConnectionState.Connecting) - this._subscriptions.enqueueSubscription(subscription); - else - this._subscriptions.startSubscription(subscription, this._connection); - break; - case ConnectionState.Closed: - msg.cb(new Error("Connection closed. Connection: " + this._esConnection.connectionName)); - break; - default: - throw new Error(util.format("Unknown state: %s.", this._state)); - } - }; - - EventStoreConnectionLogicHandler.prototype._startPersistentSubscription = function(msg) { - var self = this; - switch (this._state) - { - case ConnectionState.Init: - msg.cb(new Error(util.format("EventStoreConnection '%s' is not active.", this._esConnection.connectionName))); - break; - case ConnectionState.Connecting: - case ConnectionState.Connected: - var operation = new ConnectToPersistentSubscriptionOperation(this._settings.log, msg.cb, msg.subscriptionId, - msg.bufferSize, msg.streamId, msg.userCredentials, msg.eventAppeared, msg.subscriptionDropped, - this._settings.verboseLogging, function() { return self._connection }); - this._logDebug("StartSubscription %s %s, %s, %d, %d.", - this._state === ConnectionState.Connected ? "fire" : "enqueue", - operation.constructor.name, operation, msg.maxRetries, msg.timeout); - var subscription = createSubscriptionItem(operation, msg.maxRetries, msg.timeout); - if (this._state === ConnectionState.Connecting) - this._subscriptions.enqueueSubscription(subscription); - else - this._subscriptions.startSubscription(subscription, this._connection); - break; - case ConnectionState.Closed: - msg.cb(new Error("Connection closed. " + this._esConnection.connectionName)); - break; - default: throw new Error(util.format("Unknown state: %s.", this._state)); - } - }; - - EventStoreConnectionLogicHandler.prototype._establishTcpConnection = function(endPoints) { - var endPoint = this._settings.useSslConnection ? endPoints.secureTcpEndPoint : endPoints.tcpEndPoint; - if (endPoint == null) - { - this._closeConnection("No end point to node specified."); - return; - } - - this._logDebug("EstablishTcpConnection to [%j]", endPoint); - - if (this._state != ConnectionState.Connecting) return; - if (this._connectingPhase != ConnectingPhase.EndPointDiscovery) return; - - var self = this; - this._connectingPhase = ConnectingPhase.ConnectionEstablishing; - this._connection = new TcpPackageConnection( - this._settings.log, - endPoint, - uuid.v4(), - this._settings.useSslConnection, - this._settings.targetHost, - this._settings.validateServer, - this._settings.clientConnectionTimeout, - function(connection, pkg) { - self.enqueueMessage(new messages.HandleTcpPackageMessage(connection, pkg)); - }, - function(connection, error) { - self.enqueueMessage(new messages.TcpConnectionErrorMessage(connection, error)); - }, - function(connection) { - connection.startReceiving(); - self.enqueueMessage(new messages.TcpConnectionEstablishedMessage(connection)); - }, - function(connection, error) { - self.enqueueMessage(new messages.TcpConnectionClosedMessage(connection, error)); - } - ); - }; - - EventStoreConnectionLogicHandler.prototype._tcpConnectionEstablished = function(connection) { - if (this._state != ConnectionState.Connecting || !this._connection.equals(connection) || connection.isClosed) - { - this._logDebug("IGNORED (_state %s, _conn.Id %s, conn.Id %s, conn.closed %s): TCP connection to [%j, L%j] established.", - this._state, this._connection == null ? EmptyGuid : this._connection.connectionId, connection.connectionId, - connection.isClosed, connection.remoteEndPoint, connection.localEndPoint); - return; - } - - this._logDebug("TCP connection to [%j, L%j, %s] established.", connection.remoteEndPoint, connection.localEndPoint, connection.connectionId); - this._heartbeatInfo = { - lastPackageNumber: this._packageNumber, - isIntervalStage: true, - timeStamp: Date.now() - }; - - if (this._settings.defaultUserCredentials != null) - { - this._connectingPhase = ConnectingPhase.Authentication; - - this._authInfo = { - correlationId: uuid.v4(), - timeStamp: Date.now() - }; - this._connection.enqueueSend(new TcpPackage( - TcpCommand.Authenticate, - TcpFlags.Authenticated, - this._authInfo.correlationId, - this._settings.defaultUserCredentials.username, - this._settings.defaultUserCredentials.password)); - } - else - { - this._goToConnectedState(); - } - }; - - EventStoreConnectionLogicHandler.prototype._goToConnectedState = function() { - this._state = ConnectionState.Connected; - this._connectingPhase = ConnectingPhase.Connected; - - this._wasConnected = true; - - this.emit('connected', this._connection.remoteEndPoint); - - if (Date.now() - this._lastTimeoutsTimeStamp >= this._settings.operationTimeoutCheckPeriod) - { - this._operations.checkTimeoutsAndRetry(this._connection); - this._subscriptions.checkTimeoutsAndRetry(this._connection); - this._lastTimeoutsTimeStamp = Date.now(); - } - }; - - EventStoreConnectionLogicHandler.prototype._tcpConnectionError = function(connection, error) { - if (this._connection != connection) return; - if (this._state == ConnectionState.Closed) return; - - this._logDebug("TcpConnectionError connId %s, exc %s.", connection.connectionId, error); - this._closeConnection("TCP connection error occurred.", error); - }; - - EventStoreConnectionLogicHandler.prototype._tcpConnectionClosed = function(connection, error) { - if (this._state == ConnectionState.Init) throw new Error(); - if (this._state == ConnectionState.Closed || !this._connection.equals(connection)) - { - this._logDebug("IGNORED (_state: %s, _conn.ID: %s, conn.ID: %s): TCP connection to [%j, L%j] closed.", - this._state, this._connection == null ? EmptyGuid : this._connection.connectionId, connection.connectionId, - connection.remoteEndPoint, connection.localEndPoint); - return; - } - - this._state = ConnectionState.Connecting; - this._connectingPhase = ConnectingPhase.Reconnecting; - - this._logDebug("TCP connection to [%j, L%j, %s] closed. %s", connection.remoteEndPoint, connection.localEndPoint, connection.connectionId, error); - - this._subscriptions.purgeSubscribedAndDroppedSubscriptions(this._connection.connectionId); - this._reconnInfo = { - reconnectionAttempt: this._reconnInfo ? this._reconnInfo.reconnectionAttempt : 0, - timeStamp: Date.now() - }; - - if (this._wasConnected) - { - this._wasConnected = false; - this.emit('disconnected', connection.remoteEndPoint); - } - }; - - EventStoreConnectionLogicHandler.prototype._handleTcpPackage = function(connection, pkg) { - if (!connection.equals(this._connection) || this._state == ConnectionState.Closed || this._state == ConnectionState.Init) - { - this._logDebug("IGNORED: HandleTcpPackage connId %s, package %s, %s.", - connection.connectionId, TcpCommand.getName(pkg.command), pkg.correlationId); - return; - } - - this._logDebug("HandleTcpPackage connId %s, package %s, %s.", - this._connection.connectionId, TcpCommand.getName(pkg.command), pkg.correlationId); - this._packageNumber += 1; - - if (pkg.command == TcpCommand.HeartbeatResponseCommand) - return; - if (pkg.command == TcpCommand.HeartbeatRequestCommand) - { - this._connection.enqueueSend(new TcpPackage( - TcpCommand.HeartbeatResponseCommand, - TcpFlags.None, - pkg.correlationId)); - return; - } - - if (pkg.command == TcpCommand.Authenticated || pkg.command == TcpCommand.NotAuthenticated) - { - if (this._state == ConnectionState.Connecting - && this._connectingPhase == ConnectingPhase.Authentication - && this._authInfo.correlationId == pkg.correlationId) - { - if (pkg.command == TcpCommand.NotAuthenticated) - this.emit('authenticationFailed', "Not authenticated"); - - this._goToConnectedState(); - return; - } - } - - if (pkg.command == TcpCommand.BadRequest && pkg.correlationId == EmptyGuid) - { - var message = ""; - try { - message = pkg.data.toString(); - } catch(e) {} - var err = new Error("Bad request received from server. Error: " + message); - this._closeConnection("Connection-wide BadRequest received. Too dangerous to continue.", err); - return; - } - - var operation = this._operations.getActiveOperation(pkg.correlationId); - if (operation) - { - var result = operation.operation.inspectPackage(pkg); - this._logDebug("HandleTcpPackage OPERATION DECISION %s (%s), %s", result.decision, result.description, operation.operation); - switch (result.decision) - { - case InspectionDecision.DoNothing: break; - case InspectionDecision.EndOperation: - this._operations.removeOperation(operation); - break; - case InspectionDecision.Retry: - this._operations.scheduleOperationRetry(operation); - break; - case InspectionDecision.Reconnect: - this._reconnectTo({tcpEndPoint: result.tcpEndPoint, secureTcpEndPoint: result.secureTcpEndPoint}); - this._operations.scheduleOperationRetry(operation); - break; - default: - throw new Error("Unknown InspectionDecision: " + result.decision); - } - if (this._state == ConnectionState.Connected) - this._operations.scheduleWaitingOperations(connection); - - return; - } - - var subscription = this._subscriptions.getActiveSubscription(pkg.correlationId); - if (subscription) - { - var result = subscription.operation.inspectPackage(pkg); - this._logDebug("HandleTcpPackage SUBSCRIPTION DECISION %s (%s), %s", result.decision, result.description, subscription); - switch (result.decision) - { - case InspectionDecision.DoNothing: break; - case InspectionDecision.EndOperation: - this._subscriptions.removeSubscription(subscription); - break; - case InspectionDecision.Retry: - this._subscriptions.scheduleSubscriptionRetry(subscription); - break; - case InspectionDecision.Reconnect: - this._reconnectTo({tcpEndPoint: result.tcpEndPoint, secureTcpEndPoint: result.secureTcpEndPoint}); - this._subscriptions.scheduleSubscriptionRetry(subscription); - break; - case InspectionDecision.Subscribed: - subscription.isSubscribed = true; - break; - default: - throw new Error("Unknown InspectionDecision: " + result.decision); - } - - return; - } - - this._logDebug("HandleTcpPackage UNMAPPED PACKAGE with CorrelationId %s, Command: %s", - pkg.correlationId, TcpCommand.getName(pkg.command)); - }; - - EventStoreConnectionLogicHandler.prototype._reconnectTo = function(endPoints) { - var endPoint = this._settings.useSslConnection - ? endPoints.secureTcpEndPoint - : endPoints.tcpEndPoint; - if (endPoint == null) - { - this._closeConnection("No end point is specified while trying to reconnect."); - return; - } - - if (this._state != ConnectionState.Connected || this._connection.remoteEndPoint == endPoint) - return; - - var msg = util.format("EventStoreConnection '%s': going to reconnect to [%j]. Current endpoint: [%j, L%j].", - this._esConnection.connectionName, endPoint, this._connection.remoteEndPoint, this._connection.localEndPoint); - if (this._settings.verboseLogging) this._settings.log.info(msg); - this._closeTcpConnection(msg); - - this._state = ConnectionState.Connecting; - this._connectingPhase = ConnectingPhase.EndPointDiscovery; - this._establishTcpConnection(endPoints); - }; - - EventStoreConnectionLogicHandler.prototype._timerTick = function() { - switch (this._state) - { - case ConnectionState.Init: break; - case ConnectionState.Connecting: - if (this._connectingPhase == ConnectingPhase.Reconnecting && Date.now() - this._reconnInfo.timeStamp >= this._settings.reconnectionDelay) - { - this._logDebug("TimerTick checking reconnection..."); - - this._reconnInfo = {reconnectionAttempt: this._reconnInfo.reconnectionAttempt + 1, timeStamp: Date.now()}; - if (this._settings.maxReconnections >= 0 && this._reconnInfo.reconnectionAttempt > this._settings.maxReconnections) - this._closeConnection("Reconnection limit reached."); - else - { - this.emit('reconnecting', {}); - this._discoverEndpoint(null); - } - } - else if (this._connectingPhase == ConnectingPhase.Authentication && Date.now() - this._authInfo.timeStamp >= this._settings.operationTimeout) - { - this.emit('authenticationFailed', "Authentication timed out."); - this._goToConnectedState(); - } - else if (this._connectingPhase > ConnectingPhase.ConnectionEstablishing) - this._manageHeartbeats(); - break; - case ConnectionState.Connected: - // operations timeouts are checked only if connection is established and check period time passed - if (Date.now() - this._lastTimeoutsTimeStamp >= this._settings.operationTimeoutCheckPeriod) - { - // On mono even impossible connection first says that it is established - // so clearing of reconnection count on ConnectionEstablished event causes infinite reconnections. - // So we reset reconnection count to zero on each timeout check period when connection is established - this._reconnInfo = {reconnectionAttempt: 0, timeStamp: Date.now()}; - this._operations.checkTimeoutsAndRetry(this._connection); - this._subscriptions.checkTimeoutsAndRetry(this._connection); - this._lastTimeoutsTimeStamp = Date.now(); - } - this._manageHeartbeats(); - break; - case ConnectionState.Closed: - break; - default: - throw new Error("Unknown state: " + this._state + "."); - } - }; - - EventStoreConnectionLogicHandler.prototype._manageHeartbeats = function() { - if (this._connection == null) throw new Error(); - - var timeout = this._heartbeatInfo.isIntervalStage ? this._settings.heartbeatInterval : this._settings.heartbeatTimeout; - if (Date.now() - this._heartbeatInfo.timeStamp < timeout) - return; - - var packageNumber = this._packageNumber; - if (this._heartbeatInfo.lastPackageNumber != packageNumber) - { - this._heartbeatInfo = {lastPackageNumber: packageNumber, isIntervalStage: true, timeStamp: Date.now()}; - return; - } - - if (this._heartbeatInfo.isIntervalStage) - { - // TcpMessage.Heartbeat analog - this._connection.enqueueSend(new TcpPackage( - TcpCommand.HeartbeatRequestCommand, - TcpFlags.None, - uuid.v4())); - this._heartbeatInfo = {lastPackageNumber: this._heartbeatInfo.lastPackageNumber, isIntervalStage: false, timeStamp: Date.now()}; - } - else - { - // TcpMessage.HeartbeatTimeout analog - var msg = util.format("EventStoreConnection '%s': closing TCP connection [%j, L%j, %s] due to HEARTBEAT TIMEOUT at pkgNum %d.", - this._esConnection.connectionName, this._connection.remoteEndPoint, this._connection.localEndPoint, - this._connection.connectionId, packageNumber); - this._settings.log.info(msg); - this._closeTcpConnection(msg); - } - }; - - EventStoreConnectionLogicHandler.prototype._logDebug = function(message) { - if (!this._settings.verboseLogging) return; - - if (arguments.length > 1) - message = util.format.apply(util, Array.prototype.slice.call(arguments)); - - this._settings.log.debug("EventStoreConnection '%s': %s", this._esConnection.connectionName, message); - }; - - EventStoreConnectionLogicHandler.prototype._logInfo = function(message){ - if (arguments.length > 1) - message = util.format.apply(util, Array.prototype.slice.call(arguments)); - - this._settings.log.info("EventStoreConnection '%s': %s", this._esConnection.connectionName, message); - }; - - module.exports = EventStoreConnectionLogicHandler; - -/***/ }, -/* 12 */ -/***/ function(module, exports) { - - function typeName(t) { - if (typeof t === 'function') - return t.name; - if (typeof t === 'object') - return t.constructor.name; - throw new TypeError('type must be a function or object, not ' + typeof t); - } - - function SimpleQueuedHandler() { - this._handlers = {}; - this._messages = []; - this._isProcessing = false; - } - - SimpleQueuedHandler.prototype.registerHandler = function(type, handler) { - type = typeName(type); - this._handlers[type] = handler; - }; - - SimpleQueuedHandler.prototype.enqueueMessage = function(msg) { - this._messages.push(msg); - if (!this._isProcessing) { - this._isProcessing = true; - setImmediate(this._processQueue.bind(this)); - } - }; - - SimpleQueuedHandler.prototype._processQueue = function() { - var message = this._messages.shift(); - while(message) { - var type = typeName(message); - var handler = this._handlers[type]; - if (!handler) - throw new Error("No handler registered for message " + type); - setImmediate(handler, message); - message = this._messages.shift(); - } - this._isProcessing = false; - }; - - module.exports = SimpleQueuedHandler; - -/***/ }, -/* 13 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - var LengthPrefixMessageFramer = __webpack_require__(14); - var TcpConnection = __webpack_require__(16); - var TcpPackage = __webpack_require__(18); - var TcpCommand = __webpack_require__(20); - - /** - * @param log - * @param remoteEndPoint - * @param connectionId - * @param ssl - * @param targetHost - * @param validateServer - * @param timeout - * @param handlePackage - * @param onError - * @param connectionEstablished - * @param connectionClosed - * @constructor - * @property {string} connectionId - * @property {boolean} isClosed - * @property {object} remoteEndPoint - * @property {object} localEndPoint - */ - function TcpPackageConnection( - log, remoteEndPoint, connectionId, ssl, targetHost, validateServer, timeout, - handlePackage, onError, connectionEstablished, connectionClosed) - { - this._connectionId = connectionId; - this._log = log; - this._handlePackage = handlePackage; - this._onError = onError; - - //Setup callback for incoming messages - this._framer = new LengthPrefixMessageFramer(); - this._framer.registerMessageArrivedCallback(this._incomingMessageArrived.bind(this)); - - //TODO ssl - var self = this; - this._connection = TcpConnection.createConnectingConnection( - log, - connectionId, - remoteEndPoint, - //ssl, - //targetHost, - //validateServer, - timeout, - function(tcpConnection) { - log.debug("TcpPackageConnection: connected to [%j, L%j, %s].", tcpConnection.remoteEndPoint, tcpConnection.localEndPoint, connectionId); - connectionEstablished(self); - }, - function(conn, error) { - log.debug("TcpPackageConnection: connection to [%j, L%j, %s] failed. Error: %s.", conn.remoteEndPoint, conn.localEndPoint, connectionId, error); - connectionClosed(self, error); - }, - function (conn, had_error) { - var error; - if (had_error) - error = new Error('transmission error.'); - - log.debug("TcpPackageConnection: connection [%j, L%j, %s] was closed %s", conn.remoteEndPoint, conn.localEndPoint, - connectionId, had_error ? "with error: " + error + "." : "cleanly."); - - connectionClosed(self, error); - }); - } - Object.defineProperty(TcpPackageConnection.prototype, 'connectionId', { - enumerable: true, - get: function() { - return this._connectionId; - } - }); - Object.defineProperty(TcpPackageConnection.prototype, 'isClosed', { - enumerable: true, - get: function() { - return this._connection.isClosed; - } - }); - Object.defineProperty(TcpPackageConnection.prototype, 'remoteEndPoint', { - enumerable: true, - get: function() { - return this._connection.remoteEndPoint; - } - }); - Object.defineProperty(TcpPackageConnection.prototype, 'localEndPoint', { - enumerable: true, - get: function() { - return this._connection.localEndPoint; - } - }); - - TcpPackageConnection.prototype._onRawDataReceived = function(connection, data) { - try { - this._framer.unframeData(data); - } catch(e) { - this._log.error(e, "TcpPackageConnection: [%j, L%j, %s]. Invalid TCP frame received.", this.remoteEndPoint, this.localEndPoint, this._connectionId); - this.close("Invalid TCP frame received"); - return; - } - - connection.receive(this._onRawDataReceived.bind(this)); - }; - - TcpPackageConnection.prototype._incomingMessageArrived = function(data) { - var valid = false; - var pkg; - try - { - pkg = TcpPackage.fromBufferSegment(data); - valid = true; - this._handlePackage(this, pkg); - } - catch (e) - { - this._connection.close(util.format("Error when processing TcpPackage %s: %s", - valid ? TcpCommand.getName(pkg.command) : "", e.message)); - - var message = util.format("TcpPackageConnection: [%j, L%j, %s] ERROR for %s. Connection will be closed.", - this.remoteEndPoint, this.localEndPoint, this._connectionId, - valid ? TcpCommand.getName(pkg.command) : ""); - if (this._onError != null) - this._onError(this, e); - this._log.debug(e, message); - } - }; - - TcpPackageConnection.prototype.startReceiving = function() { - if (this._connection == null) - throw new Error("Failed connection."); - this._connection.receive(this._onRawDataReceived.bind(this)); - }; - - TcpPackageConnection.prototype.enqueueSend = function(pkg) { - if (this._connection == null) - throw new Error("Failed connection."); - this._connection.enqueueSend(this._framer.frameData(pkg.asBufferSegment())); - }; - - TcpPackageConnection.prototype.close = function(reason) { - if (this._connection == null) - throw new Error("Failed connection."); - this._connection.close(reason); - }; - - TcpPackageConnection.prototype.equals = function(other) { - if (other === null) return false; - return this._connectionId === other._connectionId; - }; - - - module.exports = TcpPackageConnection; - -/***/ }, -/* 14 */ -/***/ function(module, exports, __webpack_require__) { - - var createBufferSegment = __webpack_require__(15); - - const HeaderLength = 4; - - function LengthPrefixMessageFramer(maxPackageSize) { - this._maxPackageSize = maxPackageSize || 64*1024*1024; - this._receivedHandler = null; - this.reset(); - } - - LengthPrefixMessageFramer.prototype.reset = function() { - this._messageBuffer = null; - this._headerBytes = 0; - this._packageLength = 0; - this._bufferIndex = 0; - }; - - LengthPrefixMessageFramer.prototype.unframeData = function(bufferSegments) { - for(var i = 0; i < bufferSegments.length; i++) { - this._parse(bufferSegments[i]); - } - }; - - LengthPrefixMessageFramer.prototype._parse = function(bytes) { - var buffer = bytes.buffer; - for (var i = bytes.offset; i < bytes.offset + bytes.count; i++) - { - if (this._headerBytes < HeaderLength) - { - this._packageLength |= (buffer[i] << (this._headerBytes * 8)); // little-endian order - ++this._headerBytes; - if (this._headerBytes == HeaderLength) - { - if (this._packageLength <= 0 || this._packageLength > this._maxPackageSize) - throw new Error(["Package size is out of bounds: ", this._packageLength, "(max: ", this._maxPackageSize, "."].join('')); - - this._messageBuffer = new Buffer(this._packageLength); - } - } - else - { - var copyCnt = Math.min(bytes.count + bytes.offset - i, this._packageLength - this._bufferIndex); - bytes.buffer.copy(this._messageBuffer, this._bufferIndex, i, i + copyCnt); - this._bufferIndex += copyCnt; - i += copyCnt - 1; - - if (this._bufferIndex == this._packageLength) - { - if (this._receivedHandler != null) - this._receivedHandler(createBufferSegment(this._messageBuffer, 0, this._bufferIndex)); - this.reset(); - } - } - } - }; - - LengthPrefixMessageFramer.prototype.frameData = function(data) { - var length = data.count; - var lengthBuffer = new Buffer(HeaderLength); - lengthBuffer.writeInt32LE(length, 0); - return [ - createBufferSegment(lengthBuffer, 0, HeaderLength), - data - ]; - }; - - LengthPrefixMessageFramer.prototype.registerMessageArrivedCallback = function(handler) { - this._receivedHandler = handler; - }; - - - module.exports = LengthPrefixMessageFramer; - - -/***/ }, -/* 15 */ -/***/ function(module, exports) { - - /** - * Create a buffer segment - * @param {Buffer} buf - * @param {number} [offset] - * @param {number} [count] - * @constructor - */ - function BufferSegment(buf, offset, count) { - if (!Buffer.isBuffer(buf)) throw new TypeError('buf must be a buffer'); - - this.buffer = buf; - this.offset = offset || 0; - this.count = count || buf.length; - } - - BufferSegment.prototype.toString = function() { - return this.buffer.toString('utf8', this.offset, this.offset + this.count); - }; - - BufferSegment.prototype.toBuffer = function() { - if (this.offset === 0 && this.count === this.buffer.length) - return this.buffer; - return this.buffer.slice(this.offset, this.offset + this.count); - }; - - BufferSegment.prototype.copyTo = function(dst, offset) { - this.buffer.copy(dst, offset, this.offset, this.offset + this.count); - }; - - module.exports = function(buf, offset, count) { - return new BufferSegment(buf, offset, count); - }; - -/***/ }, -/* 16 */ -/***/ function(module, exports, __webpack_require__) { - - var net = __webpack_require__(17); - var createBufferSegment = __webpack_require__(15); - - const MaxSendPacketSize = 64 * 1000; - - function TcpConnection(log, connectionId, remoteEndPoint, onConnectionClosed) { - this._socket = null; - this._log = log; - this._connectionId = connectionId; - this._remoteEndPoint = remoteEndPoint; - this._localEndPoint = null; - this._onConnectionClosed = onConnectionClosed; - this._receiveCallback = null; - this._closed = false; - this._sendQueue = []; - this._receiveQueue = []; - - Object.defineProperty(this, 'remoteEndPoint', { - enumerable: true, - get: function() { - return this._remoteEndPoint; - } - }); - Object.defineProperty(this, 'localEndPoint', { - enumerable: true, - get: function() { - return this._localEndPoint; - } - }); - } - - TcpConnection.prototype._initSocket = function(socket) { - this._socket = socket; - this._localEndPoint = {host: socket.localAddress, port: socket.localPort}; - - this._socket.on('error', this._processError.bind(this)); - this._socket.on('data', this._processReceive.bind(this)); - }; - - TcpConnection.prototype.enqueueSend = function(bufSegmentArray) { - //console.log(bufSegmentArray); - - for(var i = 0; i < bufSegmentArray.length; i++) { - var bufSegment = bufSegmentArray[i]; - this._sendQueue.push(bufSegment.toBuffer()); - } - - this._trySend(); - }; - - TcpConnection.prototype._trySend = function() { - if (this._sendQueue.length === 0 || this._socket === null) return; - - var buffers = []; - var bytes = 0; - var sendPiece = this._sendQueue.shift(); - while(sendPiece) { - if (bytes + sendPiece.length > MaxSendPacketSize) - break; - - buffers.push(sendPiece); - bytes += sendPiece.length; - - sendPiece = this._sendQueue.shift(); - } - - var joinedBuffers = Buffer.concat(buffers, bytes); - this._socket.write(joinedBuffers); - }; - - TcpConnection.prototype._processError = function(err) { - this._closeInternal(err, "Socket error"); - }; - - TcpConnection.prototype._processReceive = function(buf) { - if (buf.length === 0) { - //NotifyReceiveCompleted(0); - this._closeInternal(null, "Socket closed"); - return; - } - - //NotifyReceiveCompleted(buf.length) - this._receiveQueue.push(buf); - - this._tryDequeueReceivedData(); - }; - - TcpConnection.prototype.receive = function(cb) { - this._receiveCallback = cb; - this._tryDequeueReceivedData(); - }; - - TcpConnection.prototype._tryDequeueReceivedData = function() { - if (this._receiveCallback === null || this._receiveQueue.length === 0) - return; - - var res = []; - while(this._receiveQueue.length > 0) { - var buf = this._receiveQueue.shift(); - var bufferSegment = createBufferSegment(buf); - res.push(bufferSegment); - } - var callback = this._receiveCallback; - this._receiveCallback = null; - - callback(this, res); - - var bytes = 0; - for(var i=0;i= data.count) - throw new Error("Login length is too big, it doesn't fit into TcpPackage."); - login = data.buffer.toString('utf8', data.offset + AuthOffset + 1, data.offset + AuthOffset + 1 + loginLen); - - var passLen = data.buffer[data.offset + AuthOffset + 1 + loginLen]; - if (AuthOffset + 1 + loginLen + 1 + passLen > data.count) - throw new Error("Password length is too big, it doesn't fit into TcpPackage."); - headerSize += 1 + loginLen + 1 + passLen; - pass = data.buffer.toString('utf8', data.offset + AuthOffset + 1 + loginLen + 1, data.offset + headerSize); - } - return new TcpPackage( - command, flags, correlationId, login, pass, - createBufferSegment(data.buffer, data.offset + headerSize, data.count - headerSize)); - }; - - TcpPackage.prototype.asBuffer = function() { - if ((this.flags & TcpFlags.Authenticated) != 0) { - var loginBytes = new Buffer(this.login); - if (loginBytes.length > 255) throw new Error("Login serialized length should be less than 256 bytes."); - var passwordBytes = new Buffer(this.password); - if (passwordBytes.length > 255) throw new Error("Password serialized length should be less than 256 bytes."); - - var res = new Buffer(MandatorySize + 2 + loginBytes.length + passwordBytes.length + (this.data ? this.data.count : 0)); - res[CommandOffset] = this.command; - res[FlagsOffset] = this.flags; - uuid.parse(this.correlationId, res, CorrelationOffset); - - res[AuthOffset] = loginBytes.length; - loginBytes.copy(res, AuthOffset + 1); - res[AuthOffset + 1 + loginBytes.length] = passwordBytes.length; - passwordBytes.copy(res, AuthOffset + 2 + loginBytes.length); - - if (this.data) - this.data.copyTo(res, res.length - this.data.count); - - return res; - } else { - var res = new Buffer(MandatorySize + (this.data ? this.data.count : 0)); - res[CommandOffset] = this.command; - res[FlagsOffset] = this.flags; - uuid.parse(this.correlationId, res, CorrelationOffset); - if (this.data) - this.data.copyTo(res, AuthOffset); - return res; - } - }; - - TcpPackage.prototype.asBufferSegment = function() { - return createBufferSegment(this.asBuffer()); - }; - - module.exports = TcpPackage; - -/***/ }, -/* 19 */ -/***/ function(module, exports) { - - const TcpFlags = { - None: 0x0, - Authenticated: 0x01 - }; - - module.exports = TcpFlags; - - -/***/ }, -/* 20 */ -/***/ function(module, exports) { - - const TcpCommand = { - HeartbeatRequestCommand: 0x01, - HeartbeatResponseCommand: 0x02, - - Ping: 0x03, - Pong: 0x04, - - PrepareAck: 0x05, - CommitAck: 0x06, - - SlaveAssignment: 0x07, - CloneAssignment: 0x08, - - SubscribeReplica: 0x10, - ReplicaLogPositionAck: 0x11, - CreateChunk: 0x12, - RawChunkBulk: 0x13, - DataChunkBulk: 0x14, - ReplicaSubscriptionRetry: 0x15, - ReplicaSubscribed: 0x16, - - // CLIENT COMMANDS - // CreateStream: 0x80, - // CreateStreamCompleted: 0x81, - - WriteEvents: 0x82, - WriteEventsCompleted: 0x83, - - TransactionStart: 0x84, - TransactionStartCompleted: 0x85, - TransactionWrite: 0x86, - TransactionWriteCompleted: 0x87, - TransactionCommit: 0x88, - TransactionCommitCompleted: 0x89, - - DeleteStream: 0x8A, - DeleteStreamCompleted: 0x8B, - - ReadEvent: 0xB0, - ReadEventCompleted: 0xB1, - ReadStreamEventsForward: 0xB2, - ReadStreamEventsForwardCompleted: 0xB3, - ReadStreamEventsBackward: 0xB4, - ReadStreamEventsBackwardCompleted: 0xB5, - ReadAllEventsForward: 0xB6, - ReadAllEventsForwardCompleted: 0xB7, - ReadAllEventsBackward: 0xB8, - ReadAllEventsBackwardCompleted: 0xB9, - - SubscribeToStream: 0xC0, - SubscriptionConfirmation: 0xC1, - StreamEventAppeared: 0xC2, - UnsubscribeFromStream: 0xC3, - SubscriptionDropped: 0xC4, - ConnectToPersistentSubscription: 0xC5, - PersistentSubscriptionConfirmation: 0xC6, - PersistentSubscriptionStreamEventAppeared: 0xC7, - CreatePersistentSubscription: 0xC8, - CreatePersistentSubscriptionCompleted: 0xC9, - DeletePersistentSubscription: 0xCA, - DeletePersistentSubscriptionCompleted: 0xCB, - PersistentSubscriptionAckEvents: 0xCC, - PersistentSubscriptionNakEvents: 0xCD, - UpdatePersistentSubscription: 0xCE, - UpdatePersistentSubscriptionCompleted: 0xCF, - - ScavengeDatabase: 0xD0, - ScavengeDatabaseCompleted: 0xD1, - - BadRequest: 0xF0, - NotHandled: 0xF1, - Authenticate: 0xF2, - Authenticated: 0xF3, - NotAuthenticated: 0xF4 - }; - - var _reverseLookup = {}; - for(var n in TcpCommand) { - var v = TcpCommand[n]; - _reverseLookup[v] = n; - } - - module.exports = TcpCommand; - module.exports.getName = function(v) { - return _reverseLookup[v]; - }; - - -/***/ }, -/* 21 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - var Hash = __webpack_require__(22); - var TcpCommand = __webpack_require__(20); - - /** - * @param {string} connectionName - * @param {object} settings - * @constructor - * @property {number} totalOperationCount - */ - function OperationsManager(connectionName, settings) { - this._connectionName = connectionName; - this._settings = settings; - - this._totalOperationCount = 0; - this._activeOperations = new Hash(); - this._waitingOperations = []; - this._retryPendingOperations = []; - } - Object.defineProperty(OperationsManager.prototype, 'totalOperationCount', { - get: function() { - return this._totalOperationCount; - } - }); - - OperationsManager.prototype.getActiveOperation = function(correlationId) { - return this._activeOperations.get(correlationId); - }; - - OperationsManager.prototype.cleanUp = function() { - var connectionClosedError = new Error(util.format("Connection '%s' was closed.", this._connectionName)); - - this._activeOperations.forEach(function(correlationId, operation){ - operation.operation.fail(connectionClosedError); - }); - this._waitingOperations.forEach(function(operation) { - operation.operation.fail(connectionClosedError); - }); - this._retryPendingOperations.forEach(function(operation) { - operation.operation.fail(connectionClosedError); - }); - - this._activeOperations.clear(); - this._waitingOperations = []; - this._retryPendingOperations = []; - this._totalOperationCount = 0; - }; - - OperationsManager.prototype.checkTimeoutsAndRetry = function(connection) { - if (!connection) throw new TypeError("Connection is null."); - - var retryOperations = []; - var removeOperations = []; - var self = this; - this._activeOperations.forEach(function(correlationId, operation) { - if (operation.connectionId != connection.connectionId) - { - retryOperations.push(operation); - } - else if (operation.timeout > 0 && Date.now() - operation.lastUpdated > self._settings.operationTimeout) - { - var err = util.format("EventStoreConnection '%s': operation never got response from server.\n" - + "UTC now: %s, operation: %s.", - self._connectionName, new Date(), operation); - self._settings.log.error(err); - - if (self._settings.failOnNoServerResponse) - { - operation.operation.fail(new Error(err)); - removeOperations.push(operation); - } - else - { - retryOperations.push(operation); - } - } - }); - - retryOperations.forEach(function(operation) { - self.scheduleOperationRetry(operation); - }); - removeOperations.forEach(function(operation) { - self.removeOperation(operation); - }); - - if (this._retryPendingOperations.length > 0) - { - this._retryPendingOperations.sort(function(x,y) { - if (x.seqNo < y.seqNo) return -1; - if (x.seqNo > y.seqNo) return 1; - return 0; - }); - this._retryPendingOperations.forEach(function(operation) { - var oldCorrId = operation.correlationId; - operation.correlationId = uuid.v4(); - operation.retryCount += 1; - self._logDebug("retrying, old corrId %s, operation %s.", oldCorrId, operation); - self.scheduleOperation(operation, connection); - }); - this._retryPendingOperations = []; - } - - this.scheduleWaitingOperations(connection); - }; - - OperationsManager.prototype.scheduleOperationRetry = function(operation) { - if (!this.removeOperation(operation)) - return; - - this._logDebug("ScheduleOperationRetry for %s.", operation); - if (operation.maxRetries >= 0 && operation.retryCount >= operation.maxRetries) - { - var err = util.format("Retry limit reached. Operation: %s, RetryCount: %d", operation, operation.retryCount); - operation.operation.fail(new Error(err)); - return; - } - this._retryPendingOperations.push(operation); - }; - - OperationsManager.prototype.removeOperation = function(operation) { - this._activeOperations.remove(operation.connectionId); - this._logDebug("RemoveOperation SUCCEEDED for %s.", operation); - this._totalOperationCount = this._activeOperations.length + this._waitingOperations.length; - return true; - }; - - OperationsManager.prototype.scheduleWaitingOperations = function(connection) { - if (!connection) throw new TypeError("connection is null."); - while (this._waitingOperations.length > 0 && this._activeOperations.length < this._settings.maxConcurrentItems) - { - this.scheduleOperation(this._waitingOperations.shift(), connection); - } - this._totalOperationCount = this._activeOperations.length + this._waitingOperations.length; - }; - - OperationsManager.prototype.enqueueOperation = function(operation) { - this._logDebug("EnqueueOperation WAITING for %s.", operation); - this._waitingOperations.push(operation); - }; - - OperationsManager.prototype.scheduleOperation = function(operation, connection) { - if (this._activeOperations.length >= this._settings.maxConcurrentItems) - { - this._logDebug("ScheduleOperation WAITING for %s.", operation); - this._waitingOperations.push(operation); - } - else - { - operation.connectionId = connection.connectionId; - operation.lastUpdated = Date.now(); - this._activeOperations.add(operation.correlationId, operation); - - var pkg = operation.operation.createNetworkPackage(operation.correlationId); - this._logDebug("ScheduleOperation package %s, %s, %s.", TcpCommand.getName(pkg.command), pkg.correlationId, operation); - connection.enqueueSend(pkg); - } - this._totalOperationCount = this._activeOperations.length + this._waitingOperations.length; - }; - - OperationsManager.prototype._logDebug = function(message) { - if (!this._settings.verboseLogging) return; - - if (arguments.length > 1) - message = util.format.apply(util, Array.prototype.slice.call(arguments)); - - this._settings.log.debug("EventStoreConnection '%s': %s.", this._connectionName, message); - }; - - module.exports = OperationsManager; - - -/***/ }, -/* 22 */ -/***/ function(module, exports) { - - /** - * @constructor - * @property {number} length - */ - function Hash() { - this._ = {}; - this._length = 0; - } - Object.defineProperty(Hash.prototype, 'length', { - get: function() { - return this._length; - } - }); - - Hash.prototype.add = function(key,value) { - this._[key] = value; - this._length++; - }; - - Hash.prototype.clear = function() { - this._ = {}; - this._length = 0; - }; - - Hash.prototype.forEach = function(cb) { - for(var k in this._) { - cb(k, this._[k]); - } - }; - - Hash.prototype.get = function(key) { - return this._[key]; - }; - - Hash.prototype.remove = function(key) { - delete this._[key]; - this._length--; - }; - - - module.exports = Hash; - - -/***/ }, -/* 23 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - var Hash = __webpack_require__(22); - - var SubscriptionDropReason = __webpack_require__(24); - - function SubscriptionsManager(connectionName, settings) { - //Ensure.NotNull(connectionName, "connectionName"); - //Ensure.NotNull(settings, "settings"); - this._connectionName = connectionName; - this._settings = settings; - - this._activeSubscriptions = new Hash(); - this._waitingSubscriptions = []; - this._retryPendingSubscriptions = []; - } - - SubscriptionsManager.prototype.getActiveSubscription = function(correlationId) { - return this._activeSubscriptions.get(correlationId); - }; - - SubscriptionsManager.prototype.cleanUp = function() { - var connectionClosedError = new Error(util.format("Connection '%s' was closed.", this._connectionName)); - - var self = this; - this._activeSubscriptions.forEach(function(correlationId, subscription){ - subscription.operation.dropSubscription(SubscriptionDropReason.ConnectionClosed, connectionClosedError); - }); - this._waitingSubscriptions.forEach(function(subscription){ - subscription.operation.dropSubscription(SubscriptionDropReason.ConnectionClosed, connectionClosedError); - }); - this._retryPendingSubscriptions.forEach(function(subscription){ - subscription.operation.dropSubscription(SubscriptionDropReason.ConnectionClosed, connectionClosedError); - }); - - this._activeSubscriptions.clear(); - this._waitingSubscriptions = []; - this._retryPendingSubscriptions = []; - }; - - SubscriptionsManager.prototype.purgeSubscribedAndDroppedSubscriptions = function() { - var self = this; - var subscriptionsToRemove = []; - this._activeSubscriptions.forEach(function(_, subscription) { - if (subscription.isSubscribed && subscription.connectionId == connectionId) { - subscription.operation.connectionClosed(); - subscriptionsToRemove.push(subscription); - } - }); - subscriptionsToRemove.forEach(function(subscription) { - self._activeSubscriptions.remove(subscription.correlationId); - }); - }; - - SubscriptionsManager.prototype.checkTimeoutsAndRetry = function(connection) { - //Ensure.NotNull(connection, "connection"); - - var self = this; - var retrySubscriptions = []; - var removeSubscriptions = []; - this._activeSubscriptions.forEach(function(_, subscription) { - if (subscription.isSubscribed) return; - if (subscription.connectionId != connection.connectionId) - { - retrySubscriptions.push(subscription); - } - else if (subscription.timeout > 0 && Date.now() - subscription.lastUpdated > self._settings.operationTimeout) - { - var err = util.format("EventStoreConnection '%s': subscription never got confirmation from server.\n" + - "UTC now: %s, operation: %s.", - self._connectionName, new Date(), subscription); - self._settings.log.error(err); - - if (self._settings.failOnNoServerResponse) - { - subscription.operation.dropSubscription(SubscriptionDropReason.SubscribingError, new Error(err)); - removeSubscriptions.push(subscription); - } - else - { - retrySubscriptions.push(subscription); - } - } - }); - - retrySubscriptions.forEach(function(subscription) { - self.scheduleSubscriptionRetry(subscription); - }); - removeSubscriptions.forEach(function(subscription) { - self.removeSubscription(subscription); - }); - - if (this._retryPendingSubscriptions.length > 0) - { - this._retryPendingSubscriptions.forEach(function(subscription) { - subscription.retryCount += 1; - self.startSubscription(subscription, connection); - }); - this._retryPendingSubscriptions = []; - } - - while (this._waitingSubscriptions.length > 0) - { - this.startSubscription(this._waitingSubscriptions.shift(), connection); - } - }; - - SubscriptionsManager.prototype.removeSubscription = function(subscription) { - this._activeSubscriptions.remove(subscription.correlationId); - this._logDebug("RemoveSubscription %s.", subscription); - return true; - }; - - SubscriptionsManager.prototype.scheduleSubscriptionRetry = function(subscription) { - if (!this.removeSubscription(subscription)) - { - this._logDebug("RemoveSubscription failed when trying to retry %s.", subscription); - return; - } - - if (subscription.maxRetries >= 0 && subscription.retryCount >= subscription.maxRetries) - { - this._logDebug("RETRIES LIMIT REACHED when trying to retry %s.", subscription); - var err = util.format("Retries limit reached. Subscription: %s RetryCount: %d.", subscription, subscription.retryCount); - subscription.operation.dropSubscription(SubscriptionDropReason.SubscribingError, new Error(err)); - return; - } - - this._logDebug("retrying subscription %s.", subscription); - this._retryPendingSubscriptions.push(subscription); - }; - - SubscriptionsManager.prototype.enqueueSubscription = function(subscriptionItem) { - this._waitingSubscriptions.push(subscriptionItem); - }; - - SubscriptionsManager.prototype.startSubscription = function(subscription, connection) { - //Ensure.NotNull(connection, "connection"); - - if (subscription.isSubscribed) - { - this._logDebug("StartSubscription REMOVING due to already subscribed %s.", subscription); - this.removeSubscription(subscription); - return; - } - - subscription.correlationId = uuid.v4(); - subscription.connectionId = connection.connectionId; - subscription.lastUpdated = Date.now(); - - this._activeSubscriptions.add(subscription.correlationId, subscription); - - if (!subscription.operation.subscribe(subscription.correlationId, connection)) - { - this._logDebug("StartSubscription REMOVING AS COULDN'T SUBSCRIBE %s.", subscription); - this.removeSubscription(subscription); - } - else - { - this._logDebug("StartSubscription SUBSCRIBING %s.", subscription); - } - }; - - SubscriptionsManager.prototype._logDebug = function(message) { - if (!this._settings.verboseLogging) return; - - var parameters = Array.prototype.slice.call(arguments, 1); - this._settings.log.debug("EventStoreConnection '%s': %s.", this._connectionName, parameters.length == 0 ? message : util.format(message, parameters)); - }; - - module.exports = SubscriptionsManager; - -/***/ }, -/* 24 */ -/***/ function(module, exports) { - - const SubscriptionDropReason = { - AccessDenied: 'accessDenied', - CatchUpError: 'catchUpError', - ConnectionClosed: 'connectionClosed', - EventHandlerException: 'eventHandlerException', - MaxSubscribersReached: 'maxSubscribersReached', - NotFound: 'notFound', - PersistentSubscriptionDeleted: 'persistentSubscriptionDeleted', - ProcessingQueueOverflow: 'processingQueueOverflow', - ServerError: 'serverError', - SubscribingError: 'subscribingError', - UserInitiated: 'userInitiated', - Unknown: 'unknown' - }; - - module.exports = SubscriptionDropReason; - -/***/ }, -/* 25 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - 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__(30); - - function VolatileSubscriptionOperation( - log, cb, streamId, resolveLinkTos, userCredentials, eventAppeared, - subscriptionDropped, verboseLogging, getConnection - ) { - SubscriptionOperation.call(this, log, cb, streamId, resolveLinkTos, userCredentials, eventAppeared, subscriptionDropped, verboseLogging, getConnection); - } - util.inherits(VolatileSubscriptionOperation, SubscriptionOperation); - - VolatileSubscriptionOperation.prototype._createSubscriptionPackage = function() { - var dto = new ClientMessage.SubscribeToStream(this._streamId, this._resolveLinkTos); - return new TcpPackage(TcpCommand.SubscribeToStream, - this._userCredentials != null ? TcpFlags.Authenticated : TcpFlags.None, - this._correlationId, - this._userCredentials != null ? this._userCredentials.username : null, - this._userCredentials != null ? this._userCredentials.password : null, - new BufferSegment(dto.toBuffer())); - }; - - VolatileSubscriptionOperation.prototype._inspectPackage = function(pkg) { - try { - if (pkg.command == TcpCommand.SubscriptionConfirmation) { - var dto = ClientMessage.SubscriptionConfirmation.decode(pkg.data.toBuffer()); - this._confirmSubscription(dto.last_commit_position, dto.last_event_number); - return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation"); - } - if (pkg.command == TcpCommand.StreamEventAppeared) { - var dto = ClientMessage.StreamEventAppeared.decode(pkg.data.toBuffer()); - this._onEventAppeared(new results.ResolvedEvent(dto.event)); - return new InspectionResult(InspectionDecision.DoNothing, "StreamEventAppeared"); - } - return null; - } catch(e) { - console.log(e.stack); - return null; - } - }; - - VolatileSubscriptionOperation.prototype._createSubscriptionObject = function(lastCommitPosition, lastEventNumber) { - return new VolatileEventStoreSubscription(this, this._streamId, lastCommitPosition, lastEventNumber); - }; - - module.exports = VolatileSubscriptionOperation; - -/***/ }, -/* 26 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(24); - - //TODO: nodify eventAppeared and subscriptionDropped, should be emit on subscription - function SubscriptionOperation( - log, cb, streamId, resolveLinkTos, userCredentials, eventAppeared, - subscriptionDropped, verboseLogging, getConnection - ) { - //TODO: validations - //Ensure.NotNull(log, "log"); - //Ensure.NotNull(source, "source"); - //Ensure.NotNull(eventAppeared, "eventAppeared"); - //Ensure.NotNull(getConnection, "getConnection"); - - this._log = log; - this._cb = cb; - this._streamId = streamId || ''; - this._resolveLinkTos = resolveLinkTos; - this._userCredentials = userCredentials; - this._eventAppeared = eventAppeared; - this._subscriptionDropped = subscriptionDropped || function() {}; - this._verboseLogging = verboseLogging; - this._getConnection = getConnection; - - this._correlationId = null; - this._unsubscribed = false; - this._subscription = null; - this._actionExecuting = false; - this._actionQueue = []; - } - - SubscriptionOperation.prototype._enqueueSend = function(pkg) { - this._getConnection().enqueueSend(pkg); - }; - - SubscriptionOperation.prototype.subscribe = function(correlationId, connection) { - if (connection === null) throw new TypeError("connection is null."); - - if (this._subscription != null || this._unsubscribed != 0) - return false; - - this._correlationId = correlationId; - connection.enqueueSend(this._createSubscriptionPackage()); - return true; - }; - - SubscriptionOperation.prototype._createSubscriptionPackage = function() { - throw new Error("SubscriptionOperation._createSubscriptionPackage abstract method called. " + this.constructor.name); - }; - - SubscriptionOperation.prototype.unsubscribe = function() { - this.dropSubscription(SubscriptionDropReason.UserInitiated, null, this._getConnection()); - }; - - SubscriptionOperation.prototype._createUnsubscriptionPackage = function() { - var msg = new ClientMessage.UnsubscribeFromStream(); - var data = new BufferSegment(msg.toBuffer()); - return new TcpPackage(TcpCommand.UnsubscribeFromStream, TcpFlags.None, this._correlationId, null, null, data); - }; - - SubscriptionOperation.prototype._inspectPackage = function(pkg) { - throw new Error("SubscriptionOperation._inspectPackage abstract method called." + this.constructor.name); - }; - - SubscriptionOperation.prototype.inspectPackage = function(pkg) { - try - { - var result = this._inspectPackage(pkg); - if (result !== null) { - return result; - } - - switch (pkg.command) - { - case TcpCommand.StreamEventAppeared: - { - var dto = ClientMessage.StreamEventAppeared.decode(pkg.data.toBuffer()); - this._onEventAppeared(new results.ResolvedEvent(dto.event)); - return new InspectionResult(InspectionDecision.DoNothing, "StreamEventAppeared"); - } - - case TcpCommand.SubscriptionDropped: - { - var dto = ClientMessage.SubscriptionDropped.decode(pkg.data.toBuffer()); - switch (dto.reason) - { - case ClientMessage.SubscriptionDropped.SubscriptionDropReason.Unsubscribed: - this.dropSubscription(SubscriptionDropReason.UserInitiated, null); - break; - case ClientMessage.SubscriptionDropped.SubscriptionDropReason.AccessDenied: - this.dropSubscription(SubscriptionDropReason.AccessDenied, - new Error(util.format("Subscription to '%s' failed due to access denied.", this._streamId || ""))); - break; - default: - if (this._verboseLogging) this._log.debug("Subscription dropped by server. Reason: %s.", dto.reason); - this.dropSubscription(SubscriptionDropReason.Unknown, - new Error(util.format("Unsubscribe reason: '%s'.", dto.reason))); - break; - } - return new InspectionResult(InspectionDecision.EndOperation, util.format("SubscriptionDropped: %s", dto.reason)); - } - - case TcpCommand.NotAuthenticated: - { - var message = pkg.data.toString(); - this.dropSubscription(SubscriptionDropReason.NotAuthenticated, - new Error(message || "Authentication error")); - return new InspectionResult(InspectionDecision.EndOperation, "NotAuthenticated"); - } - - case TcpCommand.BadRequest: - { - var message = pkg.data.toString(); - this.dropSubscription(SubscriptionDropReason.ServerError, - new Error("Server error: " + (message || ""))); - return new InspectionResult(InspectionDecision.EndOperation, util.format("BadRequest: %s", message)); - } - - case TcpCommand.NotHandled: - { - if (this._subscription != null) - throw new Error("NotHandled command appeared while we already subscribed."); - - var message = ClientMessage.NotHandled.decode(pkg.data.toBuffer()); - switch (message.reason) - { - case ClientMessage.NotHandled.NotHandledReason.NotReady: - return new InspectionResult(InspectionDecision.Retry, "NotHandled - NotReady"); - - case ClientMessage.NotHandled.NotHandledReason.TooBusy: - return new InspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy"); - - case ClientMessage.NotHandled.NotHandledReason.NotMaster: - var masterInfo = ClientMessage.NotHandled.MasterInfo.decode(message.additional_info); - return new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster", - {host: masterInfo.external_tcp_address, port: masterInfo.external_tcp_port}, - {host: masterInfo.external_secure_tcp_address, port: masterInfo.external_secure_tcp_port}); - - default: - this._log.error("Unknown NotHandledReason: %s.", message.reason); - return new InspectionResult(InspectionDecision.Retry, "NotHandled - "); - } - } - - default: - { - this.dropSubscription(SubscriptionDropReason.ServerError, - new Error("Command not expected: " + TcpCommand.getName(pkg.command))); - return new InspectionResult(InspectionDecision.EndOperation, pkg.command); - } - } - } - catch (e) - { - this.dropSubscription(SubscriptionDropReason.Unknown, e); - return new InspectionResult(InspectionDecision.EndOperation, util.format("Exception - %s", e.Message)); - } - }; - - SubscriptionOperation.prototype.connectionClosed = function() { - this.dropSubscription(SubscriptionDropReason.ConnectionClosed, new Error("Connection was closed.")); - }; - - SubscriptionOperation.prototype.timeOutSubscription = function() { - if (this._subscription !== null) - return false; - this.dropSubscription(SubscriptionDropReason.SubscribingError, null); - return true; - }; - - SubscriptionOperation.prototype.dropSubscription = function(reason, err, connection) { - if (!this._unsubscribed) - { - this._unsubscribed = true; - if (this._verboseLogging) - this._log.debug("Subscription %s to %s: closing subscription, reason: %s, exception: %s...", - this._correlationId, this._streamId || "", reason, err); - - if (reason !== SubscriptionDropReason.UserInitiated && this._subscription === null) - { - if (err === null) throw new Error(util.format("No exception provided for subscription drop reason '%s", reason)); - //TODO: this should be last thing to execute - this._cb(err); - return; - } - - if (reason === SubscriptionDropReason.UserInitiated && this._subscription !== null && connection !== null) - connection.enqueueSend(this._createUnsubscriptionPackage()); - - var self = this; - if (this._subscription !== null) - this._executeAction(function() { self._subscriptionDropped(self._subscription, reason, err); }); - } - }; - - SubscriptionOperation.prototype._confirmSubscription = function(lastCommitPosition, lastEventNumber) { - if (lastCommitPosition < -1) - throw new Error(util.format("Invalid lastCommitPosition %s on subscription confirmation.", lastCommitPosition)); - if (this._subscription !== null) - throw new Error("Double confirmation of subscription."); - - if (this._verboseLogging) - this._log.debug("Subscription %s to %s: subscribed at CommitPosition: %d, EventNumber: %d.", - this._correlationId, this._streamId || "", lastCommitPosition, lastEventNumber); - - this._subscription = this._createSubscriptionObject(lastCommitPosition, lastEventNumber); - this._cb(null, this._subscription); - }; - - SubscriptionOperation.prototype._createSubscriptionObject = function(lastCommitPosition, lastEventNumber) { - throw new Error("SubscriptionOperation._createSubscriptionObject abstract method called. " + this.constructor.name); - }; - - SubscriptionOperation.prototype._onEventAppeared = function(e) { - if (this._unsubscribed) - return; - - if (this._subscription === null) throw new Error("Subscription not confirmed, but event appeared!"); - - if (this._verboseLogging) - this._log.debug("Subscription %s to %s: event appeared (%s, %d, %s @ %s).", - this._correlationId, this._streamId || "", - e.originalStreamId, e.originalEventNumber, e.originalEvent.eventType, e.originalPosition); - - var self = this; - this._executeAction(function() { self._eventAppeared(self._subscription, e); }); - }; - - SubscriptionOperation.prototype._executeAction = function(action) { - this._actionQueue.push(action); - if (!this._actionExecuting) { - this._actionExecuting = true; - setImmediate(this._executeActions.bind(this)); - } - }; - - SubscriptionOperation.prototype._executeActions = function() { - //TODO: possible blocking loop for node.js - var action = this._actionQueue.shift(); - while (action) - { - try - { - action(); - } - catch (err) - { - this._log.error(err, "Exception during executing user callback: %s.", err.message); - } - action = this._actionQueue.shift(); - } - this._actionExecuting = false; - }; - - SubscriptionOperation.prototype.toString = function() { - return this.constructor.name; - }; - - - module.exports = SubscriptionOperation; - -/***/ }, -/* 27 */ -/***/ function(module, exports) { - - var InspectionDecision = { - DoNothing: 'doNothing', - EndOperation: 'endOperation', - Retry: 'retry', - Reconnect: 'reconnect', - Subscribed: 'subscribed' - }; - - module.exports = InspectionDecision; - -/***/ }, -/* 28 */ -/***/ function(module, exports) { - - function InspectionResult(decision, description, tcpEndPoint, secureTcpEndPoint) { - this.decision = decision; - this.description = description; - this.tcpEndPoint = tcpEndPoint || null; - this.secureTcpEndPoint = secureTcpEndPoint || null; - } - - module.exports = InspectionResult; - - -/***/ }, -/* 29 */ -/***/ function(module, exports) { - - module.exports = require("../src/messages/clientMessage"); - -/***/ }, -/* 30 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - var EventStoreSubsription = __webpack_require__(31); - - /** - * @param {SubscriptionOperation} subscriptionOperation - * @param {string} streamId - * @param {Position} lastCommitPosition - * @param {number} lastEventNumber - * @constructor - * @augments {EventStoreSubscription} - */ - function VolatileEventStoreConnection(subscriptionOperation, streamId, lastCommitPosition, lastEventNumber) { - EventStoreSubsription.call(this, streamId, lastCommitPosition, lastEventNumber); - - this._subscriptionOperation = subscriptionOperation; - } - util.inherits(VolatileEventStoreConnection, EventStoreSubsription); - - VolatileEventStoreConnection.prototype.unsubscribe = function() { - this._subscriptionOperation.unsubscribe(); - }; - - module.exports = VolatileEventStoreConnection; - - -/***/ }, -/* 31 */ -/***/ function(module, exports) { - - /*** - * EventStoreSubscription - * @param {string} streamId - * @param {number} lastCommitPosition - * @param {?number} lastEventNumber - * @constructor - * @property {boolean} isSubscribedToAll - * @property {string} streamId - * @property {number} lastCommitPosition - * @property {?number} lastEventNumber - */ - function EventStoreSubscription(streamId, lastCommitPosition, lastEventNumber) { - Object.defineProperties(this, { - isSubscribedToAll: { - value: streamId === '' - }, - streamId: { - value: streamId - }, - lastCommitPosition: { - value: lastCommitPosition - }, - lastEventNumber: { - value: lastEventNumber - } - }); - } - - /** - * Unsubscribes from the stream - */ - EventStoreSubscription.prototype.close = function() { - this.unsubscribe(); - }; - - /** - * Unsubscribes from the stream - * @abstract - */ - EventStoreSubscription.prototype.unsubscribe = function() { - throw new Error("EventStoreSubscription.unsubscribe abstract method called." + this.constructor.name); - }; - - module.exports = EventStoreSubscription; - - -/***/ }, -/* 32 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(24); - var PersistentEventStoreSubscription = __webpack_require__(33); - var ensure = __webpack_require__(6); - - function ConnectToPersistentSubscriptionOperation( - log, cb, groupName, bufferSize, streamId, userCredentials, eventAppeared, subscriptionDropped, - verboseLogging, getConnection - ) { - SubscriptionOperation.call(this, log, cb, streamId, false, userCredentials, eventAppeared, subscriptionDropped, verboseLogging, getConnection); - - this._groupName = groupName; - this._bufferSize = bufferSize; - this._subscriptionId = null; - } - util.inherits(ConnectToPersistentSubscriptionOperation, SubscriptionOperation); - - ConnectToPersistentSubscriptionOperation.prototype._createSubscriptionPackage = function() { - var dto = new ClientMessage.ConnectToPersistentSubscription(this._groupName, this._streamId, this._bufferSize); - return new TcpPackage(TcpCommand.ConnectToPersistentSubscription, - this._userCredentials !== null ? TcpFlags.Authenticated : TcpFlags.None, - this._correlationId, - this._userCredentials !== null ? this._userCredentials.username : null, - this._userCredentials !== null ? this._userCredentials.password : null, - createBufferSegment(dto.toBuffer())); - }; - - ConnectToPersistentSubscriptionOperation.prototype._inspectPackage = function(pkg) { - if (pkg.command == TcpCommand.PersistentSubscriptionConfirmation) - { - var dto = ClientMessage.PersistentSubscriptionConfirmation.decode(pkg.data.toBuffer()); - this._confirmSubscription(dto.last_commit_position, dto.last_event_number); - this._subscriptionId = dto.subscription_id; - return new InspectionResult(InspectionDecision.Subscribed, "SubscriptionConfirmation"); - } - if (pkg.command == TcpCommand.PersistentSubscriptionStreamEventAppeared) - { - var dto = ClientMessage.PersistentSubscriptionStreamEventAppeared.decode(pkg.data.toBuffer()); - this._onEventAppeared(new results.ResolvedEvent(dto.event)); - return new InspectionResult(InspectionDecision.DoNothing, "StreamEventAppeared"); - } - if (pkg.command == TcpCommand.SubscriptionDropped) - { - var dto = ClientMessage.SubscriptionDropped.decode(pkg.data.toBuffer()); - if (dto.reason == ClientMessage.SubscriptionDropped.SubscriptionDropReason.AccessDenied) - { - this.dropSubscription(SubscriptionDropReason.AccessDenied, new Error("You do not have access to the stream.")); - return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); - } - if (dto.reason == ClientMessage.SubscriptionDropped.SubscriptionDropReason.NotFound) - { - this.dropSubscription(SubscriptionDropReason.NotFound, new Error("Subscription not found")); - return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); - } - if (dto.reason == ClientMessage.SubscriptionDropped.SubscriptionDropReason.PersistentSubscriptionDeleted) - { - this.dropSubscription(SubscriptionDropReason.PersistentSubscriptionDeleted, new Error("Persistent subscription deleted.")); - return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); - } - if (dto.reason == ClientMessage.SubscriptionDropped.SubscriptionDropReason.SubscriberMaxCountReached) - { - this.dropSubscription(SubscriptionDropReason.MaxSubscribersReached, new Error("Maximum subscribers reached.")); - return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); - } - this.dropSubscription(SubscriptionDropReason.UserInitiated, null, this._getConnection()); - return new InspectionResult(InspectionDecision.EndOperation, "SubscriptionDropped"); - } - return null; - }; - - ConnectToPersistentSubscriptionOperation.prototype._createSubscriptionObject = function(lastCommitPosition, lastEventNumber) { - return new PersistentEventStoreSubscription(this, this._streamId, lastCommitPosition, lastEventNumber); - }; - - ConnectToPersistentSubscriptionOperation.prototype.notifyEventsProcessed = function(processedEvents) { - ensure.notNull(processedEvents, "processedEvents"); - var dto = new ClientMessage.PersistentSubscriptionAckEvents({ - subscription_id: this._subscriptionId, - processed_event_ids: processedEvents.map(function (x) { - return new Buffer(uuid.parse(x)); - }) - }); - - var pkg = new TcpPackage(TcpCommand.PersistentSubscriptionAckEvents, - this._userCredentials !== null ? TcpFlags.Authenticated : TcpFlags.None, - this._correlationId, - this._userCredentials !== null ? this._userCredentials.username : null, - this._userCredentials !== null ? this._userCredentials.password : null, - createBufferSegment(dto.encode().toBuffer())); - this._enqueueSend(pkg); - }; - - ConnectToPersistentSubscriptionOperation.prototype.notifyEventsFailed = function(processedEvents, action, reason) { - ensure.notNull(processedEvents, "processedEvents"); - ensure.notNull(reason, "reason"); - var dto = new ClientMessage.PersistentSubscriptionNakEvents( - this._subscriptionId, - processedEvents.map(function(x) { return new Buffer(uuid.parse(x)); }), - reason, - action); - - var pkg = new TcpPackage(TcpCommand.PersistentSubscriptionNakEvents, - this._userCredentials != null ? TcpFlags.Authenticated : TcpFlags.None, - this._correlationId, - this._userCredentials != null ? this._userCredentials.username : null, - this._userCredentials != null ? this._userCredentials.password : null, - createBufferSegment(dto.toBuffer())); - this._enqueueSend(pkg); - }; - - module.exports = ConnectToPersistentSubscriptionOperation; - - -/***/ }, -/* 33 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - var EventStoreSubscription = __webpack_require__(31); - - - function PersistentEventStoreSubscription(subscriptionOperation, streamId, lastCommitPosition, lastEventNumber) { - EventStoreSubscription.call(this, streamId, lastCommitPosition, lastEventNumber); - - this._subscriptionOperation = subscriptionOperation; - } - util.inherits(PersistentEventStoreSubscription, EventStoreSubscription); - - PersistentEventStoreSubscription.prototype.unsubscribe = function() { - this._subscriptionOperation.unsubscribe(); - }; - - PersistentEventStoreSubscription.prototype.notifyEventsProcessed = function(processedEvents) { - this._subscriptionOperation.notifyEventsProcessed(processedEvents); - }; - - PersistentEventStoreSubscription.prototype.notifyEventsFailed = function(processedEvents, action, reason) { - this._subscriptionOperation.notifyEventsFailed(processedEvents, action, reason); - }; - - module.exports = PersistentEventStoreSubscription; - - -/***/ }, -/* 34 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(38); - - - function DeleteStreamOperation(log, cb, requireMaster, stream, expectedVersion, hardDelete, userCredentials) { - OperationBase.call(this, log, cb, TcpCommand.DeleteStream, TcpCommand.DeleteStreamCompleted, userCredentials); - this._responseType = ClientMessage.DeleteStreamCompleted; - - this._requireMaster = requireMaster; - this._stream = stream; - this._expectedVersion = expectedVersion; - this._hardDelete = hardDelete; - } - util.inherits(DeleteStreamOperation, OperationBase); - - DeleteStreamOperation.prototype._createRequestDto = function() { - return new ClientMessage.DeleteStream(this._stream, this._expectedVersion, this._requireMaster, this._hardDelete); - }; - - DeleteStreamOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.OperationResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.OperationResult.PrepareTimeout: - return new InspectionResult(InspectionDecision.Retry, "PrepareTimeout"); - case ClientMessage.OperationResult.CommitTimeout: - return new InspectionResult(InspectionDecision.Retry, "CommitTimeout"); - case ClientMessage.OperationResult.ForwardTimeout: - return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); - case ClientMessage.OperationResult.WrongExpectedVersion: - this.fail(new WrongExpectedVersionError("Delete", this._stream, this._expectedVersion)); - return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion"); - case ClientMessage.OperationResult.StreamDeleted: - 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 AccessDeniedError("Delete", this._stream)); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error(util.format("Unexpected OperationResult: %d.", response.result)); - } - }; - - DeleteStreamOperation.prototype._transformResponse = function(response) { - return new results.DeleteResult(new results.Position(response.prepare_position || -1, response.commit_position || -1)); - }; - - DeleteStreamOperation.prototype.toString = function() { - return util.format("Stream: %s, ExpectedVersion: %s.", this._stream, this._expectedVersion); - }; - - module.exports = DeleteStreamOperation; - -/***/ }, -/* 35 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var Long = __webpack_require__(5); - - function WrongExpectedVersionError(action, streamOrTransactionId, expectedVersion) { - Error.captureStackTrace(this, this.constructor); - this.name = this.constructor.name; - this.action = action; - 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; - -/***/ }, -/* 36 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var Long = __webpack_require__(5); - - function StreamDeletedError(streamOrTransactionId) { - Error.captureStackTrace(this, this.constructor); - this.name = this.constructor.name; - 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; - -/***/ }, -/* 37 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var Long = __webpack_require__(5); - - function AccessDeniedError(action, streamOrTransactionId) { - Error.captureStackTrace(this, this.constructor); - this.name = this.constructor.name; - this.action = action; - 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; - -/***/ }, -/* 38 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - 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; - this._cb = cb; - this._requestCommand = requestCommand; - this._responseCommand = responseCommand; - this.userCredentials = userCredentials; - - this._completed = false; - this._response = null; - - this._responseType = null; - } - - OperationBase.prototype._createRequestDto = function() { - throw new Error('_createRequestDto not implemented.'); - }; - - OperationBase.prototype._inspectResponse = function() { - throw new Error('_inspectResponse not implemented.'); - }; - - OperationBase.prototype._transformResponse = function() { - throw new Error('_transformResponse not implemented.'); - }; - - OperationBase.prototype.fail = function(error) { - this._completed = true; - this._cb(error); - }; - - OperationBase.prototype._succeed = function() { - if (!this._completed) { - this._completed = true; - - if (this._response != null) - this._cb(null, this._transformResponse(this._response)); - else - this._cb(new Error("No result.")) - } - }; - - OperationBase.prototype.createNetworkPackage = function(correlationId) { - var dto = this._createRequestDto(); - var buf = dto.toBuffer(); - return new TcpPackage( - this._requestCommand, - this.userCredentials ? TcpFlags.Authenticated : TcpFlags.None, - correlationId, - this.userCredentials ? this.userCredentials.username : null, - this.userCredentials ? this.userCredentials.password : null, - createBufferSegment(buf)); - }; - - OperationBase.prototype.inspectPackage = function(pkg) { - try { - if (pkg.command === this._responseCommand) { - this._response = this._responseType.decode(pkg.data.toBuffer()); - return this._inspectResponse(this._response); - } - switch (pkg.command) { - case TcpCommand.NotAuthenticated: - return this._inspectNotAuthenticated(pkg); - case TcpCommand.BadRequest: - return this._inspectBadRequest(pkg); - case TcpCommand.NotHandled: - return this._inspectNotHandled(pkg); - default: - return this._inspectUnexpectedCommand(package, this._responseCommand); - } - } catch(e) { - this.fail(e); - return new InspectionResult(InspectionDecision.EndOperation, "Error - " + e.message); - } - }; - - OperationBase.prototype._inspectNotAuthenticated = function(pkg) - { - var message = ''; - try { - message = pkg.data.toString(); - } catch(e) {} - //TODO typed error - this.fail(new Error("Authentication error: " + message)); - return new InspectionResult(InspectionDecision.EndOperation, "NotAuthenticated"); - }; - - OperationBase.prototype._inspectBadRequest = function(pkg) - { - var message = ''; - try { - message = pkg.data.toString(); - } catch(e) {} - //TODO typed error - this.fail(new Error("Bad request: " + message)); - return new InspectionResult(InspectionDecision.EndOperation, "BadRequest - " + message); - }; - - OperationBase.prototype._inspectNotHandled = function(pkg) - { - var message = ClientMessage.NotHandled.decode(pkg.data.toBuffer()); - switch (message.reason) - { - case ClientMessage.NotHandled.NotHandledReason.NotReady: - return new InspectionResult(InspectionDecision.Retry, "NotHandled - NotReady"); - - case ClientMessage.NotHandled.NotHandledReason.TooBusy: - return new InspectionResult(InspectionDecision.Retry, "NotHandled - TooBusy"); - - case ClientMessage.NotHandled.NotHandledReason.NotMaster: - var masterInfo = ClientMessage.NotHandled.MasterInfo.decode(message.additional_info); - return new new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster", - {host: masterInfo.external_tcp_address, port: masterInfo.external_tcp_port}, - {host: masterInfo.external_secure_tcp_address, port: masterInfo.external_secure_tcp_port}); - - default: - this.log.error("Unknown NotHandledReason: %s.", message.reason); - return new InspectionResult(InspectionDecision.Retry, "NotHandled - "); - } - }; - - OperationBase.prototype._inspectUnexpectedCommand = function(pkg, expectedCommand) - { - if (pkg.command == expectedCommand) - throw new Error("Command shouldn't be " + TcpCommand.getName(pkg.command)); - - this.log.error("Unexpected TcpCommand received.\n" - + "Expected: %s, Actual: %s, Flags: %s, CorrelationId: %s\n" - + "Operation (%s): %s\n" - +"TcpPackage Data Dump:\n%j", - expectedCommand, TcpCommand.getName(pkg.command), pkg.flags, pkg.correlationId, - this.constructor.name, this, pkg.data); - - this.fail(new Error(util.format("Unexpected command. Expecting %s got %s.", TcpCommand.getName(expectedCommand), TcpCommand.getName(pkg.command)))); - return new InspectionResult(InspectionDecision.EndOperation, "Unexpected command - " + TcpCommand.getName(pkg.command)); - }; - - - module.exports = OperationBase; - - -/***/ }, -/* 39 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(35); - var StreamDeletedError = __webpack_require__(36); - var AccessDeniedError = __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); - this._responseType = ClientMessage.WriteEventsCompleted; - - this._requireMaster = requireMaster; - this._stream = stream; - this._expectedVersion = expectedVersion; - this._events = events; - } - util.inherits(AppendToStreamOperation, OperationBase); - - AppendToStreamOperation.prototype._createRequestDto = function() { - var dtos = this._events.map(function(ev) { - var eventId = new Buffer(uuid.parse(ev.eventId)); - return new ClientMessage.NewEvent({ - event_id: eventId, event_type: ev.type, - data_content_type: ev.isJson ? 1 : 0, metadata_content_type: 0, - data: ev.data, metadata: ev.metadata}); - }); - return new ClientMessage.WriteEvents({ - event_stream_id: this._stream, - expected_version: this._expectedVersion, - events: dtos, - require_master: this._requireMaster}); - }; - - AppendToStreamOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.OperationResult.Success: - if (this._wasCommitTimeout) - this.log.debug("IDEMPOTENT WRITE SUCCEEDED FOR %s.", this); - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.OperationResult.PrepareTimeout: - return new InspectionResult(InspectionDecision.Retry, "PrepareTimeout"); - case ClientMessage.OperationResult.ForwardTimeout: - return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); - case ClientMessage.OperationResult.CommitTimeout: - this._wasCommitTimeout = true; - return new InspectionResult(InspectionDecision.Retry, "CommitTimeout"); - case ClientMessage.OperationResult.WrongExpectedVersion: - this.fail(new WrongExpectedVersionError("Append", this._stream, this._expectedVersion)); - return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion"); - case ClientMessage.OperationResult.StreamDeleted: - 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 AccessDeniedError("Write", this._stream)); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error("Unexpected OperationResult: " + response.result); - } - }; - - AppendToStreamOperation.prototype._transformResponse = function(response) { - return new WriteResult(response.last_event_number, new Position(response.prepare_position || -1, response.commit_position || -1)); - }; - - AppendToStreamOperation.prototype.toString = function() { - return util.format("Stream: %s, ExpectedVersion: %d", this._stream, this._expectedVersion); - }; - - module.exports = AppendToStreamOperation; - - -/***/ }, -/* 40 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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 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); - this._responseType = ClientMessage.TransactionStartCompleted; - - this._requireMaster = requireMaster; - this._stream = stream; - this._expectedVersion = expectedVersion; - this._parentConnection = parentConnection; - } - util.inherits(StartTransactionOperation, OperationBase); - - StartTransactionOperation.prototype._createRequestDto = function() { - return new ClientMessage.TransactionStart(this._stream, this._expectedVersion, this._requireMaster); - }; - - StartTransactionOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.OperationResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.OperationResult.PrepareTimeout: - return new InspectionResult(InspectionDecision.Retry, "PrepareTimeout"); - case ClientMessage.OperationResult.CommitTimeout: - return new InspectionResult(InspectionDecision.Retry, "CommitTimeout"); - case ClientMessage.OperationResult.ForwardTimeout: - return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); - case ClientMessage.OperationResult.WrongExpectedVersion: - this.fail(new WrongExpectedVersionError("Start transaction", this._stream, this._expectedVersion)); - return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion"); - case ClientMessage.OperationResult.StreamDeleted: - 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 AccessDeniedError("Write", this._stream)); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); - } - }; - - StartTransactionOperation.prototype._transformResponse = function(response) { - return new EventStoreTransaction(response.transaction_id, this.userCredentials, this._parentConnection); - }; - - StartTransactionOperation.prototype.toString = function() { - return util.format("Stream: %s, ExpectedVersion: %d", this._stream, this._expectedVersion); - }; - - module.exports = StartTransactionOperation; - - -/***/ }, -/* 41 */ -/***/ function(module, exports) { - - /** - * @param {number} transactionId - * @param {UserCredentials} userCredentials - * @param {EventStoreNodeConnection} connection - * @constructor - * @property {number} transactionId - */ - function EventStoreTransaction(transactionId, userCredentials, connection) { - this._transactionId = transactionId; - this._userCredentials = userCredentials; - this._connection = connection; - - this._isCommitted = false; - this._isRolledBack = false; - - Object.defineProperties(this, { - transactionId: { - enumerable: true, get: function() { return this._transactionId; } - } - }); - } - - /** - * Commit (async) - * @returns {Promise.} - */ - EventStoreTransaction.prototype.commit = function() { - if (this._isRolledBack) throw new Error("Can't commit a rolledback transaction."); - if (this._isCommitted) throw new Error("Transaction is already committed."); - this._isCommitted = true; - return this._connection.commitTransaction(this, this._userCredentials); - }; - - /** - * Write events (async) - * @param {EventData|EventData[]} eventOrEvents - * @returns {Promise} - */ - 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"); - var events = Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents]; - return this._connection.transactionalWrite(this, events); - }; - - /** - * Rollback - */ - EventStoreTransaction.prototype.rollback = function() { - if (this._isCommitted) throw new Error("Transaction is already committed"); - this._isRolledBack = true; - }; - - module.exports = EventStoreTransaction; - -/***/ }, -/* 42 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(38); - - - function TransactionalWriteOperation(log, cb, requireMaster, transactionId, events, userCredentials) { - OperationBase.call(this, log, cb, TcpCommand.TransactionWrite, TcpCommand.TransactionWriteCompleted, userCredentials); - this._responseType = ClientMessage.TransactionWriteCompleted; - - this._requireMaster = requireMaster; - this._transactionId = transactionId; - this._events = events; - } - util.inherits(TransactionalWriteOperation, OperationBase); - - TransactionalWriteOperation.prototype._createRequestDto = function() { - var dtos = this._events.map(function(ev) { - var eventId = new Buffer(uuid.parse(ev.eventId)); - return new ClientMessage.NewEvent({ - event_id: eventId, event_type: ev.type, - data_content_type: ev.isJson ? 1 : 0, metadata_content_type: 0, - data: ev.data, metadata: ev.metadata}); - }); - return new ClientMessage.TransactionWrite(this._transactionId, dtos, this._requireMaster); - }; - - TransactionalWriteOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.OperationResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.OperationResult.PrepareTimeout: - return new InspectionResult(InspectionDecision.Retry, "PrepareTimeout"); - case ClientMessage.OperationResult.CommitTimeout: - return new InspectionResult(InspectionDecision.Retry, "CommitTimeout"); - case ClientMessage.OperationResult.ForwardTimeout: - return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); - case ClientMessage.OperationResult.AccessDenied: - 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)); - } - }; - - TransactionalWriteOperation.prototype._transformResponse = function(response) { - return null; - }; - - TransactionalWriteOperation.prototype.toString = function() { - return util.format("TransactionId: %s", this._transactionId); - }; - - module.exports = TransactionalWriteOperation; - - - -/***/ }, -/* 43 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(38); - - - function CommitTransactionOperation(log, cb, requireMaster, transactionId, userCredentials) { - OperationBase.call(this, log, cb, TcpCommand.TransactionCommit, TcpCommand.TransactionCommitCompleted, userCredentials); - this._responseType = ClientMessage.TransactionCommitCompleted; - - this._requireMaster = requireMaster; - this._transactionId = transactionId; - } - util.inherits(CommitTransactionOperation, OperationBase); - - CommitTransactionOperation.prototype._createRequestDto = function() { - return new ClientMessage.TransactionCommit(this._transactionId, this._requireMaster); - }; - - CommitTransactionOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.OperationResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.OperationResult.PrepareTimeout: - return new InspectionResult(InspectionDecision.Retry, "PrepareTimeout"); - case ClientMessage.OperationResult.CommitTimeout: - return new InspectionResult(InspectionDecision.Retry, "CommitTimeout"); - case ClientMessage.OperationResult.ForwardTimeout: - return new InspectionResult(InspectionDecision.Retry, "ForwardTimeout"); - case ClientMessage.OperationResult.WrongExpectedVersion: - this.fail(new WrongExpectedVersionError("Commit", this._transactionId)); - return new InspectionResult(InspectionDecision.EndOperation, "WrongExpectedVersion"); - case ClientMessage.OperationResult.StreamDeleted: - 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 AccessDeniedError("Write", this._transactionId)); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); - } - }; - - CommitTransactionOperation.prototype._transformResponse = function(response) { - var logPosition = new results.Position(response.prepare_position || -1, response.commit_position || -1); - return new results.WriteResult(response.last_event_number, logPosition); - }; - - CommitTransactionOperation.prototype.toString = function() { - return util.format("TransactionId: %s", this._transactionId); - }; - - module.exports = CommitTransactionOperation; - -/***/ }, -/* 44 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - 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__(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); - this._responseType = ClientMessage.ReadEventCompleted; - - this._stream = stream; - this._eventNumber = eventNumber; - this._resolveLinkTos = resolveLinkTos; - this._requireMaster = requireMaster; - } - util.inherits(ReadEventOperation, OperationBase); - - ReadEventOperation.prototype._createRequestDto = function() { - return new ClientMessage.ReadEvent(this._stream, this._eventNumber, this._resolveLinkTos, this._requireMaster); - }; - - ReadEventOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.ReadEventCompleted.ReadEventResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.ReadEventCompleted.ReadEventResult.NotFound: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "NotFound"); - case ClientMessage.ReadEventCompleted.ReadEventResult.NoStream: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "NoStream"); - case ClientMessage.ReadEventCompleted.ReadEventResult.StreamDeleted: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted"); - case ClientMessage.ReadEventCompleted.ReadEventResult.Error: - this.fail(new Error("Server error: " + response.error)); - return new InspectionResult(InspectionDecision.EndOperation, "Error"); - case ClientMessage.ReadEventCompleted.ReadEventResult.AccessDenied: - this.fail(new AccessDeniedError("Read", this._stream)); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error(util.format("Unexpected ReadEventResult: %s.", response.result)); - } - }; - - ReadEventOperation.prototype._transformResponse = function(response) { - return new results.EventReadResult(convert(response.result), this._stream, this._eventNumber, response.event); - }; - - - function convert(result) - { - switch (result) - { - case ClientMessage.ReadEventCompleted.ReadEventResult.Success: - return results.EventReadStatus.Success; - case ClientMessage.ReadEventCompleted.ReadEventResult.NotFound: - return results.EventReadStatus.NotFound; - case ClientMessage.ReadEventCompleted.ReadEventResult.NoStream: - return results.EventReadStatus.NoStream; - case ClientMessage.ReadEventCompleted.ReadEventResult.StreamDeleted: - return results.EventReadStatus.StreamDeleted; - default: - throw new Error(util.format("Unexpected ReadEventResult: %s.", result)); - } - } - - ReadEventOperation.prototype.toString = function() { - return util.format("Stream: %s, EventNumber: %s, ResolveLinkTo: %s, RequireMaster: %s", - this._stream, this._eventNumber, this._resolveLinkTos, this._requireMaster); - }; - - module.exports = ReadEventOperation; - - -/***/ }, -/* 45 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(37); - - var OperationBase = __webpack_require__(38); - - function ReadStreamEventsForwardOperation( - log, cb, stream, fromEventNumber, maxCount, resolveLinkTos, requireMaster, userCredentials - ) { - OperationBase.call(this, log, cb, TcpCommand.ReadStreamEventsForward, TcpCommand.ReadStreamEventsForwardCompleted, userCredentials); - this._responseType = ClientMessage.ReadStreamEventsCompleted; - - this._stream = stream; - this._fromEventNumber = fromEventNumber; - this._maxCount = maxCount; - this._resolveLinkTos = resolveLinkTos; - this._requireMaster = requireMaster; - } - util.inherits(ReadStreamEventsForwardOperation, OperationBase); - - ReadStreamEventsForwardOperation.prototype._createRequestDto = function() { - return new ClientMessage.ReadStreamEvents(this._stream, this._fromEventNumber, this._maxCount, this._resolveLinkTos, this._requireMaster); - }; - - ReadStreamEventsForwardOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.StreamDeleted: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted"); - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.NoStream: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "NoStream"); - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.Error: - this.fail(new Error("Server error: " + response.error)); - return new InspectionResult(InspectionDecision.EndOperation, "Error"); - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied: - this.fail(new AccessDeniedError("Read", this._stream)); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result)); - } - }; - - ReadStreamEventsForwardOperation.prototype._transformResponse = function(response) { - return new results.StreamEventsSlice( - StatusCode.convert(response.result), - this._stream, - this._fromEventNumber, - ReadDirection.Forward, - response.events, - response.next_event_number, - response.last_event_number, - response.is_end_of_stream - ) - }; - - ReadStreamEventsForwardOperation.prototype.toString = function() { - return util.format("Stream: %s, FromEventNumber: %d, MaxCount: %d, ResolveLinkTos: %s, RequireMaster: %s", - this._stream, this._fromEventNumber, this._maxCount, this._resolveLinkTos, this._requireMaster); - }; - - module.exports = ReadStreamEventsForwardOperation; - - -/***/ }, -/* 46 */ -/***/ function(module, exports) { - - const ReadDirection = { - Forward: 'forward', - Backward: 'backward' - }; - - module.exports = ReadDirection; - - -/***/ }, -/* 47 */ -/***/ function(module, exports, __webpack_require__) { - - var ClientMessage = __webpack_require__(29); - var SliceReadStatus = __webpack_require__(48); - - module.exports = {}; - - module.exports.convert = function(code) { - switch(code) { - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.Success: - return SliceReadStatus.Success; - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.NoStream: - return SliceReadStatus.StreamNotFound; - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.StreamDeleted: - return SliceReadStatus.StreamDeleted; - default: - throw new Error('Invalid code: ' + code) - } - }; - -/***/ }, -/* 48 */ -/***/ function(module, exports) { - - const SliceReadStatus = { - Success: 'success', - StreamNotFound: 'streamNotFound', - StreamDeleted: 'streamDeleted' - }; - - module.exports = SliceReadStatus; - - -/***/ }, -/* 49 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(37); - - var OperationBase = __webpack_require__(38); - - function ReadStreamEventsBackwardOperation( - log, cb, stream, fromEventNumber, maxCount, resolveLinkTos, requireMaster, userCredentials - ) { - OperationBase.call(this, log, cb, TcpCommand.ReadStreamEventsBackward, TcpCommand.ReadStreamEventsBackwardCompleted, userCredentials); - this._responseType = ClientMessage.ReadStreamEventsCompleted; - - this._stream = stream; - this._fromEventNumber = fromEventNumber; - this._maxCount = maxCount; - this._resolveLinkTos = resolveLinkTos; - this._requireMaster = requireMaster; - } - util.inherits(ReadStreamEventsBackwardOperation, OperationBase); - - ReadStreamEventsBackwardOperation.prototype._createRequestDto = function() { - return new ClientMessage.ReadStreamEvents(this._stream, this._fromEventNumber, this._maxCount, this._resolveLinkTos, this._requireMaster); - }; - - ReadStreamEventsBackwardOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.StreamDeleted: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "StreamDeleted"); - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.NoStream: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "NoStream"); - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.Error: - this.fail(new Error("Server error: " + response.error)); - return new InspectionResult(InspectionDecision.EndOperation, "Error"); - case ClientMessage.ReadStreamEventsCompleted.ReadStreamResult.AccessDenied: - this.fail(new AccessDeniedError("Read", this._stream)); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result)); - } - }; - - ReadStreamEventsBackwardOperation.prototype._transformResponse = function(response) { - return new results.StreamEventsSlice( - StatusCode.convert(response.result), - this._stream, - this._fromEventNumber, - ReadDirection.Backward, - response.events, - response.next_event_number, - response.last_event_number, - response.is_end_of_stream - ) - }; - - ReadStreamEventsBackwardOperation.prototype.toString = function() { - return util.format("Stream: %s, FromEventNumber: %d, MaxCount: %d, ResolveLinkTos: %s, RequireMaster: %s", - this._stream, this._fromEventNumber, this._maxCount, this._resolveLinkTos, this._requireMaster); - }; - - module.exports = ReadStreamEventsBackwardOperation; - - -/***/ }, -/* 50 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(37); - - var OperationBase = __webpack_require__(38); - - function ReadAllEventsForwardOperation( - log, cb, position, maxCount, resolveLinkTos, requireMaster, userCredentials - ) { - OperationBase.call(this, log, cb, TcpCommand.ReadAllEventsForward, TcpCommand.ReadAllEventsForwardCompleted, userCredentials); - this._responseType = ClientMessage.ReadAllEventsCompleted; - - this._position = position; - this._maxCount = maxCount; - this._resolveLinkTos = resolveLinkTos; - this._requireMaster = requireMaster; - } - util.inherits(ReadAllEventsForwardOperation, OperationBase); - - ReadAllEventsForwardOperation.prototype._createRequestDto = function() { - return new ClientMessage.ReadAllEvents(this._position.commitPosition, this._position.preparePosition, this._maxCount, this._resolveLinkTos, this._requireMaster); - }; - - ReadAllEventsForwardOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.ReadAllEventsCompleted.ReadAllResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.ReadAllEventsCompleted.ReadAllResult.Error: - this.fail(new Error("Server error: " + response.error)); - return new InspectionResult(InspectionDecision.EndOperation, "Error"); - case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied: - this.fail(new AccessDeniedError("Read", "$all")); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result)); - } - }; - - ReadAllEventsForwardOperation.prototype._transformResponse = function(response) { - return new results.AllEventsSlice( - ReadDirection.Forward, - new results.Position(response.commit_position, response.prepare_position), - new results.Position(response.next_commit_position, response.next_prepare_position), - response.events - ) - }; - - ReadAllEventsForwardOperation.prototype.toString = function() { - return util.format("Position: %j, MaxCount: %d, ResolveLinkTos: %s, RequireMaster: %s", - this._position, this._maxCount, this._resolveLinkTos, this._requireMaster); - }; - - module.exports = ReadAllEventsForwardOperation; - - -/***/ }, -/* 51 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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__(37); - - var OperationBase = __webpack_require__(38); - - function ReadAllEventsBackwardOperation( - log, cb, position, maxCount, resolveLinkTos, requireMaster, userCredentials - ) { - OperationBase.call(this, log, cb, TcpCommand.ReadAllEventsBackward, TcpCommand.ReadAllEventsBackwardCompleted, userCredentials); - this._responseType = ClientMessage.ReadAllEventsCompleted; - - this._position = position; - this._maxCount = maxCount; - this._resolveLinkTos = resolveLinkTos; - this._requireMaster = requireMaster; - } - util.inherits(ReadAllEventsBackwardOperation, OperationBase); - - ReadAllEventsBackwardOperation.prototype._createRequestDto = function() { - return new ClientMessage.ReadAllEvents(this._position.commitPosition, this._position.preparePosition, this._maxCount, this._resolveLinkTos, this._requireMaster); - }; - - ReadAllEventsBackwardOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.ReadAllEventsCompleted.ReadAllResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.ReadAllEventsCompleted.ReadAllResult.Error: - this.fail(new Error("Server error: " + response.error)); - return new InspectionResult(InspectionDecision.EndOperation, "Error"); - case ClientMessage.ReadAllEventsCompleted.ReadAllResult.AccessDenied: - this.fail(new AccessDeniedError("Read", "$all")); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - default: - throw new Error(util.format("Unexpected ReadStreamResult: %s.", response.result)); - } - }; - - ReadAllEventsBackwardOperation.prototype._transformResponse = function(response) { - return new results.AllEventsSlice( - ReadDirection.Backward, - new results.Position(response.commit_position, response.prepare_position), - new results.Position(response.next_commit_position, response.next_prepare_position), - response.events - ) - }; - - ReadAllEventsBackwardOperation.prototype.toString = function() { - return util.format("Position: %j, MaxCount: %d, ResolveLinkTos: %s, RequireMaster: %s", - this._position, this._maxCount, this._resolveLinkTos, this._requireMaster); - }; - - module.exports = ReadAllEventsBackwardOperation; - - -/***/ }, -/* 52 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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); - - - function CreatePersistentSubscriptionOperation(log, cb, stream, groupName, settings, userCredentials) { - OperationBase.call(this, log, cb, TcpCommand.CreatePersistentSubscription, TcpCommand.CreatePersistentSubscriptionCompleted, userCredentials); - - ensure.notNull(settings, "settings"); - this._resolveLinkTos = settings.resolveLinkTos; - this._stream = stream; - this._groupName = groupName; - this._startFromBeginning = settings.startFrom; - this._maxRetryCount = settings.maxRetryCount; - this._liveBufferSize = settings.liveBufferSize; - this._readBatchSize = settings.readBatchSize; - this._bufferSize = settings.historyBufferSize; - this._recordStatistics = settings.extraStatistics; - this._messageTimeoutMilliseconds = settings.messageTimeout; - this._checkPointAfter = settings.checkPointAfter; - this._minCheckPointCount = settings.minCheckPointCount; - this._maxCheckPointCount = settings.maxCheckPointCount; - this._maxSubscriberCount = settings.maxSubscriberCount; - this._namedConsumerStrategy = settings.namedConsumerStrategy; - - this._responseType = ClientMessage.CreatePersistentSubscriptionCompleted; - } - util.inherits(CreatePersistentSubscriptionOperation, OperationBase); - - CreatePersistentSubscriptionOperation.prototype._createRequestDto = function() { - return new ClientMessage.CreatePersistentSubscription(this._groupName, this._stream, this._resolveLinkTos, - this._startFromBeginning, this._messageTimeoutMilliseconds, this._recordStatistics, this._liveBufferSize, - this._readBatchSize, this._bufferSize, this._maxRetryCount, - this._namedConsumerStrategy == SystemConsumerStrategies.RoundRobin, this._checkPointAfter, - this._maxCheckPointCount, this._minCheckPointCount, this._maxSubscriberCount, this._namedConsumerStrategy); - }; - - CreatePersistentSubscriptionOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.CreatePersistentSubscriptionCompleted.CreatePersistentSubscriptionResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.CreatePersistentSubscriptionCompleted.CreatePersistentSubscriptionResult.Fail: - this.fail(new Error(util.format("Subscription group %s on stream %s failed '%s'", this._groupName, this._stream, response.reason))); - return new InspectionResult(InspectionDecision.EndOperation, "Fail"); - case ClientMessage.CreatePersistentSubscriptionCompleted.CreatePersistentSubscriptionResult.AccessDenied: - this.fail(new Error(util.format("Write access denied for stream '%s'.", this._stream))); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - case ClientMessage.CreatePersistentSubscriptionCompleted.CreatePersistentSubscriptionResult.AlreadyExists: - this.fail(new Error(util.format("Subscription group %s on stream %s already exists", this._groupName, this._stream))); - return new InspectionResult(InspectionDecision.EndOperation, "AlreadyExists"); - default: - throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); - } - }; - - CreatePersistentSubscriptionOperation.prototype._transformResponse = function(response) { - return new results.PersistentSubscriptionCreateResult(results.PersistentSubscriptionCreateStatus.Success); - }; - - CreatePersistentSubscriptionOperation.prototype.toString = function() { - return util.format("Stream: %s, Group Name: %s", this._stream, this._groupName); - }; - - module.exports = CreatePersistentSubscriptionOperation; - - -/***/ }, -/* 53 */ -/***/ function(module, exports) { - - const SystemConsumerStrategies = { - DispatchToSingle: 'DispatchToSingle', - RoundRobin: 'RoundRobin', - Pinned: 'Pinned' - }; - - module.exports = SystemConsumerStrategies; - - -/***/ }, -/* 54 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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); - - - function UpdatePersistentSubscriptionOperation(log, cb, stream, groupName, settings, userCredentials) { - OperationBase.call(this, log, cb, TcpCommand.UpdatePersistentSubscription, TcpCommand.UpdatePersistentSubscriptionCompleted, userCredentials); - - ensure.notNull(settings, "settings"); - this._resolveLinkTos = settings.resolveLinkTos; - this._stream = stream; - this._groupName = groupName; - this._startFromBeginning = settings.startFrom; - this._maxRetryCount = settings.maxRetryCount; - this._liveBufferSize = settings.liveBufferSize; - this._readBatchSize = settings.readBatchSize; - this._bufferSize = settings.historyBufferSize; - this._recordStatistics = settings.extraStatistics; - this._messageTimeoutMilliseconds = settings.messageTimeout; - this._checkPointAfter = settings.checkPointAfter; - this._minCheckPointCount = settings.minCheckPointCount; - this._maxCheckPointCount = settings.maxCheckPointCount; - this._maxSubscriberCount = settings.maxSubscriberCount; - this._namedConsumerStrategy = settings.namedConsumerStrategy; - - this._responseType = ClientMessage.UpdatePersistentSubscriptionCompleted; - } - util.inherits(UpdatePersistentSubscriptionOperation, OperationBase); - - UpdatePersistentSubscriptionOperation.prototype._createRequestDto = function() { - return new ClientMessage.UpdatePersistentSubscription(this._groupName, this._stream, this._resolveLinkTos, - this._startFromBeginning, this._messageTimeoutMilliseconds, this._recordStatistics, this._liveBufferSize, - this._readBatchSize, this._bufferSize, this._maxRetryCount, - this._namedConsumerStrategy == SystemConsumerStrategies.RoundRobin, this._checkPointAfter, - this._maxCheckPointCount, this._minCheckPointCount, this._maxSubscriberCount, this._namedConsumerStrategy); - }; - - UpdatePersistentSubscriptionOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.UpdatePersistentSubscriptionCompleted.UpdatePersistentSubscriptionResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.UpdatePersistentSubscriptionCompleted.UpdatePersistentSubscriptionResult.Fail: - this.fail(new Error(util.format("Subscription group %s on stream %s failed '%s'", this._groupName, this._stream, response.reason))); - return new InspectionResult(InspectionDecision.EndOperation, "Fail"); - case ClientMessage.UpdatePersistentSubscriptionCompleted.UpdatePersistentSubscriptionResult.AccessDenied: - this.fail(new Error(util.format("Write access denied for stream '%s'.", this._stream))); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - case ClientMessage.UpdatePersistentSubscriptionCompleted.UpdatePersistentSubscriptionResult.DoesNotExist: - this.fail(new Error(util.format("Subscription group %s on stream %s does not exist", this._groupName, this._stream))); - return new InspectionResult(InspectionDecision.EndOperation, "DoesNotExist"); - default: - throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); - } - }; - - UpdatePersistentSubscriptionOperation.prototype._transformResponse = function(response) { - return new results.PersistentSubscriptionUpdateResult(results.PersistentSubscriptionUpdateStatus.Success); - }; - - UpdatePersistentSubscriptionOperation.prototype.toString = function() { - return util.format("Stream: %s, Group Name: %s", this._stream, this._groupName); - }; - - module.exports = UpdatePersistentSubscriptionOperation; - - -/***/ }, -/* 55 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var uuid = __webpack_require__(2); - - 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); - - - function DeletePersistentSubscriptionOperation(log, cb, stream, groupName, userCredentials) { - OperationBase.call(this, log, cb, TcpCommand.DeletePersistentSubscription, TcpCommand.DeletePersistentSubscriptionCompleted, userCredentials); - - this._stream = stream; - this._groupName = groupName; - - this._responseType = ClientMessage.DeletePersistentSubscriptionCompleted; - } - util.inherits(DeletePersistentSubscriptionOperation, OperationBase); - - DeletePersistentSubscriptionOperation.prototype._createRequestDto = function() { - return new ClientMessage.DeletePersistentSubscription(this._groupName, this._stream); - }; - - DeletePersistentSubscriptionOperation.prototype._inspectResponse = function(response) { - switch (response.result) - { - case ClientMessage.DeletePersistentSubscriptionCompleted.DeletePersistentSubscriptionResult.Success: - this._succeed(); - return new InspectionResult(InspectionDecision.EndOperation, "Success"); - case ClientMessage.DeletePersistentSubscriptionCompleted.DeletePersistentSubscriptionResult.Fail: - this.fail(new Error(util.format("Subscription group %s on stream %s failed '%s'", this._groupName, this._stream, response.reason))); - return new InspectionResult(InspectionDecision.EndOperation, "Fail"); - case ClientMessage.DeletePersistentSubscriptionCompleted.DeletePersistentSubscriptionResult.AccessDenied: - this.fail(new Error(util.format("Write access denied for stream '%s'.", this._stream))); - return new InspectionResult(InspectionDecision.EndOperation, "AccessDenied"); - case ClientMessage.DeletePersistentSubscriptionCompleted.DeletePersistentSubscriptionResult.DoesNotExist: - this.fail(new Error(util.format("Subscription group %s on stream %s does not exist", this._groupName, this._stream))); - return new InspectionResult(InspectionDecision.EndOperation, "DoesNotExist"); - default: - throw new Error(util.format("Unexpected OperationResult: %s.", response.result)); - } - }; - - DeletePersistentSubscriptionOperation.prototype._transformResponse = function(response) { - return new results.PersistentSubscriptionDeleteResult(results.PersistentSubscriptionDeleteStatus.Success); - }; - - DeletePersistentSubscriptionOperation.prototype.toString = function() { - return util.format("Stream: %s, Group Name: %s", this._stream, this._groupName); - }; - - module.exports = DeletePersistentSubscriptionOperation; - - -/***/ }, -/* 56 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - var EventStoreCatchUpSubscription = __webpack_require__(57); - var SliceReadStatus = __webpack_require__(48); - - function EventStoreStreamCatchUpSubscription( - connection, log, streamId, fromEventNumberExclusive, resolveLinkTos, userCredentials, - eventAppeared, liveProcessingStarted, subscriptionDropped, - verboseLogging, readBatchSize - ){ - EventStoreCatchUpSubscription.call(this, connection, log, streamId, resolveLinkTos, userCredentials, - eventAppeared, liveProcessingStarted, subscriptionDropped, - verboseLogging, readBatchSize); - - //Ensure.NotNullOrEmpty(streamId, "streamId"); - - this._lastProcessedEventNumber = fromEventNumberExclusive || -1; - this._nextReadEventNumber = fromEventNumberExclusive || 0; - } - util.inherits(EventStoreStreamCatchUpSubscription, EventStoreCatchUpSubscription); - - EventStoreStreamCatchUpSubscription.prototype._readEventsTill = function( - connection, resolveLinkTos, userCredentials, lastCommitPosition, lastEventNumber - ) { - var self = this; - - function processEvents(events, index) { - index = index || 0; - if (index >= events.length) return Promise.resolve(); - - return new Promise(function(resolve, reject) { - self._tryProcess(events[index]); - resolve(); - }) - .then(function() { - return processEvents(events, index + 1); - }); - } - - function readNext() { - return connection.readStreamEventsForward(self.streamId, self._nextReadEventNumber, self.readBatchSize, resolveLinkTos, userCredentials) - .then(function(slice) { - switch(slice.status) { - case SliceReadStatus.Success: - return processEvents(slice.events) - .then(function() { - self._nextReadEventNumber = slice.nextEventNumber; - var done = Promise.resolve(lastEventNumber === null ? slice.isEndOfStream : slice.nextEventNumber > lastEventNumber); - if (!done && slice.isEndOfStream) - return done.delay(10); - return done; - }); - break; - case SliceReadStatus.StreamNotFound: - if (lastEventNumber && lastEventNumber !== -1) - throw new Error(util.format("Impossible: stream %s disappeared in the middle of catching up subscription.", self.streamId)); - return true; - case SliceReadStatus.StreamDeleted: - throw new Error("Stream deleted: " + self.streamId); - default: - throw new Error("Unexpected StreamEventsSlice.Status: %s.", slice.status); - } - }) - .then(function(done) { - if (done || self._shouldStop) - return; - return readNext(); - }) - } - return readNext() - .then(function() { - if (self._verbose) - self._log.debug("Catch-up Subscription to %s: finished reading events, nextReadEventNumber = %d.", - self.isSubscribedToAll ? '' : self.streamId, self._nextReadEventNumber); - }); - }; - - EventStoreStreamCatchUpSubscription.prototype._tryProcess = function(e) { - var processed = false; - if (e.originalEventNumber > this._lastProcessedEventNumber) { - this._eventAppeared(this, e); - this._lastProcessedEventNumber = e.originalEventNumber; - processed = true; - } - if (this._verbose) - this._log.debug("Catch-up Subscription to %s: %s event (%s, %d, %s @ %d).", - this.isSubscribedToAll ? '' : this.streamId, processed ? "processed" : "skipping", - e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, e.originalEventNumber) - }; - - - module.exports = EventStoreStreamCatchUpSubscription; - - -/***/ }, -/* 57 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - var SubscriptionDropReason = __webpack_require__(24); - var results = __webpack_require__(3); - - const DefaultReadBatchSize = 500; - const DefaultMaxPushQueueSize = 10000; - const MaxReadSize = 4096; - - function DropSubscriptionEvent() {} - - /** - * @param connection - * @param log - * @param streamId - * @param resolveLinkTos - * @param userCredentials - * @param eventAppeared - * @param liveProcessingStarted - * @param subscriptionDropped - * @param verboseLogging - * @param readBatchSize - * @param maxPushQueueSize - * @constructor - * @property {boolean} isSubscribedToAll - * @property {string} streamId - * @property {number} readBatchSize - * @property {number} maxPushQueueSize - */ - function EventStoreCatchUpSubscription( - connection, log, streamId, resolveLinkTos, userCredentials, - eventAppeared, liveProcessingStarted, subscriptionDropped, - verboseLogging, readBatchSize, maxPushQueueSize - ) { - readBatchSize = readBatchSize || DefaultReadBatchSize; - maxPushQueueSize = maxPushQueueSize || DefaultMaxPushQueueSize; - //Ensure.NotNull(connection, "connection"); - //Ensure.NotNull(log, "log"); - //Ensure.NotNull(eventAppeared, "eventAppeared"); - //Ensure.Positive(readBatchSize, "readBatchSize"); - //Ensure.Positive(maxPushQueueSize, "maxPushQueueSize"); - if (readBatchSize > MaxReadSize) throw new Error(util.format("Read batch size should be less than %d. For larger reads you should page.", MaxReadSize)); - - this._connection = connection; - this._log = log; - this._streamId = streamId || ''; - this._resolveLinkTos = resolveLinkTos; - this._userCredentials = userCredentials; - this._shouldStop = false; - this._stopped = false; - this._isDropped = false; - this._subscription = null; - this._liveQueue = []; - this._dropData = null; - this._isProcessing = false; - - Object.defineProperties(this, { - isSubscribedToAll: { value: this._streamId === '' }, - streamId: { value: this._streamId }, - readBatchSize: { value: readBatchSize }, - maxPushQueueSize: { value: maxPushQueueSize } - }); - - this._eventAppeared = eventAppeared; - this._liveProcessingStarted = liveProcessingStarted; - this._subscriptionDropped = subscriptionDropped; - this._verbose = verboseLogging; - - var self = this; - this._onReconnect = function() { - if (self._verbose) self._log.debug("Catch-up Subscription to %s: recovering after reconnection.", self._streamId || ''); - if (self._verbose) self._log.debug("Catch-up Subscription to %s: unhooking from connection.Connected.", self._streamId || ''); - self._connection.removeListener('connected', self._onReconnect); - self._runSubscription(); - } - } - - /** - * @param {EventStoreNodeConnection} connection - * @param {boolean} resolveLinkTos - * @param {UserCredentials} userCredentials - * @param {?number} lastCommitPosition - * @param {?number} lastEventNumber - * @private - * @abstract - */ - EventStoreCatchUpSubscription.prototype._readEventsTill = function( - connection, resolveLinkTos, userCredentials, lastCommitPosition, lastEventNumber - ) { - throw new Error("EventStoreCatchUpSubscription._readEventsTill abstract method called. " + this.constructor.name); - }; - - /** - * @param {ResolvedEvent} e - * @private - * @abstract - */ - EventStoreCatchUpSubscription.prototype._tryProcess = function(e) { - throw new Error("EventStoreCatchUpSubscription._tryProcess abstract method called. " + this.constructor.name); - }; - - EventStoreCatchUpSubscription.prototype.start = function() { - if (this._verbose) this._log.debug("Catch-up Subscription to %s: starting...", this._streamId || ''); - this._runSubscription(); - }; - - EventStoreCatchUpSubscription.prototype.stop = function() { - if (this._verbose) this._log.debug("Catch-up Subscription to %s: requesting stop...", this._streamId || ''); - - if (this._verbose) this._log.debug("Catch-up Subscription to %s: unhooking from connection.Connected.", this._streamId || ''); - this._connection.removeListener('connected', this._onReconnect); - - this._shouldStop = true; - this._enqueueSubscriptionDropNotification(SubscriptionDropReason.UserInitiated, null); - /* - if (timeout) { - if (this._verbose) this._log.debug("Waiting on subscription to stop"); - if (!this._stopped.Wait(timeout)) - throw new TimeoutException(string.Format("Could not stop {0} in time.", GetType().Name)); - } - */ - }; - - EventStoreCatchUpSubscription.prototype._runSubscription = function() { - var logStreamName = this._streamId || ''; - - if (this._verbose) this._log.debug("Catch-up Subscription to %s: running...", logStreamName); - - var self = this; - this._stopped = false; - if (this._verbose) this._log.debug("Catch-up Subscription to %s: pulling events...", logStreamName); - this._readEventsTill(this._connection, this._resolveLinkTos, this._userCredentials, null, null) - .then(function() { - if (self._shouldStop) return; - if (self._verbose) self._log.debug("Catch-up Subscription to %s: subscribing...", logStreamName); - if (self._streamId === '') - return self._connection.subscribeToAll(self._resolveLinkTos, self._enqueuePushedEvent.bind(self), self._serverSubscriptionDropped.bind(self), self._userCredentials); - else - return self._connection.subscribeToStream(self._streamId, self._resolveLinkTos, self._enqueuePushedEvent.bind(self), self._serverSubscriptionDropped.bind(self), self._userCredentials); - }) - .then(function(subscription) { - if (subscription === undefined) return; - if (self._verbose) self._log.debug("Catch-up Subscription to %s: pulling events (if left)...", logStreamName); - self._subscription = subscription; - return self._readEventsTill(self._connection, self._resolveLinkTos, self._userCredentials, subscription.lastCommitPosition, subscription.lastEventNumber) - }) - .catch(function(err) { - self._dropSubscription(SubscriptionDropReason.CatchUpError, err); - return true; - }) - .then(function(faulted) { - if (faulted) return; - if (self._shouldStop) { - self._dropSubscription(SubscriptionDropReason.UserInitiated, null); - return; - } - if (self._verbose) self._log.debug("Catch-up Subscription to %s: processing live events...", logStreamName); - if (self._liveProcessingStarted) - try { - self._liveProcessingStarted(self); - } catch(e) { - self._log.error(e, "Catch-up Subscription to %s: liveProcessingStarted callback failed.", logStreamName); - } - if (self._verbose) self._log.debug("Catch-up Subscription to %s: hooking to connection.Connected", logStreamName); - self._connection.on('connected', self._onReconnect); - self._allowProcessing = true; - self._ensureProcessingPushQueue(); - }); - }; - - EventStoreCatchUpSubscription.prototype._enqueuePushedEvent = function(subscription, e) { - if (this._verbose) - this._log.debug("Catch-up Subscription to %s: event appeared (%s, %d, %s @ %s).", - this._streamId || '', - e.originalStreamId, e.originalEventNumber, e.originalEvent.eventType, e.originalPosition); - - if (this._liveQueue.length >= this.maxPushQueueSize) - { - this._enqueueSubscriptionDropNotification(SubscriptionDropReason.ProcessingQueueOverflow, null); - subscription.unsubscribe(); - return; - } - - this._liveQueue.push(e); - - if (this._allowProcessing) - this._ensureProcessingPushQueue(); - }; - - EventStoreCatchUpSubscription.prototype._serverSubscriptionDropped = function(subscription, reason, err) { - this._enqueueSubscriptionDropNotification(reason, err); - }; - - EventStoreCatchUpSubscription.prototype._enqueueSubscriptionDropNotification = function(reason, error) { - // if drop data was already set -- no need to enqueue drop again, somebody did that already - if (this._dropData) return; - this._dropData = {reason: reason, error: error}; - this._liveQueue.push(new DropSubscriptionEvent()); - if (this._allowProcessing) - this._ensureProcessingPushQueue(); - }; - - EventStoreCatchUpSubscription.prototype._ensureProcessingPushQueue = function() { - if (this._isProcessing) return; - - this._isProcessing = true; - setImmediate(this._processLiveQueue.bind(this)); - }; - - EventStoreCatchUpSubscription.prototype._processLiveQueue = function() { - var ev = this._liveQueue.shift(); - //TODO: possible blocking while, use when - while(ev) { - if (ev instanceof DropSubscriptionEvent) { - if (!this._dropData) this._dropData = {reason: SubscriptionDropReason.Unknown, error: new Error("Drop reason not specified.")}; - this._dropSubscription(this._dropData.reason, this._dropData.error); - this._isProcessing = false; - return; - } - - try { - this._tryProcess(ev); - } - catch(err) { - this._dropSubscription(SubscriptionDropReason.EventHandlerException, err); - return; - } - ev = this._liveQueue.shift(); - } - - this._isProcessing = false; - }; - - EventStoreCatchUpSubscription.prototype._dropSubscription = function(reason, error) { - if (this._isDropped) return; - - this._isDropped = true; - if (this._verbose) - this._log.debug("Catch-up Subscription to %s: dropping subscription, reason: %s %s.", - this._streamId || '', reason, error); - - if (this._subscription) - this._subscription.unsubscribe(); - if (this._subscriptionDropped) - try { - this._subscriptionDropped(this, reason, error); - } catch(e) { - this._log.error(e, "Catch-up Subscription to %s: subscriptionDropped callback failed.", this._streamId || ''); - } - this._stopped = true; - }; - - module.exports = EventStoreCatchUpSubscription; - -/***/ }, -/* 58 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - var EventStoreCatchUpSubscription = __webpack_require__(57); - var results = __webpack_require__(3); - - - function EventStoreAllCatchUpSubscription( - connection, log, fromPositionExclusive, resolveLinkTos, userCredentials, - eventAppeared, liveProcessingStarted, subscriptionDropped, - verboseLogging, readBatchSize - ) { - EventStoreCatchUpSubscription.call(this, connection, log, '', resolveLinkTos, userCredentials, - eventAppeared, liveProcessingStarted, subscriptionDropped, - verboseLogging, readBatchSize); - - this._lastProcessedPosition = fromPositionExclusive || new results.Position(-1,-1); - this._nextReadPosition = fromPositionExclusive || new results.Position(0,0); - } - util.inherits(EventStoreAllCatchUpSubscription, EventStoreCatchUpSubscription); - - EventStoreAllCatchUpSubscription.prototype._readEventsTill = function( - connection, resolveLinkTos, userCredentials, lastCommitPosition, lastEventNumber - ) { - var self = this; - - function processEvents(events, index) { - index = index || 0; - if (index >= events.length) return Promise.resolve(); - if (events[index].originalPosition === null) throw new Error("Subscription event came up with no OriginalPosition."); - - return new Promise(function(resolve, reject) { - self._tryProcess(events[index]); - resolve(); - }) - .then(function() { - return processEvents(events, index + 1); - }); - } - - function readNext() { - return connection.readAllEventsForward(self._nextReadPosition, self.readBatchSize, resolveLinkTos, userCredentials) - .then(function(slice) { - return processEvents(slice.events) - .then(function() { - self._nextReadPosition = slice.nextPosition; - var done = lastCommitPosition === null - ? slice.isEndOfStream - : slice.nextPosition.compareTo(new results.Position(lastCommitPosition, lastCommitPosition)) >= 0; - if (!done && slice.isEndOfStream) - return Promise.resolve(done).delay(10); - return Promise.resolve(done); - }); - }) - .then(function(done) { - if (done || self._shouldStop) - return; - return readNext(); - }); - } - - return readNext() - .then(function() { - if (self._verbose) - self._log.debug("Catch-up Subscription to %s: finished reading events, nextReadPosition = %s.", - self.isSubscribedToAll ? "" : self.streamId, self._nextReadPosition); - }); - }; - - - EventStoreAllCatchUpSubscription.prototype._tryProcess = function(e) { - var processed = false; - if (e.originalPosition.compareTo(this._lastProcessedPosition) > 0) - { - this._eventAppeared(this, e); - this._lastProcessedPosition = e.originalPosition; - processed = true; - } - if (this._verbose) - this._log.debug("Catch-up Subscription to %s: %s event (%s, %d, %s @ %s).", - this.streamId || '', processed ? "processed" : "skipping", - e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, e.originalPosition); - }; - - module.exports = EventStoreAllCatchUpSubscription; - - -/***/ }, -/* 59 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - - var EventStorePersistentSubscriptionBase = __webpack_require__(60); - var messages = __webpack_require__(10); - - function EventStorePersistentSubscription( - subscriptionId, streamId, eventAppeared, subscriptionDropped, userCredentials, log, verboseLogging, settings, - handler, bufferSize, autoAck - ) { - bufferSize = bufferSize === undefined ? 10 : bufferSize; - autoAck = autoAck === undefined ? true : !!autoAck; - - EventStorePersistentSubscriptionBase.call(this, subscriptionId, streamId, eventAppeared, subscriptionDropped, - userCredentials, log, verboseLogging, settings, bufferSize, autoAck); - - this._handler = handler; - } - util.inherits(EventStorePersistentSubscription, EventStorePersistentSubscriptionBase); - - EventStorePersistentSubscription.prototype._startSubscription = function( - subscriptionId, streamId, bufferSize, userCredentials, onEventAppeared, onSubscriptionDropped, settings - ) { - var self = this; - return new Promise(function(resolve, reject){ - function cb(err, result) { - if (err) return reject(err); - resolve(result); - } - self._handler.enqueueMessage(new messages.StartPersistentSubscriptionMessage(cb, subscriptionId, streamId, - bufferSize, userCredentials, onEventAppeared, onSubscriptionDropped, settings.maxRetries, - settings.operationTimeout)); - }); - }; - - module.exports = EventStorePersistentSubscription; - -/***/ }, -/* 60 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(4); - var ensure = __webpack_require__(6); - var PersistentSubscriptionNakEventAction = __webpack_require__(61); - var SubscriptionDropReason = __webpack_require__(24); - - function DropSubscriptionEvent() {} - - function EventStorePersistentSubscriptionBase( - subscriptionId, streamId, - eventAppeared, subscriptionDropped, - userCredentials, log, verboseLogging, settings, bufferSize, autoAck - ) { - bufferSize = bufferSize === undefined ? 10 : bufferSize; - autoAck = autoAck === undefined ? true : autoAck; - - this._subscriptionId = subscriptionId; - this._streamId = streamId; - this._eventAppeared = eventAppeared; - this._subscriptionDropped = subscriptionDropped; - this._userCredentials = userCredentials; - this._log = log; - this._verbose = verboseLogging; - this._settings = settings; - this._bufferSize = bufferSize; - this._autoAck = autoAck; - - this._subscription = null; - this._dropData = null; - this._queue = []; - this._isProcessing = false; - this._isDropped = false; - } - - EventStorePersistentSubscriptionBase.prototype.start = function() { - this._stopped = false; - - var self = this; - this._startSubscription(this._subscriptionId, this._streamId, this._bufferSize, this._userCredentials, - this._onEventAppeared.bind(this), this._onSubscriptionDropped.bind(this), this._settings) - .then(function(subscription) { - self._subscription = subscription; - }); - }; - - EventStorePersistentSubscriptionBase.prototype._startSubscription = function() { - throw new Error("EventStorePersistentSubscriptionBase._startSubscription abstract method called." + - this.constructor.name); - }; - - /** - * @param {ResolvedEvent[]|ResolvedEvent} events - */ - EventStorePersistentSubscriptionBase.prototype.acknowledge = function(events) { - ensure.notNull(events, "events"); - - if (this._subscription === null) throw new Error("Invalid operation. Subscription is not active yet."); - if (!Array.isArray(events)) - events = [events]; - var ids = events.map(function(x) { return x.originalEvent.eventId; }); - this._subscription.notifyEventsProcessed(ids); - }; - - /** - * @param {ResolvedEvent[]|ResolvedEvent} events - * @param {number} action One of PersistentSubscriptionNakEventAction - * @param {string} reason - */ - EventStorePersistentSubscriptionBase.prototype.fail = function(events, action, reason) { - ensure.notNull(events, "events"); - PersistentSubscriptionNakEventAction.isValid(action); - ensure.notNull(reason, "reason"); - - if (this._subscription === null) throw new Error("Invalid operation. Subscription is not active yet."); - if (!Array.isArray(events)) - events = [events]; - var ids = events.map(function(x) { return x.originalEvent.eventId; }); - this._subscription.notifyEventsFailed(ids, action, reason); - }; - - EventStorePersistentSubscriptionBase.prototype.stop = function() { - if (this._verbose) this._log.debug("Persistent Subscription to %s: requesting stop...", this._streamId); - this._enqueueSubscriptionDropNotification(SubscriptionDropReason.UserInitiated, null); - //TODO figure out timeout with Promise still running - //if (!_stopped.Wait(timeout)) - //throw new TimeoutException(string.Format("Could not stop {0} in time.", GetType().Name)); - }; - - EventStorePersistentSubscriptionBase.prototype._enqueueSubscriptionDropNotification = function(reason, error) { - // if drop data was already set -- no need to enqueue drop again, somebody did that already - if (!this._dropData) { - this._dropData = {reason: reason, error: error}; - this._enqueue(new DropSubscriptionEvent()); - } - }; - - EventStorePersistentSubscriptionBase.prototype._onSubscriptionDropped = function(subscription, reason, exception) { - this._enqueueSubscriptionDropNotification(reason, exception); - }; - - EventStorePersistentSubscriptionBase.prototype._onEventAppeared = function(subscription, resolvedEvent) { - this._enqueue(resolvedEvent); - }; - - EventStorePersistentSubscriptionBase.prototype._enqueue = function(resolvedEvent) { - this._queue.push(resolvedEvent); - if (!this._isProcessing) { - this._isProcessing = true; - setImmediate(this._processQueue.bind(this)); - } - }; - - EventStorePersistentSubscriptionBase.prototype._processQueue = function() { - //do - //{ - var e = this._queue.shift(); - while (e) - { - if (e instanceof DropSubscriptionEvent) // drop subscription artificial ResolvedEvent - { - if (this._dropData === null) throw new Error("Drop reason not specified."); - this._dropSubscription(this._dropData.reason, this._dropData.error); - return; - } - if (this._dropData !== null) - { - this._dropSubscription(this._dropData.reason, this._dropData.error); - return; - } - try - { - this._eventAppeared(this, e); - if(this._autoAck) - this._subscription.notifyEventsProcessed([e.originalEvent.eventId]); - if (this._verbose) - this._log.debug("Persistent Subscription to %s: processed event (%s, %d, %s @ %d).", - this._streamId, e.originalEvent.eventStreamId, e.originalEvent.eventNumber, e.originalEvent.eventType, - e.originalEventNumber); - } - catch (err) - { - //TODO GFY should we autonak here? - this._dropSubscription(SubscriptionDropReason.EventHandlerException, err); - return; - } - e = this._queue.shift(); - } - this._isProcessing = false; - //} while (_queue.Count > 0 && Interlocked.CompareExchange(ref _isProcessing, 1, 0) == 0); - }; - - EventStorePersistentSubscriptionBase.prototype._dropSubscription = function(reason, error) { - if (!this._isDropped) - { - this._isDropped = true; - if (this._verbose) - this._log.debug("Persistent Subscription to %s: dropping subscription, reason: %s %s.", - this._streamId, reason, error); - - if (this._subscription !== null) - this._subscription.unsubscribe(); - if (this._subscriptionDropped !== null) - this._subscriptionDropped(this, reason, error); - this._stopped = true; - } - }; - - module.exports = EventStorePersistentSubscriptionBase; - - -/***/ }, -/* 61 */ -/***/ function(module, exports) { - - const PersistentSubscriptionNakEventAction = { - Unknown: 0, - Park: 1, - Retry: 2, - Skip: 3, - Stop: 4 - }; - - module.exports = PersistentSubscriptionNakEventAction; - module.exports.isValid = function(value) { - for(var k in PersistentSubscriptionNakEventAction) - if (PersistentSubscriptionNakEventAction[k] === value) return true; - return false; - }; - - -/***/ }, -/* 62 */ -/***/ function(module, exports) { - - module.exports.metastreamOf = function(stream) { - return '$$' + stream; - }; - module.exports.isMetastream = function(stream) { - return stream.indexOf('$$') === 0; - }; - -/***/ }, -/* 63 */ -/***/ function(module, exports) { - - const SystemEventTypes = { - StreamMetadata: '$metadata' - }; - - module.exports = SystemEventTypes; - - -/***/ }, -/* 64 */ -/***/ function(module, exports) { - - function StaticEndpointDiscoverer(tcpEndPoint, useSsl) { - this._nodeEndpoints = { - tcpEndPoint: useSsl ? null : tcpEndPoint, - secureTcpEndPoint: useSsl ? tcpEndPoint : null - } - } - - StaticEndpointDiscoverer.prototype.discover = function(failedTcpEndpoint) { - return Promise.resolve(this._nodeEndpoints); - }; - - module.exports = StaticEndpointDiscoverer; - -/***/ }, -/* 65 */ -/***/ function(module, exports) { - - function NoopLogger() { - } - NoopLogger.prototype.error = function() {}; - NoopLogger.prototype.debug = function() {}; - NoopLogger.prototype.info = function() {}; - - module.exports = NoopLogger; - -/***/ }, -/* 66 */ -/***/ function(module, exports, __webpack_require__) { - - var ensure = __webpack_require__(6); - - /** - * @param {string} username - * @param {string} password - * @constructor - * @property {string} username - * @property {string} password - */ - function UserCredentials(username, password) { - ensure.notNullOrEmpty(username, 'username'); - ensure.notNullOrEmpty(password, 'password'); - - Object.defineProperties(this, { - username: {enumerable: true, value: username}, - password: {enumerable: true, value: password} - }); - } - - module.exports = UserCredentials; - -/***/ }, -/* 67 */ -/***/ function(module, exports, __webpack_require__) { - - var SystemConsumerStrategies = __webpack_require__(53); - - function PersistentSubscriptionSettings( - resolveLinkTos, startFrom, extraStatistics, messageTimeout, - maxRetryCount, liveBufferSize, readBatchSize, historyBufferSize, - checkPointAfter, minCheckPointCount, maxCheckPointCount, - maxSubscriberCount, namedConsumerStrategy - ) { - this.resolveLinkTos = resolveLinkTos; - this.startFrom = startFrom; - this.extraStatistics = extraStatistics; - this.messageTimeout = messageTimeout; - this.maxRetryCount = maxRetryCount; - this.liveBufferSize = liveBufferSize; - this.readBatchSize = readBatchSize; - this.historyBufferSize = historyBufferSize; - this.checkPointAfter = checkPointAfter; - this.minCheckPointCount = minCheckPointCount; - this.maxCheckPointCount = maxCheckPointCount; - this.maxSubscriberCount = maxSubscriberCount; - this.namedConsumerStrategy = namedConsumerStrategy; - } - - module.exports.create = function() { - return new PersistentSubscriptionSettings(false, -1, false, 30000, 500, 500, 10, 20, 2000, 10, 1000, 0, SystemConsumerStrategies.RoundRobin); - }; - -/***/ }, -/* 68 */ -/***/ function(module, exports) { - - const SystemMetadata = { - maxAge: '$maxAge', - maxCount: '$maxCount', - truncateBefore: '$tb', - cacheControl: '$cacheControl', - acl: '$acl', - aclRead: '$r', - aclWrite: '$w', - aclDelete: '$d', - aclMetaRead: '$mr', - aclMetaWrite: '$mw', - userStreamAcl: '$userStreamAcl', - systemStreamAcl: '$systemStreamAcl' - }; - - module.exports = SystemMetadata; - -/***/ } -/******/ ]); \ No newline at end of file diff --git a/package.json b/package.json index a45a6b0..c328bf9 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,14 @@ "version": "0.0.2", "description": "A port of the EventStore .Net ClientAPI to Node.js", "main": "index.js", + "directories": { + "lib": "lib", + "test": "test" + }, "scripts": { + "clean": "rm lib/dist.js", + "build": "webpack", + "pretest": "npm run build", "test": "nodeunit" }, "repository": { @@ -22,12 +29,16 @@ }, "homepage": "https://github.com/nicdex/eventstore-node#readme", "dependencies": { - "long": "^3.0.3", - "protobufjs": "^5.0.1", - "uuid": "^2.0.1" + "long": "^3.2", + "protobufjs": "^5.0", + "uuid": "^2.0" }, "engines": { "node": ">=0.12" }, - "engineStrict": true + "engineStrict": true, + "devDependencies": { + "nodeunit": "^0.10.2", + "webpack": "^1.13.2" + } } diff --git a/src/clientOperations/subscriptionOperation.js b/src/clientOperations/subscriptionOperation.js index 4d0468f..36bfd49 100644 --- a/src/clientOperations/subscriptionOperation.js +++ b/src/clientOperations/subscriptionOperation.js @@ -189,7 +189,6 @@ SubscriptionOperation.prototype.dropSubscription = function(reason, err, connect if (reason !== SubscriptionDropReason.UserInitiated && this._subscription === null) { if (err === null) throw new Error(util.format("No exception provided for subscription drop reason '%s", reason)); - //TODO: this should be last thing to execute this._cb(err); return; } diff --git a/src/clientOperations/volatileSubscriptionOperation.js b/src/clientOperations/volatileSubscriptionOperation.js index 570ac17..15b3bfe 100644 --- a/src/clientOperations/volatileSubscriptionOperation.js +++ b/src/clientOperations/volatileSubscriptionOperation.js @@ -9,7 +9,7 @@ var BufferSegment = require('../common/bufferSegment'); var InspectionDecision = require('../systemData/inspectionDecision'); var InspectionResult = require('./../systemData/inspectionResult'); var results = require('../results'); -var VolatileEventStoreSubscription = require('../volatileEventStoreConnection'); +var VolatileEventStoreSubscription = require('../volatileEventStoreSubscription'); function VolatileSubscriptionOperation( log, cb, streamId, resolveLinkTos, userCredentials, eventAppeared, diff --git a/src/eventStoreConnection.js b/src/eventStoreConnection.js index 518e088..0ed9a65 100644 --- a/src/eventStoreConnection.js +++ b/src/eventStoreConnection.js @@ -43,13 +43,21 @@ function merge(a,b) { /** * Create an EventStore connection * @param {object} settings - * @param {object} tcpEndPoint + * @param {string|object} endPoint * @param {string} [connectionName] * @returns {EventStoreNodeConnection} */ -module.exports.create = function(settings, tcpEndPoint, connectionName) { - //TODO: cluster connection - var mergedSettings = merge(defaultConnectionSettings, settings || {}); - var endpointDiscoverer = new StaticEndpointDiscoverer(tcpEndPoint, settings.useSslConnection); - return new EventStoreNodeConnection(mergedSettings, endpointDiscoverer, connectionName || null); +module.exports.create = function(settings, endPoint, connectionName) { + if (typeof endPoint === 'object') { + var mergedSettings = merge(defaultConnectionSettings, settings || {}); + var endpointDiscoverer = new StaticEndpointDiscoverer(endPoint, settings.useSslConnection); + return new EventStoreNodeConnection(mergedSettings, endpointDiscoverer, connectionName || null); + } + if (typeof endPoint === 'string') { + //TODO: tcpEndpoint represented as tcp://hostname:port + //TODO: cluster discovery via dns represented as discover://dns:?port + throw new Error('Not implemented.'); + } + //TODO: cluster discovery via gossip seeds in settings + throw new Error('Not implemented.'); }; \ No newline at end of file diff --git a/src/eventStoreNodeConnection.js b/src/eventStoreNodeConnection.js index 8405f74..b243c6d 100644 --- a/src/eventStoreNodeConnection.js +++ b/src/eventStoreNodeConnection.js @@ -381,8 +381,10 @@ EventStoreNodeConnection.prototype.readAllEventsBackward = function( EventStoreNodeConnection.prototype.subscribeToStream = function( stream, resolveLinkTos, eventAppeared, subscriptionDropped, userCredentials ) { - if (typeof stream !== 'string' || stream === '') throw new TypeError("stream must be a non-empty string."); - if (typeof eventAppeared !== 'function') throw new TypeError("eventAppeared must be a function."); + ensure.notNullOrEmpty(stream, "stream"); + ensure.isTypeOf(Function, eventAppeared, "eventAppeared"); + if (subscriptionDropped) + ensure.isTypeOf(Function, subscriptionDropped, "subscriptionDropped"); var self = this; return new Promise(function(resolve,reject) { diff --git a/src/volatileEventStoreConnection.js b/src/volatileEventStoreSubscription.js similarity index 62% rename from src/volatileEventStoreConnection.js rename to src/volatileEventStoreSubscription.js index 735d805..d0a74f8 100644 --- a/src/volatileEventStoreConnection.js +++ b/src/volatileEventStoreSubscription.js @@ -10,15 +10,15 @@ var EventStoreSubsription = require('./eventStoreSubscription'); * @constructor * @augments {EventStoreSubscription} */ -function VolatileEventStoreConnection(subscriptionOperation, streamId, lastCommitPosition, lastEventNumber) { +function VolatileEventStoreSubscription(subscriptionOperation, streamId, lastCommitPosition, lastEventNumber) { EventStoreSubsription.call(this, streamId, lastCommitPosition, lastEventNumber); this._subscriptionOperation = subscriptionOperation; } -util.inherits(VolatileEventStoreConnection, EventStoreSubsription); +util.inherits(VolatileEventStoreSubscription, EventStoreSubsription); -VolatileEventStoreConnection.prototype.unsubscribe = function() { +VolatileEventStoreSubscription.prototype.unsubscribe = function() { this._subscriptionOperation.unsubscribe(); }; -module.exports = VolatileEventStoreConnection; +module.exports = VolatileEventStoreSubscription; diff --git a/test/client_test.js b/test/client_test.js index 76007ec..2ca5a37 100644 --- a/test/client_test.js +++ b/test/client_test.js @@ -163,7 +163,7 @@ module.exports = { .catch(function(err) { test.done(err); }); - },*/ + }, 'Test Subscribe to Stream': function(test) { var done = false; function eventAppeared() { @@ -188,7 +188,7 @@ module.exports = { done = true; test.done(err); }) - }, + } 'Test Subscribe to All': function(test) { var done = false; function eventAppeared() { @@ -233,11 +233,12 @@ module.exports = { self.conn.appendToStream(testStreamName, client.expectedVersion.any, events); } function subscriptionDropped(connection, reason, error) { + console.log(reason); 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.done(error); } - //this.conn.appendToStream() + this.conn.appendToStream(testStreamName, client.expectedVersion.noStream, ) var subscription = this.conn.subscribeToStreamFrom(testStreamName, null, false, eventAppeared, liveProcessingStarted, subscriptionDropped); }, 'Test Subscribe to All From': function(test) { @@ -264,55 +265,8 @@ module.exports = { test.done(error); } var subscription = this.conn.subscribeToAllFrom(null, false, eventAppeared, liveProcessingStarted, subscriptionDropped, userCredentialsForAll); - }, - 'Test Set Stream Metadata Raw': function(test) { - this.conn.setStreamMetadataRaw(testStreamName, client.expectedVersion.emptyStream, {$maxCount: 100}) - .then(function(result) { - test.done(); - }) - .catch(function(err) { - test.done(err); - }); - }, - 'Test Get Stream Metadata Raw': function(test) { - this.conn.getStreamMetadataRaw(testStreamName) - .then(function(result) { - test.done(); - }) - .catch(function(err) { - test.done(err); - }); - }, - 'Test Create Persistent Subscription': function(test) { - var settings = client.PersistentSubscriptionSettings.create(); - this.conn.createPersistentSubscription(testStreamName, 'consumer-1', settings, userCredentialsForAll) - .then(function(result) { - test.done(); - }) - .catch(function(err) { - test.done(err); - }); - }, - //TODO: Update Persistent Subscription - 'Test ConnectTo Persistent Subscription': function(test) { - function eventAppeared(s, e) { - s.stop(); - } - function subscriptionDropped(connection, reason, error) { - test.done(error); - } - var subscription = this.conn.connectToPersistentSubscription(testStreamName, 'consumer-1', eventAppeared, subscriptionDropped); - this.conn.appendToStream(testStreamName, client.expectedVersion.any, [createRandomEvent()]); - }, - 'Test Delete Persistent Subscription': function(test) { - this.conn.deletePersistentSubscription(testStreamName, 'consumer-1', userCredentialsForAll) - .then(function(result) { - test.done(); - }) - .catch(function(err) { - test.done(err); - }); - }/*, + },*/ + /*, 'Test Delete Stream': function(test) { this.conn.deleteStream(testStreamName, client.expectedVersion.any) .then(function(result) { diff --git a/test/common/base_test.js b/test/common/base_test.js index 4c475f7..5f5f276 100644 --- a/test/common/base_test.js +++ b/test/common/base_test.js @@ -17,6 +17,7 @@ var tcpEndPoint = {host: 'localhost', port: 1113}; function setUp(cb) { this.log = settings.log; this.testStreamName = 'test-' + uuid.v4(); + this.log.info('A', this.testStreamName); var connected = false; this.conn = client.EventStoreConnection.create(settings, tcpEndPoint); this.conn.connect() diff --git a/test/connection_test.js b/test/connection_test.js index 953960f..bc4bba7 100644 --- a/test/connection_test.js +++ b/test/connection_test.js @@ -22,7 +22,7 @@ module.exports = { test.done(); } }, - 'Connect To Endpoint That Don\'t Exist': function(test) { + 'Connect To Endpoint That Doesn\'t Exist': function(test) { var tcpEndpoint = {hostname: 'localhost', port: 1114}; var conn = client.EventStoreConnection.create(testBase.settings({maxReconnections:1}), tcpEndpoint); conn.connect() diff --git a/test/metadata_test.js b/test/metadata_test.js new file mode 100644 index 0000000..7f50ae3 --- /dev/null +++ b/test/metadata_test.js @@ -0,0 +1,26 @@ +var util = require('util'); +var uuid = require('uuid'); +var client = require('../src/client'); + +module.exports = { + 'Test Set Stream Metadata Raw': function(test) { + this.conn.setStreamMetadataRaw(this.testStreamName, client.expectedVersion.emptyStream, {$maxCount: 100}) + .then(function(result) { + test.done(); + }) + .catch(function(err) { + test.done(err); + }); + }, + 'Test Get Stream Metadata Raw': function(test) { + this.conn.getStreamMetadataRaw(this.testStreamName) + .then(function(result) { + test.done(); + }) + .catch(function(err) { + test.done(err); + }); + } +}; + +require('./common/base_test').init(module.exports); diff --git a/test/persistentSubscription_test.js b/test/persistentSubscription_test.js new file mode 100644 index 0000000..3d76d07 --- /dev/null +++ b/test/persistentSubscription_test.js @@ -0,0 +1,46 @@ +var util = require('util'); +var uuid = require('uuid'); +var client = require('../src/client'); +const adminCredentials = new client.UserCredentials("admin", "changeit"); + +function createRandomEvent() { + return client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, {createdAt: Date.now()}, 'testEvent'); +} + +var testStreamName = 'test' + uuid.v4(); + +module.exports = { + 'Test Create Persistent Subscription': function(test) { + var settings = client.PersistentSubscriptionSettings.create(); + this.conn.createPersistentSubscription(testStreamName, 'consumer-1', settings, adminCredentials) + .then(function(result) { + test.done(); + }) + .catch(function(err) { + test.done(err); + }); + }, + //TODO: Update Persistent Subscription + 'Test ConnectTo Persistent Subscription': function(test) { + function eventAppeared(s, e) { + s.stop(); + } + function subscriptionDropped(connection, reason, error) { + test.done(error); + } + var subscription = this.conn.connectToPersistentSubscription(testStreamName, 'consumer-1', eventAppeared, subscriptionDropped); + this.log.info('ABC', subscription); + this.conn.appendToStream(testStreamName, client.expectedVersion.any, [createRandomEvent()]); + }, + 'Test Delete Persistent Subscription': function(test) { + this.conn.deletePersistentSubscription(testStreamName, 'consumer-1', adminCredentials) + .then(function(result) { + test.done(); + }) + .catch(function(err) { + test.done(err); + }); + } +}; + +require('./common/base_test').init(module.exports); \ No newline at end of file diff --git a/test/subscribeToAllFrom_test.js b/test/subscribeToAllFrom_test.js new file mode 100644 index 0000000..9f2f7af --- /dev/null +++ b/test/subscribeToAllFrom_test.js @@ -0,0 +1,38 @@ +var util = require('util'); +var uuid = require('uuid'); +var client = require('../src/client'); +const allCredentials = new client.UserCredentials("admin", "changeit"); + +function createRandomEvent() { + return client.createJsonEventData(uuid.v4(), {a: uuid.v4(), b: Math.random()}, {createdAt: Date.now()}, 'testEvent'); +} + +module.exports = { + 'Test Subscribe to All From': function(test) { + var self = this; + var liveProcessing = false; + var catchUpEvents = []; + var liveEvents = []; + function eventAppeared(s, e) { + if (liveProcessing) { + liveEvents.push(e); + s.stop(); + } else { + catchUpEvents.push(e); + } + } + function liveProcessingStarted() { + liveProcessing = true; + var events = [createRandomEvent()]; + self.conn.appendToStream(self.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.done(error); + } + var subscription = this.conn.subscribeToAllFrom(null, false, eventAppeared, liveProcessingStarted, subscriptionDropped, allCredentials); + } +}; + +require('./common/base_test').init(module.exports); \ No newline at end of file diff --git a/test/subscribeToAll_test.js b/test/subscribeToAll_test.js new file mode 100644 index 0000000..82a5d7f --- /dev/null +++ b/test/subscribeToAll_test.js @@ -0,0 +1,44 @@ +const uuid = require('uuid'); +const client = require('../src/client'); +const allCredentials = new client.UserCredentials("admin", "changeit"); + +module.exports = { + 'Test Subscribe To All Happy Path': function(test) { + const resolveLinkTos = false; + const numberOfPublishedEvents = 5; + var publishedEvents = []; + for(var i=0;i= 1, "Expecting at least 1 catchUp event, got " + catchUpEvents.length); + test.done(error); + } + + var events = [createRandomEvent()]; + this.conn.appendToStream(self.testStreamName, client.expectedVersion.noStream, events) + .then(function() { + var subscription = self.conn.subscribeToStreamFrom(self.testStreamName, null, false, eventAppeared, liveProcessingStarted, subscriptionDropped); + + test.areEqual("subscription.streamId", subscription.streamId, self.testStreamName); + test.areEqual("subscription.isSubscribedToAll", subscription.isSubscribedToAll, false); + test.areEqual("subscription.readBatchSize", subscription.readBatchSize, 500); + test.areEqual("subscription.maxPushQueueSize", subscription.maxPushQueueSize, 10000); + }); + } +}; + +require('./common/base_test').init(module.exports); \ No newline at end of file diff --git a/test/subscribeToStream_test.js b/test/subscribeToStream_test.js new file mode 100644 index 0000000..aa50dfd --- /dev/null +++ b/test/subscribeToStream_test.js @@ -0,0 +1,45 @@ +const uuid = require('uuid'); +const client = require('../src/client'); + +module.exports = { + 'Test Subscribe To Stream Happy Path': function(test) { + const resolveLinkTos = false; + const numberOfPublishedEvents = 5; + var publishedEvents = []; + for(var i=0;i