| 257 | } |
| 258 | |
| 259 | func (r *streamReader) Read(p []byte) (n int, err error) { |
| 260 | if r.err != nil { |
| 261 | return 0, r.err |
| 262 | } |
| 263 | if len(r.pending) == 0 { |
| 264 | var ( |
| 265 | bCh = make(chan []byte, 1) |
| 266 | errCh = make(chan error, 1) |
| 267 | ) |
| 268 | success := js.FuncOf(func(this js.Value, args []js.Value) any { |
| 269 | result := args[0] |
| 270 | if result.Get("done").Bool() { |
| 271 | errCh <- io.EOF |
| 272 | return nil |
| 273 | } |
| 274 | value := make([]byte, result.Get("value").Get("byteLength").Int()) |
| 275 | js.CopyBytesToGo(value, result.Get("value")) |
| 276 | bCh <- value |
| 277 | return nil |
| 278 | }) |
| 279 | defer success.Release() |
| 280 | failure := js.FuncOf(func(this js.Value, args []js.Value) any { |
| 281 | // Assumes it's a TypeError. See |
| 282 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError |
| 283 | // for more information on this type. See |
| 284 | // https://streams.spec.whatwg.org/#byob-reader-read for the spec on |
| 285 | // the read method. |
| 286 | errCh <- errors.New(args[0].Get("message").String()) |
| 287 | return nil |
| 288 | }) |
| 289 | defer failure.Release() |
| 290 | r.stream.Call("read").Call("then", success, failure) |
| 291 | select { |
| 292 | case b := <-bCh: |
| 293 | r.pending = b |
| 294 | case err := <-errCh: |
| 295 | r.err = err |
| 296 | return 0, err |
| 297 | } |
| 298 | } |
| 299 | n = copy(p, r.pending) |
| 300 | r.pending = r.pending[n:] |
| 301 | return n, nil |
| 302 | } |
| 303 | |
| 304 | func (r *streamReader) Close() error { |
| 305 | // This ignores any error returned from cancel method. So far, I did not encounter any concrete |