Effect CommunityEC
Effect Community5mo ago
1 reply
kesin

Creating a Cookie Atom with Effect and Handling Server-Side Rendering

I'm relatively new to effect and only started looking at atom today.

I was inspired by the searchParam example, and tried to create some similar behavior for cookies.

export const cookieAtom = <A, I>(options: {
  name: string
  schema: Schema.Schema<A, I>
}) => {
  const store = globalThis.cookieStore
  const decode = Schema.decodeEither(options.schema)

  const getValue = pipe(
    Effect.promise(() => store.get(options.name)),
    Effect.map(Option.fromNullable),
    Effect.map(
      Option.match({
        onNone: () => Option.none<A>(),
        onSome: (value) => Either.getRight(decode(value as I))
      })
    )
  )

  return Atom.make(
    Effect.fn(function*(get: Atom.Context) {
      const handleChange = () => {
        store.get(options.name).then((newValue) => {
          if (newValue === null) {
            get.setSelf(Option.none<A>())
            return
          }

          get.setSelf(Either.getRight(decode(newValue as I)))
        })
      }

      store.addEventListener("change", handleChange)
      get.addFinalizer(() => {
        store.removeEventListener("change", handleChange)
      })

      return yield* getValue
    })
  )
}


Can I get some guidance on if I'm moving in the right direction (or possible improvements)?

I know that I should have a more clever approach to server rendering... perhaps the cookieStore should be isomorphically provided (i.e. separate implementations for client and server runtimes)?
Was this page helpful?