298 lines
8.6 KiB
JavaScript
298 lines
8.6 KiB
JavaScript
|
var util = require('util');
|
||
|
var uuid = require('uuid');
|
||
|
var ensure = require('./common/utils/ensure');
|
||
|
|
||
|
function toNumber(obj) {
|
||
|
if (typeof obj === 'number')
|
||
|
return obj;
|
||
|
if (typeof obj !== 'object')
|
||
|
throw new TypeError(util.format("'%s' is not a number.", obj));
|
||
|
if (!obj.hasOwnProperty('low') || !obj.hasOwnProperty('high') || !obj.hasOwnProperty('unsigned'))
|
||
|
throw new Error("Invalid number.");
|
||
|
return (obj.low + (obj.high * 0xffffffff));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {!number} commitPosition
|
||
|
* @param {!number} preparePosition
|
||
|
* @constructor
|
||
|
* @property {!number} commitPosition
|
||
|
* @property {!number} preparePosition
|
||
|
*/
|
||
|
function Position(commitPosition, preparePosition) {
|
||
|
Object.defineProperties(this, {
|
||
|
commitPosition: {
|
||
|
enumerable: true, value: toNumber(commitPosition)
|
||
|
},
|
||
|
preparePosition: {
|
||
|
enumerable: true, value: toNumber(preparePosition)
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
Position.prototype.compareTo = function(other) {
|
||
|
if (this.commitPosition < other.commitPosition || (this.commitPosition === other.commitPosition && this.preparePosition < other.preparePosition))
|
||
|
return -1;
|
||
|
if (this.commitPosition > other.commitPosition || (this.commitPosition === other.commitPosition && this.preparePosition > other.preparePosition))
|
||
|
return 1;
|
||
|
return 0;
|
||
|
};
|
||
|
|
||
|
Position.prototype.toString = function() {
|
||
|
return util.format("%d/%d", this.commitPosition, this.preparePosition);
|
||
|
};
|
||
|
|
||
|
|
||
|
const EventReadStatus = {
|
||
|
Success: 'success',
|
||
|
NotFound: 'notFound',
|
||
|
NoStream: 'noStream',
|
||
|
StreamDeleted: 'streamDeleted'
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* @param {object} ev
|
||
|
* @constructor
|
||
|
* @property {string} eventStreamId
|
||
|
* @property {string} eventId
|
||
|
* @property {number} eventNumber
|
||
|
* @property {string} eventType
|
||
|
* @property {number} createdEpoch
|
||
|
* @property {?Buffer} data
|
||
|
* @property {?Buffer} metadata
|
||
|
* @property {boolean} isJson
|
||
|
*/
|
||
|
function RecordedEvent(ev) {
|
||
|
Object.defineProperties(this, {
|
||
|
eventStreamId: {enumerable: true, value: ev.event_stream_id},
|
||
|
eventId: {enumerable: true, value: uuid.unparse(ev.event_id.buffer, ev.event_id.offset)},
|
||
|
eventNumber: {enumerable: true, value: ev.event_number},
|
||
|
eventType: {enumerable: true, value: ev.event_type},
|
||
|
//Javascript doesn't have .Net precision for time, so we use created_epoch for created
|
||
|
created: {enumerable: true, value: new Date(ev.created_epoch || 0)},
|
||
|
createdEpoch: {enumerable: true, value: ev.created_epoch ? toNumber(ev.created_epoch) : 0},
|
||
|
data: {enumerable: true, value: ev.data ? ev.data.toBuffer() : new Buffer(0)},
|
||
|
metadata: {enumerable: true, value: ev.metadata ? ev.metadata.toBuffer() : new Buffer(0)},
|
||
|
isJson: {enumerable: true, value: ev.data_content_type == 1}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {object} ev
|
||
|
* @constructor
|
||
|
* @property {?RecordedEvent} event
|
||
|
* @property {?RecordedEvent} link
|
||
|
* @property {?RecordedEvent} originalEvent
|
||
|
* @property {boolean} isResolved
|
||
|
* @property {?Position} originalPosition
|
||
|
* @property {string} originalStreamId
|
||
|
* @property {number} originalEventNumber
|
||
|
*/
|
||
|
function ResolvedEvent(ev) {
|
||
|
Object.defineProperties(this, {
|
||
|
event: {
|
||
|
enumerable: true,
|
||
|
value: ev.event === null ? null : new RecordedEvent(ev.event)
|
||
|
},
|
||
|
link: {
|
||
|
enumerable: true,
|
||
|
value: ev.link === null ? null : new RecordedEvent(ev.link)
|
||
|
},
|
||
|
originalEvent: {
|
||
|
enumerable: true,
|
||
|
get: function() {
|
||
|
return this.link || this.event;
|
||
|
}
|
||
|
},
|
||
|
isResolved: {
|
||
|
enumerable: true,
|
||
|
get: function() {
|
||
|
return this.link !== null && this.event !== null;
|
||
|
}
|
||
|
},
|
||
|
originalPosition: {
|
||
|
enumerable: true,
|
||
|
value: (ev.commit_position && ev.prepare_position) ? new Position(ev.commit_position, ev.prepare_position) : null
|
||
|
},
|
||
|
originalStreamId: {
|
||
|
enumerable: true,
|
||
|
get: function() {
|
||
|
return this.originalEvent.eventStreamId;
|
||
|
}
|
||
|
},
|
||
|
originalEventNumber: {
|
||
|
enumerable: true,
|
||
|
get: function() {
|
||
|
return this.originalEvent.eventNumber;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @param {string} status
|
||
|
* @param {string} stream
|
||
|
* @param {number} eventNumber
|
||
|
* @param {object} event
|
||
|
* @constructor
|
||
|
* @property {string} status
|
||
|
* @property {string} stream
|
||
|
* @property {number} eventNumber
|
||
|
* @property {ResolvedEvent} event
|
||
|
*/
|
||
|
function EventReadResult(status, stream, eventNumber, event) {
|
||
|
Object.defineProperties(this, {
|
||
|
status: {enumerable: true, value: status},
|
||
|
stream: {enumerable: true, value: stream},
|
||
|
eventNumber: {enumerable: true, value: eventNumber},
|
||
|
event: {
|
||
|
enumerable: true, value: status === EventReadStatus.Success ? new ResolvedEvent(event) : null
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {number} nextExpectedVersion
|
||
|
* @param {Position} logPosition
|
||
|
* @constructor
|
||
|
* @property {number} nextExpectedVersion
|
||
|
* @property {Position} logPosition
|
||
|
*/
|
||
|
function WriteResult(nextExpectedVersion, logPosition) {
|
||
|
Object.defineProperties(this, {
|
||
|
nextExpectedVersion: {
|
||
|
enumerable: true, value: nextExpectedVersion
|
||
|
},
|
||
|
logPosition: {
|
||
|
enumerable: true, value: logPosition
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {string} status
|
||
|
* @param {string} stream
|
||
|
* @param {number} fromEventNumber
|
||
|
* @param {string} readDirection
|
||
|
* @param {object[]} events
|
||
|
* @param {number} nextEventNumber
|
||
|
* @param {number} lastEventNumber
|
||
|
* @param {boolean} isEndOfStream
|
||
|
* @constructor
|
||
|
* @property {string} status
|
||
|
* @property {string} stream
|
||
|
* @property {number} fromEventNumber
|
||
|
* @property {string} readDirection
|
||
|
* @property {ResolvedEvent[]} events
|
||
|
* @property {number} nextEventNumber
|
||
|
* @property {number} lastEventNumber
|
||
|
* @property {boolean} isEndOfStream
|
||
|
*/
|
||
|
function StreamEventsSlice(
|
||
|
status, stream, fromEventNumber, readDirection, events, nextEventNumber, lastEventNumber, isEndOfStream
|
||
|
) {
|
||
|
Object.defineProperties(this, {
|
||
|
status: {
|
||
|
enumerable: true, value: status
|
||
|
},
|
||
|
stream: {
|
||
|
enumerable: true, value: stream
|
||
|
},
|
||
|
fromEventNumber: {
|
||
|
enumerable: true, value: fromEventNumber
|
||
|
},
|
||
|
readDirection: {
|
||
|
enumerable: true, value: readDirection
|
||
|
},
|
||
|
events: {
|
||
|
enumerable: true, value: events ? events.map(function(ev) { return new ResolvedEvent(ev); }) : []
|
||
|
},
|
||
|
nextEventNumber: {
|
||
|
enumerable: true, value: nextEventNumber
|
||
|
},
|
||
|
lastEventNumber: {
|
||
|
enumerable: true, value: lastEventNumber
|
||
|
},
|
||
|
isEndOfStream: {
|
||
|
enumerable: true, value: isEndOfStream
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @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) {
|
||
|
Object.defineProperties(this, {
|
||
|
readDirection: {
|
||
|
enumerable: true, value: readDirection
|
||
|
},
|
||
|
fromPosition: {
|
||
|
enumerable: true, value: fromPosition
|
||
|
},
|
||
|
nextPosition: {
|
||
|
enumerable: true, value: nextPosition
|
||
|
},
|
||
|
events: {
|
||
|
enumerable: true, value: events ? events.map(function(ev){ return new ResolvedEvent(ev); }) : []
|
||
|
},
|
||
|
isEndOfStream: {
|
||
|
enumerable: true, value: events === null || events.length === 0
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {Position} logPosition
|
||
|
* @constructor
|
||
|
* @property {Position} logPosition
|
||
|
*/
|
||
|
function DeleteResult(logPosition) {
|
||
|
Object.defineProperties(this, {
|
||
|
logPosition: {
|
||
|
enumerable: true, value: logPosition
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {string} stream
|
||
|
* @param {boolean} isStreamDeleted
|
||
|
* @param {number} metastreamVersion
|
||
|
* @param {object} streamMetadata
|
||
|
* @constructor
|
||
|
* @property {string} stream
|
||
|
* @property {boolean} isStreamDeleted
|
||
|
* @property {number} metastreamVersion
|
||
|
* @property {object} streamMetadata
|
||
|
*/
|
||
|
function RawStreamMetadataResult(stream, isStreamDeleted, metastreamVersion, streamMetadata) {
|
||
|
ensure.notNullOrEmpty(stream);
|
||
|
Object.defineProperties(this, {
|
||
|
stream: {enumerable: true, value: stream},
|
||
|
isStreamDeleted: {enumerable: true, value: isStreamDeleted},
|
||
|
metastreamVersion: {enumerable: true, value: metastreamVersion},
|
||
|
streamMetadata: {enumerable: true, value: streamMetadata}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Exports Constructors
|
||
|
module.exports.Position = Position;
|
||
|
module.exports.toNumber = toNumber;
|
||
|
module.exports.ResolvedEvent = ResolvedEvent;
|
||
|
module.exports.EventReadStatus = EventReadStatus;
|
||
|
module.exports.EventReadResult = EventReadResult;
|
||
|
module.exports.WriteResult = WriteResult;
|
||
|
module.exports.StreamEventsSlice = StreamEventsSlice;
|
||
|
module.exports.AllEventsSlice = AllEventsSlice;
|
||
|
module.exports.DeleteResult = DeleteResult;
|
||
|
module.exports.RawStreamMetadataResult = RawStreamMetadataResult;
|