Skip to content

Instantly share code, notes, and snippets.

@mauricioklein
Last active January 22, 2019 15:51
Show Gist options
  • Save mauricioklein/68d91ea4b839dfe27993d7999ec61421 to your computer and use it in GitHub Desktop.
Save mauricioklein/68d91ea4b839dfe27993d7999ec61421 to your computer and use it in GitHub Desktop.
CQRS
const uuidv1 = require('uuid/v1');
class OrderId {
id: string
constructor(id: string) {
this.id = id
}
static fromString(id: string): OrderId {
return new this(id)
}
static generateNew(): OrderId {
return new this(uuidv1())
}
equals(other: OrderId): boolean {
return this.id === other.id
}
toString(): string {
return this.id
}
}
const orderA = new OrderId("123")
const orderB = OrderId.generateNew()
const orderC = OrderId.fromString("123")
console.log("Order A:", orderA.toString())
console.log("Order B:", orderB.toString())
console.log("Order C:", orderC.toString())
console.log("Order A equals to Order B?", orderA.equals(orderB))
console.log("Order A equals to itself?", orderA.equals(orderA))
console.log("Order A equals to Order C?", orderA.equals(orderC))
import uuidv1 from 'uuid/v1';
import * as moment from 'moment'
const FORMAT: string = "YYYY-MM-DD HH:mm:ss"
class Timestamp {
unixTs: number
constructor(timestamp: string) {
const parsedDateTime = moment(timestamp, FORMAT)
if(!parsedDateTime.isValid()) throw `"${timestamp}" is not a valid datetime`
this.unixTs = parsedDateTime.unix()
}
equals(other: Timestamp): boolean {
return this.unixTs === other.unixTs
}
isBefore(other: Timestamp): boolean {
return (this.unixTs < other.unixTs)
}
isAfter(other: Timestamp): boolean {
return (this.unixTs > other.unixTs)
}
toString(): string {
return moment.unix(this.unixTs).format(FORMAT)
}
}
const ts1 = new Timestamp("2019-01-20 08:00:00")
const ts2 = new Timestamp("2019-01-22 11:12:00")
console.log("TS1", ts1.toString());
console.log("TS2", ts2.toString());
console.log("TS1 equals TS2?", ts1 === ts2);
console.log("TS1 before TS2?", ts1.isBefore(ts2));
console.log("TS1 after TS2?", ts1.isAfter(ts2));
const ts3 = new Timestamp("wicbniwdbvwibvb")
import * as moment from 'moment'
const FORMAT: string = "YYYY-MM-DD HH:mm:ss"
class InvalidTimestampError extends Error {
constructor(timestamp) {
super(`${timestamp}" is not a valid datetime`)
}
}
class Timestamp {
private unixTs: number
constructor(timestamp: string) {
const parsedDateTime = moment(timestamp, FORMAT)
if(!parsedDateTime.isValid()) throw new InvalidTimestampError(timestamp)
this.unixTs = parsedDateTime.unix()
}
equals(other: Timestamp): boolean {
return this.unixTs === other.unixTs
}
isBefore(other: Timestamp): boolean {
return this.unixTs < other.unixTs
}
isAfter(other: Timestamp): boolean {
return this.unixTs > other.unixTs
}
toString(): string {
return moment.unix(this.unixTs).format(FORMAT)
}
}
class MemberRegistered {
private _id: string
private _name: string
private _email: string
private _registeredAt: Timestamp
constructor(id: string, name: string, email: string, registeredAt: Timestamp) {
this._id = id
this._name = name
this._email = email
this._registeredAt = registeredAt
}
get id(): string {
return this._id
}
get name(): string {
return this._name
}
get email(): string {
return this._email
}
get registeredAt(): Timestamp {
return this._registeredAt
}
}
const id = "123"
const name = "Max Mustermann"
const email = "[email protected]"
const registeredAt = new Timestamp("2019-01-20 08:00:00")
const event = new MemberRegistered(id, name, email, registeredAt)
console.log("ID:", event.id);
console.log("Name:", event.name);
console.log("Email:", event.email);
console.log("Registered at:", event.registeredAt.toString());
import * as moment from 'moment'
const FORMAT: string = "YYYY-MM-DD HH:mm:ss"
class InvalidTimestampError extends Error {
constructor(timestamp) {
super(`${timestamp}" is not a valid datetime`)
}
}
class Timestamp {
private unixTs: number
constructor(timestamp: string) {
const parsedDateTime = moment(timestamp, FORMAT)
if(!parsedDateTime.isValid()) throw new InvalidTimestampError(timestamp)
this.unixTs = parsedDateTime.unix()
}
equals(other: Timestamp): boolean {
return this.unixTs === other.unixTs
}
isBefore(other: Timestamp): boolean {
return this.unixTs < other.unixTs
}
isAfter(other: Timestamp): boolean {
return this.unixTs > other.unixTs
}
toString(): string {
return moment.unix(this.unixTs).format(FORMAT)
}
}
class MemberChangedTheirEmail {
private _memberId: string
private _oldEmail: string
private _newEmail: string
private _timestamp: Timestamp
constructor(memberId: string, oldEmail: string, newEmail: string, timestamp: Timestamp) {
this._memberId = memberId
this._oldEmail = oldEmail
this._newEmail = newEmail
this._timestamp = timestamp
}
get memberId(): string {
return this._memberId
}
get oldEmail(): string {
return this._oldEmail
}
get newEmail(): string {
return this._newEmail
}
get timestamp(): Timestamp {
return this._timestamp
}
}
const memberId = "123"
const oldEmail = "[email protected]"
const newEmail = "[email protected]"
const registeredAt = new Timestamp("2019-01-20 08:00:00")
const event = new MemberChangedTheirEmail(memberId, oldEmail, newEmail, registeredAt)
console.log("Member ID:", event.memberId);
console.log("Old email:", event.oldEmail);
console.log("New email:", event.newEmail);
console.log("Timestamp:", event.timestamp.toString());
import * as moment from 'moment'
import { appendFile } from 'fs'
const FORMAT: string = "YYYY-MM-DD HH:mm:ss"
class InvalidTimestampError extends Error {
constructor(timestamp) {
super(`${timestamp}" is not a valid datetime`)
}
}
class Timestamp {
private unixTs: number
constructor(timestamp: string) {
const parsedDateTime = moment(timestamp, FORMAT)
if(!parsedDateTime.isValid()) throw new InvalidTimestampError(timestamp)
this.unixTs = parsedDateTime.unix()
}
equals(other: Timestamp): boolean {
return this.unixTs === other.unixTs
}
isBefore(other: Timestamp): boolean {
return this.unixTs < other.unixTs
}
isAfter(other: Timestamp): boolean {
return this.unixTs > other.unixTs
}
toString(): string {
return moment.unix(this.unixTs).format(FORMAT)
}
}
class MemberRegistered {
private _id: string
private _name: string
private _email: string
private _registeredAt: Timestamp
constructor(id: string, name: string, email: string, registeredAt: Timestamp) {
this._id = id
this._name = name
this._email = email
this._registeredAt = registeredAt
}
get id(): string {
return this._id
}
get name(): string {
return this._name
}
get email(): string {
return this._email
}
get registeredAt(): Timestamp {
return this._registeredAt
}
}
class MemberChangedTheirEmail {
private _memberId: string
private _oldEmail: string
private _newEmail: string
private _timestamp: Timestamp
constructor(memberId: string, oldEmail: string, newEmail: string, timestamp: Timestamp) {
this._memberId = memberId
this._oldEmail = oldEmail
this._newEmail = newEmail
this._timestamp = timestamp
}
get memberId(): string {
return this._memberId
}
get oldEmail(): string {
return this._oldEmail
}
get newEmail(): string {
return this._newEmail
}
get timestamp(): Timestamp {
return this._timestamp
}
}
const LOG_FILE_PATH = "./events.log"
interface Handleble {
handle(event: any)
}
class LogEvents {
handle(event: any) {
appendFile(LOG_FILE_PATH, this.toMsg(event), err => {
if (err) console.error(`Failed to log event: ${err}`)
});
}
private toMsg(event: any) {
return `Received an event of type ${event.constructor.name}\n`
}
}
const logEvents = new LogEvents
const memberId = "123"
const memberName = "Max Mustermann"
const oldEmail = "[email protected]"
const newEmail = "[email protected]"
const registeredAt = new Timestamp("2019-01-20 08:00:00")
const memberRegisteredEvent = new MemberRegistered(memberId, memberName, oldEmail, registeredAt)
const memberChangedEmailEvent = new MemberChangedTheirEmail(memberId, oldEmail, newEmail, registeredAt)
logEvents.handle(memberRegisteredEvent)
logEvents.handle(memberChangedEmailEvent)
import * as moment from 'moment'
import { appendFile } from 'fs'
import { listeners } from 'cluster';
const FORMAT: string = "YYYY-MM-DD HH:mm:ss"
class InvalidTimestampError extends Error {
constructor(timestamp) {
super(`${timestamp}" is not a valid datetime`)
}
}
class Timestamp {
private unixTs: number
constructor(timestamp: string) {
const parsedDateTime = moment(timestamp, FORMAT)
if(!parsedDateTime.isValid()) throw new InvalidTimestampError(timestamp)
this.unixTs = parsedDateTime.unix()
}
equals(other: Timestamp): boolean {
return this.unixTs === other.unixTs
}
isBefore(other: Timestamp): boolean {
return this.unixTs < other.unixTs
}
isAfter(other: Timestamp): boolean {
return this.unixTs > other.unixTs
}
toString(): string {
return moment.unix(this.unixTs).format(FORMAT)
}
}
class MemberRegistered {
private _id: string
private _name: string
private _email: string
private _registeredAt: Timestamp
constructor(id: string, name: string, email: string, registeredAt: Timestamp) {
this._id = id
this._name = name
this._email = email
this._registeredAt = registeredAt
}
get id(): string {
return this._id
}
get name(): string {
return this._name
}
get email(): string {
return this._email
}
get registeredAt(): Timestamp {
return this._registeredAt
}
}
class MemberChangedTheirEmail {
private _memberId: string
private _oldEmail: string
private _newEmail: string
private _timestamp: Timestamp
constructor(memberId: string, oldEmail: string, newEmail: string, timestamp: Timestamp) {
this._memberId = memberId
this._oldEmail = oldEmail
this._newEmail = newEmail
this._timestamp = timestamp
}
get memberId(): string {
return this._memberId
}
get oldEmail(): string {
return this._oldEmail
}
get newEmail(): string {
return this._newEmail
}
get timestamp(): Timestamp {
return this._timestamp
}
}
const LOG_FILE_PATH = "./events.log"
interface Handleble {
handle(event: any)
}
class LogEvents {
handle(event: any) {
appendFile(LOG_FILE_PATH, this.toMsg(event), err => {
if (err) console.error(`Failed to log event: ${err}`)
});
}
private toMsg(event: any) {
return `Received an event of type ${event.constructor.name}\n`
}
}
class EventDispatcher {
private listeners
constructor() {
this.listeners = []
}
addListener(listener: Handleble) {
this.listeners.push(listener)
}
dispatch(event: any) {
this.listeners.forEach(listener => listener.handle(event))
}
}
const memberId = "123"
const memberName = "Max Mustermann"
const oldEmail = "[email protected]"
const newEmail = "[email protected]"
const registeredAt = new Timestamp("2019-01-20 08:00:00")
const memberRegisteredEvent = new MemberRegistered(memberId, memberName, oldEmail, registeredAt)
const memberChangedEmailEvent = new MemberChangedTheirEmail(memberId, oldEmail, newEmail, registeredAt)
const logEvents = new LogEvents
const dispatcher = new EventDispatcher
dispatcher.addListener(logEvents)
dispatcher.dispatch(memberRegisteredEvent)
dispatcher.dispatch(memberChangedEmailEvent)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment