makeStream = (acks, data) => {
  const stream = harden({
    /**
     * @param {TWrite} value
     */
    next(value) {
      // Note the shallow freeze since value is not guaranteed to be freezable
      // (typed arrays are not).
      data.put(freeze({ value, done: false }));
      return acks.get();
    },
    /**
     * @param {TWriteReturn} value
     */
    return(value) {
      data.put(freeze({ value, done: true }));
      return acks.get();
    },
    /**
     * @param {Error} error
     */
    throw(error) {
      data.put(harden(Promise.reject(error)));
      return acks.get();
    },
    [Symbol.asyncIterator]() {
      return stream;
    },
  });
  return stream;
}
@template TRead
@template TWrite
@template TReadReturn
@template TWriteReturn
@param {import('./types.js').AsyncSpring<IteratorResult<TRead, TReadReturn>>} acks
@param {import('./types.js').AsyncSink<IteratorResult<TWrite, TWriteReturn>>} data