UNPKG

node-eventstore-client2

Version:

A port of the EventStore .Net ClientAPI to Node.js

1,583 lines (1,354 loc) 251 kB
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] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = 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; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 36); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = require("util"); /***/ }), /* 1 */ /***/ (function(module, exports) { const TcpCommand = Object.freeze({ 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, IdentifyClient: 0xF5, ClientIdentified: 0xF6, getName: function(v) { return _reverseLookup[v]; } }); var _reverseLookup = {}; for(var n in TcpCommand) { if (n === 'getName') continue; var v = TcpCommand[n]; _reverseLookup[v] = n; } module.exports = TcpCommand; /***/ }), /* 2 */ /***/ (function(module, exports) { module.exports = require("../src/messages/clientMessage"); /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { var guidParse = __webpack_require__(13); var Long = __webpack_require__(9); var ensure = __webpack_require__(8); /** * @public * @param {!number|!Long} commitPosition * @param {!number|!Long} preparePosition * @constructor * @property {!Long} commitPosition * @property {!Long} preparePosition */ function Position(commitPosition, preparePosition) { ensure.notNull(commitPosition, "commitPosition"); ensure.notNull(preparePosition, "preparePosition"); this.commitPosition = Long.fromValue(commitPosition); this.preparePosition = Long.fromValue(preparePosition); Object.freeze(this); } Position.prototype.compareTo = function(other) { if (this.commitPosition.lt(other.commitPosition) || (this.commitPosition.eq(other.commitPosition)&& this.preparePosition.lt(other.preparePosition))) { return -1; } if (this.commitPosition.gt(other.commitPosition) || (this.commitPosition.eq(other.commitPosition) && this.preparePosition.gt(other.preparePosition))) { return 1; } return 0; }; Position.prototype.toString = function() { return [this.commitPosition.toString(), this.preparePosition.toString()].join("/"); }; Position.start = new Position(0,0); Position.end = new Position(-1,-1); const EventReadStatus = Object.freeze({ Success: 'success', NotFound: 'notFound', NoStream: 'noStream', StreamDeleted: 'streamDeleted' }); /** * @param {object} ev * @constructor * @property {string} eventStreamId * @property {string} eventId * @property {Long} eventNumber * @property {string} eventType * @property {number} createdEpoch * @property {?Buffer} data * @property {?Buffer} metadata * @property {boolean} isJson */ function RecordedEvent(ev) { const ce = ev.createdEpoch ? (Number.isInteger(ev.createdEpoch) ? ev.createdEpoch : ev.createdEpoch.toNumber()) : 0 this.eventStreamId = ev.eventStreamId; this.eventId = guidParse.unparse(ev.eventId); this.eventNumber = ev.eventNumber; this.eventType = ev.eventType; this.created = new Date(ce); this.createdEpoch = ce; this.data = ev.data ? ev.data : new Buffer(0); this.metadata = ev.metadata ? ev.metadata : new Buffer(0); this.isJson = ev.dataContentType === 1; Object.freeze(this); } /** * @param {object} ev * @constructor * @property {?RecordedEvent} event * @property {?RecordedEvent} link * @property {?RecordedEvent} originalEvent * @property {boolean} isResolved * @property {?Position} originalPosition * @property {string} originalStreamId * @property {Long} originalEventNumber */ function ResolvedEvent(ev) { this.event = ev.event === null ? null : new RecordedEvent(ev.event); this.link = ev.link === null ? null : new RecordedEvent(ev.link); this.originalEvent = this.link || this.event; this.isResolved = this.link !== null && this.event !== null; this.originalPosition = (ev.commitPosition && ev.preparePosition) ? new Position(ev.commitPosition, ev.preparePosition) : null; this.originalStreamId = this.originalEvent && this.originalEvent.eventStreamId; this.originalEventNumber = this.originalEvent && this.originalEvent.eventNumber; Object.freeze(this); } /** * * @param {string} status * @param {string} stream * @param {Long} eventNumber * @param {object} event * @constructor * @property {string} status * @property {string} stream * @property {Long} eventNumber * @property {ResolvedEvent} event */ function EventReadResult(status, stream, eventNumber, event) { this.status = status; this.stream = stream; this.eventNumber = eventNumber; this.event = status === EventReadStatus.Success ? new ResolvedEvent(event) : null; Object.freeze(this); } /** * @param {number} nextExpectedVersion * @param {Position} logPosition * @constructor * @property {Long} nextExpectedVersion * @property {Position} logPosition */ function WriteResult(nextExpectedVersion, logPosition) { this.nextExpectedVersion = nextExpectedVersion; this.logPosition = logPosition; Object.freeze(this); } /** * @param {string} status * @param {string} stream * @param {Long} fromEventNumber * @param {string} readDirection * @param {object[]} events * @param {Long} nextEventNumber * @param {Long} lastEventNumber * @param {boolean} isEndOfStream * @constructor * @property {string} status * @property {string} stream * @property {Long} fromEventNumber * @property {string} readDirection * @property {ResolvedEvent[]} events * @property {Long} nextEventNumber * @property {Long} lastEventNumber * @property {boolean} isEndOfStream */ function StreamEventsSlice( status, stream, fromEventNumber, readDirection, events, nextEventNumber, lastEventNumber, isEndOfStream ) { this.status = status; this.stream = stream; this.fromEventNumber = fromEventNumber; this.readDirection = readDirection; this.events = events ? events.map(function(ev) { return new ResolvedEvent(ev); }) : []; this.nextEventNumber = nextEventNumber; this.lastEventNumber = lastEventNumber; this.isEndOfStream = isEndOfStream; Object.freeze(this); } /** * @param {string} readDirection * @param {Position} fromPosition * @param {Position} nextPosition * @param {ResolvedEvent[]} events * @constructor * @property {string} readDirection * @property {Position} fromPosition * @property {Position} nextPosition * @property {ResolvedEvent[]} events */ function AllEventsSlice(readDirection, fromPosition, nextPosition, events) { this.readDirection = readDirection; this.fromPosition = fromPosition; this.nextPosition = nextPosition; this.events = events ? events.map(function(ev){ return new ResolvedEvent(ev); }) : []; this.isEndOfStream = events === null || events.length === 0; Object.freeze(this); } /** * @param {Position} logPosition * @constructor * @property {Position} logPosition */ function DeleteResult(logPosition) { this.logPosition = logPosition; Object.freeze(this); } /** * @param {string} stream * @param {boolean} isStreamDeleted * @param {Long} metastreamVersion * @param {object} streamMetadata * @constructor * @property {string} stream * @property {boolean} isStreamDeleted * @property {Long} metastreamVersion * @property {object} streamMetadata */ function RawStreamMetadataResult(stream, isStreamDeleted, metastreamVersion, streamMetadata) { ensure.notNullOrEmpty(stream); this.stream = stream; this.isStreamDeleted = isStreamDeleted; this.metastreamVersion = metastreamVersion; this.streamMetadata = streamMetadata; Object.freeze(this); } const PersistentSubscriptionCreateStatus = Object.freeze({ Success: 'success', NotFound: 'notFound', Failure: 'failure' }); /** * @param {string} status * @constructor * @property {string} status */ function PersistentSubscriptionCreateResult(status) { this.status = status; Object.freeze(this); } const PersistentSubscriptionUpdateStatus = Object.freeze({ Success: 'success', NotFound: 'notFound', Failure: 'failure', AccessDenied: 'accessDenied' }); /** * @param {string} status * @constructor * @property {string} status */ function PersistentSubscriptionUpdateResult(status) { this.status = status; Object.freeze(this); } const PersistentSubscriptionDeleteStatus = Object.freeze({ Success: 'success', Failure: 'failure' }); /** * @param {string} status * @constructor * @property {string} status */ function PersistentSubscriptionDeleteResult(status) { this.status = status; Object.freeze(this); } // Exports Constructors exports.Position = Position; exports.ResolvedEvent = ResolvedEvent; exports.EventReadStatus = EventReadStatus; exports.EventReadResult = EventReadResult; exports.WriteResult = WriteResult; exports.StreamEventsSlice = StreamEventsSlice; exports.AllEventsSlice = AllEventsSlice; exports.DeleteResult = DeleteResult; exports.RawStreamMetadataResult = RawStreamMetadataResult; exports.PersistentSubscriptionCreateResult = PersistentSubscriptionCreateResult; exports.PersistentSubscriptionCreateStatus = PersistentSubscriptionCreateStatus; exports.PersistentSubscriptionUpdateResult = PersistentSubscriptionUpdateResult; exports.PersistentSubscriptionUpdateStatus = PersistentSubscriptionUpdateStatus; exports.PersistentSubscriptionDeleteResult = PersistentSubscriptionDeleteResult; exports.PersistentSubscriptionDeleteStatus = PersistentSubscriptionDeleteStatus; /***/ }), /* 4 */ /***/ (function(module, exports) { var InspectionDecision = Object.freeze({ DoNothing: 'doNothing', EndOperation: 'endOperation', Retry: 'retry', Reconnect: 'reconnect', Subscribed: 'subscribed' }); module.exports = InspectionDecision; /***/ }), /* 5 */ /***/ (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; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { var util = __webpack_require__(0); var TcpPackage = __webpack_require__(11); var TcpCommand = __webpack_require__(1); var TcpFlags = __webpack_require__(12); var InspectionDecision = __webpack_require__(4); var ClientMessage = __webpack_require__(2); var InspectionResult = __webpack_require__(5); var createBufferSegment = __webpack_require__(10); 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) { 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.constructor.encode(dto).finish(); 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(pkg, 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.additionalInfo); return new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster", {host: masterInfo.externalTcpAddress, port: masterInfo.externalTcpPort}, {host: masterInfo.externalSecureTcpAddress, port: masterInfo.externalSecureTcpPort}); default: this.log.error("Unknown NotHandledReason: %s.", message.reason); return new InspectionResult(InspectionDecision.Retry, "NotHandled - <unknown>"); } }; 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; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { var util = __webpack_require__(0); var Long = __webpack_require__(9); 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; Object.freeze(this); return; } if (Long.isLong(streamOrTransactionId)) { this.message = util.format("%s access denied for transaction %s.", action, streamOrTransactionId); this.transactionId = streamOrTransactionId; Object.freeze(this); return; } throw new TypeError("second argument must be a stream name or transaction Id."); } util.inherits(AccessDeniedError, Error); module.exports = AccessDeniedError; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { var Long = __webpack_require__(9); module.exports.notNullOrEmpty = function(value, name) { if (value === null) throw new TypeError(name + " should not be null."); if (value === '') throw new Error(name + " should not be empty."); }; module.exports.notNull = function(value, name) { if (value === null) throw new TypeError(name + " should not be null."); }; function isInteger(value, name) { if (typeof value !== 'number' || value % 1 !== 0) throw new TypeError(name + " should be an integer."); } module.exports.isInteger = isInteger; module.exports.isLongOrInteger = function(value, name) { if (typeof value === 'number') { return isInteger(value, name); } else if (!Long.isLong(value)) { throw new TypeError(name + " should be a Long|number."); } }; module.exports.isArrayOf = function(expectedType, value, name) { if (!Array.isArray(value)) throw new TypeError(name + " should be an array."); if (!value.every(function(x) { return x instanceof expectedType; })) { throw new TypeError([name, " should be an array of ", expectedType.name, "."].join("")); } }; module.exports.isTypeOf = function(expectedType, value, name, nullAllowed) { if (nullAllowed && value === null) return; if (!(value instanceof expectedType)) { throw new TypeError([name, " should be of type '", expectedType.name, "'", nullAllowed ? " or null" : "", "."].join("")); } }; module.exports.positive = function(value, name) { if (value <= 0) throw new Error(name + " should be positive."); }; module.exports.nonNegative = function(value, name) { if (value < 0) throw new Error(name + " should be non-negative."); }; /***/ }), /* 9 */ /***/ (function(module, exports) { module.exports = require("long"); /***/ }), /* 10 */ /***/ (function(module, exports) { /** * Create a buffer segment * @private * @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); }; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { var guidParse = __webpack_require__(13); var createBufferSegment = __webpack_require__(10); var TcpFlags = __webpack_require__(12); const CommandOffset = 0; const FlagsOffset = CommandOffset + 1; const CorrelationOffset = FlagsOffset + 1; const AuthOffset = CorrelationOffset + 16; const MandatorySize = AuthOffset; function TcpPackage(command, flags, correlationId, login, password, data) { this.command = command; this.flags = flags; this.correlationId = correlationId; this.login = login || null; this.password = password || null; this.data = data || null; } TcpPackage.fromBufferSegment = function(data) { if (data.length < MandatorySize) throw new Error("ArraySegment too short, length: " + data.length); var command = data.buffer[data.offset + CommandOffset]; var flags = data.buffer[data.offset + FlagsOffset]; var correlationId = guidParse.unparse(data.buffer, data.offset + CorrelationOffset); var headerSize = MandatorySize; var login = null, pass = null; if ((flags & TcpFlags.Authenticated) !== 0) { var loginLen = data.buffer[data.offset + AuthOffset]; if (AuthOffset + 1 + loginLen + 1 >= 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; guidParse.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; guidParse.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; /***/ }), /* 12 */ /***/ (function(module, exports) { const TcpFlags = Object.freeze({ None: 0x0, Authenticated: 0x01 }); module.exports = TcpFlags; /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // Maps for number <-> hex string conversion var _byteToHex = []; var _hexToByte = {}; for (var i = 0; i < 256; i++) { _byteToHex[i] = (i + 0x100).toString(16).substr(1); _hexToByte[_byteToHex[i]] = i; } // **`parse()` - Parse a UUID into it's component bytes** function parse(s, buf, offset) { const i = (buf && offset) || 0; var ii = 0; if (buf) buf.fill(0, i, i + 16); buf = buf || new Buffer(16); s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { if (ii < 16) { // Don't overflow! buf[i + ii++] = _hexToByte[oct]; } }); var buf2 = new Buffer(buf.slice(i, i + 16)); buf[i + 0] = buf2[3]; buf[i + 1] = buf2[2]; buf[i + 2] = buf2[1]; buf[i + 3] = buf2[0]; buf[i + 4] = buf2[5]; buf[i + 5] = buf2[4]; buf[i + 6] = buf2[7]; buf[i + 7] = buf2[6]; return buf; } // **`unparse()` - Convert UUID byte array (ala parse()) into a string** function unparse(buf, offset) { var i = offset || 0; return '03020100-0504-0706-0809-101112131415'.replace(/\d{2}/g, function (num) { var j = parseInt(num, 10); return _byteToHex[buf[i+j]]; }) } exports.parse = parse; exports.unparse = unparse; /***/ }), /* 14 */ /***/ (function(module, exports) { const SubscriptionDropReason = Object.freeze({ 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; /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { var util = __webpack_require__(0); var Long = __webpack_require__(9); 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; Object.freeze(this); return; } if (Long.isLong(streamOrTransactionId)) { this.message = util.format("%s transaction failed due to WrongExpectedVersion. Transaction Id: %s.", action, streamOrTransactionId); this.transactionId = streamOrTransactionId; Object.freeze(this); return; } throw new TypeError("second argument must be a stream name or a transaction Id."); } util.inherits(WrongExpectedVersionError, Error); module.exports = WrongExpectedVersionError; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { var util = __webpack_require__(0); var Long = __webpack_require__(9); 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; Object.freeze(this); return; } if (Long.isLong(streamOrTransactionId)) { this.message = util.format("Stream is deleted for transaction %s.", streamOrTransactionId); this.transactionId = streamOrTransactionId; Object.freeze(this); return; } throw new TypeError("second argument must be a stream name or transaction Id."); } util.inherits(StreamDeletedError, Error); module.exports = StreamDeletedError; /***/ }), /* 17 */ /***/ (function(module, exports) { const SystemConsumerStrategies = Object.freeze({ DispatchToSingle: 'DispatchToSingle', RoundRobin: 'RoundRobin', Pinned: 'Pinned' }); module.exports = SystemConsumerStrategies; /***/ }), /* 18 */ /***/ (function(module, exports) { module.exports = require("uuid"); /***/ }), /* 19 */ /***/ (function(module, exports) { const ReadDirection = Object.freeze({ Forward: 'forward', Backward: 'backward' }); module.exports = ReadDirection; /***/ }), /* 20 */ /***/ (function(module, exports, __webpack_require__) { var util = __webpack_require__(0); 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); /** * @private * @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 }; /***/ }), /* 21 */ /***/ (function(module, exports) { const SliceReadStatus = Object.freeze({ Success: 'success', StreamNotFound: 'streamNotFound', StreamDeleted: 'streamDeleted' }); module.exports = SliceReadStatus; /***/ }), /* 22 */ /***/ (function(module, exports) { const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; function isValidId(id) { if (typeof id !== 'string') return false; return uuidRegex.test(id); } /** * Create an EventData * @private * @param {string} eventId * @param {string} type * @param {boolean} [isJson] * @param {Buffer} [data] * @param {Buffer} [metadata] * @constructor */ function EventData(eventId, type, isJson, data, metadata) { if (!isValidId(eventId)) throw new TypeError("eventId must be a string containing a UUID."); if (typeof type !== 'string' || type === '') throw new TypeError("type must be a non-empty string."); if (isJson && typeof isJson !== 'boolean') throw new TypeError("isJson must be a boolean."); if (data && !Buffer.isBuffer(data)) throw new TypeError("data must be a Buffer."); if (metadata && !Buffer.isBuffer(metadata)) throw new TypeError("metadata must be a Buffer."); this.eventId = eventId; this.type = type; this.isJson = isJson || false; this.data = data || new Buffer(0); this.metadata = metadata || new Buffer(0); Object.freeze(this); } module.exports = EventData; /***/ }), /* 23 */ /***/ (function(module, exports) { function GossipSeed(endPoint, hostName) { if (typeof endPoint !== 'object' || !endPoint.host || !endPoint.port) throw new TypeError('endPoint must be have host and port properties.'); this.endPoint = endPoint; this.hostName = hostName; Object.freeze(this); } module.exports = GossipSeed; /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { var EventStoreNodeConnection = __webpack_require__(39); var StaticEndpointDiscoverer = __webpack_require__(72); var ClusterDnsEndPointDiscoverer = __webpack_require__(73); var NoopLogger = __webpack_require__(34); var ensure = __webpack_require__(8); var defaultConnectionSettings = Object.freeze({ log: new NoopLogger(), verboseLogging: false, maxQueueSize: 5000, maxConcurrentItems: 5000, maxRetries: 10, maxReconnections: 10, requireMaster: true, reconnectionDelay: 100, operationTimeout: 7*1000, operationTimeoutCheckPeriod: 1000, defaultUserCredentials: null, useSslConnection: false, targetHost: null, validateServer: false, failOnNoServerResponse: false, heartbeatInterval: 750, heartbeatTimeout: 1500, clientConnectionTimeout: 1000, // Cluster Settings clusterDns: '', maxDiscoverAttempts: 10, externalGossipPort: 0, gossipTimeout: 1000 }); function merge(a,b) { var c = {}; Object.getOwnPropertyNames(a).forEach(function(k) { c[k] = a[k]; }); Object.getOwnPropertyNames(b).forEach(function(k) { c[k] = b[k]; }); return c; } function createFromTcpEndpoint(settings, tcpEndpoint, connectionName) { if (!tcpEndpoint.port || !tcpEndpoint.host) throw new TypeError('endPoint object must have host and port properties.'); var mergedSettings = merge(defaultConnectionSettings, settings || {}); var endpointDiscoverer = new StaticEndpointDiscoverer(tcpEndpoint, settings.useSslConnection); return new EventStoreNodeConnection(mergedSettings, null, endpointDiscoverer, connectionName || null); } function createFromStringEndpoint(settings, endPoint, connectionName) { var m = endPoint.match(/^(tcp|discover):\/\/([^:]+):?(\d+)?$/); if (!m) throw new Error('endPoint string must be tcp://hostname[:port] or discover://dns[:port]'); var scheme = m[1]; var host = m[2] || null; var port = m[3] ? parseInt(m[3]) : null; if (scheme === 'tcp') { var tcpEndpoint = { host: host, port: port || 1113 }; return createFromTcpEndpoint(settings, tcpEndpoint, connectionName); } if (scheme === 'discover') { return createFromClusterDns(settings, host, port || 2113, connectionName); } throw new Error('Invalid scheme for endPoint: ' + scheme); } function createFromClusterDns(connectionSettings, clusterDns, externalGossipPort, connectionName) { ensure.notNull(connectionSettings, "connectionSettings"); ensure.notNull(clusterDns, "clusterDns"); var mergedSettings = merge(defaultConnectionSettings, connectionSettings || {}); var clusterSettings = { clusterDns: clusterDns, gossipSeeds: null, externalGossipPort: externalGossipPort, maxDiscoverAttempts: mergedSettings.maxDiscoverAttempts, gossipTimeout: mergedSettings.gossipTimeout }; var endPointDiscoverer = new ClusterDnsEndPointDiscoverer(mergedSettings.log, clusterSettings.clusterDns, clusterSettings.maxDiscoverAttempts, clusterSettings.externalGossipPort, clusterSettings.gossipSeeds, clusterSettings.gossipTimeout ); return new EventStoreNodeConnection(mergedSettings, clusterSettings, endPointDiscoverer, connectionName); } function createFromGossipSeeds(connectionSettings, gossipSeeds, connectionName) { ensure.notNull(connectionSettings, "connectionSettings"); ensure.notNull(gossipSeeds, "gossipSeeds"); var mergedSettings = merge(defaultConnectionSettings, connectionSettings || {}); var clusterSettings = { clusterDns: '', gossipSeeds: gossipSeeds, externalGossipPort: 0, maxDiscoverAttempts: mergedSettings.maxDiscoverAttempts, gossipTimeout: mergedSettings.gossipTimeout }; var endPointDiscoverer = new ClusterDnsEndPointDiscoverer(mergedSettings.log, clusterSettings.clusterDns, clusterSettings.maxDiscoverAttempts, clusterSettings.externalGossipPort, clusterSettings.gossipSeeds, clusterSettings.gossipTimeout ); return new EventStoreNodeConnection(mergedSettings, clusterSettings, endPointDiscoverer, connectionName); } /** * Create an EventStore connection * @public * @alias createConnection * @param {object} settings * @param {boolean} [settings.verboseLogging=false] * @param {number} [settings.maxQueueSize=5000] * @param {number} [settings.maxConcurrentItems=5000] * @param {number} [settings.maxRetries=10] * @param {number} [settings.maxReconnections=10] * @param {boolean} [settings.requireMaster=true] * @param {number} [settings.reconnectionDelay=100] * @param {number} [settings.operationTimeout=7000] * @param {number} [settings.operationTimeoutCheckPeriod=1000] * @param {object} [settings.defaultUserCredentials=null] - The default user credentials to use for requests * @param {boolean} [settings.useSslConnection=false] - Whether to use SSL or not * @param {object} [settings.targetHost=null] * @param {boolean} [settings.validateServer=false] * @param {boolean} [settings.failOnNoServerResponse=false] * @param {number} [settings.heartbeatInterval=750] * @param {number} [settings.heartbeatTimeout=1500] * @param {number} [settings.clientConnectionTimeout=1000] * @param {string} [settings.clusterDns=''] * @param {number} [settings.maxDiscoverAttempts=10] * @param {number} [settings.externalGossipPort=0] * @param {number} [settings.gossipTimeout=1000] * @param {string|object|array} endPointOrGossipSeeds * @param {string} [connectionName] * @returns {EventStoreNodeConnection} */ module.exports.create = function(settings, endPointOrGossipSeeds, connectionName) { if (Array.isArray(endPointOrGossipSeeds)) return createFromGossipSeeds(settings, endPointOrGossipSeeds, connectionName); if (typeof endPointOrGossipSeeds === 'object') return createFromTcpEndpoint(settings, endPointOrGossipSeeds, connectionName); if (typeof endPointOrGossipSeeds === 'string') return createFromStringEndpoint(settings, endPointOrGossipSeeds, connectionName); throw new TypeError('endPointOrGossipSeeds must be an object, a string or an array.'); }; /***/ }), /* 25 */ /***/ (function(module, exports) { module.exports = require("events"); /***/ }), /* 26 */ /***/ (function(module, exports) { /** * @private * @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; /***/ }), /* 27 */ /***/ (function(module, exports, __webpack_require__) { var util = __webpack_require__(0); var TcpCommand = __webpack_require__(1); var TcpFlags = __webpack_require__(12); var InspectionDecision = __webpack_require__(4); var InspectionResult = __webpack_require__(5); var ClientMessage = __webpack_require__(2); var TcpPackage = __webpack_require__(11); var BufferSegment = __webpack_require__(10); var results = __webpack_require__(3); var SubscriptionDropReason = __webpack_require__(14); //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) 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(ClientMessage.UnsubscribeFromStream.encode(msg).finish()); 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 || "<all>"))); 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 || "<no 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.additionalInfo); return new InspectionResult(InspectionDecision.Reconnect, "NotHandled - NotMaster", {host: masterInfo.externalTcpAddress, port: masterInfo.externalTcpPort}, {host: masterInfo.externalSecureTcpAddress, port: masterInfo.externalSecureTcpPort}); default: this._log.error("Unknown NotHandledReason: %s.", message.reason); return new InspectionResult(InspectionDecision.Retry, "NotHandled - <unknown>"); } } 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); retu