Exploring Composable Effect.Services for Component Requirements in TypeScript

Relay + GraphQL is fantastic for code locality and composing data requirements
What if we could do something like that, with with composable Effect.Services instead of GraphQL
I've been exploring it and I've made some good progress. Barely scratched the surface, but I'm already pretty hooked

Solves the problem of composing component Requirements without needing to fix TypeScript itself. Zero extra tooling.

https://gist.github.com/subtleGradient/00f326213ea59c4660584fbd078dabf8

Needs work, obviously. But I think this is showing some promise.

export class TaskListViewProps extends Effect.Service<TaskListViewProps>()("TaskListViewProps", {
  effect: Effect.gen(function* () {
    const tasksAtom = Atom.make(yield* TaskModel.allTasks);
    const selectedTaskAtom = Atom.make({ id: 1, name: "New Task", status: "pending" })
    return { tasksAtom, selectedTaskAtom };
  })
}) { }

export function TaskListView(props: TaskListViewProps & { abc?: number; }) {
  const tasksResult = useAtomSuspense(props.tasksAtom);
  const setSelectedTask = useAtomSet(props.selectedTaskAtom);
  return <>
    <ol>
      {tasksResult.value?.map((task) =>
        <li key={task.id}>
          <button onClick={() => startTransition(() => setSelectedTask(task))}>Select</button>
          <TaskView {...TaskViewProps.makeStatic(task)} />
        </li>
      )}
    </ol>
    <TaskView {...TaskViewProps.make({ taskAtom: props.selectedTaskAtom })} />
  </>
}
Was this page helpful?