vigetlabs / microcosm

Flux with actions at center stage. Write optimistic updates, cancel requests, and track changes with ease.
http://code.viget.com/microcosm/
MIT License
487 stars 29 forks source link

[microcosm] Split Subject.hash into separate class #514

Closed nhunzaker closed 6 years ago

nhunzaker commented 6 years ago

But it was getting pretty massive, and I didn't like having it as a static method on Subject. This commit moves this function into a separate class that extends from Subject.

What is Subject.hash

Subject.hash is a method used in a few places to reduce an object of nested asynchronous values into a POJO. This is extremely useful for building view models and for generally reducing down any complex async type in Microcosm down into something usable to the outside world:

import { http } from 'microcosm-http'

let answer = Subject.hash({
  users: http.get('/users'),
  postsWithComments: Subject.hash({
    posts: http.get('/posts'),
    comments: http.get('/comments')
  }).map(mergePostsWithComments)
})

// This will emit a stream of updates as it gets answers
answer.subscribe({
  next() {}, // Partially loaded. You might have users, but not posts
  complete() { }, // All users, posts, and comments are loaded
  error () {} // Something went wrong with this entire behavior
})

// Or say you stop caring:
// with microcosm-http, this would cancel all requests
answer.cancel()

This request behavior is additionally illustrated in the file-uploads example.

Why call it SubjectHash?

I don't know. I think this is the closest thing we have to the concept of a ViewModel, but it covers a broad use case of behavior. SubjectTree also came to mind, or something that doesn't use the word Subject, which is pretty vague. I have an issue to track that in https://github.com/vigetlabs/microcosm/issues/511

codecov-io commented 6 years ago

Codecov Report

Merging #514 into master will decrease coverage by 0.01%. The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #514      +/-   ##
==========================================
- Coverage   98.79%   98.78%   -0.02%     
==========================================
  Files          29       30       +1     
  Lines         745      738       -7     
  Branches      149      147       -2     
==========================================
- Hits          736      729       -7     
  Misses          9        9
Impacted Files Coverage Δ
packages/microcosm/src/observable.js 96.07% <ø> (-0.99%) :arrow_down:
packages/microcosm/src/coroutine.js 100% <100%> (ø) :arrow_up:
packages/microcosm-dom/src/action-form.js 100% <100%> (ø) :arrow_up:
packages/microcosm-dom/src/presenter.js 100% <100%> (ø) :arrow_up:
packages/microcosm-dom/src/action-button.js 100% <100%> (ø) :arrow_up:
packages/microcosm/src/subject.js 100% <100%> (+0.99%) :arrow_up:
packages/microcosm/src/microcosm.js 100% <100%> (ø) :arrow_up:
packages/microcosm/src/subject-map.js 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 0372345...a8acb59. Read the comment docs.

nhunzaker commented 6 years ago

@zporter Renamed this to SubjectMap. I'm going to keep jamming on a name, but I'm hopeful that I'll hit some clarity once I've better distinguished the responsibility of this component in Presenters vs Microcosm itself.

Thanks for the review!