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