[{"data":1,"prerenderedAt":2032},["ShallowReactive",2],{"docs:/docs/high-level-sdks/stream":3},{"id":4,"title":5,"body":6,"description":17,"extension":2026,"meta":2027,"navigation":239,"path":2028,"seo":2029,"stem":2030,"__hash__":2031},"docs/docs/high-level-sdks/stream.md","Stream SDK",{"type":7,"value":8,"toc":2012},"minimark",[9,14,18,23,33,38,74,78,115,162,171,198,371,375,399,422,426,1163,1167,1170,1173,1178,1361,1484,1488,1615,1618,1624,1803,1857,1861,2008],[10,11,13],"h1",{"id":12},"nolagstream","@nolag/stream",[15,16,17],"p",{},"Live streaming engagement with comments, reactions, and polls.",[19,20,22],"h2",{"id":21},"overview","Overview",[15,24,25,28,29,32],{},[26,27,13],"code",{}," adds real-time viewer engagement to any live stream. Viewers can post comments, fire reaction bursts, and vote in polls. Broadcasters get live viewer counts and the ability to create and close polls on the fly. Reactions are aggregated into bursts so a wave of emoji becomes one animation rather than a thousand. Your app owns one core NoLag client and injects it into ",[26,30,31],{},"NoLagStream","; the wrapper attaches its behaviour to that connection.",[34,35,37],"h3",{"id":36},"key-features","Key Features",[39,40,41,45,48,54,57,71],"ul",{},[42,43,44],"li",{},"Comment stream with per-viewer author info",[42,46,47],{},"Ephemeral reaction bursts for fire-and-forget emoji animations",[42,49,50,51],{},"Live polls with real-time vote tallying, closed with ",[26,52,53],{},"closePoll()",[42,55,56],{},"Live viewer count updated as viewers join and leave",[42,58,59,60,63,64,63,67,70],{},"Viewer roles (",[26,61,62],{},"viewer",", ",[26,65,66],{},"moderator",[26,68,69],{},"host",") carried in presence",[42,72,73],{},"Automatic reconnection with subscriptions and presence restored",[19,75,77],{"id":76},"how-it-works","How It Works",[15,79,80,82,83,86,87,90,91,94,95,98,99,102,103,106,107,110,111,114],{},[26,81,31],{}," attaches to an injected ",[26,84,85],{},"@nolag/js-sdk"," client and maintains a lobby for viewer counts. Calling ",[26,88,89],{},"joinStream()"," creates a ",[26,92,93],{},"StreamRoom"," that subscribes to three topics: ",[26,96,97],{},"comments"," for viewer comments, ",[26,100,101],{},"_reactions"," for emoji bursts, and ",[26,104,105],{},"polls"," for poll creation, votes, and close events. A ",[26,108,109],{},"CommentStore"," accumulates comments while a ",[26,112,113],{},"PollManager"," tracks the active poll and its running vote totals. The app owns the socket lifecycle; the wrapper never opens or closes it.",[116,117,118,131],"table",{},[119,120,121],"thead",{},[122,123,124,128],"tr",{},[125,126,127],"th",{},"Topic",[125,129,130],{},"Purpose",[132,133,134,144,153],"tbody",{},[122,135,136,141],{},[137,138,139],"td",{},[26,140,97],{},[137,142,143],{},"Viewer comments: text, author info, timestamp",[122,145,146,150],{},[137,147,148],{},[26,149,101],{},[137,151,152],{},"Emoji reaction bursts",[122,154,155,159],{},[137,156,157],{},[26,158,105],{},[137,160,161],{},"Poll creation, vote updates, and close events",[15,163,164,165,170],{},"A viewer who joins sees comments and polls published from that moment on. A fresh subscribe or an ordinary reconnect never replays history; see ",[166,167,169],"a",{"href":168},"/docs/concepts/replay","Replay"," for the one case where the broker replays messages.",[172,173,175],"callout",{"type":174},"info",[15,176,177,181,182,185,186,189,190,193,194,197],{},[178,179,180],"strong",{},"Before you start."," Create an app from the ",[26,183,184],{},"nolag-stream-sdk"," blueprint. That seeds the room this SDK expects (",[26,187,188],{},"live-stream",") and the ",[26,191,192],{},"online"," lobby, and returns an app slug with a random suffix. That slug is the ",[26,195,196],{},"appName"," you pass to the wrapper. You can also do this in the portal: Apps, New App, pick the blueprint.",[199,200,201],"code-tabs",{},[202,203,209],"pre",{"className":204,"code":205,"filename":206,"language":207,"meta":208,"style":208},"language-typescript shiki shiki-themes github-light github-dark","import { NoLagApi } from \"@nolag/js-sdk\";\n\nconst api = new NoLagApi(process.env.NOLAG_API_KEY); // nlg_live_...\nconst app = await api.apps.create({ name: \"My App\", blueprintId: \"nolag-stream-sdk\" });\nconsole.log(app.slug); // e.g. \"my-app-a3f9\": this is your appName\n\nconst actor = await api.actors.create({ name: \"web-client\", actorType: \"user\" });\nconsole.log(actor.accessToken); // shown once; keep it\n","Setup (server side, once)","typescript","",[26,210,211,234,241,274,308,323,328,358],{"__ignoreMap":208},[212,213,216,220,224,227,231],"span",{"class":214,"line":215},"line",1,[212,217,219],{"class":218},"szBVR","import",[212,221,223],{"class":222},"sVt8B"," { NoLagApi } ",[212,225,226],{"class":218},"from",[212,228,230],{"class":229},"sZZnC"," \"@nolag/js-sdk\"",[212,232,233],{"class":222},";\n",[212,235,237],{"class":214,"line":236},2,[212,238,240],{"emptyLinePlaceholder":239},true,"\n",[212,242,244,247,251,254,257,261,264,267,270],{"class":214,"line":243},3,[212,245,246],{"class":218},"const",[212,248,250],{"class":249},"sj4cs"," api",[212,252,253],{"class":218}," =",[212,255,256],{"class":218}," new",[212,258,260],{"class":259},"sScJk"," NoLagApi",[212,262,263],{"class":222},"(process.env.",[212,265,266],{"class":249},"NOLAG_API_KEY",[212,268,269],{"class":222},"); ",[212,271,273],{"class":272},"sJ8bj","// nlg_live_...\n",[212,275,277,279,282,284,287,290,293,296,299,302,305],{"class":214,"line":276},4,[212,278,246],{"class":218},[212,280,281],{"class":249}," app",[212,283,253],{"class":218},[212,285,286],{"class":218}," await",[212,288,289],{"class":222}," api.apps.",[212,291,292],{"class":259},"create",[212,294,295],{"class":222},"({ name: ",[212,297,298],{"class":229},"\"My App\"",[212,300,301],{"class":222},", blueprintId: ",[212,303,304],{"class":229},"\"nolag-stream-sdk\"",[212,306,307],{"class":222}," });\n",[212,309,311,314,317,320],{"class":214,"line":310},5,[212,312,313],{"class":222},"console.",[212,315,316],{"class":259},"log",[212,318,319],{"class":222},"(app.slug); ",[212,321,322],{"class":272},"// e.g. \"my-app-a3f9\": this is your appName\n",[212,324,326],{"class":214,"line":325},6,[212,327,240],{"emptyLinePlaceholder":239},[212,329,331,333,336,338,340,343,345,347,350,353,356],{"class":214,"line":330},7,[212,332,246],{"class":218},[212,334,335],{"class":249}," actor",[212,337,253],{"class":218},[212,339,286],{"class":218},[212,341,342],{"class":222}," api.actors.",[212,344,292],{"class":259},[212,346,295],{"class":222},[212,348,349],{"class":229},"\"web-client\"",[212,351,352],{"class":222},", actorType: ",[212,354,355],{"class":229},"\"user\"",[212,357,307],{"class":222},[212,359,361,363,365,368],{"class":214,"line":360},8,[212,362,313],{"class":222},[212,364,316],{"class":259},[212,366,367],{"class":222},"(actor.accessToken); ",[212,369,370],{"class":272},"// shown once; keep it\n",[19,372,374],{"id":373},"installation","Installation",[199,376,377],{},[202,378,383],{"className":379,"code":380,"filename":381,"language":382,"meta":208,"style":208},"language-bash shiki shiki-themes github-light github-dark","npm install @nolag/stream @nolag/js-sdk\n","Terminal","bash",[26,384,385],{"__ignoreMap":208},[212,386,387,390,393,396],{"class":214,"line":215},[212,388,389],{"class":259},"npm",[212,391,392],{"class":229}," install",[212,394,395],{"class":229}," @nolag/stream",[212,397,398],{"class":229}," @nolag/js-sdk\n",[172,400,401],{"type":174},[15,402,403,406,407,409,410,413,414,417,418,421],{},[178,404,405],{},"Shared connection."," One core NoLag client can back several wrapper SDKs at once, for example stream engagement, chat, and notify on a single socket, as long as each wrapper uses a distinct ",[26,408,196],{},". Each wrapper attaches its handlers on construction and releases them with ",[26,411,412],{},"detach()",", and never touches the socket itself. Your app owns ",[26,415,416],{},"connect()"," and ",[26,419,420],{},"disconnect()",".",[19,423,425],{"id":424},"quick-start","Quick Start",[199,427,428],{},[202,429,432],{"className":204,"code":430,"filename":431,"language":207,"meta":208,"style":208},"import { NoLag } from '@nolag/js-sdk'\nimport { NoLagStream } from '@nolag/stream'\n\n// The app owns one core client. In a browser, pass a token provider so the\n// SDK can mint fresh short-lived client tokens from your backend.\nconst client = NoLag(async () => (await (await fetch('/api/nolag-token')).json()).token)\n\n// Inject the client into the stream wrapper (role: 'viewer', 'moderator', or 'host')\nconst stream = new NoLagStream({\n  client,\n  appName: APP_SLUG, // the slug returned when you created the app\n  username: 'Alice',\n  role: 'viewer',\n})\n\nawait client.connect()   // the app owns the connection\nawait stream.ready()     // wrapper setup complete\n\n// Join the seeded stream\nconst room = stream.joinStream('live-stream')\n\n// Display live viewer count\nstream.on('viewerCountChanged', (count) => {\n  console.log('Viewers:', count)\n})\n\n// Send a comment. Publishers never receive their own comments back, so the\n// wrapper adds it to the local store and emits `commentSent`.\nroom.sendComment('This is amazing!')\n\n// Listen for comments from other viewers\nroom.on('comment', (c) => {\n  console.log(`[${c.username}]: ${c.text}`)\n})\n\n// Send a reaction burst\nroom.sendReaction('🔥')\n\nroom.on('reaction', ({ emoji, count }) => {\n  console.log(`${count}x ${emoji}`)\n})\n\n// Create a poll (typically broadcaster-side). Polls stay open until closePoll().\nconst poll = room.createPoll({\n  question: 'Which feature next?',\n  options: ['Dark mode', 'Mobile app', 'API access'],\n})\n\n// Vote on the active poll\nroom.votePoll(poll.id, 1) // vote for index 1\n\nroom.on('pollUpdated', (p) => {\n  console.log('Results:', p.options.map((o) => `${o.text}: ${o.votes}`))\n})\n\n// Close it when you are done\nroom.closePoll(poll.id)\n\n// Teardown: the wrapper releases its handlers; the app closes the socket.\nstream.detach()\nclient.disconnect()\n","TypeScript",[26,433,434,446,458,462,467,472,523,527,532,550,556,570,582,593,599,604,621,638,643,649,672,677,683,712,728,733,738,744,750,766,771,777,800,834,839,844,850,865,870,899,922,927,932,938,956,967,989,994,999,1005,1024,1029,1051,1103,1108,1113,1119,1130,1135,1141,1152],{"__ignoreMap":208},[212,435,436,438,441,443],{"class":214,"line":215},[212,437,219],{"class":218},[212,439,440],{"class":222}," { NoLag } ",[212,442,226],{"class":218},[212,444,445],{"class":229}," '@nolag/js-sdk'\n",[212,447,448,450,453,455],{"class":214,"line":236},[212,449,219],{"class":218},[212,451,452],{"class":222}," { NoLagStream } ",[212,454,226],{"class":218},[212,456,457],{"class":229}," '@nolag/stream'\n",[212,459,460],{"class":214,"line":243},[212,461,240],{"emptyLinePlaceholder":239},[212,463,464],{"class":214,"line":276},[212,465,466],{"class":272},"// The app owns one core client. In a browser, pass a token provider so the\n",[212,468,469],{"class":214,"line":310},[212,470,471],{"class":272},"// SDK can mint fresh short-lived client tokens from your backend.\n",[212,473,474,476,479,481,484,487,490,493,496,499,502,504,506,509,511,514,517,520],{"class":214,"line":325},[212,475,246],{"class":218},[212,477,478],{"class":249}," client",[212,480,253],{"class":218},[212,482,483],{"class":259}," NoLag",[212,485,486],{"class":222},"(",[212,488,489],{"class":218},"async",[212,491,492],{"class":222}," () ",[212,494,495],{"class":218},"=>",[212,497,498],{"class":222}," (",[212,500,501],{"class":218},"await",[212,503,498],{"class":222},[212,505,501],{"class":218},[212,507,508],{"class":259}," fetch",[212,510,486],{"class":222},[212,512,513],{"class":229},"'/api/nolag-token'",[212,515,516],{"class":222},")).",[212,518,519],{"class":259},"json",[212,521,522],{"class":222},"()).token)\n",[212,524,525],{"class":214,"line":330},[212,526,240],{"emptyLinePlaceholder":239},[212,528,529],{"class":214,"line":360},[212,530,531],{"class":272},"// Inject the client into the stream wrapper (role: 'viewer', 'moderator', or 'host')\n",[212,533,535,537,540,542,544,547],{"class":214,"line":534},9,[212,536,246],{"class":218},[212,538,539],{"class":249}," stream",[212,541,253],{"class":218},[212,543,256],{"class":218},[212,545,546],{"class":259}," NoLagStream",[212,548,549],{"class":222},"({\n",[212,551,553],{"class":214,"line":552},10,[212,554,555],{"class":222},"  client,\n",[212,557,559,562,565,567],{"class":214,"line":558},11,[212,560,561],{"class":222},"  appName: ",[212,563,564],{"class":249},"APP_SLUG",[212,566,63],{"class":222},[212,568,569],{"class":272},"// the slug returned when you created the app\n",[212,571,573,576,579],{"class":214,"line":572},12,[212,574,575],{"class":222},"  username: ",[212,577,578],{"class":229},"'Alice'",[212,580,581],{"class":222},",\n",[212,583,585,588,591],{"class":214,"line":584},13,[212,586,587],{"class":222},"  role: ",[212,589,590],{"class":229},"'viewer'",[212,592,581],{"class":222},[212,594,596],{"class":214,"line":595},14,[212,597,598],{"class":222},"})\n",[212,600,602],{"class":214,"line":601},15,[212,603,240],{"emptyLinePlaceholder":239},[212,605,607,609,612,615,618],{"class":214,"line":606},16,[212,608,501],{"class":218},[212,610,611],{"class":222}," client.",[212,613,614],{"class":259},"connect",[212,616,617],{"class":222},"()   ",[212,619,620],{"class":272},"// the app owns the connection\n",[212,622,624,626,629,632,635],{"class":214,"line":623},17,[212,625,501],{"class":218},[212,627,628],{"class":222}," stream.",[212,630,631],{"class":259},"ready",[212,633,634],{"class":222},"()     ",[212,636,637],{"class":272},"// wrapper setup complete\n",[212,639,641],{"class":214,"line":640},18,[212,642,240],{"emptyLinePlaceholder":239},[212,644,646],{"class":214,"line":645},19,[212,647,648],{"class":272},"// Join the seeded stream\n",[212,650,652,654,657,659,661,664,666,669],{"class":214,"line":651},20,[212,653,246],{"class":218},[212,655,656],{"class":249}," room",[212,658,253],{"class":218},[212,660,628],{"class":222},[212,662,663],{"class":259},"joinStream",[212,665,486],{"class":222},[212,667,668],{"class":229},"'live-stream'",[212,670,671],{"class":222},")\n",[212,673,675],{"class":214,"line":674},21,[212,676,240],{"emptyLinePlaceholder":239},[212,678,680],{"class":214,"line":679},22,[212,681,682],{"class":272},"// Display live viewer count\n",[212,684,686,689,692,694,697,700,704,707,709],{"class":214,"line":685},23,[212,687,688],{"class":222},"stream.",[212,690,691],{"class":259},"on",[212,693,486],{"class":222},[212,695,696],{"class":229},"'viewerCountChanged'",[212,698,699],{"class":222},", (",[212,701,703],{"class":702},"s4XuR","count",[212,705,706],{"class":222},") ",[212,708,495],{"class":218},[212,710,711],{"class":222}," {\n",[212,713,715,718,720,722,725],{"class":214,"line":714},24,[212,716,717],{"class":222},"  console.",[212,719,316],{"class":259},[212,721,486],{"class":222},[212,723,724],{"class":229},"'Viewers:'",[212,726,727],{"class":222},", count)\n",[212,729,731],{"class":214,"line":730},25,[212,732,598],{"class":222},[212,734,736],{"class":214,"line":735},26,[212,737,240],{"emptyLinePlaceholder":239},[212,739,741],{"class":214,"line":740},27,[212,742,743],{"class":272},"// Send a comment. Publishers never receive their own comments back, so the\n",[212,745,747],{"class":214,"line":746},28,[212,748,749],{"class":272},"// wrapper adds it to the local store and emits `commentSent`.\n",[212,751,753,756,759,761,764],{"class":214,"line":752},29,[212,754,755],{"class":222},"room.",[212,757,758],{"class":259},"sendComment",[212,760,486],{"class":222},[212,762,763],{"class":229},"'This is amazing!'",[212,765,671],{"class":222},[212,767,769],{"class":214,"line":768},30,[212,770,240],{"emptyLinePlaceholder":239},[212,772,774],{"class":214,"line":773},31,[212,775,776],{"class":272},"// Listen for comments from other viewers\n",[212,778,780,782,784,786,789,791,794,796,798],{"class":214,"line":779},32,[212,781,755],{"class":222},[212,783,691],{"class":259},[212,785,486],{"class":222},[212,787,788],{"class":229},"'comment'",[212,790,699],{"class":222},[212,792,793],{"class":702},"c",[212,795,706],{"class":222},[212,797,495],{"class":218},[212,799,711],{"class":222},[212,801,803,805,807,809,812,814,816,819,822,824,826,829,832],{"class":214,"line":802},33,[212,804,717],{"class":222},[212,806,316],{"class":259},[212,808,486],{"class":222},[212,810,811],{"class":229},"`[${",[212,813,793],{"class":222},[212,815,421],{"class":229},[212,817,818],{"class":222},"username",[212,820,821],{"class":229},"}]: ${",[212,823,793],{"class":222},[212,825,421],{"class":229},[212,827,828],{"class":222},"text",[212,830,831],{"class":229},"}`",[212,833,671],{"class":222},[212,835,837],{"class":214,"line":836},34,[212,838,598],{"class":222},[212,840,842],{"class":214,"line":841},35,[212,843,240],{"emptyLinePlaceholder":239},[212,845,847],{"class":214,"line":846},36,[212,848,849],{"class":272},"// Send a reaction burst\n",[212,851,853,855,858,860,863],{"class":214,"line":852},37,[212,854,755],{"class":222},[212,856,857],{"class":259},"sendReaction",[212,859,486],{"class":222},[212,861,862],{"class":229},"'🔥'",[212,864,671],{"class":222},[212,866,868],{"class":214,"line":867},38,[212,869,240],{"emptyLinePlaceholder":239},[212,871,873,875,877,879,882,885,888,890,892,895,897],{"class":214,"line":872},39,[212,874,755],{"class":222},[212,876,691],{"class":259},[212,878,486],{"class":222},[212,880,881],{"class":229},"'reaction'",[212,883,884],{"class":222},", ({ ",[212,886,887],{"class":702},"emoji",[212,889,63],{"class":222},[212,891,703],{"class":702},[212,893,894],{"class":222}," }) ",[212,896,495],{"class":218},[212,898,711],{"class":222},[212,900,902,904,906,908,911,913,916,918,920],{"class":214,"line":901},40,[212,903,717],{"class":222},[212,905,316],{"class":259},[212,907,486],{"class":222},[212,909,910],{"class":229},"`${",[212,912,703],{"class":222},[212,914,915],{"class":229},"}x ${",[212,917,887],{"class":222},[212,919,831],{"class":229},[212,921,671],{"class":222},[212,923,925],{"class":214,"line":924},41,[212,926,598],{"class":222},[212,928,930],{"class":214,"line":929},42,[212,931,240],{"emptyLinePlaceholder":239},[212,933,935],{"class":214,"line":934},43,[212,936,937],{"class":272},"// Create a poll (typically broadcaster-side). Polls stay open until closePoll().\n",[212,939,941,943,946,948,951,954],{"class":214,"line":940},44,[212,942,246],{"class":218},[212,944,945],{"class":249}," poll",[212,947,253],{"class":218},[212,949,950],{"class":222}," room.",[212,952,953],{"class":259},"createPoll",[212,955,549],{"class":222},[212,957,959,962,965],{"class":214,"line":958},45,[212,960,961],{"class":222},"  question: ",[212,963,964],{"class":229},"'Which feature next?'",[212,966,581],{"class":222},[212,968,970,973,976,978,981,983,986],{"class":214,"line":969},46,[212,971,972],{"class":222},"  options: [",[212,974,975],{"class":229},"'Dark mode'",[212,977,63],{"class":222},[212,979,980],{"class":229},"'Mobile app'",[212,982,63],{"class":222},[212,984,985],{"class":229},"'API access'",[212,987,988],{"class":222},"],\n",[212,990,992],{"class":214,"line":991},47,[212,993,598],{"class":222},[212,995,997],{"class":214,"line":996},48,[212,998,240],{"emptyLinePlaceholder":239},[212,1000,1002],{"class":214,"line":1001},49,[212,1003,1004],{"class":272},"// Vote on the active poll\n",[212,1006,1008,1010,1013,1016,1019,1021],{"class":214,"line":1007},50,[212,1009,755],{"class":222},[212,1011,1012],{"class":259},"votePoll",[212,1014,1015],{"class":222},"(poll.id, ",[212,1017,1018],{"class":249},"1",[212,1020,706],{"class":222},[212,1022,1023],{"class":272},"// vote for index 1\n",[212,1025,1027],{"class":214,"line":1026},51,[212,1028,240],{"emptyLinePlaceholder":239},[212,1030,1032,1034,1036,1038,1041,1043,1045,1047,1049],{"class":214,"line":1031},52,[212,1033,755],{"class":222},[212,1035,691],{"class":259},[212,1037,486],{"class":222},[212,1039,1040],{"class":229},"'pollUpdated'",[212,1042,699],{"class":222},[212,1044,15],{"class":702},[212,1046,706],{"class":222},[212,1048,495],{"class":218},[212,1050,711],{"class":222},[212,1052,1054,1056,1058,1060,1063,1066,1069,1072,1075,1077,1079,1082,1084,1086,1088,1091,1093,1095,1098,1100],{"class":214,"line":1053},53,[212,1055,717],{"class":222},[212,1057,316],{"class":259},[212,1059,486],{"class":222},[212,1061,1062],{"class":229},"'Results:'",[212,1064,1065],{"class":222},", p.options.",[212,1067,1068],{"class":259},"map",[212,1070,1071],{"class":222},"((",[212,1073,1074],{"class":702},"o",[212,1076,706],{"class":222},[212,1078,495],{"class":218},[212,1080,1081],{"class":229}," `${",[212,1083,1074],{"class":222},[212,1085,421],{"class":229},[212,1087,828],{"class":222},[212,1089,1090],{"class":229},"}: ${",[212,1092,1074],{"class":222},[212,1094,421],{"class":229},[212,1096,1097],{"class":222},"votes",[212,1099,831],{"class":229},[212,1101,1102],{"class":222},"))\n",[212,1104,1106],{"class":214,"line":1105},54,[212,1107,598],{"class":222},[212,1109,1111],{"class":214,"line":1110},55,[212,1112,240],{"emptyLinePlaceholder":239},[212,1114,1116],{"class":214,"line":1115},56,[212,1117,1118],{"class":272},"// Close it when you are done\n",[212,1120,1122,1124,1127],{"class":214,"line":1121},57,[212,1123,755],{"class":222},[212,1125,1126],{"class":259},"closePoll",[212,1128,1129],{"class":222},"(poll.id)\n",[212,1131,1133],{"class":214,"line":1132},58,[212,1134,240],{"emptyLinePlaceholder":239},[212,1136,1138],{"class":214,"line":1137},59,[212,1139,1140],{"class":272},"// Teardown: the wrapper releases its handlers; the app closes the socket.\n",[212,1142,1144,1146,1149],{"class":214,"line":1143},60,[212,1145,688],{"class":222},[212,1147,1148],{"class":259},"detach",[212,1150,1151],{"class":222},"()\n",[212,1153,1155,1158,1161],{"class":214,"line":1154},61,[212,1156,1157],{"class":222},"client.",[212,1159,1160],{"class":259},"disconnect",[212,1162,1151],{"class":222},[19,1164,1166],{"id":1165},"api-reference","API Reference",[34,1168,31],{"id":1169},"nolagstream-1",[15,1171,1172],{},"The main class. Attaches to the injected core client, manages lobby viewer counts, and the stream room lifecycle.",[1174,1175,1177],"h4",{"id":1176},"constructor-options","Constructor Options",[116,1179,1180,1193],{},[119,1181,1182],{},[122,1183,1184,1187,1190],{},[125,1185,1186],{},"Option",[125,1188,1189],{},"Type",[125,1191,1192],{},"Description",[132,1194,1195,1213,1229,1243,1261,1276,1293,1308,1326,1343],{},[122,1196,1197,1202,1207],{},[137,1198,1199],{},[26,1200,1201],{},"client",[137,1203,1204],{},[26,1205,1206],{},"NoLagSocket",[137,1208,1209,1212],{},[178,1210,1211],{},"Required."," The injected core NoLag client the app owns and connects.",[122,1214,1215,1219,1224],{},[137,1216,1217],{},[26,1218,818],{},[137,1220,1221],{},[26,1222,1223],{},"string",[137,1225,1226,1228],{},[178,1227,1211],{}," Display name for this viewer.",[122,1230,1231,1236,1240],{},[137,1232,1233],{},[26,1234,1235],{},"avatar",[137,1237,1238],{},[26,1239,1223],{},[137,1241,1242],{},"Optional avatar URL.",[122,1244,1245,1250,1255],{},[137,1246,1247],{},[26,1248,1249],{},"role",[137,1251,1252],{},[26,1253,1254],{},"'viewer' | 'moderator' | 'host'",[137,1256,1257,1258,1260],{},"Viewer role carried in presence (default ",[26,1259,590],{},").",[122,1262,1263,1268,1273],{},[137,1264,1265],{},[26,1266,1267],{},"metadata",[137,1269,1270],{},[26,1271,1272],{},"Record\u003Cstring, unknown>",[137,1274,1275],{},"Optional custom data attached to viewer presence.",[122,1277,1278,1282,1286],{},[137,1279,1280],{},[26,1281,196],{},[137,1283,1284],{},[26,1285,1223],{},[137,1287,1288,1289,1292],{},"The app slug returned when you created the app (default ",[26,1290,1291],{},"'stream'",", which only works if an app with exactly that slug exists).",[122,1294,1295,1300,1305],{},[137,1296,1297],{},[26,1298,1299],{},"streams",[137,1301,1302],{},[26,1303,1304],{},"string[]",[137,1306,1307],{},"Streams to join once the wrapper is ready.",[122,1309,1310,1315,1320],{},[137,1311,1312],{},[26,1313,1314],{},"maxCommentCache",[137,1316,1317],{},[26,1318,1319],{},"number",[137,1321,1322,1323,1260],{},"Max comments kept in memory per stream (default ",[26,1324,1325],{},"500",[122,1327,1328,1333,1337],{},[137,1329,1330],{},[26,1331,1332],{},"reactionWindow",[137,1334,1335],{},[26,1336,1319],{},[137,1338,1339,1340,1260],{},"Reaction burst aggregation window in ms (default ",[26,1341,1342],{},"3000",[122,1344,1345,1350,1355],{},[137,1346,1347],{},[26,1348,1349],{},"debug",[137,1351,1352],{},[26,1353,1354],{},"boolean",[137,1356,1357,1358,1260],{},"Enable wrapper debug logging (default ",[26,1359,1360],{},"false",[116,1362,1363,1375],{},[119,1364,1365],{},[122,1366,1367,1370,1373],{},[125,1368,1369],{},"Method / Property",[125,1371,1372],{},"Returns",[125,1374,1192],{},[132,1376,1377,1392,1406,1426,1440,1455,1470],{},[122,1378,1379,1384,1389],{},[137,1380,1381],{},[26,1382,1383],{},"ready()",[137,1385,1386],{},[26,1387,1388],{},"Promise\u003Cvoid>",[137,1390,1391],{},"Resolves once wrapper setup completed",[122,1393,1394,1398,1403],{},[137,1395,1396],{},[26,1397,412],{},[137,1399,1400],{},[26,1401,1402],{},"void",[137,1404,1405],{},"Release this wrapper's handlers and topics; terminal, never closes the socket",[122,1407,1408,1413,1417],{},[137,1409,1410],{},[26,1411,1412],{},"joinStream(name, opts?)",[137,1414,1415],{},[26,1416,93],{},[137,1418,1419,1420,1423,1424],{},"Join a live stream session; ",[26,1421,1422],{},"opts.filters"," limits comments and polls to matching values; throws before ",[26,1425,1383],{},[122,1427,1428,1433,1437],{},[137,1429,1430],{},[26,1431,1432],{},"leaveStream(name)",[137,1434,1435],{},[26,1436,1402],{},[137,1438,1439],{},"Leave a stream and unsubscribe from its topics",[122,1441,1442,1447,1452],{},[137,1443,1444],{},[26,1445,1446],{},"getRooms()",[137,1448,1449],{},[26,1450,1451],{},"StreamRoom[]",[137,1453,1454],{},"All joined streams",[122,1456,1457,1462,1467],{},[137,1458,1459],{},[26,1460,1461],{},"getOnlineViewers()",[137,1463,1464],{},[26,1465,1466],{},"StreamViewer[]",[137,1468,1469],{},"All viewers currently online in the lobby",[122,1471,1472,1477,1481],{},[137,1473,1474],{},[26,1475,1476],{},"viewerCount",[137,1478,1479],{},[26,1480,1319],{},[137,1482,1483],{},"Current lobby viewer count, including you",[34,1485,1487],{"id":1486},"events-nolagstream","Events: NoLagStream",[116,1489,1490,1502],{},[119,1491,1492],{},[122,1493,1494,1497,1500],{},[125,1495,1496],{},"Event",[125,1498,1499],{},"Payload",[125,1501,1192],{},[132,1503,1504,1517,1532,1544,1556,1571,1586,1600],{},[122,1505,1506,1511,1514],{},[137,1507,1508],{},[26,1509,1510],{},"connected",[137,1512,1513],{},"none",[137,1515,1516],{},"Wrapper setup completed on a fresh connection",[122,1518,1519,1524,1529],{},[137,1520,1521],{},[26,1522,1523],{},"disconnected",[137,1525,1526],{},[26,1527,1528],{},"reason: string",[137,1530,1531],{},"Connection closed",[122,1533,1534,1539,1541],{},[137,1535,1536],{},[26,1537,1538],{},"reconnecting",[137,1540,1513],{},[137,1542,1543],{},"The client is attempting to reconnect",[122,1545,1546,1551,1553],{},[137,1547,1548],{},[26,1549,1550],{},"reconnected",[137,1552,1513],{},[137,1554,1555],{},"Reconnection successful; streams are restored automatically",[122,1557,1558,1563,1568],{},[137,1559,1560],{},[26,1561,1562],{},"error",[137,1564,1565],{},[26,1566,1567],{},"error: Error",[137,1569,1570],{},"Unrecoverable error occurred",[122,1572,1573,1578,1583],{},[137,1574,1575],{},[26,1576,1577],{},"viewerOnline",[137,1579,1580],{},[26,1581,1582],{},"viewer: StreamViewer",[137,1584,1585],{},"A viewer appeared in the lobby",[122,1587,1588,1593,1597],{},[137,1589,1590],{},[26,1591,1592],{},"viewerOffline",[137,1594,1595],{},[26,1596,1582],{},[137,1598,1599],{},"A viewer left the lobby",[122,1601,1602,1607,1612],{},[137,1603,1604],{},[26,1605,1606],{},"viewerCountChanged",[137,1608,1609],{},[26,1610,1611],{},"count: number",[137,1613,1614],{},"Lobby viewer count changed",[34,1616,93],{"id":1617},"streamroom",[15,1619,1620,1621,1623],{},"Returned by ",[26,1622,89],{},". Handles comments, reactions, polls, and per-stream viewer presence.",[116,1625,1626,1636],{},[119,1627,1628],{},[122,1629,1630,1632,1634],{},[125,1631,1369],{},[125,1633,1372],{},[125,1635,1192],{},[132,1637,1638,1653,1668,1682,1703,1717,1731,1745,1763,1775,1790],{},[122,1639,1640,1645,1650],{},[137,1641,1642],{},[26,1643,1644],{},"sendComment(text, opts?)",[137,1646,1647],{},[26,1648,1649],{},"StreamComment",[137,1651,1652],{},"Publish a comment to this stream; returns the optimistic local copy",[122,1654,1655,1660,1665],{},[137,1656,1657],{},[26,1658,1659],{},"getComments()",[137,1661,1662],{},[26,1663,1664],{},"StreamComment[]",[137,1666,1667],{},"All comments in the local store",[122,1669,1670,1675,1679],{},[137,1671,1672],{},[26,1673,1674],{},"sendReaction(emoji)",[137,1676,1677],{},[26,1678,1402],{},[137,1680,1681],{},"Fire an ephemeral reaction to all viewers",[122,1683,1684,1689,1694],{},[137,1685,1686],{},[26,1687,1688],{},"createPoll(opts)",[137,1690,1691],{},[26,1692,1693],{},"Poll",[137,1695,1696,1697,1700,1701],{},"Create a poll from ",[26,1698,1699],{},"{ question, options: string[] }","; it stays open until ",[26,1702,53],{},[122,1704,1705,1710,1714],{},[137,1706,1707],{},[26,1708,1709],{},"votePoll(pollId, optionIndex)",[137,1711,1712],{},[26,1713,1402],{},[137,1715,1716],{},"Submit a vote for an option by its zero-based index",[122,1718,1719,1724,1728],{},[137,1720,1721],{},[26,1722,1723],{},"closePoll(pollId)",[137,1725,1726],{},[26,1727,1402],{},[137,1729,1730],{},"Close the poll and broadcast final results",[122,1732,1733,1738,1742],{},[137,1734,1735],{},[26,1736,1737],{},"getViewers()",[137,1739,1740],{},[26,1741,1466],{},[137,1743,1744],{},"Remote viewers present in this stream",[122,1746,1747,1752,1756],{},[137,1748,1749],{},[26,1750,1751],{},"setFilters(values, opts?)",[137,1753,1754],{},[26,1755,1402],{},[137,1757,1758,1759],{},"Replace the comment and poll filters; see ",[166,1760,1762],{"href":1761},"/docs/concepts/filters","Filters",[122,1764,1765,1769,1773],{},[137,1766,1767],{},[26,1768,97],{},[137,1770,1771],{},[26,1772,1664],{},[137,1774,1667],{},[122,1776,1777,1782,1787],{},[137,1778,1779],{},[26,1780,1781],{},"activePoll",[137,1783,1784],{},[26,1785,1786],{},"Poll | undefined",[137,1788,1789],{},"The currently open poll, if any",[122,1791,1792,1796,1800],{},[137,1793,1794],{},[26,1795,1476],{},[137,1797,1798],{},[26,1799,1319],{},[137,1801,1802],{},"Viewers present in this stream, including you",[15,1804,1805,1806,1808,1809,63,1812,63,1815,63,1817,63,1820,63,1822,63,1825,63,1828,1831,1832,1835,1836,1808,1838,63,1840,63,1843,63,1846,63,1849,63,1852,1831,1855,421],{},"A ",[26,1807,1649],{}," has ",[26,1810,1811],{},"id",[26,1813,1814],{},"viewerId",[26,1816,818],{},[26,1818,1819],{},"avatar?",[26,1821,828],{},[26,1823,1824],{},"data?",[26,1826,1827],{},"timestamp",[26,1829,1830],{},"status",", and ",[26,1833,1834],{},"isReplay",". A ",[26,1837,1693],{},[26,1839,1811],{},[26,1841,1842],{},"question",[26,1844,1845],{},"options: { text, votes }[]",[26,1847,1848],{},"createdBy",[26,1850,1851],{},"closed",[26,1853,1854],{},"totalVotes",[26,1856,1827],{},[34,1858,1860],{"id":1859},"events-streamroom","Events: StreamRoom",[116,1862,1863,1873],{},[119,1864,1865],{},[122,1866,1867,1869,1871],{},[125,1868,1496],{},[125,1870,1499],{},[125,1872,1192],{},[132,1874,1875,1889,1903,1924,1938,1952,1966,1981,1995],{},[122,1876,1877,1882,1886],{},[137,1878,1879],{},[26,1880,1881],{},"comment",[137,1883,1884],{},[26,1885,1649],{},[137,1887,1888],{},"A comment arrived from another viewer",[122,1890,1891,1896,1900],{},[137,1892,1893],{},[26,1894,1895],{},"commentSent",[137,1897,1898],{},[26,1899,1649],{},[137,1901,1902],{},"Your own comment was added to the local store and published",[122,1904,1905,1910,1915],{},[137,1906,1907],{},[26,1908,1909],{},"reaction",[137,1911,1912],{},[26,1913,1914],{},"ReactionBurst",[137,1916,1917,1918,1920,1921],{},"Reactions aggregated over ",[26,1919,1332],{},": ",[26,1922,1923],{},"{ emoji, count, windowStart, windowEnd }",[122,1925,1926,1931,1935],{},[137,1927,1928],{},[26,1929,1930],{},"pollCreated",[137,1932,1933],{},[26,1934,1693],{},[137,1936,1937],{},"A new poll was opened",[122,1939,1940,1945,1949],{},[137,1941,1942],{},[26,1943,1944],{},"pollUpdated",[137,1946,1947],{},[26,1948,1693],{},[137,1950,1951],{},"Vote tallies updated",[122,1953,1954,1959,1963],{},[137,1955,1956],{},[26,1957,1958],{},"pollClosed",[137,1960,1961],{},[26,1962,1693],{},[137,1964,1965],{},"Poll closed with final results",[122,1967,1968,1973,1978],{},[137,1969,1970],{},[26,1971,1972],{},"viewerJoined",[137,1974,1975],{},[26,1976,1977],{},"StreamViewer",[137,1979,1980],{},"A viewer joined this stream",[122,1982,1983,1988,1992],{},[137,1984,1985],{},[26,1986,1987],{},"viewerLeft",[137,1989,1990],{},[26,1991,1977],{},[137,1993,1994],{},"A viewer left this stream",[122,1996,1997,2001,2005],{},[137,1998,1999],{},[26,2000,1606],{},[137,2002,2003],{},[26,2004,1611],{},[137,2006,2007],{},"Viewer count for this stream changed",[2009,2010,2011],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":208,"searchDepth":236,"depth":236,"links":2013},[2014,2017,2018,2019,2020],{"id":21,"depth":236,"text":22,"children":2015},[2016],{"id":36,"depth":243,"text":37},{"id":76,"depth":236,"text":77},{"id":373,"depth":236,"text":374},{"id":424,"depth":236,"text":425},{"id":1165,"depth":236,"text":1166,"children":2021},[2022,2023,2024,2025],{"id":1169,"depth":243,"text":31},{"id":1486,"depth":243,"text":1487},{"id":1617,"depth":243,"text":93},{"id":1859,"depth":243,"text":1860},"md",{},"/docs/high-level-sdks/stream",{"title":5,"description":17},"docs/high-level-sdks/stream","rRVjaiK0yUGQmW59P6cC0L_ZVGn9A-aV5C5gjzXqK0w",1789869420610]