pvorona/observable

Experiments with API

Opened this issue · 0 comments

Caching observe that doesn't call get on each dependency and instead memoizes last seen values.

  • What's the use case and why is it useful?

Unify eager and lazy interfaces

What's the purpose?

  1. Expose new observable.lazy interface
  2. observable.lazy interface can be used to implement animatable and reduce code duplication
  3. Symmetrical APIs for eager and lazy

Variants:

  • References: observable.eager and observable.lazy
  • Reference with default to eager: observable and observable.lazy
  • Options:observable(1, { lazy: true }) and observable(1, { lazy: false })

Initialize observable with function.

What's the purpose?

  1. Hiding side effects
  2. Scoping related logic

Negative side effects:

  1. Observable initialized without value => boxed type is T | undefined instead of T. This is an implementation detail, the public interface is unchanged.
Examples:
  • Sync function, Immediate invocation + interval:
const time = observable(set => {
   set(Date.now())
   setInterval(() => {
     set(Date.now())
   }, 1000)
 })
  • Async function + fetch:
const data = observable(async (set) => {
  set({ state: 'loading' })
  try {
    const response = await fetch('api')
    const data = await response.json()
    set({ state: 'success', data })
  } catch (error) {
    set({ state: 'failure', error })
  }
})
  • Async:
 const time = observable(async (set) => {
   while (true) {
     set(Date.now())
     await delay(1000)
   }
 })
  • Async generator:
const time = observable(() * => {
   while (true) {
     yield Date.now()
     await delay(1000)
   }
 })

Lazy as option:

  • computeLazy -> compute with { lazy: true }
  • observe starts having lazy as well. What are the use cases for lazy observation?

Done:

Observe with options

  • observe with or without values: { collectValues: boolean }
  • observe with or without immediate invocation: { fireImmediate: boolean }