Skip to content

Return async iterables from commands #16190

Description

@Rich-Harris

Describe the problem

If a command kicks off a long-running task, and you want to get progress updates, you basically have to return an ID and use that to call a query.live. It involves a bunch of book-keeping on both sides of the network divide.

In some respects this is the right way to deal with it — you can use that live query in different contexts, and if it's a really long running task then you can come back to it after navigating somewhere else — but for a lot of smaller jobs, being able to get progress reports directly from the command is the sweet spot.

Describe the proposed solution

Something like this — essentially, adding async iterables to the list of things that commands can return:

export const insertLargeThing = command(v.object(...), async function* (data) {
  yield { progress: 0 };

  const task = startTask(data);

  while (!task.done) {
    yield { progress: task.progress };
    await sleep(50);
  }
});
<button
  onclick={async () => {
    for await (const task of insertLargeThing(...)) {
      progress = task.progress;
    }

    done = true;
  }}
>
  insert large thing
</button>

Alternatives considered

not doing this

Importance

nice to have

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions