stream.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // src/utils/stream.ts
  2. var StreamingApi = class {
  3. writer;
  4. encoder;
  5. writable;
  6. abortSubscribers = [];
  7. responseReadable;
  8. /**
  9. * Whether the stream has been aborted.
  10. */
  11. aborted = false;
  12. /**
  13. * Whether the stream has been closed normally.
  14. */
  15. closed = false;
  16. constructor(writable, _readable) {
  17. this.writable = writable;
  18. this.writer = writable.getWriter();
  19. this.encoder = new TextEncoder();
  20. const reader = _readable.getReader();
  21. this.abortSubscribers.push(async () => {
  22. await reader.cancel();
  23. });
  24. this.responseReadable = new ReadableStream({
  25. async pull(controller) {
  26. const { done, value } = await reader.read();
  27. done ? controller.close() : controller.enqueue(value);
  28. },
  29. cancel: () => {
  30. this.abort();
  31. }
  32. });
  33. }
  34. async write(input) {
  35. try {
  36. if (typeof input === "string") {
  37. input = this.encoder.encode(input);
  38. }
  39. await this.writer.write(input);
  40. } catch {
  41. }
  42. return this;
  43. }
  44. async writeln(input) {
  45. await this.write(input + "\n");
  46. return this;
  47. }
  48. sleep(ms) {
  49. return new Promise((res) => setTimeout(res, ms));
  50. }
  51. async close() {
  52. try {
  53. await this.writer.close();
  54. } catch {
  55. }
  56. this.closed = true;
  57. }
  58. async pipe(body) {
  59. this.writer.releaseLock();
  60. await body.pipeTo(this.writable, { preventClose: true });
  61. this.writer = this.writable.getWriter();
  62. }
  63. onAbort(listener) {
  64. this.abortSubscribers.push(listener);
  65. }
  66. /**
  67. * Abort the stream.
  68. * You can call this method when stream is aborted by external event.
  69. */
  70. abort() {
  71. if (!this.aborted) {
  72. this.aborted = true;
  73. this.abortSubscribers.forEach((subscriber) => subscriber());
  74. }
  75. }
  76. };
  77. export {
  78. StreamingApi
  79. };