Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sketchpad: Event-driven design in TypeScript
// Playing around with TypeScript
// Inspiration: https://github.com/abdullin/omni
// core.event
interface DomainEventType {
name: string;
}
interface DomainEvent {
_type: DomainEventType;
}
// lang.ids
type EventId = string;
type TaskId = string;
// lang.events
var TaskAdded: DomainEventType = {name: 'TaskAdded'};
interface TaskAddedAttributes {
eventId: EventId;
taskId: TaskId;
name: string;
}
interface TaskAddedEvent extends DomainEvent, TaskAddedAttributes {}
function newTaskAdded(attr: TaskAddedAttributes): TaskAddedEvent {
return objectAssign(attr, {_type: TaskAdded});
}
var TaskRemoved: DomainEventType = {name: 'TaskRemoved'};
interface TaskRemovedAttributes {
eventId: EventId;
taskId: TaskId;
}
interface TaskRemovedEvent extends DomainEvent, TaskRemovedAttributes {}
function newTaskRemoved(attr: TaskRemovedAttributes): TaskRemovedEvent {
return objectAssign(attr, {_type: TaskRemoved});
}
// views.store
interface TaskItem {
taskId: TaskId;
name: string;
inbox: boolean;
}
interface Store {
[index: string]: TaskItem;
}
function addTask(s: Store, id: TaskId, name: string): Store {
s[id] = {
taskId: id,
name: name,
inbox: false
};
return s;
}
function removeTask(s: Store, id: TaskId): Store {
delete s[id];
return s;
}
// views.denormalizer
function handleEvent(s: Store, e: any): Store {
// Would've liked to use `e: DomainEvent` in func signature but can't...
switch (e._type) {
case TaskAdded:
s = addTask(s, e.taskId, e.name);
break;
case TaskRemoved:
s = removeTask(s, e.taskId);
break;
}
return s;
}
// playground
var s: Store = {};
var e1: TaskAddedEvent = newTaskAdded({
eventId: '12',
taskId: '45',
name: 'Clean dishes'
});
var e2: TaskRemovedEvent = newTaskRemoved({
eventId: '34',
taskId: '45'
});
console.log(JSON.stringify(s));
s = handleEvent(s, e1);
console.log(JSON.stringify(s));
s = handleEvent(s, e2);
console.log(JSON.stringify(s));
// lib
function objectAssign (target, source) {
var from;
var keys;
var to = Object(target);
for (var s = 1; s < arguments.length; s++) {
from = arguments[s];
keys = Object.keys(Object(from));
for (var i = 0; i < keys.length; i++) {
to[keys[i]] = from[keys[i]];
}
}
return to;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.