Open joedski opened 5 years ago
Thinking about it, we don't actually care how the sources are created, only what their types are. We could just do something like this:
export default {
mixins: [StreamsMixin],
streams: {
sources({ fromWatch }) {
// Watch a prop or data named 'label'.
const labelProp = fromWatch('label')
// Watch the result of combining two props.
const combinedProp = fromWatch(() => this.a + this.b)
// Watch options.
const deepProp = fromWatch('someObject', { deep: true })
// Plain streams if we're just shoving things in from events.
const buttonClicks = flyd.stream()
return { labelProp, combinedProp, deepProp, buttonClicks }
},
// the sources arg here then has the type of the return value
// of the sources function above.
sinks(sources) {
const clickCount = sources.buttonClicks.pipe(flyd.scan(acc => acc + 1, 0))
const clickCountLabel = flyd.combine(
(clickCount, clickCountLabel, self, changed) => {
return `${clickCount()} ${clickCountLabel()}`
},
[clickCount, sources.labelProp]
)
return {
clickCount,
clickCountLabel,
}
},
},
}
where fromWatch
is just a convenience function that does this:
const fromWatch = (watchHandler, watchOptions) => {
const stream = flyd.stream()
this.$watch(watchHandler, next => stream(next), { immediate: true, ...watchOptions })
return stream
}
This gives us the ability to infer a type for sources
based on what's written, without saying anything about the implementation. Excellent.
The way
source()
works doesn't really lend itself to Typescript component typing. How to resolve that?streams
is an object with asources
map of names to watches andsinks
is a function that accepts the map of names to source streams and returns the map of names to sink streams. It's mildly annoying, but declares everything up front. Just have to not kill tsc...Example