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