Skip to content

Instantly share code, notes, and snippets.

@zerkalica
Last active January 27, 2016 10:27
Show Gist options
  • Save zerkalica/dbebb92dce21f1a320ae to your computer and use it in GitHub Desktop.
Save zerkalica/dbebb92dce21f1a320ae to your computer and use it in GitHub Desktop.
Observable collection updater
type Socket = {
create(url: string): Observable;
}
type PostAueryArg = {
id: string;
}
type Comment = {
id: string;
text: string;
from: string;
}
class CommentImpl {
id: string;
text: string;
from: string;
}
@asyncmodel(commentsUpdater)
class CommentCollection extends BaseCollection {
createItem(): Comment {
return new CommentImpl()
}
}
type InitEvent = {
kind: 'init';
comments: Array<Comment>;
}
type CreateCommentEvent = {
kind: 'create';
comment: Comment;
}
type DeleteEvent = {
kind: 'delete';
id: string;
}
type UpdateCommentEvent = {
kind: 'update';
comment: Comment;
}
type CRUDEvent = InitEvent | CreateCommentEvent | UpdateCommentEvent | DeleteEvent;
type Getter<V> = () => V;
// #1
@loader(getter(CommentCollection), SocketImpl, PostAueryArgImpl)
function commentsUpdater(getColl: Getter<CommentCollection>, socket: Socket, post: PostAueryArg) {
const observable: Observable = socket.create(`/post/${post.id}comments/crud`);
return observable.map(function onEvent(event: CRUDEvent) {
const coll: CommentCollection = getColl()
switch (event.kind) {
case 'init':
return coll.init(event.comments)
case 'create':
return coll.add(event.comment)
case 'delete':
return coll.delete(event.id)
case 'update':
return coll.set(event.comment.id, (comment: Comment) => event.comment))
default:
throw new Error('Unknown comments update event: ' + event.kind)
}
})
}
// #2
@loader(SocketImpl, PostAueryArgImpl)
function commentsUpdater(socket: Socket, post: PostAueryArg) {
const observable: Observable = socket.create(`/post/${post.id}comments/crud`);
return observable.map(function onEvent(event: CRUDEvent) {
return function updateCommentsEvent(coll: CommentCollection) {
switch (event.kind) {
case 'init':
return coll.init(event.comments)
case 'create':
return coll.add(event.comment)
case 'delete':
return coll.delete(event.id)
case 'update':
return coll.set(event.comment.id, (comment: Comment) => event.comment))
default:
throw new Error('Unknown comments update event: ' + event.kind)
}
}
})
}
// #3
@asyncFacet(SocketImpl, PostAueryArgImpl)
function commentsCrud(socket: Socket, post: PostAueryArg): Observable {
return socket.create(`/post/${post.id}comments/crud`);
}
@facet(commentsCrud, CommentCollection)
function commentsUpdater(commentsCrud: Observable, coll: CommentCollection) {
return commentsCrud.map(function onEvent(event: CRUDEvent) {
switch (event.kind) {
case 'init':
return coll.init(event.comments)
case 'create':
return coll.add(event.comment)
case 'delete':
return coll.delete(event.id)
case 'update':
return coll.set(event.comment.id, (comment: Comment) => event.comment))
default:
throw new Error('Unknown comments update event: ' + event.kind)
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment