Last active
January 27, 2016 10:27
-
-
Save zerkalica/dbebb92dce21f1a320ae to your computer and use it in GitHub Desktop.
Observable collection updater
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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