[{"data":1,"prerenderedAt":751},["ShallowReactive",2],{"page:\u002Fextensions\u002Fkubb-labs\u002Fplugin-fetch\u002Fguides\u002Fserver-sent-events":3},{"id":4,"frontmatter":5,"title":6,"heading":6,"body":7,"path":750,"source":4},"extensions\u002Fkubb-labs\u002Fplugin-fetch\u002Fguides\u002Fserver-sent-events.md",{},"Server-sent events",{"type":8,"value":9,"toc":741},"minimark",[10,23,28,39,158,163,238,244,248,255,343,350,427,431,438,560,564,567,730],[11,12,13,14,18,19,22],"p",{},"Operations returning ",[15,16,17],"code",{},"text\u002Fevent-stream"," produce a typed stream rather than a ",[15,20,21],{},"RequestResult",".",[24,25,27],"h2",{"id":26},"consume-a-stream","Consume a stream",[11,29,30,31,34,35,38],{},"Read the ",[15,32,33],{},"EventStreamResult.stream"," with ",[15,36,37],{},"for await",":",[40,41,45],"pre",{"language":42,"code":43,"class":44},"typescript","import { streamEvents } from '.\u002Fgen\u002Fclients\u002FstreamEvents'\n\nconst { stream } = await streamEvents({})\n\nfor await (const event of stream) {\n  console.info(event.data)\n}","highlights",[15,46,48,75,76,75,78,75,103,75,105,75,127,75,153],{"class":47},"language-typescript",[49,50,53,57,61,65,68,71],"span",{"class":51,"style":52},"line","display: inline",[49,54,56],{"style":55},"color:#d73a49;--hls-dark:#f97583","import ",[49,58,60],{"style":59},"color:#005cc5;--hls-dark:#79b8ff","{ ",[49,62,64],{"style":63},"color:#24292e;--hls-dark:#e1e4e8","streamEvents ",[49,66,67],{"style":59},"} ",[49,69,70],{"style":55},"from ",[49,72,74],{"style":73},"color:#032f62;--hls-dark:#9ecbff","'.\u002Fgen\u002Fclients\u002FstreamEvents'","\n",[49,77],{"class":51,"style":52},[49,79,80,83,85,88,90,93,96,100],{"class":51,"style":52},[49,81,82],{"style":55},"const ",[49,84,60],{"style":59},[49,86,87],{"style":63},"stream ",[49,89,67],{"style":59},[49,91,92],{"style":55},"= ",[49,94,95],{"style":55},"await ",[49,97,99],{"style":98},"color:#6f42c1;--hls-dark:#b392f0","streamEvents",[49,101,102],{"style":59},"({})",[49,104],{"class":51,"style":52},[49,106,107,110,113,115,118,121,124],{"class":51,"style":52},[49,108,109],{"style":55},"for await ",[49,111,112],{"style":59},"(",[49,114,82],{"style":55},[49,116,117],{"style":63},"event ",[49,119,120],{"style":55},"of ",[49,122,123],{"style":63},"stream",[49,125,126],{"style":59},") {",[49,128,129,132,135,137,140,142,145,147,150],{"class":51,"style":52},[49,130,131],{"style":59},"  ",[49,133,134],{"style":63},"console",[49,136,22],{"style":55},[49,138,139],{"style":98},"info",[49,141,112],{"style":59},[49,143,144],{"style":63},"event",[49,146,22],{"style":55},[49,148,149],{"style":59},"data",[49,151,152],{"style":59},")",[49,154,155],{"class":51,"style":52},[49,156,157],{"style":59},"}",[11,159,160,162],{},[15,161,149],{}," is typed from the operation's response schema. Each event also carries the optional SSE\nfields, so you can branch on the event name or read the id:",[40,164,166],{"language":42,"code":165,"class":44},"type ServerSentEvent\u003CTData> = {\n  data: TData\n  event?: string\n  id?: string\n  retry?: number\n}",[15,167,168,75,188,75,199,75,211,75,222,75,234],{"class":47},[49,169,170,173,176,179,182,185],{"class":51,"style":52},[49,171,172],{"style":55},"type ",[49,174,175],{"style":98},"ServerSentEvent",[49,177,178],{"style":55},"\u003C",[49,180,181],{"style":98},"TData",[49,183,184],{"style":55},"> = ",[49,186,187],{"style":59},"{",[49,189,190,192,194,197],{"class":51,"style":52},[49,191,131],{"style":59},[49,193,149],{"style":59},[49,195,196],{"style":63},": ",[49,198,181],{"style":98},[49,200,201,203,205,208],{"class":51,"style":52},[49,202,131],{"style":98},[49,204,144],{"style":63},[49,206,207],{"style":63},"?: ",[49,209,210],{"style":98},"string",[49,212,213,215,218,220],{"class":51,"style":52},[49,214,131],{"style":98},[49,216,217],{"style":63},"id",[49,219,207],{"style":63},[49,221,210],{"style":98},[49,223,224,226,229,231],{"class":51,"style":52},[49,225,131],{"style":98},[49,227,228],{"style":63},"retry",[49,230,207],{"style":63},[49,232,233],{"style":98},"number",[49,235,236],{"class":51,"style":52},[49,237,157],{"style":59},[11,239,240,241,243],{},"The runtime parses each event's ",[15,242,149],{}," as JSON when it is valid and keeps it as the raw string\notherwise.",[24,245,247],{"id":246},"stop-early","Stop early",[11,249,250,251,254],{},"Break out of the loop to stop reading. The underlying reader is canceled when the iterator\nfinishes, so an early ",[15,252,253],{},"break"," releases the stream:",[40,256,258],{"language":42,"code":257,"class":44},"const { stream } = await streamEvents({})\n\nfor await (const event of stream) {\n  if (event.event === 'done') break\n  render(event.data)\n}",[15,259,260,75,278,75,280,75,296,75,322,75,339],{"class":47},[49,261,262,264,266,268,270,272,274,276],{"class":51,"style":52},[49,263,82],{"style":55},[49,265,60],{"style":59},[49,267,87],{"style":63},[49,269,67],{"style":59},[49,271,92],{"style":55},[49,273,95],{"style":55},[49,275,99],{"style":98},[49,277,102],{"style":59},[49,279],{"class":51,"style":52},[49,281,282,284,286,288,290,292,294],{"class":51,"style":52},[49,283,109],{"style":55},[49,285,112],{"style":59},[49,287,82],{"style":55},[49,289,117],{"style":63},[49,291,120],{"style":55},[49,293,123],{"style":63},[49,295,126],{"style":59},[49,297,298,300,303,305,307,309,311,314,317,320],{"class":51,"style":52},[49,299,131],{"style":59},[49,301,302],{"style":55},"if ",[49,304,112],{"style":59},[49,306,144],{"style":63},[49,308,22],{"style":55},[49,310,117],{"style":59},[49,312,313],{"style":55},"=== ",[49,315,316],{"style":73},"'done'",[49,318,319],{"style":59},") ",[49,321,253],{"style":55},[49,323,324,326,329,331,333,335,337],{"class":51,"style":52},[49,325,131],{"style":55},[49,327,328],{"style":98},"render",[49,330,112],{"style":59},[49,332,144],{"style":63},[49,334,22],{"style":55},[49,336,149],{"style":59},[49,338,152],{"style":59},[49,340,341],{"class":51,"style":52},[49,342,157],{"style":59},[11,344,345,346,349],{},"To stop a stream from outside the loop, pass an ",[15,347,348],{},"AbortSignal"," and abort it. Aborting ends the\nrequest and the iteration:",[40,351,353],{"language":42,"code":352,"class":44},"const controller = new AbortController()\nconst { stream } = await streamEvents({ signal: controller.signal })\n\n\u002F\u002F elsewhere, for example on component unmount\ncontroller.abort()",[15,354,355,75,373,75,408,75,410,75,416],{"class":47},[49,356,357,359,362,364,367,370],{"class":51,"style":52},[49,358,82],{"style":55},[49,360,361],{"style":63},"controller ",[49,363,92],{"style":55},[49,365,366],{"style":55},"new ",[49,368,369],{"style":98},"AbortController",[49,371,372],{"style":59},"()",[49,374,375,377,379,381,383,385,387,389,392,395,397,400,402,405],{"class":51,"style":52},[49,376,82],{"style":55},[49,378,60],{"style":59},[49,380,87],{"style":63},[49,382,67],{"style":59},[49,384,92],{"style":55},[49,386,95],{"style":55},[49,388,99],{"style":98},[49,390,391],{"style":59},"({ ",[49,393,394],{"style":59},"signal",[49,396,196],{"style":55},[49,398,399],{"style":63},"controller",[49,401,22],{"style":55},[49,403,404],{"style":59},"signal ",[49,406,407],{"style":59},"})",[49,409],{"class":51,"style":52},[49,411,412],{"class":51,"style":52},[49,413,415],{"style":414},"color:#6a737d;--hls-dark:#6a737d","\u002F\u002F elsewhere, for example on component unmount",[49,417,418,420,422,425],{"class":51,"style":52},[49,419,399],{"style":63},[49,421,22],{"style":55},[49,423,424],{"style":98},"abort",[49,426,372],{"style":59},[24,428,430],{"id":429},"read-the-response","Read the response",[11,432,433,434,437],{},"Read status and headers from the native ",[15,435,436],{},"response"," before iterating:",[40,439,441],{"language":42,"code":440,"class":44},"const { stream, response } = await streamEvents({})\n\nconsole.info(response.status) \u002F\u002F 200\nconsole.info(response.headers.get('x-stream-id'))\n\nfor await (const event of stream) {\n  handle(event.data)\n}",[15,442,443,75,467,75,469,75,491,75,521,75,523,75,539,75,556],{"class":47},[49,444,445,447,449,451,454,457,459,461,463,465],{"class":51,"style":52},[49,446,82],{"style":55},[49,448,60],{"style":59},[49,450,123],{"style":63},[49,452,453],{"style":55},", ",[49,455,456],{"style":63},"response ",[49,458,67],{"style":59},[49,460,92],{"style":55},[49,462,95],{"style":55},[49,464,99],{"style":98},[49,466,102],{"style":59},[49,468],{"class":51,"style":52},[49,470,471,473,475,477,479,481,483,486,488],{"class":51,"style":52},[49,472,134],{"style":63},[49,474,22],{"style":55},[49,476,139],{"style":98},[49,478,112],{"style":59},[49,480,436],{"style":63},[49,482,22],{"style":55},[49,484,485],{"style":59},"status",[49,487,319],{"style":59},[49,489,490],{"style":414},"\u002F\u002F 200",[49,492,493,495,497,499,501,503,505,508,510,513,515,518],{"class":51,"style":52},[49,494,134],{"style":63},[49,496,22],{"style":55},[49,498,139],{"style":98},[49,500,112],{"style":59},[49,502,436],{"style":63},[49,504,22],{"style":55},[49,506,507],{"style":59},"headers",[49,509,22],{"style":55},[49,511,512],{"style":98},"get",[49,514,112],{"style":59},[49,516,517],{"style":73},"'x-stream-id'",[49,519,520],{"style":59},"))",[49,522],{"class":51,"style":52},[49,524,525,527,529,531,533,535,537],{"class":51,"style":52},[49,526,109],{"style":55},[49,528,112],{"style":59},[49,530,82],{"style":55},[49,532,117],{"style":63},[49,534,120],{"style":55},[49,536,123],{"style":63},[49,538,126],{"style":59},[49,540,541,543,546,548,550,552,554],{"class":51,"style":52},[49,542,131],{"style":59},[49,544,545],{"style":98},"handle",[49,547,112],{"style":59},[49,549,144],{"style":63},[49,551,22],{"style":55},[49,553,149],{"style":59},[49,555,152],{"style":59},[49,557,558],{"class":51,"style":52},[49,559,157],{"style":59},[24,561,563],{"id":562},"handle-errors","Handle errors",[11,565,566],{},"Catch non-2xx responses around the call and iteration, and rethrow other errors such as connection failures:",[40,568,570],{"language":42,"code":569,"class":44},"import { ResponseError } from '.\u002Fgen\u002F.kubb\u002Fclient'\n\ntry {\n  const { stream } = await streamEvents({})\n  for await (const event of stream) {\n    handle(event.data)\n  }\n} catch (error) {\n  if (!ResponseError.is(error)) throw error\n  console.error('stream rejected', error.status)\n}",[15,571,572,75,588,75,590,75,597,75,617,75,635,75,652,75,657,75,671,75,702,75,726],{"class":47},[49,573,574,576,578,581,583,585],{"class":51,"style":52},[49,575,56],{"style":55},[49,577,60],{"style":59},[49,579,580],{"style":98},"ResponseError ",[49,582,67],{"style":59},[49,584,70],{"style":55},[49,586,587],{"style":73},"'.\u002Fgen\u002F.kubb\u002Fclient'",[49,589],{"class":51,"style":52},[49,591,592,595],{"class":51,"style":52},[49,593,594],{"style":55},"try ",[49,596,187],{"style":59},[49,598,599,601,603,605,607,609,611,613,615],{"class":51,"style":52},[49,600,131],{"style":59},[49,602,82],{"style":55},[49,604,60],{"style":59},[49,606,87],{"style":63},[49,608,67],{"style":59},[49,610,92],{"style":55},[49,612,95],{"style":55},[49,614,99],{"style":98},[49,616,102],{"style":59},[49,618,619,621,623,625,627,629,631,633],{"class":51,"style":52},[49,620,131],{"style":59},[49,622,109],{"style":55},[49,624,112],{"style":59},[49,626,82],{"style":55},[49,628,117],{"style":63},[49,630,120],{"style":55},[49,632,123],{"style":63},[49,634,126],{"style":59},[49,636,637,640,642,644,646,648,650],{"class":51,"style":52},[49,638,639],{"style":59},"    ",[49,641,545],{"style":98},[49,643,112],{"style":59},[49,645,144],{"style":63},[49,647,22],{"style":55},[49,649,149],{"style":59},[49,651,152],{"style":59},[49,653,654],{"class":51,"style":52},[49,655,656],{"style":59},"  }",[49,658,659,661,664,666,669],{"class":51,"style":52},[49,660,67],{"style":59},[49,662,663],{"style":55},"catch ",[49,665,112],{"style":59},[49,667,668],{"style":63},"error",[49,670,126],{"style":59},[49,672,673,675,677,679,682,685,687,690,692,694,697,700],{"class":51,"style":52},[49,674,131],{"style":59},[49,676,302],{"style":55},[49,678,112],{"style":59},[49,680,681],{"style":55},"!",[49,683,684],{"style":98},"ResponseError",[49,686,22],{"style":55},[49,688,689],{"style":98},"is",[49,691,112],{"style":59},[49,693,668],{"style":63},[49,695,696],{"style":59},")) ",[49,698,699],{"style":55},"throw ",[49,701,668],{"style":63},[49,703,704,707,709,711,713,716,718,720,722,724],{"class":51,"style":52},[49,705,706],{"style":63},"  console",[49,708,22],{"style":55},[49,710,668],{"style":98},[49,712,112],{"style":59},[49,714,715],{"style":73},"'stream rejected'",[49,717,453],{"style":55},[49,719,668],{"style":63},[49,721,22],{"style":55},[49,723,485],{"style":59},[49,725,152],{"style":59},[49,727,728],{"class":51,"style":52},[49,729,157],{"style":59},[731,732,734,735,737,738,740],"blockquote",{"as":733},"note","A drop mid-stream ends the ",[15,736,37],{}," loop. Track the last event's ",[15,739,217],{}," if you need to reconnect\nfrom where the stream stopped.",{"title":742,"searchDepth":743,"depth":743,"links":744},"",5,[745,747,748,749],{"id":26,"depth":746,"text":27},2,{"id":246,"depth":746,"text":247},{"id":429,"depth":746,"text":430},{"id":562,"depth":746,"text":563},"\u002Fextensions\u002Fkubb-labs\u002Fplugin-fetch\u002Fguides\u002Fserver-sent-events",1793747915079]