liveblocks 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
- import{a as W,b as Je,c as Y,d as F,e as ne,f as D,g,h as be,i as Ge}from"./chunk-27HMDMOH.js";import{Promise_withResolvers as ss,WebsocketCloseCodes as Dt}from"@liveblocks/core";import{ZenRelay as rs}from"@liveblocks/zenrouter";import Ue from"bun";import{join as ns}from"path";import{nanoid as bo,Permission as Et}from"@liveblocks/core";import{ProtocolVersion as ht}from"@liveblocks/server";import{nanoid as eo,WebsocketCloseCodes as He}from"@liveblocks/core";import{DefaultMap as to,Room as oo}from"@liveblocks/server";import{Database as so}from"bun:sqlite";import{mkdirSync as Xe,mkdtempSync as ro,rmSync as no}from"fs";import{tmpdir as io}from"os";import{dirname as ao,join as pe,resolve as Ke}from"path";import{asPos as zt,CrdtType as G,nn as Vt}from"@liveblocks/core";import{makeInMemorySnapshot as Kt,NestedMap as Ht,plainLsonToNodeStream as Xt,quote as B}from"@liveblocks/server";import{Database as Wt}from"bun:sqlite";function K(t){try{return t!==void 0?JSON.parse(t):void 0}catch{return}}function ze(t){if(t>512)throw new Error("More than 512 params not supported");return new Array(t).fill("?").join(",")}function qt(t){return Array.isArray(t)?t:Array.from(t)}function Zt(t){return t.query("SELECT node_id, crdt_json FROM nodes").values().map(([e,o])=>[e,K(o)])}function ie(t,e){let o=t.prepare(`INSERT INTO nodes (node_id, crdt_json)
1
+ import{a as Z,b as $e,c as z,d as F,e as ie,f as P,g,h as Oe,i as Ye}from"./chunk-27HMDMOH.js";import{Promise_withResolvers as os,WebsocketCloseCodes as jt}from"@liveblocks/core";import{ZenRelay as ss}from"@liveblocks/zenrouter";import Je from"bun";import{join as rs}from"path";import{nanoid as So}from"@liveblocks/core";import{ProtocolVersion as It}from"@liveblocks/server";import{nanoid as to,WebsocketCloseCodes as We}from"@liveblocks/core";import{DefaultMap as oo,Room as so}from"@liveblocks/server";import{Database as ro}from"bun:sqlite";import{mkdirSync as qe,mkdtempSync as no,rmSync as io}from"fs";import{tmpdir as ao}from"os";import{dirname as co,join as fe,resolve as Xe}from"path";import{asPos as zt,CrdtType as $,nn as Kt}from"@liveblocks/core";import{makeInMemorySnapshot as Ht,NestedMap as Xt,plainLsonToNodeStream as Wt,quote as J}from"@liveblocks/server";import{Database as qt}from"bun:sqlite";function H(t){try{return t!==void 0?JSON.parse(t):void 0}catch{return}}function Ke(t){if(t>512)throw new Error("More than 512 params not supported");return new Array(t).fill("?").join(",")}function Zt(t){return Array.isArray(t)?t:Array.from(t)}function Qt(t){return t.query("SELECT node_id, crdt_json FROM nodes").values().map(([e,o])=>[e,H(o)])}function ae(t,e){let o=t.prepare(`INSERT INTO nodes (node_id, crdt_json)
2
2
  VALUES (?, ?)
3
- ON CONFLICT (node_id) DO UPDATE SET crdt_json = ?`);t.transaction(i=>{for(let[a,d]of i){let c=JSON.stringify(d);o.run(a,c,c)}})(e)}function Ve(t,e){let o=qt(e),s=o.length;t.query(`DELETE FROM nodes WHERE node_id IN (${ze(s)})`).run(...o)}function $e(t){let e=new Ht;for(let[o,s]of t){if(s.parentId===void 0)continue;let i=e.get(s.parentId,s.parentKey);(i===void 0||o>i)&&e.set(s.parentId,s.parentKey,o)}return e}function Qt(t,e){let o=new Map(Zt(t));o.has("root")||o.set("root",{type:G.OBJECT,data:{}});let s=new Set,i=["root"],a=new Map,d=$e(o);for(;i.length>0;){let h=i.pop(),S=Vt(o.get(h));if(S.type===G.OBJECT)for(let u of d.keysAt(h))Object.prototype.hasOwnProperty.call(S.data,u)&&(delete S.data[u],s.add(h),e.warn(`[integrity] Found data key ${B(u)} from ${B(h)} (conflicted with child node)`));if(S.type!==G.REGISTER)i.push(...d.valuesAt(h));else if(o.get(S.parentId)?.type===G.OBJECT)continue;a.set(h,S)}let c=new Set;for(let[h,S]of o)a.has(h)||(S.parentId!==void 0&&a.has(S.parentId)?a.get(S.parentId)?.type===G.REGISTER?e.warn(`[integrity] Found unreachable node ${B(h)} (child of live register)`):e.warn(`[integrity] Found conflicting sibling ${B(h)} (conflicted with ${B(d.get(S.parentId,S.parentKey))} at ${B(S.parentKey)})`):e.warn(`[integrity] Found orphan ${B(h)}`),c.add(h),s.delete(h));if(s.size>0||c.size>0){if(s.size>0){let h=new Map;for(let S of s){let u=a.get(S);u!==void 0&&h.set(S,u)}ie(t,h)}c.size>0&&Ve(t,c)}let f=c.size===0?d:$e(a);return{nodes:a,revNodes:f}}function Ye(t,e){return t?.type===G.OBJECT&&Object.prototype.hasOwnProperty.call(t.data,e)&&t.data[e]!==void 0}var me=class{db;constructor(e){let o=new Wt(e,{create:!0});o.run("PRAGMA journal_mode = WAL"),o.run("PRAGMA case_sensitive_like = ON"),o.run("PRAGMA foreign_keys = ON"),o.run(`CREATE TABLE IF NOT EXISTS system (
3
+ ON CONFLICT (node_id) DO UPDATE SET crdt_json = ?`);t.transaction(i=>{for(let[a,d]of i){let c=JSON.stringify(d);o.run(a,c,c)}})(e)}function He(t,e){let o=Zt(e),s=o.length;t.query(`DELETE FROM nodes WHERE node_id IN (${Ke(s)})`).run(...o)}function Ve(t){let e=new Xt;for(let[o,s]of t){if(s.parentId===void 0)continue;let i=e.get(s.parentId,s.parentKey);(i===void 0||o>i)&&e.set(s.parentId,s.parentKey,o)}return e}function eo(t,e){let o=new Map(Qt(t));o.has("root")||o.set("root",{type:$.OBJECT,data:{}});let s=new Set,i=["root"],a=new Map,d=Ve(o);for(;i.length>0;){let _=i.pop(),S=Kt(o.get(_));if(S.type===$.OBJECT)for(let E of d.keysAt(_))Object.prototype.hasOwnProperty.call(S.data,E)&&(delete S.data[E],s.add(_),e.warn(`[integrity] Found data key ${J(E)} from ${J(_)} (conflicted with child node)`));if(S.type!==$.REGISTER)i.push(...d.valuesAt(_));else if(o.get(S.parentId)?.type===$.OBJECT)continue;a.set(_,S)}let c=new Set;for(let[_,S]of o)a.has(_)||(S.parentId!==void 0&&a.has(S.parentId)?a.get(S.parentId)?.type===$.REGISTER?e.warn(`[integrity] Found unreachable node ${J(_)} (child of live register)`):e.warn(`[integrity] Found conflicting sibling ${J(_)} (conflicted with ${J(d.get(S.parentId,S.parentKey))} at ${J(S.parentKey)})`):e.warn(`[integrity] Found orphan ${J(_)}`),c.add(_),s.delete(_));if(s.size>0||c.size>0){if(s.size>0){let _=new Map;for(let S of s){let E=a.get(S);E!==void 0&&_.set(S,E)}ae(t,_)}c.size>0&&He(t,c)}let f=c.size===0?d:Ve(a);return{nodes:a,revNodes:f}}function ze(t,e){return t?.type===$.OBJECT&&Object.prototype.hasOwnProperty.call(t.data,e)&&t.data[e]!==void 0}var pe=class{db;constructor(e){let o=new qt(e,{create:!0});o.run("PRAGMA journal_mode = WAL"),o.run("PRAGMA case_sensitive_like = ON"),o.run("PRAGMA foreign_keys = ON"),o.run(`CREATE TABLE IF NOT EXISTS system (
4
4
  setting TEXT NOT NULL,
5
5
  jval TEXT NOT NULL,
6
6
  PRIMARY KEY (setting)
@@ -37,7 +37,7 @@ import{a as W,b as Je,c as Y,d as F,e as ne,f as D,g,h as be,i as Ge}from"./chun
37
37
  updated_at INTEGER NOT NULL,
38
38
  PRIMARY KEY (feed_id, message_id),
39
39
  FOREIGN KEY (feed_id) REFERENCES feeds(feed_id) ON DELETE CASCADE
40
- )`),o.run("CREATE INDEX IF NOT EXISTS idx_feed_messages_feed_created ON feed_messages(feed_id, created_at DESC, message_id DESC)"),this.db=o}load_nodes_api(e){let o=this.db,{nodes:s,revNodes:i}=Qt(o,e),a=m=>s.get(m),d=(m,p)=>i.get(m,p),c=(m,p)=>i.has(m,p);function f(m,p){let y;for(let b of i.keysAt(m)){let O=zt(b);O>p&&(y===void 0||O<y)&&(y=O)}return y}function h(m,p,y=!1){let b=a(p.parentId);if(b===void 0)throw new Error(`No such parent ${B(p.parentId)}`);if(p.type===G.REGISTER&&b.type===G.OBJECT)throw new Error("Cannot add register under object");let O=d(p.parentId,p.parentKey);if(O!==m){let _=Ye(b,p.parentKey);if(O!==void 0||_)if(y)v(p.parentId,p.parentKey);else throw new Error(`Key ${B(p.parentKey)} already exists`);i.set(p.parentId,p.parentKey,m)}s.set(m,p),ie(o,[[m,p]])}function S(m,p){let y=a(m);if(y?.parentId===void 0)return;if(c(y.parentId,p))throw new Error(`Pos ${B(p)} already taken`);i.delete(y.parentId,y.parentKey);let b={...y,parentKey:p};s.set(m,b),i.set(y.parentId,p,m),ie(o,[[m,b]])}function u(m,p,y=!1){let b=a(m);if(b?.type!==G.OBJECT)return;for(let _ of Object.keys(p)){let U=d(m,_);if(U!==void 0)if(y)T(U);else throw new Error(`Child node already exists under ${_}`)}let O={...b,data:{...b.data,...p}};s.set(m,O),ie(o,[[m,O]])}function T(m){let p=a(m);if(p?.parentId===void 0)return;i.delete(p.parentId,p.parentKey);let y=[],b=[m];for(;b.length>0;){let O=b.pop();b.push(...i.valuesAt(O)),s.delete(O),i.deleteAll(O),y.push(O)}Ve(o,y)}function v(m,p){let y=a(m);if(Ye(y,p)){let{[p]:O,..._}=y.data,U={...y,data:_};s.set(m,U),ie(o,[[m,U]])}let b=d(m,p);b!==void 0&&T(b)}return{get_node:a,iter_nodes:()=>s.entries(),has_node:m=>s.has(m),get_child_at:d,has_child_at:c,get_next_sibling:f,set_child:h,move_sibling:S,delete_node:T,delete_child_key:v,set_object_data:u,get_snapshot(m){return Kt(s)}}}DANGEROUSLY_reset_nodes(e){let o=this.db.prepare("DELETE FROM nodes"),s=this.db.prepare("INSERT INTO nodes (node_id, crdt_json) VALUES (?, ?)");this.db.transaction(()=>{o.run();for(let[a,d]of Xt(e))s.run(a,JSON.stringify(d))})()}raw_iter_nodes(){return this.db.query("SELECT node_id, crdt_json FROM nodes").values().map(([e,o])=>[e,K(o)])}get_meta(e){let s=this.db.query("SELECT jval FROM metadata WHERE key = ?").get(e)?.jval;if(s!==void 0)return K(s)??null}put_meta(e,o){let s=JSON.stringify(o);this.db.run(`INSERT INTO metadata (key, jval)
40
+ )`),o.run("CREATE INDEX IF NOT EXISTS idx_feed_messages_feed_created ON feed_messages(feed_id, created_at DESC, message_id DESC)"),this.db=o}load_nodes_api(e){let o=this.db,{nodes:s,revNodes:i}=eo(o,e),a=m=>s.get(m),d=(m,l)=>i.get(m,l),c=(m,l)=>i.has(m,l);function f(m,l){let I;for(let y of i.keysAt(m)){let C=zt(y);C>l&&(I===void 0||C<I)&&(I=C)}return I}function _(m,l,I=!1){let y=a(l.parentId);if(y===void 0)throw new Error(`No such parent ${J(l.parentId)}`);if(l.type===$.REGISTER&&y.type===$.OBJECT)throw new Error("Cannot add register under object");let C=d(l.parentId,l.parentKey);if(C!==m){let M=ze(y,l.parentKey);if(C!==void 0||M)if(I)b(l.parentId,l.parentKey);else throw new Error(`Key ${J(l.parentKey)} already exists`);i.set(l.parentId,l.parentKey,m)}s.set(m,l),ae(o,[[m,l]])}function S(m,l){let I=a(m);if(I?.parentId===void 0)return;if(c(I.parentId,l))throw new Error(`Pos ${J(l)} already taken`);i.delete(I.parentId,I.parentKey);let y={...I,parentKey:l};s.set(m,y),i.set(I.parentId,l,m),ae(o,[[m,y]])}function E(m,l,I=!1){let y=a(m);if(y?.type!==$.OBJECT)return;for(let M of Object.keys(l)){let T=d(m,M);if(T!==void 0)if(I)p(T);else throw new Error(`Child node already exists under ${M}`)}let C={...y,data:{...y.data,...l}};s.set(m,C),ae(o,[[m,C]])}function p(m){let l=a(m);if(l?.parentId===void 0)return;i.delete(l.parentId,l.parentKey);let I=[],y=[m];for(;y.length>0;){let C=y.pop();y.push(...i.valuesAt(C)),s.delete(C),i.deleteAll(C),I.push(C)}He(o,I)}function b(m,l){let I=a(m);if(ze(I,l)){let{[l]:C,...M}=I.data,T={...I,data:M};s.set(m,T),ae(o,[[m,T]])}let y=d(m,l);y!==void 0&&p(y)}return{get_node:a,iter_nodes:()=>s.entries(),has_node:m=>s.has(m),get_child_at:d,has_child_at:c,get_next_sibling:f,set_child:_,move_sibling:S,delete_node:p,delete_child_key:b,set_object_data:E,get_snapshot(m){return Ht(s)}}}DANGEROUSLY_reset_nodes(e){let o=this.db.prepare("DELETE FROM nodes"),s=this.db.prepare("INSERT INTO nodes (node_id, crdt_json) VALUES (?, ?)");this.db.transaction(()=>{o.run();for(let[a,d]of Wt(e))s.run(a,JSON.stringify(d))})()}raw_iter_nodes(){return this.db.query("SELECT node_id, crdt_json FROM nodes").values().map(([e,o])=>[e,H(o)])}get_meta(e){let s=this.db.query("SELECT jval FROM metadata WHERE key = ?").get(e)?.jval;if(s!==void 0)return H(s)??null}put_meta(e,o){let s=JSON.stringify(o);this.db.run(`INSERT INTO metadata (key, jval)
41
41
  VALUES (?, ?)
42
42
  ON CONFLICT (key) DO UPDATE SET jval = ?
43
43
  `,[e,s,s])}delete_meta(e){this.db.query("DELETE FROM metadata WHERE key = ?").run(e)}next_actor(){let e=this.db.query(`INSERT INTO system (setting, jval)
@@ -45,14 +45,14 @@ import{a as W,b as Je,c as Y,d as F,e as ne,f as D,g,h as be,i as Ge}from"./chun
45
45
  ON CONFLICT (setting) DO UPDATE SET jval = json(CAST(jval AS INTEGER) + 1)
46
46
  RETURNING jval`).get();return JSON.parse(e.jval)}iter_y_updates(e){return this.db.query("SELECT key, data FROM ydocs WHERE doc_id = ?").values(e)}write_y_updates(e,o,s){this.db.query(`INSERT INTO ydocs
47
47
  VALUES (?, ?, ?)
48
- ON CONFLICT (doc_id, key) DO UPDATE SET data = ?`).run(e,o,s,s)}delete_y_updates(e,o){let s=o.length;this.db.query(`DELETE FROM ydocs WHERE doc_id = ? AND key IN (${ze(s)})`).run(e,...o)}DANGEROUSLY_wipe_all_y_updates(){this.db.query("DELETE FROM ydocs").run()}list_leased_sessions(){let e=this.db.query("SELECT session_id, jpresence, updated_at, juserinfo, ttl, actor_id FROM leased_sessions").all();return Array.from(e,o=>[o.session_id,{sessionId:o.session_id,presence:K(o.jpresence)??null,updatedAt:o.updated_at,info:K(o.juserinfo)??{name:""},ttl:o.ttl,actorId:o.actor_id}])}get_leased_session(e){let o=this.db.query("SELECT session_id, jpresence, updated_at, juserinfo, ttl, actor_id FROM leased_sessions WHERE session_id = ?").get(e);if(o!=null)return{sessionId:o.session_id,presence:K(o.jpresence)??null,updatedAt:o.updated_at,info:K(o.juserinfo)??{name:""},ttl:o.ttl,actorId:o.actor_id}}put_leased_session(e){this.db.query(`INSERT INTO leased_sessions (session_id, jpresence, updated_at, juserinfo, ttl, actor_id)
48
+ ON CONFLICT (doc_id, key) DO UPDATE SET data = ?`).run(e,o,s,s)}delete_y_updates(e,o){let s=o.length;this.db.query(`DELETE FROM ydocs WHERE doc_id = ? AND key IN (${Ke(s)})`).run(e,...o)}DANGEROUSLY_wipe_all_y_updates(){this.db.query("DELETE FROM ydocs").run()}list_leased_sessions(){let e=this.db.query("SELECT session_id, jpresence, updated_at, juserinfo, ttl, actor_id FROM leased_sessions").all();return Array.from(e,o=>[o.session_id,{sessionId:o.session_id,presence:H(o.jpresence)??null,updatedAt:o.updated_at,info:H(o.juserinfo)??{name:""},ttl:o.ttl,actorId:o.actor_id}])}get_leased_session(e){let o=this.db.query("SELECT session_id, jpresence, updated_at, juserinfo, ttl, actor_id FROM leased_sessions WHERE session_id = ?").get(e);if(o!=null)return{sessionId:o.session_id,presence:H(o.jpresence)??null,updatedAt:o.updated_at,info:H(o.juserinfo)??{name:""},ttl:o.ttl,actorId:o.actor_id}}put_leased_session(e){this.db.query(`INSERT INTO leased_sessions (session_id, jpresence, updated_at, juserinfo, ttl, actor_id)
49
49
  VALUES (?, ?, ?, ?, ?, ?)
50
50
  ON CONFLICT (session_id) DO UPDATE SET
51
51
  jpresence = excluded.jpresence,
52
52
  updated_at = excluded.updated_at,
53
53
  juserinfo = excluded.juserinfo,
54
54
  ttl = excluded.ttl,
55
- actor_id = excluded.actor_id`).run(e.sessionId,JSON.stringify(e.presence),e.updatedAt,JSON.stringify(e.info),e.ttl,e.actorId)}delete_leased_session(e){this.db.query("DELETE FROM leased_sessions WHERE session_id = ?").run(e)}list_feeds(e){let o=Math.min(e?.limit??20,100),s=e?.since,i=e?.cursor,a=e?.metadata,d="SELECT feed_id, jmetadata, created_at, updated_at FROM feeds WHERE 1=1",c=[];if(a!==void 0)for(let[u,T]of Object.entries(a)){let v=typeof T=="boolean"?Number(T):T;d+=" AND json_extract(jmetadata, '$.' || ?) = ?",c.push(u,v)}if(s!==void 0&&(d+=" AND created_at >= ?",c.push(s)),i!==void 0)try{let u=JSON.parse(Buffer.from(i.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[T,v]=u;d+=" AND (created_at < ? OR (created_at = ? AND feed_id < ?))",c.push(v,v,T)}catch{}d+=" ORDER BY created_at DESC, feed_id DESC LIMIT ?",c.push(o+1);let f=this.db.query(d).all(...c),h;if(f.length>o){f.pop();let u=f[f.length-1];if(u){let T=[u.feed_id,u.created_at];h=Buffer.from(JSON.stringify(T),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}return{feeds:f.map(u=>({feedId:u.feed_id,metadata:JSON.parse(u.jmetadata),createdAt:u.created_at,updatedAt:u.updated_at})),nextCursor:h}}get_feed(e){let o=this.db.query("SELECT feed_id, jmetadata, created_at, updated_at FROM feeds WHERE feed_id = ?").get(e);if(o!=null)return{feedId:o.feed_id,metadata:JSON.parse(o.jmetadata),createdAt:o.created_at,updatedAt:o.updated_at}}create_feed(e){let o=this.db.query("SELECT feed_id FROM feeds WHERE feed_id = ?").get(e.feedId);if(o!=null)throw new Error(`Feed ${e.feedId} already exists`);this.db.query("INSERT INTO feeds (feed_id, jmetadata, created_at, updated_at) VALUES (?, ?, ?, ?)").run(e.feedId,JSON.stringify(e.metadata),e.createdAt,e.updatedAt)}update_feed_metadata(e,o){let s=this.db.query("UPDATE feeds SET jmetadata = ? WHERE feed_id = ? RETURNING feed_id, jmetadata, created_at, updated_at").get(JSON.stringify(o),e);if(s==null)throw new Error(`Feed ${e} not found`)}delete_feed(e){this.db.query("DELETE FROM feeds WHERE feed_id = ?").run(e)}list_feed_messages(e,o){let s=Math.min(o?.limit??20,100),i=o?.since,a=o?.cursor,d="SELECT feed_id, message_id, jdata, created_at, updated_at FROM feed_messages WHERE feed_id = ?",c=[e];if(i!==void 0&&(d+=" AND created_at >= ?",c.push(i)),a!==void 0)try{let u=JSON.parse(Buffer.from(a.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[T,v]=u;d+=" AND (created_at < ? OR (created_at = ? AND message_id < ?))",c.push(v,v,T)}catch{}d+=" ORDER BY created_at DESC, message_id DESC LIMIT ?",c.push(s+1);let f=this.db.query(d).all(...c),h;if(f.length>s){f.pop();let u=f[f.length-1];if(u){let T=[u.message_id,u.created_at];h=Buffer.from(JSON.stringify(T),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}return{messages:f.map(u=>({id:u.message_id,data:JSON.parse(u.jdata),createdAt:u.created_at,updatedAt:u.updated_at})),nextCursor:h}}add_feed_message(e,o){if(this.get_feed(e)===void 0)throw new Error(`Feed ${e} not found`);this.db.query("INSERT INTO feed_messages (feed_id, message_id, jdata, created_at, updated_at) VALUES (?, ?, ?, ?, ?)").run(e,o.id,JSON.stringify(o.data),o.createdAt,o.updatedAt)}update_feed_message(e,o,s,i){let a=this.db.query("SELECT feed_id, message_id, jdata, created_at, updated_at FROM feed_messages WHERE feed_id = ? AND message_id = ?").get(e,o);if(a==null)throw new Error(`Feed message ${o} not found in feed ${e}`);let d=i??Date.now();if(d<a.updated_at)return{id:a.message_id,data:JSON.parse(a.jdata),createdAt:a.created_at,updatedAt:a.updated_at};let c=this.db.query("UPDATE feed_messages SET jdata = ?, updated_at = ? WHERE feed_id = ? AND message_id = ? AND updated_at <= ? RETURNING feed_id, message_id, jdata, created_at, updated_at").get(JSON.stringify(s),d,e,o,d);if(c==null){let f=this.db.query("SELECT feed_id, message_id, jdata, created_at, updated_at FROM feed_messages WHERE feed_id = ? AND message_id = ?").get(e,o);if(f==null)throw new Error(`Feed message ${o} not found in feed ${e}`);return{id:f.message_id,data:JSON.parse(f.jdata),createdAt:f.created_at,updatedAt:f.updated_at}}return{id:c.message_id,data:JSON.parse(c.jdata),createdAt:c.created_at,updatedAt:c.updated_at}}delete_feed_message(e,o){this.db.query("DELETE FROM feed_messages WHERE feed_id = ? AND message_id = ?").run(e,o)}close(){this.db.close()}};var co=".liveblocks/v1",fe=co,We=!1,H=null;function qe(){return pe(fe,"rooms")}function Z(){if(H)return;let t=pe(fe,"db.sql");Xe(ao(t),{recursive:!0});let e=new so(t,{create:!0});e.run("PRAGMA journal_mode = WAL"),e.run("PRAGMA foreign_keys = ON"),e.run(`CREATE TABLE IF NOT EXISTS rooms (
55
+ actor_id = excluded.actor_id`).run(e.sessionId,JSON.stringify(e.presence),e.updatedAt,JSON.stringify(e.info),e.ttl,e.actorId)}delete_leased_session(e){this.db.query("DELETE FROM leased_sessions WHERE session_id = ?").run(e)}list_feeds(e){let o=Math.min(e?.limit??20,100),s=e?.since,i=e?.cursor,a=e?.metadata,d="SELECT feed_id, jmetadata, created_at, updated_at FROM feeds WHERE 1=1",c=[];if(a!==void 0)for(let[E,p]of Object.entries(a)){let b=typeof p=="boolean"?Number(p):p;d+=" AND json_extract(jmetadata, '$.' || ?) = ?",c.push(E,b)}if(s!==void 0&&(d+=" AND created_at >= ?",c.push(s)),i!==void 0)try{let E=JSON.parse(Buffer.from(i.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[p,b]=E;d+=" AND (created_at < ? OR (created_at = ? AND feed_id < ?))",c.push(b,b,p)}catch{}d+=" ORDER BY created_at DESC, feed_id DESC LIMIT ?",c.push(o+1);let f=this.db.query(d).all(...c),_;if(f.length>o){f.pop();let E=f[f.length-1];if(E){let p=[E.feed_id,E.created_at];_=Buffer.from(JSON.stringify(p),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}return{feeds:f.map(E=>({feedId:E.feed_id,metadata:JSON.parse(E.jmetadata),createdAt:E.created_at,updatedAt:E.updated_at})),nextCursor:_}}get_feed(e){let o=this.db.query("SELECT feed_id, jmetadata, created_at, updated_at FROM feeds WHERE feed_id = ?").get(e);if(o!=null)return{feedId:o.feed_id,metadata:JSON.parse(o.jmetadata),createdAt:o.created_at,updatedAt:o.updated_at}}create_feed(e){let o=this.db.query("SELECT feed_id FROM feeds WHERE feed_id = ?").get(e.feedId);if(o!=null)throw new Error(`Feed ${e.feedId} already exists`);this.db.query("INSERT INTO feeds (feed_id, jmetadata, created_at, updated_at) VALUES (?, ?, ?, ?)").run(e.feedId,JSON.stringify(e.metadata),e.createdAt,e.updatedAt)}update_feed_metadata(e,o){let s=this.db.query("UPDATE feeds SET jmetadata = ? WHERE feed_id = ? RETURNING feed_id, jmetadata, created_at, updated_at").get(JSON.stringify(o),e);if(s==null)throw new Error(`Feed ${e} not found`)}delete_feed(e){this.db.query("DELETE FROM feeds WHERE feed_id = ?").run(e)}list_feed_messages(e,o){let s=Math.min(o?.limit??20,100),i=o?.since,a=o?.cursor,d="SELECT feed_id, message_id, jdata, created_at, updated_at FROM feed_messages WHERE feed_id = ?",c=[e];if(i!==void 0&&(d+=" AND created_at >= ?",c.push(i)),a!==void 0)try{let E=JSON.parse(Buffer.from(a.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[p,b]=E;d+=" AND (created_at < ? OR (created_at = ? AND message_id < ?))",c.push(b,b,p)}catch{}d+=" ORDER BY created_at DESC, message_id DESC LIMIT ?",c.push(s+1);let f=this.db.query(d).all(...c),_;if(f.length>s){f.pop();let E=f[f.length-1];if(E){let p=[E.message_id,E.created_at];_=Buffer.from(JSON.stringify(p),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}return{messages:f.map(E=>({id:E.message_id,data:JSON.parse(E.jdata),createdAt:E.created_at,updatedAt:E.updated_at})),nextCursor:_}}add_feed_message(e,o){if(this.get_feed(e)===void 0)throw new Error(`Feed ${e} not found`);this.db.query("INSERT INTO feed_messages (feed_id, message_id, jdata, created_at, updated_at) VALUES (?, ?, ?, ?, ?)").run(e,o.id,JSON.stringify(o.data),o.createdAt,o.updatedAt)}update_feed_message(e,o,s,i){let a=this.db.query("SELECT feed_id, message_id, jdata, created_at, updated_at FROM feed_messages WHERE feed_id = ? AND message_id = ?").get(e,o);if(a==null)throw new Error(`Feed message ${o} not found in feed ${e}`);let d=i??Date.now();if(d<a.updated_at)return{id:a.message_id,data:JSON.parse(a.jdata),createdAt:a.created_at,updatedAt:a.updated_at};let c=this.db.query("UPDATE feed_messages SET jdata = ?, updated_at = ? WHERE feed_id = ? AND message_id = ? AND updated_at <= ? RETURNING feed_id, message_id, jdata, created_at, updated_at").get(JSON.stringify(s),d,e,o,d);if(c==null){let f=this.db.query("SELECT feed_id, message_id, jdata, created_at, updated_at FROM feed_messages WHERE feed_id = ? AND message_id = ?").get(e,o);if(f==null)throw new Error(`Feed message ${o} not found in feed ${e}`);return{id:f.message_id,data:JSON.parse(f.jdata),createdAt:f.created_at,updatedAt:f.updated_at}}return{id:c.message_id,data:JSON.parse(c.jdata),createdAt:c.created_at,updatedAt:c.updated_at}}delete_feed_message(e,o){this.db.query("DELETE FROM feed_messages WHERE feed_id = ? AND message_id = ?").run(e,o)}close(){this.db.close()}};var uo=".liveblocks/v1",ge=uo,Ze=!1,X=null;function Qe(){return fe(ge,"rooms")}function ee(){if(X)return;let t=fe(ge,"db.sql");qe(co(t),{recursive:!0});let e=new ro(t,{create:!0});e.run("PRAGMA journal_mode = WAL"),e.run("PRAGMA foreign_keys = ON"),e.run(`CREATE TABLE IF NOT EXISTS rooms (
56
56
  room_id TEXT NOT NULL PRIMARY KEY,
57
57
  internal_id TEXT NOT NULL UNIQUE,
58
58
  organization_id TEXT NOT NULL,
@@ -71,13 +71,13 @@ import{a as W,b as Je,c as Y,d as F,e as ne,f as D,g,h as be,i as Ge}from"./chun
71
71
  scopes TEXT NOT NULL,
72
72
  PRIMARY KEY (room_id, group_id),
73
73
  FOREIGN KEY (room_id) REFERENCES rooms(room_id) ON DELETE CASCADE
74
- ) STRICT`),H=e}function Q(){if(!H)throw new Error("Rooms DB not initialized");return H}function Ze(t){let e=Q(),o=e.query("SELECT user_id, scopes FROM room_user_permissions WHERE room_id = ?").all(t.room_id),s=e.query("SELECT group_id, scopes FROM room_group_permissions WHERE room_id = ?").all(t.room_id),i={};for(let d of o)i[d.user_id]=JSON.parse(d.scopes);let a={};for(let d of s)a[d.group_id]=JSON.parse(d.scopes);return{id:t.room_id,internalId:t.internal_id,organizationId:t.organization_id,defaultAccesses:JSON.parse(t.default_permissions),usersAccesses:i,groupsAccesses:a,metadata:JSON.parse(t.metadata),createdAt:t.created_at}}function q(t){let e=Q().query("SELECT room_id, internal_id, organization_id, default_permissions, metadata, created_at FROM rooms WHERE room_id = ?").get(t);if(e)return Ze(e)}var uo="default";function Qe(t,e){let o=Q(),s=eo(),i=new Date().toISOString(),a=e?.organizationId??uo,d=e?.defaultAccesses??["room:write"],c=e?.metadata??{};if(o.run("INSERT INTO rooms (room_id, internal_id, organization_id, default_permissions, metadata, created_at) VALUES (?, ?, ?, ?, ?, ?)",[t,s,a,JSON.stringify(d),JSON.stringify(c),i]),e?.usersAccesses)for(let[f,h]of Object.entries(e.usersAccesses))o.run("INSERT INTO room_user_permissions (room_id, user_id, scopes) VALUES (?, ?, ?)",[t,f,JSON.stringify(h)]);if(e?.groupsAccesses)for(let[f,h]of Object.entries(e.groupsAccesses))o.run("INSERT INTO room_group_permissions (room_id, group_id, scopes) VALUES (?, ?, ?)",[t,f,JSON.stringify(h)]);return{id:t,internalId:s,organizationId:a,defaultAccesses:d,usersAccesses:e?.usersAccesses??{},groupsAccesses:e?.groupsAccesses??{},metadata:c,createdAt:i}}function lo(t,e){let o=Q(),s=q(t);if(s){if(e.defaultAccesses!==void 0&&o.run("UPDATE rooms SET default_permissions = ? WHERE room_id = ?",[JSON.stringify(e.defaultAccesses),t]),e.metadata!==void 0){let i={...s.metadata,...e.metadata};o.run("UPDATE rooms SET metadata = ? WHERE room_id = ?",[JSON.stringify(i),t])}if(e.usersAccesses!==void 0)for(let[i,a]of Object.entries(e.usersAccesses))a===null?o.run("DELETE FROM room_user_permissions WHERE room_id = ? AND user_id = ?",[t,i]):o.run(`INSERT INTO room_user_permissions (room_id, user_id, scopes) VALUES (?, ?, ?)
74
+ ) STRICT`),X=e}function te(){if(!X)throw new Error("Rooms DB not initialized");return X}function et(t){let e=te(),o=e.query("SELECT user_id, scopes FROM room_user_permissions WHERE room_id = ?").all(t.room_id),s=e.query("SELECT group_id, scopes FROM room_group_permissions WHERE room_id = ?").all(t.room_id),i={};for(let d of o)i[d.user_id]=JSON.parse(d.scopes);let a={};for(let d of s)a[d.group_id]=JSON.parse(d.scopes);return{id:t.room_id,internalId:t.internal_id,organizationId:t.organization_id,defaultAccesses:JSON.parse(t.default_permissions),usersAccesses:i,groupsAccesses:a,metadata:JSON.parse(t.metadata),createdAt:t.created_at}}function Q(t){let e=te().query("SELECT room_id, internal_id, organization_id, default_permissions, metadata, created_at FROM rooms WHERE room_id = ?").get(t);if(e)return et(e)}var lo="default";function tt(t,e){let o=te(),s=to(),i=new Date().toISOString(),a=e?.organizationId??lo,d=e?.defaultAccesses??["room:write"],c=e?.metadata??{};if(o.run("INSERT INTO rooms (room_id, internal_id, organization_id, default_permissions, metadata, created_at) VALUES (?, ?, ?, ?, ?, ?)",[t,s,a,JSON.stringify(d),JSON.stringify(c),i]),e?.usersAccesses)for(let[f,_]of Object.entries(e.usersAccesses))o.run("INSERT INTO room_user_permissions (room_id, user_id, scopes) VALUES (?, ?, ?)",[t,f,JSON.stringify(_)]);if(e?.groupsAccesses)for(let[f,_]of Object.entries(e.groupsAccesses))o.run("INSERT INTO room_group_permissions (room_id, group_id, scopes) VALUES (?, ?, ?)",[t,f,JSON.stringify(_)]);return{id:t,internalId:s,organizationId:a,defaultAccesses:d,usersAccesses:e?.usersAccesses??{},groupsAccesses:e?.groupsAccesses??{},metadata:c,createdAt:i}}function mo(t,e){let o=te(),s=Q(t);if(s){if(e.defaultAccesses!==void 0&&o.run("UPDATE rooms SET default_permissions = ? WHERE room_id = ?",[JSON.stringify(e.defaultAccesses),t]),e.metadata!==void 0){let i={...s.metadata,...e.metadata};o.run("UPDATE rooms SET metadata = ? WHERE room_id = ?",[JSON.stringify(i),t])}if(e.usersAccesses!==void 0)for(let[i,a]of Object.entries(e.usersAccesses))a===null?o.run("DELETE FROM room_user_permissions WHERE room_id = ? AND user_id = ?",[t,i]):o.run(`INSERT INTO room_user_permissions (room_id, user_id, scopes) VALUES (?, ?, ?)
75
75
  ON CONFLICT (room_id, user_id) DO UPDATE SET scopes = ?`,[t,i,JSON.stringify(a),JSON.stringify(a)]);if(e.groupsAccesses!==void 0)for(let[i,a]of Object.entries(e.groupsAccesses))a===null?o.run("DELETE FROM room_group_permissions WHERE room_id = ? AND group_id = ?",[t,i]):o.run(`INSERT INTO room_group_permissions (room_id, group_id, scopes) VALUES (?, ?, ?)
76
- ON CONFLICT (room_id, group_id) DO UPDATE SET scopes = ?`,[t,i,JSON.stringify(a),JSON.stringify(a)]);return q(t)}}function mo(t){Q().run("DELETE FROM rooms WHERE room_id = ?",[t])}function et(t){let e=qe(),o=Ke(e,`${t}.sql`);if(!o.startsWith(Ke(e)+"/"))throw new Error("Invalid internal ID");return o}var M=new to(t=>{let e=q(t)??Qe(t);Xe(qe(),{recursive:!0});let o=new me(et(e.internalId));return new oo(t,{storage:o})});function tt(){let t=ro(pe(io(),"liveblocks-dev-"));return fe=pe(t,"data"),We=!0,t}function C(t){return Z(),q(t)}function ge(t,e){Z();let o=q(t);if(o)return o;let s=Qe(t,e);return M.getOrCreate(t),s}function ot(t){Z();let e=Q(),o=[],s=[];if(t?.organizationId&&(o.push("organization_id = ?"),s.push(t.organizationId)),t?.roomId){o.push("room_id LIKE ? ESCAPE '\\'");let d=t.roomId.value.replace(/[%_\\]/g,"\\$&");s.push(`${d}%`)}if(t?.metadata)for(let[d,c]of Object.entries(t.metadata))o.push("JSON_EXTRACT(metadata, ?) = ?"),s.push(`$.${JSON.stringify(d)}`,c);let i=o.length>0?` WHERE ${o.join(" AND ")}`:"";return e.query(`SELECT room_id, internal_id, organization_id, default_permissions, metadata, created_at
76
+ ON CONFLICT (room_id, group_id) DO UPDATE SET scopes = ?`,[t,i,JSON.stringify(a),JSON.stringify(a)]);return Q(t)}}function po(t){te().run("DELETE FROM rooms WHERE room_id = ?",[t])}function ot(t){let e=Qe(),o=Xe(e,`${t}.sql`);if(!o.startsWith(Xe(e)+"/"))throw new Error("Invalid internal ID");return o}var U=new oo(t=>{let e=Q(t)??tt(t);qe(Qe(),{recursive:!0});let o=new pe(ot(e.internalId));return new so(t,{storage:o})});function st(){let t=no(fe(ao(),"liveblocks-dev-"));return ge=fe(t,"data"),Ze=!0,t}function L(t){return ee(),Q(t)}function Ee(t,e){ee();let o=Q(t);if(o)return o;let s=tt(t,e);return U.getOrCreate(t),s}function rt(t){ee();let e=te(),o=[],s=[];if(t?.organizationId&&(o.push("organization_id = ?"),s.push(t.organizationId)),t?.roomId){o.push("room_id LIKE ? ESCAPE '\\'");let d=t.roomId.value.replace(/[%_\\]/g,"\\$&");s.push(`${d}%`)}if(t?.metadata)for(let[d,c]of Object.entries(t.metadata))o.push("JSON_EXTRACT(metadata, ?) = ?"),s.push(`$.${JSON.stringify(d)}`,c);let i=o.length>0?` WHERE ${o.join(" AND ")}`:"";return e.query(`SELECT room_id, internal_id, organization_id, default_permissions, metadata, created_at
77
77
  FROM rooms
78
- ${i}`).all(...s).map(Ze)}function st(t,e){return Z(),lo(t,e)}async function rt(t){Z();let e=q(t),o=M.get(t);if(o&&(o.endSessionBy(()=>!0,He.KICKED,"Deliberately disconnected"),o.unload(),o.driver.close(),M.delete(t)),e){let s=et(e.internalId);try{await Bun.write(s,""),await Bun.file(s).unlink()}catch{}mo(t)}}function J(t){return Z(),M.getOrCreate(t)}var ye=null;function nt(t){ye=t;for(let e of M.values())e.runInMaintenanceMode(()=>t).catch(()=>{});t.then(()=>{ye=null})}function it(t){if(ye!==null)return!0;let e=M.get(t);return e!==void 0&&e.isInMaintenance}function ae(){let t=[];for(let[e,o]of M)for(let s of o.listSessions())t.push({roomId:e,actor:s.actor,userId:s.user.id??s.user.anonymousId,connectedAt:s.createdAt,lastActiveAt:s.lastActiveAt});return t}function at(t,e){let o=M.get(t);return o?o.endSessionBy(s=>s.actor===e,He.KICKED,"Deliberately disconnected")>0:!1}function dt(){for(let t of M.values())t.unload();M.clear()}function Re(){for(let t of M.values())t.unload(),t.driver.close();M.clear(),H&&(H.close(),H=null),We&&no(fe,{recursive:!0,force:!0})}import{nanoid as fo,Permission as go,tryParseJson as lt}from"@liveblocks/core";import{array as ft,constant as de,enum_ as Eo,number as gt,object as we,optional as Ce,record as ho,string as Le,taggedUnion as Io}from"decoders";import{inexact as po,optional as ct,string as ut}from"decoders";var ee=po({name:ct(ut),avatar:ct(ut)}).refineType();var To=we({alg:de("none")}),vo=we({k:de("acc"),pid:de("localdev"),uid:Le,ui:Ce(ee),perms:ho(ft(Eo(go))),exp:gt}),_o=we({k:de("id"),pid:de("localdev"),uid:Le,ui:Ce(ee),gids:Ce(ft(Le)),exp:gt}),So=Io("k",{acc:vo,id:_o});function mt(t){return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function pt(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),o=e+"=".repeat((4-e.length%4)%4);return atob(o)}function Ne(t){let e=Math.floor(Date.now()/1e3),o={...t,iat:e,exp:e+60*60,jti:fo(12)},s=mt(JSON.stringify({alg:"none",typ:"JWT"})),i=mt(JSON.stringify(o));return`${s}.${i}.`}function Ee(t){let e=t.split(".");if(e.length!==3)return null;let[o,s,i]=e;if(i!==""||!To.value(lt(pt(o))))return null;let a=So.value(lt(pt(s)));return!a||a.exp<Math.floor(Date.now()/1e3)?null:a}function yo(t,e){if(t.perms[e])return t.perms[e];for(let[o,s]of Object.entries(t.perms))if(o.endsWith("*")){let i=o.slice(0,-1);if(e.startsWith(i))return s}return[]}function Ro(t,e){let o=C(e);if(!o)return[];let s=new Set(o.defaultAccesses);if(t.gids)for(let i of t.gids)for(let a of o.groupsAccesses[i]??[])s.add(a);for(let i of o.usersAccesses[t.uid]??[])s.add(i);return Array.from(s)}function Oo(t,e){return t.k==="acc"?yo(t,e):Ro(t,e)}function It(t){let e=new URL(t.url),o=e.pathname==="/v7"?ht.V7:e.pathname==="/v8"?ht.V8:null;if(o===null)return{ok:!1};let s=e.searchParams.get("roomId");if(!s)return{ok:!1};let i=e.searchParams.get("tok");if(i!==null){let d=Ee(i);if(!d)return{ok:!1};let c=Oo(d,s);return c.length===0?{ok:!1}:{ok:!0,roomId:s,ticketData:{version:o,id:d.uid,info:d.ui,scopes:c}}}let a=e.searchParams.get("pubkey");return a!==null?a!=="pk_localdev"?{ok:!1,xwarn:"You can only use 'pk_localdev' as the public key"}:(ge(s,{defaultAccesses:[Et.Write]}),{ok:!0,roomId:s,ticketData:{version:o,anonymousId:bo(),scopes:[Et.Write]}}):{ok:!1}}function Co(t){return t.trim().split(`
79
- `).filter(Boolean).map(e=>{let o=e.match(/^(.+?):(\d+):(.*)$/);return o?{file:o[1],line:parseInt(o[2],10),text:o[3]}:null}).filter(e=>e!==null)}async function Tt(...t){try{let e=["git","grep","-nF",...t.flatMap(i=>["-e",i]),"--","."],o=Bun.spawn(e,{stdout:"pipe",stderr:"pipe"}),s=await new Response(o.stdout).text();return await o.exited,Co(s)}catch{return[]}}function Lo(t){let e=t.trim();return e.startsWith("#")||e.startsWith("//")||e.startsWith("*")||e.startsWith("/*")}var Ae=[{pattern:"<LiveblocksProvider",expected:"baseUrl=",fixSnippet:t=>`${Y("baseUrl")}=${F(`"${t}"`)}`,closePattern:">"},{pattern:"createClient(",expected:"baseUrl:",fixSnippet:t=>`${Y("baseUrl")}: ${F(`"${t}"`)}`,closePattern:")"},{pattern:"new Liveblocks(",expected:"baseUrl:",fixSnippet:t=>`${Y("baseUrl")}: ${F(`"${t}"`)}`,closePattern:")"}];async function vt(t){let e=Ae.map(c=>c.pattern),o=[...new Set(Ae.map(c=>c.expected))],[s,i]=await Promise.all([Tt(...e),Tt(...o)]);if(s.length===0)return[];let a=new Set(i.map(c=>c.file)),d=[];for(let c of s){if(Lo(c.text)||a.has(c.file))continue;let f=Ae.find(h=>c.text.includes(h.pattern));f&&d.push({match:c,check:f})}if(d.length>0){console.log(),console.warn(W("\u26A0 Your project may not be configured for the local dev server.")),console.log(),console.log(` Missing baseUrl in the following location(s):
80
- `);for(let{match:c,check:f}of d)console.log(` ${Je(`${c.file}:${c.line}`)}`),console.log(` To fix, add ${f.fixSnippet(t)} to ${Y(f.pattern)}${Y(f.closePattern)}`),console.log();console.log(g(" \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E")),console.log(g(" \u2502 \u{1F4A1} ")+"Press "+D("p")+" to copy an AI fix prompt to your clipboard"+g(" \u2502")),console.log(g(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F")),console.log(),console.log(g(" To skip this check, use --no-check")),console.log()}return d}var wo={"<LiveblocksProvider":"baseUrl={...}","createClient(":"baseUrl: ...","new Liveblocks(":"baseUrl: ..."};function _t(t,e){let o=t.map(({match:s,check:i})=>{let a=wo[i.pattern]??"baseUrl: ...";return` - In \`${s.file}\` at line ${s.line}, add \`${a}\` to the \`${i.pattern}\` call`}).join(`
78
+ ${i}`).all(...s).map(et)}function nt(t,e){return ee(),mo(t,e)}async function it(t){ee();let e=Q(t),o=U.get(t);if(o&&(o.endSessionBy(()=>!0,We.KICKED,"Deliberately disconnected"),o.unload(),o.driver.close(),U.delete(t)),e){let s=ot(e.internalId);try{await Bun.write(s,""),await Bun.file(s).unlink()}catch{}po(t)}}function G(t){return ee(),U.getOrCreate(t)}var Ce=null;function at(t){Ce=t;for(let e of U.values())e.runInMaintenanceMode(()=>t).catch(()=>{});t.then(()=>{Ce=null})}function dt(t){if(Ce!==null)return!0;let e=U.get(t);return e!==void 0&&e.isInMaintenance}function de(){let t=[];for(let[e,o]of U)for(let s of o.listSessions())t.push({roomId:e,actor:s.actor,userId:s.user.id??s.user.anonymousId,connectedAt:s.createdAt,lastActiveAt:s.lastActiveAt});return t}function ct(t,e){let o=U.get(t);return o?o.endSessionBy(s=>s.actor===e,We.KICKED,"Deliberately disconnected")>0:!1}function ut(){for(let t of U.values())t.unload();U.clear()}function Le(){for(let t of U.values())t.unload(),t.driver.close();U.clear(),X&&(X.close(),X=null),Ze&&io(ge,{recursive:!0,force:!0})}import{nanoid as go,tryParseJson as pt}from"@liveblocks/core";import{array as Et,constant as ce,enum_ as Eo,number as ht,object as xe,optional as Ne,record as ho,string as Ae,taggedUnion as Io}from"decoders";import{inexact as fo,optional as lt,string as mt}from"decoders";var oe=fo({name:lt(mt),avatar:lt(mt)}).refineType();var W={RoomRead:"room:read",RoomWrite:"room:write",CommentsWrite:"comments:write",FeedsWrite:"feeds:write",RoomPresenceWrite:"room:presence:write",CommentsRead:"comments:read"};var To=xe({alg:ce("none")}),vo=xe({k:ce("acc"),pid:ce("localdev"),uid:Ae,ui:Ne(oe),perms:ho(Et(Eo(W))),exp:ht}),_o=xe({k:ce("id"),pid:ce("localdev"),uid:Ae,ui:Ne(oe),gids:Ne(Et(Ae)),exp:ht}),bo=Io("k",{acc:vo,id:_o});function ft(t){return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function gt(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),o=e+"=".repeat((4-e.length%4)%4);return atob(o)}function ke(t){let e=Math.floor(Date.now()/1e3),o={...t,iat:e,exp:e+60*60,jti:go(12)},s=ft(JSON.stringify({alg:"none",typ:"JWT"})),i=ft(JSON.stringify(o));return`${s}.${i}.`}function he(t){let e=t.split(".");if(e.length!==3)return null;let[o,s,i]=e;if(i!==""||!To.value(pt(gt(o))))return null;let a=bo.value(pt(gt(s)));return!a||a.exp<Math.floor(Date.now()/1e3)?null:a}function yo(t,e){if(t.perms[e])return t.perms[e];for(let[o,s]of Object.entries(t.perms))if(o.endsWith("*")){let i=o.slice(0,-1);if(e.startsWith(i))return s}return[]}function Ro(t,e){let o=L(e);if(!o)return[];let s=new Set(o.defaultAccesses);if(t.gids)for(let i of t.gids)for(let a of o.groupsAccesses[i]??[])s.add(a);for(let i of o.usersAccesses[t.uid]??[])s.add(i);return Array.from(s)}function Oo(t,e){return t.k==="acc"?yo(t,e):Ro(t,e)}function Tt(t){let e=new URL(t.url),o=e.pathname==="/v7"?It.V7:e.pathname==="/v8"?It.V8:null;if(o===null)return{ok:!1};let s=e.searchParams.get("roomId");if(!s)return{ok:!1};let i=e.searchParams.get("tok");if(i!==null){let d=he(i);if(!d)return{ok:!1};let c=Oo(d,s);return c.length===0?{ok:!1}:{ok:!0,roomId:s,ticketData:{version:o,id:d.uid,info:d.ui,scopes:c}}}let a=e.searchParams.get("pubkey");return a!==null?a!=="pk_localdev"?{ok:!1,xwarn:"You can only use 'pk_localdev' as the public key"}:(Ee(s,{defaultAccesses:[W.RoomWrite]}),{ok:!0,roomId:s,ticketData:{version:o,anonymousId:So(),scopes:[W.RoomWrite]}}):{ok:!1}}function Co(t){return t.trim().split(`
79
+ `).filter(Boolean).map(e=>{let o=e.match(/^(.+?):(\d+):(.*)$/);return o?{file:o[1],line:parseInt(o[2],10),text:o[3]}:null}).filter(e=>e!==null)}async function vt(...t){try{let e=["git","grep","-nF",...t.flatMap(i=>["-e",i]),"--","."],o=Bun.spawn(e,{stdout:"pipe",stderr:"pipe"}),s=await new Response(o.stdout).text();return await o.exited,Co(s)}catch{return[]}}function Lo(t){let e=t.trim();return e.startsWith("#")||e.startsWith("//")||e.startsWith("*")||e.startsWith("/*")}var Pe=[{pattern:"<LiveblocksProvider",expected:"baseUrl=",fixSnippet:t=>`${z("baseUrl")}=${F(`"${t}"`)}`,closePattern:">"},{pattern:"createClient(",expected:"baseUrl:",fixSnippet:t=>`${z("baseUrl")}: ${F(`"${t}"`)}`,closePattern:")"},{pattern:"new Liveblocks(",expected:"baseUrl:",fixSnippet:t=>`${z("baseUrl")}: ${F(`"${t}"`)}`,closePattern:")"}];async function _t(t){let e=Pe.map(c=>c.pattern),o=[...new Set(Pe.map(c=>c.expected))],[s,i]=await Promise.all([vt(...e),vt(...o)]);if(s.length===0)return[];let a=new Set(i.map(c=>c.file)),d=[];for(let c of s){if(Lo(c.text)||a.has(c.file))continue;let f=Pe.find(_=>c.text.includes(_.pattern));f&&d.push({match:c,check:f})}if(d.length>0){console.log(),console.warn(Z("\u26A0 Your project may not be configured for the local dev server.")),console.log(),console.log(` Missing baseUrl in the following location(s):
80
+ `);for(let{match:c,check:f}of d)console.log(` ${$e(`${c.file}:${c.line}`)}`),console.log(` To fix, add ${f.fixSnippet(t)} to ${z(f.pattern)}${z(f.closePattern)}`),console.log();console.log(g(" \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E")),console.log(g(" \u2502 \u{1F4A1} ")+"Press "+P("p")+" to copy an AI fix prompt to your clipboard"+g(" \u2502")),console.log(g(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F")),console.log(),console.log(g(" To skip this check, use --no-check")),console.log()}return d}var wo={"<LiveblocksProvider":"baseUrl={...}","createClient(":"baseUrl: ...","new Liveblocks(":"baseUrl: ..."};function bt(t,e){let o=t.map(({match:s,check:i})=>{let a=wo[i.pattern]??"baseUrl: ...";return` - In \`${s.file}\` at line ${s.line}, add \`${a}\` to the \`${i.pattern}\` call`}).join(`
81
81
  `);return`# Set up Liveblocks dev server
82
82
 
83
83
  1. Check which system the application is using for environment variables, then
@@ -138,7 +138,7 @@ new Liveblocks({
138
138
 
139
139
  Explain to the user that you've enabled the Liveblocks dev server by adding a an
140
140
  environment variable to the application, and share which file it is in. Explain
141
- that the user can disable this by setting it to "false".`}import{execSync as No}from"node:child_process";function St(t){let e=process.platform==="darwin"?"pbcopy":process.platform==="win32"?"clip.exe":"xclip -selection clipboard";No(e,{input:t})}import Ao from"bun";function bt(t,e){let{promise:o,resolve:s}=Promise.withResolvers();return Ao.connect({hostname:e,port:t,socket:{data(){},open(i){i.end(),s(!0)},error(){s(!1)},connectError(){s(!1)}}}),o}function xe(t,e=!1){t&&console.log((e?ne:W)(` \u26A0 ${t}`))}import{Permission as ko}from"@liveblocks/core";import{ZenRouter as Po}from"@liveblocks/zenrouter";import{array as Rt,enum_ as Do,object as Ot,optional as Pe,record as jo,string as De}from"decoders";import{json as xo}from"@liveblocks/zenrouter";import{json as yt}from"@liveblocks/zenrouter";function ke(t,e,o){return yt(t,e,{"X-LB-Warn":o})}function N(t,e,o="This is a dummy response."){return ke(t,e,o)}function r(t="This endpoint isn't implemented in the Liveblocks dev server."){return yt({error:"Not implemented",message:t},501,{"X-LB-Warn":t})}function he(t){let e=t.headers.get("Authorization");if(e==="Bearer sk_localdev")return!0;if(!e)throw xo({error:"Unauthorized",message:"Missing secret key"},401);if(e.startsWith("Bearer "))throw ke({error:"Forbidden",message:"Invalid secret key. You can only use 'sk_localdev' as a secret key"},403,"You can only use 'sk_localdev' as the secret key");return!1}var Mo=Do(ko),ce=new Po({authorize:({req:t})=>he(t)});ce.route("POST /v2/authorize-user",Ot({userId:De,userInfo:Pe(ee),permissions:jo(Rt(Mo))}),({body:t})=>({token:Ne({k:"acc",pid:"localdev",uid:t.userId,perms:t.permissions,ui:t.userInfo})}));ce.route("POST /v2/identify-user",Ot({userId:De,userInfo:Pe(ee),groupIds:Pe(Rt(De))}),({body:t})=>({token:Ne({k:"id",pid:"localdev",uid:t.userId,ui:t.userInfo,gids:t.groupIds})}));import{ZenRouter as Uo}from"@liveblocks/zenrouter";var l=new Uo({cors:{allowCredentials:!0,maxAge:600,exposeHeaders:["X-LB-Warn"]},authorize:({req:t})=>{let e=t.headers.get("Authorization");if(!e?.startsWith("Bearer "))return!1;let o=e.slice(7);return Ee(o)!==null}});l.route("GET /v2/c/threads",()=>N({threads:[],inboxNotifications:[],subscriptions:[],meta:{nextCursor:null,requestedAt:new Date().toISOString(),permissionHints:{}}}));l.route("GET /v2/c/threads/delta",()=>N({threads:[],inboxNotifications:[],subscriptions:[],meta:{requestedAt:new Date().toISOString(),permissionHints:{}}}));l.route("GET /v2/c/inbox-notifications",()=>N({inboxNotifications:[],threads:[],subscriptions:[],groups:[],meta:{nextCursor:null,requestedAt:new Date().toISOString()}}));l.route("GET /v2/c/inbox-notifications/count",()=>N({count:0}));l.route("GET /v2/c/inbox-notifications/delta",()=>N({inboxNotifications:[],threads:[],subscriptions:[],groups:[],deletedInboxNotifications:[],deletedThreads:[],deletedSubscriptions:[],meta:{requestedAt:new Date().toISOString()}}));l.route("GET /v2/c/rooms/<roomId>/threads",()=>N({data:[],inboxNotifications:[],subscriptions:[],meta:{nextCursor:null,requestedAt:new Date().toISOString(),permissionHints:{}}}));l.route("GET /v2/c/rooms/<roomId>/threads/delta",()=>N({data:[],inboxNotifications:[],subscriptions:[],deletedThreads:[],deletedInboxNotifications:[],deletedSubscriptions:[],meta:{requestedAt:new Date().toISOString(),permissionHints:{}}}));l.route("POST /v2/c/rooms/<roomId>/text-metadata",()=>N({status:"ok"}));l.route("PUT /v2/c/rooms/<roomId>/attachments/<attachmentId>/upload/<name>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<name>",()=>r()),l.route("PUT /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>/<partNumber>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>/complete",()=>r()),l.route("DELETE /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/attachments/presigned-urls",()=>r()),l.route("POST /v2/c/rooms/<roomId>/send-message",()=>r()),l.route("GET /v2/c/rooms/<roomId>/storage",()=>r()),l.route("POST /v2/c/rooms/<roomId>/version",()=>r()),l.route("GET /v2/c/rooms/<roomId>/y-version/<version>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/ai/contextual-prompt",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/search",()=>r()),l.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/metadata",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/mark-as-resolved",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/mark-as-unresolved",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/subscribe",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/unsubscribe",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments",()=>r()),l.route("GET /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/metadata",()=>r()),l.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/reactions",()=>r()),l.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/reactions/<emoji>",()=>r()),l.route("GET /v2/c/rooms/<roomId>/threads/comments/search",()=>r()),l.route("GET /v2/c/rooms/<roomId>/threads/<threadId>/participants",()=>r()),l.route("GET /v2/c/rooms/<roomId>/notification-settings",()=>r()),l.route("GET /v2/c/rooms/<roomId>/subscription-settings",()=>r()),l.route("POST /v2/c/rooms/<roomId>/notification-settings",()=>r()),l.route("POST /v2/c/rooms/<roomId>/subscription-settings",()=>r()),l.route("DELETE /v2/c/inbox-notifications",()=>r()),l.route("POST /v2/c/inbox-notifications/read",()=>r()),l.route("DELETE /v2/c/inbox-notifications/<inboxNotificationId>",()=>r()),l.route("POST /v2/c/rooms/<roomId>/inbox-notifications/read",()=>r()),l.route("POST /v2/c/rooms/<roomId>/text-mentions",()=>r()),l.route("DELETE /v2/c/rooms/<roomId>/text-mentions/<mentionId>",()=>r()),l.route("GET /v2/c/notification-settings",()=>r()),l.route("POST /v2/c/notification-settings",()=>r()),l.route("GET /v2/c/rooms/<roomId>/thread-with-notification/<threadId>",()=>r()),l.route("GET /v2/c/urls/metadata",()=>r()),l.route("GET /v2/c/rooms/<roomId>/versions",()=>r()),l.route("GET /v2/c/rooms/<roomId>/versions/delta",()=>r()),l.route("POST /v2/c/groups/find",()=>r());import{abort as Lt,html as Bo,json as Jo,ZenRouter as Go}from"@liveblocks/zenrouter";var Ct=`<!doctype html>
141
+ that the user can disable this by setting it to "false".`}import{execSync as No}from"node:child_process";function St(t){let e=process.platform==="darwin"?"pbcopy":process.platform==="win32"?"clip.exe":"xclip -selection clipboard";No(e,{input:t})}import Ao from"bun";function yt(t,e){let{promise:o,resolve:s}=Promise.withResolvers();return Ao.connect({hostname:e,port:t,socket:{data(){},open(i){i.end(),s(!0)},error(){s(!1)},connectError(){s(!1)}}}),o}function De(t,e=!1){t&&console.log((e?ie:Z)(` \u26A0 ${t}`))}import{ZenRouter as ko}from"@liveblocks/zenrouter";import{array as Ot,enum_ as Po,object as Ct,optional as Me,record as Do,string as Ue}from"decoders";import{json as xo}from"@liveblocks/zenrouter";import{json as Rt}from"@liveblocks/zenrouter";function je(t,e,o){return Rt(t,e,{"X-LB-Warn":o})}function N(t,e,o="This is a dummy response."){return je(t,e,o)}function r(t="This endpoint isn't implemented in the Liveblocks dev server."){return Rt({error:"Not implemented",message:t},501,{"X-LB-Warn":t})}function Ie(t){let e=t.headers.get("Authorization");if(e==="Bearer sk_localdev")return!0;if(!e)throw xo({error:"Unauthorized",message:"Missing secret key"},401);if(e.startsWith("Bearer "))throw je({error:"Forbidden",message:"Invalid secret key. You can only use 'sk_localdev' as a secret key"},403,"You can only use 'sk_localdev' as the secret key");return!1}var jo=Po(W),ue=new ko({authorize:({req:t})=>Ie(t)});ue.route("POST /v2/authorize-user",Ct({userId:Ue,userInfo:Me(oe),permissions:Do(Ot(jo))}),({body:t})=>({token:ke({k:"acc",pid:"localdev",uid:t.userId,perms:t.permissions,ui:t.userInfo})}));ue.route("POST /v2/identify-user",Ct({userId:Ue,userInfo:Me(oe),groupIds:Me(Ot(Ue))}),({body:t})=>({token:ke({k:"id",pid:"localdev",uid:t.userId,ui:t.userInfo,gids:t.groupIds})}));import{ZenRouter as Mo}from"@liveblocks/zenrouter";var u=new Mo({cors:{allowCredentials:!0,maxAge:600,exposeHeaders:["X-LB-Warn"]},authorize:({req:t})=>{let e=t.headers.get("Authorization");if(!e?.startsWith("Bearer "))return!1;let o=e.slice(7);return he(o)!==null}});u.route("GET /v2/c/threads",()=>N({threads:[],inboxNotifications:[],subscriptions:[],meta:{nextCursor:null,requestedAt:new Date().toISOString(),permissionHints:{}}}));u.route("GET /v2/c/threads/delta",()=>N({threads:[],inboxNotifications:[],subscriptions:[],meta:{requestedAt:new Date().toISOString(),permissionHints:{}}}));u.route("GET /v2/c/inbox-notifications",()=>N({inboxNotifications:[],threads:[],subscriptions:[],groups:[],meta:{nextCursor:null,requestedAt:new Date().toISOString()}}));u.route("GET /v2/c/inbox-notifications/count",()=>N({count:0}));u.route("GET /v2/c/inbox-notifications/delta",()=>N({inboxNotifications:[],threads:[],subscriptions:[],groups:[],deletedInboxNotifications:[],deletedThreads:[],deletedSubscriptions:[],meta:{requestedAt:new Date().toISOString()}}));u.route("GET /v2/c/rooms/<roomId>/threads",()=>N({data:[],inboxNotifications:[],subscriptions:[],meta:{nextCursor:null,requestedAt:new Date().toISOString(),permissionHints:{}}}));u.route("GET /v2/c/rooms/<roomId>/threads/delta",()=>N({data:[],inboxNotifications:[],subscriptions:[],deletedThreads:[],deletedInboxNotifications:[],deletedSubscriptions:[],meta:{requestedAt:new Date().toISOString(),permissionHints:{}}}));u.route("POST /v2/c/rooms/<roomId>/text-metadata",()=>N({status:"ok"}));u.route("PUT /v2/c/rooms/<roomId>/attachments/<attachmentId>/upload/<name>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<name>",()=>r()),u.route("PUT /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>/<partNumber>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>/complete",()=>r()),u.route("DELETE /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/attachments/presigned-urls",()=>r()),u.route("POST /v2/c/rooms/<roomId>/send-message",()=>r()),u.route("GET /v2/c/rooms/<roomId>/storage",()=>r()),u.route("POST /v2/c/rooms/<roomId>/version",()=>r()),u.route("GET /v2/c/rooms/<roomId>/y-version/<version>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/ai/contextual-prompt",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/search",()=>r()),u.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/metadata",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/mark-as-resolved",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/mark-as-unresolved",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/subscribe",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/unsubscribe",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments",()=>r()),u.route("GET /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/metadata",()=>r()),u.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/reactions",()=>r()),u.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/reactions/<emoji>",()=>r()),u.route("GET /v2/c/rooms/<roomId>/threads/comments/search",()=>r()),u.route("GET /v2/c/rooms/<roomId>/threads/<threadId>/participants",()=>r()),u.route("GET /v2/c/rooms/<roomId>/notification-settings",()=>r()),u.route("GET /v2/c/rooms/<roomId>/subscription-settings",()=>r()),u.route("POST /v2/c/rooms/<roomId>/notification-settings",()=>r()),u.route("POST /v2/c/rooms/<roomId>/subscription-settings",()=>r()),u.route("DELETE /v2/c/inbox-notifications",()=>r()),u.route("POST /v2/c/inbox-notifications/read",()=>r()),u.route("DELETE /v2/c/inbox-notifications/<inboxNotificationId>",()=>r()),u.route("POST /v2/c/rooms/<roomId>/inbox-notifications/read",()=>r()),u.route("POST /v2/c/rooms/<roomId>/text-mentions",()=>r()),u.route("DELETE /v2/c/rooms/<roomId>/text-mentions/<mentionId>",()=>r()),u.route("GET /v2/c/notification-settings",()=>r()),u.route("POST /v2/c/notification-settings",()=>r()),u.route("GET /v2/c/rooms/<roomId>/thread-with-notification/<threadId>",()=>r()),u.route("GET /v2/c/urls/metadata",()=>r()),u.route("GET /v2/c/rooms/<roomId>/versions",()=>r()),u.route("GET /v2/c/rooms/<roomId>/versions/delta",()=>r()),u.route("POST /v2/c/groups/find",()=>r());import{abort as wt,html as Fo,json as Bo,ZenRouter as Jo}from"@liveblocks/zenrouter";var Lt=`<!doctype html>
142
142
  <html lang="en">
143
143
  <head>
144
144
  <meta charset="UTF-8" />
@@ -394,7 +394,7 @@ that the user can disable this by setting it to "false".`}import{execSync as No}
394
394
  </main>
395
395
  </body>
396
396
  </html>
397
- `;var te=new Go({authorize:()=>!0});te.route("GET /v7",()=>Lt(426));te.route("GET /v8",()=>Lt(426));te.route("GET /health",()=>Jo({status:"ok"}));te.route("GET /",()=>Bo(Ct.replace("__VERSION__","1.2.1")));import{QueryParser as Vo}from"@liveblocks/query-parser";import{jsonObjectYolo as Ko,ROOT_YDOC_ID as je,snapshotToLossyJson_eager as Ho,snapshotToPlainLson_eager as xt}from"@liveblocks/server";import{json as Ie,ZenRouter as Xo}from"@liveblocks/zenrouter";import{array as X,constant as Wo,either as qo,enum_ as Zo,nullable as At,object as Me,optional as $,record as ue,string as P}from"decoders";import{Base64 as Qo}from"js-base64";import*as Te from"yjs";import*as w from"yjs";function $o(t){return t.content instanceof w.ContentFormat||t.content instanceof w.ContentEmbed?"text":"arr"in t.content?"array":"str"in t.content?"text":"type"in t.content?"xml":"unknown"}function Yo(t){let e=[],o=t;for(;o!==null;){if(!o.deleted)if(o.content instanceof w.ContentType)e.push(o.content.type.toJSON());else if(o.content instanceof w.ContentString)e.push(o.content.str);else if(o.content instanceof w.ContentFormat){let{key:s,value:i}=o.content;e.push({key:s,value:i})}else o.content instanceof w.ContentEmbed&&e.push(o.content.embed);o=o.right}return e}function wt(t,e,o,s=!1){if(!e._first&&e._map instanceof Map&&e._map.size>0)return t.getMap(o).toJSON();if(e._first!==null){let i=$o(e._first);if(i==="text")return s?Yo(e._first):t.getText(o).toJSON();if(i==="array")return t.getArray(o).toJSON();if(i==="xml")return t.getXmlFragment(o).toJSON()}return e.toJSON()}var zo={ytext:w.Text,yxmlfragment:w.XmlFragment,yxmltext:w.XmlText,ymap:w.Map,yarray:w.Array};function Nt(t,e="",o=!1,s=""){let i={};if(e.length){if(t.share.has(e)){if(s.length){let a=zo[s];if(a)return t.get(e,a).toJSON()}return{[e]:wt(t,t.share.get(e),e,o)}}return{[e]:""}}for(let[a,d]of t.share)i[a]=wt(t,d,a,o);return i}var kt=(o=>(o.PlainLson="plain-lson",o.LossyJson="json",o))(kt||{}),es=Zo(kt),Pt=ue(P,qo(P,X(P))),n=new Xo({authorize:({req:t})=>he(t)});function A(t){return Ie({error:"ROOM_NOT_FOUND",message:`Room with id "${t}" not found.`},404)}var ts=new Vo({fields:{roomId:"string"},indexableFields:{metadata:"token"}});function os(t){let e=ts.parse(t),o={};for(let s of e.query.allOf)switch(s.type){case"PrefixCondition":{s.field.type==="DirectField"&&s.field.ref.name==="roomId"&&(o.roomId={value:s.prefix.value,operator:"^"});break}case"ExactCondition":{s.field.type==="KeyedField"&&s.field.base.name==="metadata"&&s.value.type==="LiteralString"&&(o.metadata??={},o.metadata[s.field.key]=s.value.value);break}}return o}function ve(t){return{type:"room",id:t.id,organizationId:t.organizationId,createdAt:t.createdAt,metadata:t.metadata,defaultAccesses:t.defaultAccesses,groupsAccesses:t.groupsAccesses,usersAccesses:t.usersAccesses}}n.route("GET /v2/rooms/<roomId>",({p:t})=>{let e=C(t.roomId);if(!e)throw A(t.roomId);return ve(e)});n.route("GET /v2/rooms",({url:t})=>{let e,o=t.searchParams.get("query");if(o)try{e=os(o)}catch(d){return Ie({error:"INVALID_QUERY",message:d instanceof Error?d.message:String(d)},422)}else{let d={};for(let[c,f]of t.searchParams.entries())c.startsWith("metadata.")&&(d[c.slice(9)]=f);Object.keys(d).length>0&&(e={metadata:d})}let s=t.searchParams.get("organizationId")??void 0;return s&&(e={...e,organizationId:s}),{data:ot(e).map(ve),nextPage:null,nextCursor:null}});n.route("POST /v2/rooms",Me({id:P,organizationId:$(P),defaultAccesses:$(X(P)),metadata:$(Pt),usersAccesses:$(ue(P,X(P))),groupsAccesses:$(ue(P,X(P)))}),({body:t})=>{if(C(t.id))return Ie({error:"ROOM_ALREADY_EXISTS",message:`Room with id "${t.id}" already exists.`},409);let e=ge(t.id,{organizationId:t.organizationId,defaultAccesses:t.defaultAccesses,metadata:t.metadata,usersAccesses:t.usersAccesses,groupsAccesses:t.groupsAccesses});return ve(e)});n.route("POST /v2/rooms/<roomId>",Me({defaultAccesses:$(X(P)),metadata:$(Pt),usersAccesses:$(ue(P,At(X(P)))),groupsAccesses:$(ue(P,At(X(P))))}),({p:t,body:e})=>{let o=st(t.roomId,{defaultAccesses:e.defaultAccesses,metadata:e.metadata,usersAccesses:e.usersAccesses,groupsAccesses:e.groupsAccesses});if(!o)throw A(t.roomId);return ve(o)});n.route("DELETE /v2/rooms/<roomId>",async({p:t})=>(await rt(t.roomId),new Response(null,{status:204})));n.route("GET /v2/rooms/<roomId>/storage",async({url:t,p:e})=>{if(!C(e.roomId))throw A(e.roomId);let o=es.value(t.searchParams.get("format"))??"plain-lson",s=J(e.roomId);await s.load();let i=s.storage.loadedDriver.get_snapshot(!1),a=o==="json"?Ho(i):xt(i);return new Response(JSON.stringify(a),{status:200,headers:{"Content-Type":"application/json"}})});n.route("POST /v2/rooms/<roomId>/storage",Me({liveblocksType:Wo("LiveObject"),data:Ko}).refineType(),async({p:t,body:e})=>{if(!C(t.roomId))throw A(t.roomId);let o=J(t.roomId);await o.load();let s=o.storage.loadedDriver.get_snapshot(!1),i=xt(s);return Object.keys(i.data).length>0?new Response(JSON.stringify({error:"CANNOT_UPDATE_EXISTING_STORAGE",message:"The room already has storage data. It's only possible to initialize the storage for an empty room.",suggestion:"Create another room or clear this room storage first."}),{status:409,headers:{"Content-Type":"application/json"}}):(await o.driver.DANGEROUSLY_reset_nodes(e),o.unload(),new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}}))});n.route("DELETE /v2/rooms/<roomId>/storage",async({p:t})=>{if(!C(t.roomId))throw A(t.roomId);let e=J(t.roomId);await e.load();let o={liveblocksType:"LiveObject",data:{}};return await e.driver.DANGEROUSLY_reset_nodes(o),e.unload(),new Response(null,{status:204})});n.route("GET /v2/rooms/<roomId>/ydoc",async({url:t,p:e})=>{if(!C(e.roomId))throw A(e.roomId);let o=J(e.roomId);await o.load();let s=t.searchParams.get("key")??"",i=t.searchParams.get("type")??"",a=t.searchParams.get("guid")??je,d=t.searchParams.get("formatting")!==null,c=await o.yjsStorage.getYDoc(a),f=Nt(c,s,d,i);return new Response(JSON.stringify(f),{status:200,headers:{"Content-Type":"application/json"}})});n.route("PUT /v2/rooms/<roomId>/ydoc",async({req:t,url:e,p:o})=>{if(t.headers.get("content-type")!=="application/octet-stream")return new Response(JSON.stringify({error:"BAD_REQUEST",message:'Expected "Content-Type" header to be "application/octet-stream", and the HTTP body to be a valid binary Yjs update.'}),{status:400,headers:{"Content-Type":"application/json"}});if(!C(o.roomId))throw A(o.roomId);let s=J(o.roomId);await s.load();let i=await t.arrayBuffer(),a=Qo.fromUint8Array(new Uint8Array(i)),d=e.searchParams.get("guid"),f=e.searchParams.get("encoder")==="v2",h=d&&d!==je?d:void 0;try{return await s.mutex.runExclusive(()=>s.yjsStorage.addYDocUpdate({},a,h,f)),new Response(JSON.stringify({success:!0}),{status:200,headers:{"Content-Type":"application/json"}})}catch(S){return new Response(JSON.stringify({error:"UNPROCESSABLE_ENTITY",message:S instanceof Error?S.message:"Could not apply update",suggestion:"Please ensure the update is correct, and you selected the correct encoder to use (v1 or v2)."}),{status:422,headers:{"Content-Type":"application/json"}})}});n.route("GET /v2/rooms/<roomId>/ydoc-binary",async({url:t,p:e})=>{if(!C(e.roomId))throw A(e.roomId);let o=J(e.roomId);await o.load();let s=t.searchParams.get("guid")??je,i=t.searchParams.get("encoder"),a=await o.yjsStorage.getYDoc(s),d=i==="v2"?Te.encodeStateAsUpdateV2(a):Te.encodeStateAsUpdate(a);return new Response(d,{status:200,headers:{"Content-Type":"application/octet-stream"}})});n.route("GET /v2/rooms/<roomId>/active_users",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);let o=J(t.roomId).listSessions().map(s=>({type:"user",connectionId:s.actor,id:s.user.id,info:s.user.info}));return Ie({data:o})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);return N({ok:!0})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>/messages/<messageId>",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);return N({ok:!0})});n.route("GET /v2/rooms/<roomId>/feeds",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);return N({feeds:[{feedId:"123",metadata:{title:"Test Feed",description:"This is a test feed"},timestamp:new Date().getTime()}],nextCursor:null})});n.route("GET /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);return N({feedId:"123",timestamp:new Date().getTime(),metadata:{title:"Test Feed",description:"This is a test feed"}})});n.route("GET /v2/rooms/<roomId>/feeds/<feedId>/messages",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);return N({messages:[{messageId:"123",data:{content:"This is a test message"}}],nextCursor:null})});n.route("PATCH /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);let e=Date.now();return N({feedId:t.feedId,createdAt:e,updatedAt:e,metadata:{title:"Test Feed",description:"This is a test feed"}})});n.route("PATCH /v2/rooms/<roomId>/feeds/<feedId>/messages/<messageId>",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);let e=Date.now();return N({id:t.messageId,createdAt:e,updatedAt:e,data:{content:"This is a test message"}})});n.route("POST /v2/rooms/<roomId>/feeds",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);return N({feedId:"123",timestamp:new Date().getTime(),metadata:{title:"Test Feed",description:"This is a test feed"}})});n.route("POST /v2/rooms/<roomId>/feeds/<feedId>/messages",({p:t})=>{if(!C(t.roomId))throw A(t.roomId);return N({id:"123",timestamp:new Date().getTime(),data:{content:"This is a test message"}})});n.route("PATCH /v2/rooms/<roomId>/storage/json-patch",()=>r()),n.route("POST /v2/rooms/<roomId>/presence",()=>r()),n.route("GET /v2/rooms/<roomId>/threads",()=>r()),n.route("POST /v2/rooms/<roomId>/upsert",()=>r()),n.route("POST /v2/rooms/<roomId>/update-room-id",()=>r()),n.route("POST /v2/rooms/<roomId>/update-organization-id",()=>r()),n.route("GET /v2/rooms/<roomId>/prewarm",()=>r()),n.route("POST /v2/rooms/<roomId>/broadcast_event",()=>r()),n.route("GET /v2/rooms/<roomId>/versions",()=>r()),n.route("GET /v2/rooms/<roomId>/version/<version>",()=>r()),n.route("POST /v2/rooms/<roomId>/version",()=>r()),n.route("POST /v2/rooms/<roomId>/threads",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/mark-as-resolved",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/mark-as-unresolved",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/subscribe",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/unsubscribe",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/subscriptions",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/metadata",()=>r()),n.route("DELETE /v2/rooms/<roomId>/threads/<threadId>",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/participants",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/inbox-notifications",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/metadata",()=>r()),n.route("DELETE /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/add-reaction",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/remove-reaction",()=>r()),n.route("GET /v2/rooms/<roomId>/attachments/<attachmentId>",()=>r()),n.route("GET /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>r()),n.route("GET /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>r()),n.route("POST /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>r()),n.route("POST /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>r()),n.route("DELETE /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>r()),n.route("DELETE /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>r()),n.route("GET /v2/users/<userId>/inbox-notifications/<inboxNotificationId>",()=>r()),n.route("DELETE /v2/users/<userId>/inbox-notifications/<inboxNotificationId>",()=>r()),n.route("GET /v2/users/<userId>/inbox-notifications",()=>r()),n.route("DELETE /v2/users/<userId>/inbox-notifications",()=>r()),n.route("GET /v2/users/<userId>/notification-settings",()=>r()),n.route("POST /v2/users/<userId>/notification-settings",()=>r()),n.route("DELETE /v2/users/<userId>/notification-settings",()=>r()),n.route("GET /v2/users/<userId>/room-subscription-settings",()=>r()),n.route("POST /v2/inbox-notifications/trigger",()=>r()),n.route("POST /v2/inbox-notifications/<inboxNotificationId>/read",()=>r()),n.route("POST /v2/groups",()=>r()),n.route("GET /v2/groups/<groupId>",()=>r()),n.route("POST /v2/groups/<groupId>/add-members",()=>r()),n.route("POST /v2/groups/<groupId>/remove-members",()=>r()),n.route("DELETE /v2/groups/<groupId>",()=>r()),n.route("GET /v2/groups",()=>r()),n.route("GET /v2/users/<userId>/groups",()=>r()),n.route("GET /v2/ai/copilots",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/<knowledgeSourceId>",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/file/<knowledgeSourceId>",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/web/<knowledgeSourceId>/links",()=>r()),n.route("POST /v2/ai/copilots",()=>r()),n.route("POST /v2/ai/copilots/<copilotId>",()=>r()),n.route("POST /v2/ai/copilots/<copilotId>/knowledge/web",()=>r()),n.route("DELETE /v2/ai/copilots/<copilotId>",()=>r()),n.route("DELETE /v2/ai/copilots/<copilotId>/knowledge/file/<knowledgeSourceId>",()=>r()),n.route("DELETE /v2/ai/copilots/<copilotId>/knowledge/web/<knowledgeSourceId>",()=>r()),n.route("PUT /v2/ai/copilots/<copilotId>/knowledge/file/<fileName>",()=>r()),n.route("GET /v2/management/projects",()=>r()),n.route("GET /v2/management/projects/<projectId>",()=>r()),n.route("POST /v2/management/projects",()=>r()),n.route("POST /v2/management/projects/<projectId>",()=>r()),n.route("DELETE /v2/management/projects/<projectId>",()=>r()),n.route("GET /v2/management/projects/<projectId>/webhooks",()=>r()),n.route("GET /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>r()),n.route("GET /v2/management/projects/<projectId>/webhooks/<webhookId>/additional-headers",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/additional-headers",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/delete-additional-headers",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/recover-failed-messages",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/secret/roll",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/test",()=>r()),n.route("DELETE /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>r()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/activate",()=>r()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/deactivate",()=>r()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/roll",()=>r()),n.route("POST /v2/management/projects/<projectId>/api-keys/secret/roll",()=>r());function jt(t,e,o,s){if(!t.upgrade(e,{data:{refuseConnection:{code:o,message:s}}}))return new Response("Could not upgrade to WebSocket",{status:426})}var oe=new rs;oe.relay("/v2/authorize-user/*",ce);oe.relay("/v2/identify-user/*",ce);oe.relay("/v2/c/*",l);oe.relay("/v2/*",n);oe.relay("/*",te);var Fe=1153;function Mt(t){if(t===void 0)return;let e=Number(t);return Number.isInteger(e)&&e>0&&e<=65535?e:void 0}function is(t){return process.platform==="win32"?[process.env.COMSPEC||"cmd.exe","/c",t]:["sh","-c",t]}function as(t){return"'"+t.replace(/'/g,"'\\''")+"'"}var ds={description:"Start the local Liveblocks dev server",async run(t){let{options:e,args:o}=Ge(t,{port:{type:"string",short:"p",default:Fe.toString()},host:{type:"string"},cmd:{type:"string",short:"c"},help:{type:"boolean",short:"h",default:!1},"no-check":{type:"boolean",default:!1},ci:{type:"boolean",default:!1},verbose:{type:"boolean",short:"v",default:!1}},{allowPositionals:!0});if(o.length>0&&!e.cmd&&(console.error(ne("Extra arguments are only supported with --cmd (-c)")),process.exit(1)),o.length>0&&e.cmd){let u=o.map(as).join(" ");e.cmd.includes("{}")?e.cmd=e.cmd.replaceAll("{}",u):e.cmd+=" "+u}if(e.help){console.log("Usage: liveblocks dev [options]"),console.log(),console.log("Start the local Liveblocks dev server"),console.log(),console.log("Options:"),console.log(` --port, -p Port to listen on (default: ${Fe})`),console.log(" --host Host to bind to (default: localhost)"),console.log(" --cmd, -c Run a one-off command against a fresh server instance, then"),console.log(" shut down. Does not affect your local data in .liveblocks/."),console.log(" Extra args are appended to the command, or replace {} if"),console.log(" present. Use -- before args starting with -."),console.log(" --ci Start a fresh server instance on every boot, ideal for CI"),console.log(" --no-check Skip project setup check on start"),console.log(" --verbose, -v Show verbose output"),console.log(" --help, -h Show help");return}let s=!1;e.ci&&(s=!0,e["no-check"]=!0),e.cmd&&(s=!0,e["no-check"]=!0);let i=Mt(e.port)??Mt(process.env.LIVEBLOCKS_DEVSERVER_PORT)??Fe,a=e.host||process.env.LIVEBLOCKS_DEVSERVER_HOST||"localhost",d=s?tt():null;await bt(i,a)&&(console.error(`Port ${i} is already in use.
398
- Is another dev server already running?`),process.exit(1));let c;function f(){return Ue.serve({hostname:a,port:i,async fetch(u,T){if(u.headers.get("Upgrade")==="websocket"){let O=It(u);if(!O.ok)return xe(O.xwarn,!0),jt(T,u,Dt.NOT_ALLOWED,"You have no access to this room");let{roomId:_,ticketData:U}=O;if(it(_))return jt(T,u,Dt.TRY_AGAIN_LATER,"Server is undergoing maintenance, try again later");let se=J(_);await se.load();let x=await se.createTicket(U),k=x.sessionKey;if(T.upgrade(u,{data:{room:se,ticket:x,sessionKey:k}})){console.log(`${F("101")} WS ${new URL(u.url).pathname}${g(` - ${_}`)}`);return}return new Response("Could not upgrade to WebSocket",{status:426})}let v=new URL(u.url);if(u.method==="POST"&&v.pathname==="/crash")return console.log(`${F("204")} POST /crash`),setTimeout(()=>void h(),0),new Response(null,{status:204});let L=`${u.method} ${v.pathname}`,m=await oe.fetch(u),p=m.status,y=p>=500?ne(p):p>=400?W(p):F(p);console.log(`${y} ${L}`);let b=m.headers.get("X-LB-Warn")??void 0;return xe(b,!m.ok),m},error(u){return console.error(u),new Response("An unknown error occurred",{status:500})},websocket:{async open(u){let{refuseConnection:T,room:v,ticket:L}=u.data;if(T){u.close(T.code,T.message);return}v&&L&&await v.startBrowserSession(L,u)},async message(u,T){let{room:v,sessionKey:L}=u.data;v&&L&&await v.handleData(L,T)},close(u,T,v){let{room:L,sessionKey:m}=u.data;L&&m&&L.endBrowserSession(m,T,v)}}})}c=f();async function h(){dt(),await c.stop(!0),c=f(),console.log("Crash \u{1F4A5}")}let S=u=>process.stderr.write(u+`
399
- `);if(e.cmd){S(`Liveblocks dev server ${g("v1.2.1")} running at http://${c.hostname}:${c.port}`),d&&e.verbose&&S(g(`Ephemeral mode, using ${d}`));let u=ns(d,"server.log");S(g(`Server logs: ${u}`));let T=Ue.file(u).writer(),v=(...m)=>{T.write(m.map(String).join(" ")+`
400
- `),T.flush()};console.log=v,console.error=v;let L=1;try{let m=Ue.spawn(is(e.cmd),{stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LIVEBLOCKS_DEV_SERVER_HOST:a,LIVEBLOCKS_DEV_SERVER_PORT:String(i)}}),p=()=>{m.kill()};process.on("SIGTERM",p),process.on("SIGINT",p),L=await m.exited}finally{T.end(),await c.stop(),Re(),S(g("Liveblocks dev server shut down"))}process.exit(L)}else{let u=`http://${a}:${i}`,T=e["no-check"]?[]:await vt(u),v="logs",L=null,m=null,p=null,y=`http://${c.hostname}:${c.port}`,b=()=>{let R=v==="logs"?D(" Logs "):g(" Logs "),I=v==="sockets"?D(" Sockets "):g(" Sockets "),E=R+g("|")+I,re=(m?Y("\u23F8 maintenance")+" ":"")+g(`Liveblocks running at ${y}`),_e=process.stdout.columns??80,Se=Math.max(1,_e-be(E).length-be(re).length);return E+" ".repeat(Se)+re},O=[],_=console.log.bind(console);console.log=(...R)=>{let I=R.map(String).join(" ");O.push(I),v==="logs"&&_(I)};let U=()=>g(" ")+D("q")+g(" quit, ")+D("!")+g(" crash, ")+D("c")+g(" clear"),se=()=>{p&&(clearInterval(p),p=null),v="logs",process.stdout.write("\x1B[2J\x1B[H"),_(b()),_(U()),_();for(let R of O)_(R)},x=0,k=[],z=R=>`${R.roomId}:${R.actor}`,Be=()=>{k=ae().map(R=>({...R,alive:!0}))},Ut=()=>{let R=new Set(ae().map(z));for(let E of k)E.alive=R.has(z(E));let I=new Set(k.map(z));for(let E of ae())I.has(z(E))||k.push({...E,alive:!0})},Ft=R=>{let I=Date.now()-R,E=Math.floor(I/1e3);if(E<60)return`${E}s`;let j=Math.floor(E/60);return j<60?`${j}m`:`${Math.floor(j/60)}h`},Bt=R=>{if(!R)return"";let I=Date.now()-R;return I<1e3?" "+F("\u25CF"):I<3e3?" "+g(F("\u25CF")):I<5e3?" "+g("\u25CF"):""},le=(R,I)=>{let E=R+I;for(;E>=0&&E<k.length;){if(k[E].alive)return E;E+=I}return R},V=()=>{Ut();let R=k.filter(E=>E.alive).length;if(process.stdout.write("\x1B[2J\x1B[H"),_(b()),_(g(" ")+D("\u2191\u2193")+g(" navigate, ")+D("k")+g(" kill, ")+D("m")+g(m?" maintenance off, ":" maintenance on, ")+D("r")+g(" refresh")),_(),_(" "+D("Connections")+g(` (${R} alive)`)),_(),k.length===0){_(g(" No active connections"));return}if(x>=k.length&&(x=k.length-1),!k[x]?.alive){let E=le(x,-1);x=k[E]?.alive?E:le(x,1)}let I=new Map;for(let E of ae())I.set(z(E),E.lastActiveAt);for(let E=0;E<k.length;E++){let j=k[E];if(!j.alive){_(g(` ${j.roomId} \xB7 actor=${j.actor} \xB7 disconnected`));continue}let re=E===x?F("\u25B6 "):" ",_e=j.userId??g("anonymous"),Se=Ft(j.connectedAt),$t=I.get(z(j)),Yt=Bt($t);_(`${re}${D(j.roomId)} ${g("\xB7")} actor=${j.actor} ${g("\xB7")} ${_e} ${g("\xB7")} ${g(Se)}${Yt}`)}},Jt=()=>{v="sockets",x=0,Be(),V(),p=setInterval(()=>V(),1e3)},Gt=()=>{if(m)m(),m=null;else{let{promise:R,resolve:I}=ss();nt(R),m=I}};process.stdout.write("\x1B[2J\x1B[H"),_(b()),_(U()),_(),d&&e.verbose&&console.log(g(`Ephemeral mode, using ${d}`)),process.stdin.setRawMode?.(!0),process.stdin.resume(),process.stdin.on("data",R=>{let I=R.toString();if(I===""||I==="q"){c.stop(!0).then(()=>{Re(),process.exit(0)});return}if(I==="m"){Gt(),v==="sockets"?V():(process.stdout.write("\x1B[s\x1B[H\x1B[2K"),_(b()),process.stdout.write("\x1B[u"));return}if((I==="s"||I==="\x1B[C")&&v!=="sockets"){Jt();return}if((I==="l"||I==="\x1B[D")&&v!=="logs"){se();return}if(v==="sockets"){if(I==="\x1B[A")x=le(x,-1),V();else if(I==="\x1B[B")x=le(x,1),V();else if(I==="k"){let E=k[x];E?.alive&&(at(E.roomId,E.actor),V())}else I==="r"&&(Be(),x=0,V());return}if(I==="!")L!==null?(clearTimeout(L),L=null,h()):(console.log("Simulating crash in 2.5s... (press ! again to crash now)"),L=setTimeout(()=>{L=null,h()},2500));else if(I==="c")O.length=0,process.stdout.write("\x1B[2J\x1B[H"),_(b()),_(U()),_();else if(I==="p")if(T.length>0){let E=_t(T,u);St(E),console.log(g("Copied AI fix prompt to clipboard"))}else console.log(g("No setup issues detected"))})}}},wr=ds;export{wr as default};
397
+ `;var se=new Jo({authorize:()=>!0});se.route("GET /v7",()=>wt(426));se.route("GET /v8",()=>wt(426));se.route("GET /health",()=>Bo({status:"ok"}));se.route("GET /",()=>Fo(Lt.replace("__VERSION__","1.3.0")));import{QueryParser as Vo}from"@liveblocks/query-parser";import{jsonObjectYolo as zo,ROOT_YDOC_ID as Fe,snapshotToLossyJson_eager as Ko,snapshotToPlainLson_eager as kt}from"@liveblocks/server";import{json as Te,ZenRouter as Ho}from"@liveblocks/zenrouter";import{array as q,constant as Xo,either as Wo,enum_ as qo,nullable as xt,object as Be,optional as Y,record as le,string as D}from"decoders";import{Base64 as Zo}from"js-base64";import*as ve from"yjs";import*as w from"yjs";function Go(t){return t.content instanceof w.ContentFormat||t.content instanceof w.ContentEmbed?"text":"arr"in t.content?"array":"str"in t.content?"text":"type"in t.content?"xml":"unknown"}function $o(t){let e=[],o=t;for(;o!==null;){if(!o.deleted)if(o.content instanceof w.ContentType)e.push(o.content.type.toJSON());else if(o.content instanceof w.ContentString)e.push(o.content.str);else if(o.content instanceof w.ContentFormat){let{key:s,value:i}=o.content;e.push({key:s,value:i})}else o.content instanceof w.ContentEmbed&&e.push(o.content.embed);o=o.right}return e}function Nt(t,e,o,s=!1){if(!e._first&&e._map instanceof Map&&e._map.size>0)return t.getMap(o).toJSON();if(e._first!==null){let i=Go(e._first);if(i==="text")return s?$o(e._first):t.getText(o).toJSON();if(i==="array")return t.getArray(o).toJSON();if(i==="xml")return t.getXmlFragment(o).toJSON()}return e.toJSON()}var Yo={ytext:w.Text,yxmlfragment:w.XmlFragment,yxmltext:w.XmlText,ymap:w.Map,yarray:w.Array};function At(t,e="",o=!1,s=""){let i={};if(e.length){if(t.share.has(e)){if(s.length){let a=Yo[s];if(a)return t.get(e,a).toJSON()}return{[e]:Nt(t,t.share.get(e),e,o)}}return{[e]:""}}for(let[a,d]of t.share)i[a]=Nt(t,d,a,o);return i}var Pt=(o=>(o.PlainLson="plain-lson",o.LossyJson="json",o))(Pt||{}),Qo=qo(Pt),Dt=le(D,Wo(D,q(D))),n=new Ho({authorize:({req:t})=>Ie(t)});function k(t){return Te({error:"ROOM_NOT_FOUND",message:`Room with id "${t}" not found.`},404)}var es=new Vo({fields:{roomId:"string"},indexableFields:{metadata:"token"}});function ts(t){let e=es.parse(t),o={};for(let s of e.query.allOf)switch(s.type){case"PrefixCondition":{s.field.type==="DirectField"&&s.field.ref.name==="roomId"&&(o.roomId={value:s.prefix.value,operator:"^"});break}case"ExactCondition":{s.field.type==="KeyedField"&&s.field.base.name==="metadata"&&s.value.type==="LiteralString"&&(o.metadata??={},o.metadata[s.field.key]=s.value.value);break}}return o}function _e(t){return{type:"room",id:t.id,organizationId:t.organizationId,createdAt:t.createdAt,metadata:t.metadata,defaultAccesses:t.defaultAccesses,groupsAccesses:t.groupsAccesses,usersAccesses:t.usersAccesses}}n.route("GET /v2/rooms/<roomId>",({p:t})=>{let e=L(t.roomId);if(!e)throw k(t.roomId);return _e(e)});n.route("GET /v2/rooms",({url:t})=>{let e,o=t.searchParams.get("query");if(o)try{e=ts(o)}catch(d){return Te({error:"INVALID_QUERY",message:d instanceof Error?d.message:String(d)},422)}else{let d={};for(let[c,f]of t.searchParams.entries())c.startsWith("metadata.")&&(d[c.slice(9)]=f);Object.keys(d).length>0&&(e={metadata:d})}let s=t.searchParams.get("organizationId")??void 0;return s&&(e={...e,organizationId:s}),{data:rt(e).map(_e),nextPage:null,nextCursor:null}});n.route("POST /v2/rooms",Be({id:D,organizationId:Y(D),defaultAccesses:Y(q(D)),metadata:Y(Dt),usersAccesses:Y(le(D,q(D))),groupsAccesses:Y(le(D,q(D)))}),({body:t})=>{if(L(t.id))return Te({error:"ROOM_ALREADY_EXISTS",message:`Room with id "${t.id}" already exists.`},409);let e=Ee(t.id,{organizationId:t.organizationId,defaultAccesses:t.defaultAccesses,metadata:t.metadata,usersAccesses:t.usersAccesses,groupsAccesses:t.groupsAccesses});return _e(e)});n.route("POST /v2/rooms/<roomId>",Be({defaultAccesses:Y(q(D)),metadata:Y(Dt),usersAccesses:Y(le(D,xt(q(D)))),groupsAccesses:Y(le(D,xt(q(D))))}),({p:t,body:e})=>{let o=nt(t.roomId,{defaultAccesses:e.defaultAccesses,metadata:e.metadata,usersAccesses:e.usersAccesses,groupsAccesses:e.groupsAccesses});if(!o)throw k(t.roomId);return _e(o)});n.route("DELETE /v2/rooms/<roomId>",async({p:t})=>(await it(t.roomId),new Response(null,{status:204})));n.route("GET /v2/rooms/<roomId>/storage",async({url:t,p:e})=>{if(!L(e.roomId))throw k(e.roomId);let o=Qo.value(t.searchParams.get("format"))??"plain-lson",s=G(e.roomId);await s.load();let i=s.storage.loadedDriver.get_snapshot(!1),a=o==="json"?Ko(i):kt(i);return new Response(JSON.stringify(a),{status:200,headers:{"Content-Type":"application/json"}})});n.route("POST /v2/rooms/<roomId>/storage",Be({liveblocksType:Xo("LiveObject"),data:zo}).refineType(),async({p:t,body:e})=>{if(!L(t.roomId))throw k(t.roomId);let o=G(t.roomId);await o.load();let s=o.storage.loadedDriver.get_snapshot(!1),i=kt(s);return Object.keys(i.data).length>0?new Response(JSON.stringify({error:"CANNOT_UPDATE_EXISTING_STORAGE",message:"The room already has storage data. It's only possible to initialize the storage for an empty room.",suggestion:"Create another room or clear this room storage first."}),{status:409,headers:{"Content-Type":"application/json"}}):(await o.driver.DANGEROUSLY_reset_nodes(e),o.unload(),new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}}))});n.route("DELETE /v2/rooms/<roomId>/storage",async({p:t})=>{if(!L(t.roomId))throw k(t.roomId);let e=G(t.roomId);await e.load();let o={liveblocksType:"LiveObject",data:{}};return await e.driver.DANGEROUSLY_reset_nodes(o),e.unload(),new Response(null,{status:204})});n.route("GET /v2/rooms/<roomId>/ydoc",async({url:t,p:e})=>{if(!L(e.roomId))throw k(e.roomId);let o=G(e.roomId);await o.load();let s=t.searchParams.get("key")??"",i=t.searchParams.get("type")??"",a=t.searchParams.get("guid")??Fe,d=t.searchParams.get("formatting")!==null,c=await o.yjsStorage.getYDoc(a),f=At(c,s,d,i);return new Response(JSON.stringify(f),{status:200,headers:{"Content-Type":"application/json"}})});n.route("PUT /v2/rooms/<roomId>/ydoc",async({req:t,url:e,p:o})=>{if(t.headers.get("content-type")!=="application/octet-stream")return new Response(JSON.stringify({error:"BAD_REQUEST",message:'Expected "Content-Type" header to be "application/octet-stream", and the HTTP body to be a valid binary Yjs update.'}),{status:400,headers:{"Content-Type":"application/json"}});if(!L(o.roomId))throw k(o.roomId);let s=G(o.roomId);await s.load();let i=await t.arrayBuffer(),a=Zo.fromUint8Array(new Uint8Array(i)),d=e.searchParams.get("guid"),f=e.searchParams.get("encoder")==="v2",_=d&&d!==Fe?d:void 0;try{return await s.mutex.runExclusive(()=>s.yjsStorage.addYDocUpdate({},a,_,f)),new Response(JSON.stringify({success:!0}),{status:200,headers:{"Content-Type":"application/json"}})}catch(S){return new Response(JSON.stringify({error:"UNPROCESSABLE_ENTITY",message:S instanceof Error?S.message:"Could not apply update",suggestion:"Please ensure the update is correct, and you selected the correct encoder to use (v1 or v2)."}),{status:422,headers:{"Content-Type":"application/json"}})}});n.route("GET /v2/rooms/<roomId>/ydoc-binary",async({url:t,p:e})=>{if(!L(e.roomId))throw k(e.roomId);let o=G(e.roomId);await o.load();let s=t.searchParams.get("guid")??Fe,i=t.searchParams.get("encoder"),a=await o.yjsStorage.getYDoc(s),d=i==="v2"?ve.encodeStateAsUpdateV2(a):ve.encodeStateAsUpdate(a);return new Response(d,{status:200,headers:{"Content-Type":"application/octet-stream"}})});n.route("GET /v2/rooms/<roomId>/active_users",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);let o=G(t.roomId).listSessions().map(s=>({type:"user",connectionId:s.actor,id:s.user.id,info:s.user.info}));return Te({data:o})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);return N({ok:!0})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>/messages/<messageId>",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);return N({ok:!0})});n.route("GET /v2/rooms/<roomId>/feeds",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);return N({feeds:[{feedId:"123",metadata:{title:"Test Feed",description:"This is a test feed"},timestamp:new Date().getTime()}],nextCursor:null})});n.route("GET /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);return N({feedId:"123",timestamp:new Date().getTime(),metadata:{title:"Test Feed",description:"This is a test feed"}})});n.route("GET /v2/rooms/<roomId>/feeds/<feedId>/messages",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);return N({messages:[{messageId:"123",data:{content:"This is a test message"}}],nextCursor:null})});n.route("PATCH /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);let e=Date.now();return N({feedId:t.feedId,createdAt:e,updatedAt:e,metadata:{title:"Test Feed",description:"This is a test feed"}})});n.route("PATCH /v2/rooms/<roomId>/feeds/<feedId>/messages/<messageId>",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);let e=Date.now();return N({id:t.messageId,createdAt:e,updatedAt:e,data:{content:"This is a test message"}})});n.route("POST /v2/rooms/<roomId>/feeds",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);return N({feedId:"123",timestamp:new Date().getTime(),metadata:{title:"Test Feed",description:"This is a test feed"}})});n.route("POST /v2/rooms/<roomId>/feeds/<feedId>/messages",({p:t})=>{if(!L(t.roomId))throw k(t.roomId);return N({id:"123",timestamp:new Date().getTime(),data:{content:"This is a test message"}})});n.route("PATCH /v2/rooms/<roomId>/storage/json-patch",()=>r()),n.route("POST /v2/rooms/<roomId>/presence",()=>r()),n.route("GET /v2/rooms/<roomId>/threads",()=>r()),n.route("POST /v2/rooms/<roomId>/upsert",()=>r()),n.route("POST /v2/rooms/<roomId>/update-room-id",()=>r()),n.route("POST /v2/rooms/<roomId>/update-organization-id",()=>r()),n.route("GET /v2/rooms/<roomId>/prewarm",()=>r()),n.route("POST /v2/rooms/<roomId>/broadcast_event",()=>r()),n.route("GET /v2/rooms/<roomId>/versions",()=>r()),n.route("GET /v2/rooms/<roomId>/version/<version>",()=>r()),n.route("POST /v2/rooms/<roomId>/version",()=>r()),n.route("POST /v2/rooms/<roomId>/threads",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/mark-as-resolved",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/mark-as-unresolved",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/subscribe",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/unsubscribe",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/subscriptions",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/metadata",()=>r()),n.route("DELETE /v2/rooms/<roomId>/threads/<threadId>",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/participants",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/inbox-notifications",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments",()=>r()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/metadata",()=>r()),n.route("DELETE /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/add-reaction",()=>r()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/remove-reaction",()=>r()),n.route("GET /v2/rooms/<roomId>/attachments/<attachmentId>",()=>r()),n.route("GET /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>r()),n.route("GET /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>r()),n.route("POST /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>r()),n.route("POST /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>r()),n.route("DELETE /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>r()),n.route("DELETE /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>r()),n.route("GET /v2/users/<userId>/inbox-notifications/<inboxNotificationId>",()=>r()),n.route("DELETE /v2/users/<userId>/inbox-notifications/<inboxNotificationId>",()=>r()),n.route("GET /v2/users/<userId>/inbox-notifications",()=>r()),n.route("DELETE /v2/users/<userId>/inbox-notifications",()=>r()),n.route("GET /v2/users/<userId>/notification-settings",()=>r()),n.route("POST /v2/users/<userId>/notification-settings",()=>r()),n.route("DELETE /v2/users/<userId>/notification-settings",()=>r()),n.route("GET /v2/users/<userId>/room-subscription-settings",()=>r()),n.route("POST /v2/inbox-notifications/trigger",()=>r()),n.route("POST /v2/inbox-notifications/<inboxNotificationId>/read",()=>r()),n.route("POST /v2/groups",()=>r()),n.route("GET /v2/groups/<groupId>",()=>r()),n.route("POST /v2/groups/<groupId>/add-members",()=>r()),n.route("POST /v2/groups/<groupId>/remove-members",()=>r()),n.route("DELETE /v2/groups/<groupId>",()=>r()),n.route("GET /v2/groups",()=>r()),n.route("GET /v2/users/<userId>/groups",()=>r()),n.route("GET /v2/ai/copilots",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/<knowledgeSourceId>",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/file/<knowledgeSourceId>",()=>r()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/web/<knowledgeSourceId>/links",()=>r()),n.route("POST /v2/ai/copilots",()=>r()),n.route("POST /v2/ai/copilots/<copilotId>",()=>r()),n.route("POST /v2/ai/copilots/<copilotId>/knowledge/web",()=>r()),n.route("DELETE /v2/ai/copilots/<copilotId>",()=>r()),n.route("DELETE /v2/ai/copilots/<copilotId>/knowledge/file/<knowledgeSourceId>",()=>r()),n.route("DELETE /v2/ai/copilots/<copilotId>/knowledge/web/<knowledgeSourceId>",()=>r()),n.route("PUT /v2/ai/copilots/<copilotId>/knowledge/file/<fileName>",()=>r()),n.route("GET /v2/management/projects",()=>r()),n.route("GET /v2/management/projects/<projectId>",()=>r()),n.route("POST /v2/management/projects",()=>r()),n.route("POST /v2/management/projects/<projectId>",()=>r()),n.route("DELETE /v2/management/projects/<projectId>",()=>r()),n.route("GET /v2/management/projects/<projectId>/webhooks",()=>r()),n.route("GET /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>r()),n.route("GET /v2/management/projects/<projectId>/webhooks/<webhookId>/additional-headers",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/additional-headers",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/delete-additional-headers",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/recover-failed-messages",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/secret/roll",()=>r()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/test",()=>r()),n.route("DELETE /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>r()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/activate",()=>r()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/deactivate",()=>r()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/roll",()=>r()),n.route("POST /v2/management/projects/<projectId>/api-keys/secret/roll",()=>r());function Mt(t,e,o,s){if(!t.upgrade(e,{data:{refuseConnection:{code:o,message:s}}}))return new Response("Could not upgrade to WebSocket",{status:426})}var re=new ss;re.relay("/v2/authorize-user/*",ue);re.relay("/v2/identify-user/*",ue);re.relay("/v2/c/*",u);re.relay("/v2/*",n);re.relay("/*",se);var Ge=1153;function Ut(t){if(t===void 0)return;let e=Number(t);return Number.isInteger(e)&&e>0&&e<=65535?e:void 0}function ns(t){return process.platform==="win32"?[process.env.COMSPEC||"cmd.exe","/c",t]:["sh","-c",t]}function is(t){return"'"+t.replace(/'/g,"'\\''")+"'"}var as={description:"Start the local Liveblocks dev server",async run(t){let{options:e,args:o}=Ye(t,{port:{type:"string",short:"p",default:Ge.toString()},host:{type:"string"},cmd:{type:"string",short:"c"},help:{type:"boolean",short:"h",default:!1},"no-check":{type:"boolean",default:!1},ci:{type:"boolean",default:!1},verbose:{type:"boolean",short:"v",default:!1}},{allowPositionals:!0});if(o.length>0&&!e.cmd&&(console.error(ie("Extra arguments are only supported with --cmd (-c)")),process.exit(1)),o.length>0&&e.cmd){let p=o.map(is).join(" ");e.cmd.includes("{}")?e.cmd=e.cmd.replaceAll("{}",p):e.cmd+=" "+p}if(e.help){console.log("Usage: liveblocks dev [options]"),console.log(),console.log("Start the local Liveblocks dev server"),console.log(),console.log("Options:"),console.log(` --port, -p Port to listen on (default: ${Ge})`),console.log(" --host Host to bind to (default: localhost)"),console.log(" --cmd, -c Run a one-off command against a fresh server instance, then"),console.log(" shut down. Does not affect your local data in .liveblocks/."),console.log(" Extra args are appended to the command, or replace {} if"),console.log(" present. Use -- before args starting with -."),console.log(" --ci Start a fresh server instance on every boot, ideal for CI"),console.log(" --no-check Skip project setup check on start"),console.log(" --verbose, -v Show verbose output"),console.log(" --help, -h Show help");return}let s=!1;e.ci&&(s=!0,e["no-check"]=!0),e.cmd&&(s=!0,e["no-check"]=!0);let i=Ut(e.port)??Ut(process.env.LIVEBLOCKS_DEVSERVER_PORT)??Ge,a=e.host||process.env.LIVEBLOCKS_DEVSERVER_HOST||"localhost",d=s?st():null;await yt(i,a)&&(console.error(`Port ${i} is already in use.
398
+ Is another dev server already running?`),process.exit(1));let c,f=!1;function _(){return Je.serve({hostname:a,port:i,async fetch(p,b){if(p.headers.get("Upgrade")==="websocket"){let T=Tt(p);if(!T.ok)return De(T.xwarn,!0),Mt(b,p,jt.NOT_ALLOWED,"You have no access to this room");let{roomId:B,ticketData:be}=T;if(dt(B))return Mt(b,p,jt.TRY_AGAIN_LATER,"Server is undergoing maintenance, try again later");let A=G(B);await A.load();let x=await A.createTicket(be),V=x.sessionKey;if(b.upgrade(p,{data:{room:A,ticket:x,sessionKey:V}})){console.log(`${F("101")} WS ${new URL(p.url).pathname}${g(` - ${B}`)}`);return}return new Response("Could not upgrade to WebSocket",{status:426})}let O=new URL(p.url);if(p.method==="POST"&&O.pathname==="/crash")return console.log(`${F("204")} POST /crash`),setTimeout(()=>void S(),0),new Response(null,{status:204});let m=`${p.method} ${O.pathname}`,l;if(f)try{l=await p.clone().text()}catch{}let I=await re.fetch(p),y=I.status,C=y>=500?ie(y):y>=400?Z(y):F(y);console.log(`${C} ${m}`);let M=I.headers.get("X-LB-Warn")??void 0;if(De(M,!I.ok),f){if(l)try{let T=JSON.parse(l);console.log(g(` \u2192 ${JSON.stringify(T)}`))}catch{}try{let T=await I.clone().text(),B=JSON.parse(T);console.log(g(` \u2190 ${JSON.stringify(B)}`))}catch{}}return I},error(p){return console.error(p),new Response("An unknown error occurred",{status:500})},websocket:{async open(p){let{refuseConnection:b,room:O,ticket:m}=p.data;if(b){p.close(b.code,b.message);return}O&&m&&await O.startBrowserSession(m,p)},async message(p,b){let{room:O,sessionKey:m}=p.data;O&&m&&await O.handleData(m,b)},close(p,b,O){let{room:m,sessionKey:l}=p.data;m&&l&&m.endBrowserSession(l,b,O)}}})}c=_();async function S(){ut(),await c.stop(!0),c=_(),console.log("Crash \u{1F4A5}")}let E=p=>process.stderr.write(p+`
399
+ `);if(e.cmd){E(`Liveblocks dev server ${g("v1.3.0")} running at http://${c.hostname}:${c.port}`),d&&e.verbose&&E(g(`Ephemeral mode, using ${d}`));let p=rs(d,"server.log");E(g(`Server logs: ${p}`));let b=Je.file(p).writer(),O=(...l)=>{b.write(l.map(String).join(" ")+`
400
+ `),b.flush()};console.log=O,console.error=O;let m=1;try{let l=Je.spawn(ns(e.cmd),{stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LIVEBLOCKS_DEV_SERVER_HOST:a,LIVEBLOCKS_DEV_SERVER_PORT:String(i)}}),I=()=>{l.kill()};process.on("SIGTERM",I),process.on("SIGINT",I),m=await l.exited}finally{b.end(),await c.stop(),Le(),E(g("Liveblocks dev server shut down"))}process.exit(m)}else{let p=`http://${a}:${i}`,b=e["no-check"]?[]:await _t(p),O="logs",m=null,l=null,I=null,y=`http://${c.hostname}:${c.port}`,C=()=>{let R=O==="logs"?P(" Logs "):g(" Logs "),v=O==="sockets"?P(" Sockets "):g(" Sockets "),h=R+g("|")+v,ne=(l?z("\u23F8 maintenance")+" ":"")+g(`Liveblocks running at ${y}`),ye=process.stdout.columns??80,Re=Math.max(1,ye-Oe(h).length-Oe(ne).length);return h+" ".repeat(Re)+ne},M=[],T=console.log.bind(console);console.log=(...R)=>{let v=R.map(String).join(" ");M.push(v),O==="logs"&&T(v)};let B=()=>g(" ")+P("q")+g(" quit, ")+P("!")+g(" crash, ")+P("c")+g(" clear, ")+P("v")+g(f?" verbose (on)":" verbose"),be=()=>{I&&(clearInterval(I),I=null),O="logs",process.stdout.write("\x1B[2J\x1B[H"),T(C()),T(B()),T();for(let R of M)T(R)},A=0,x=[],V=R=>`${R.roomId}:${R.actor}`,Se=()=>{x=de().map(R=>({...R,alive:!0}))},Ft=()=>{let R=new Set(de().map(V));for(let h of x)h.alive=R.has(V(h));let v=new Set(x.map(V));for(let h of de())v.has(V(h))||x.push({...h,alive:!0})},Bt=R=>{let v=Date.now()-R,h=Math.floor(v/1e3);if(h<60)return`${h}s`;let j=Math.floor(h/60);return j<60?`${j}m`:`${Math.floor(j/60)}h`},Jt=R=>{if(!R)return"";let v=Date.now()-R;return v<1e3?" "+F("\u25CF"):v<3e3?" "+g(F("\u25CF")):v<5e3?" "+g("\u25CF"):""},me=(R,v)=>{let h=R+v;for(;h>=0&&h<x.length;){if(x[h].alive)return h;h+=v}return R},K=()=>{Ft();let R=x.filter(h=>h.alive).length;if(process.stdout.write("\x1B[2J\x1B[H"),T(C()),T(g(" ")+P("\u2191\u2193")+g(" navigate, ")+P("k")+g(" kill, ")+P("m")+g(l?" maintenance off, ":" maintenance on, ")+P("r")+g(" refresh")),T(),T(" "+P("Connections")+g(` (${R} alive)`)),T(),x.length===0){T(g(" No active connections"));return}if(A>=x.length&&(A=x.length-1),!x[A]?.alive){let h=me(A,-1);A=x[h]?.alive?h:me(A,1)}let v=new Map;for(let h of de())v.set(V(h),h.lastActiveAt);for(let h=0;h<x.length;h++){let j=x[h];if(!j.alive){T(g(` ${j.roomId} \xB7 actor=${j.actor} \xB7 disconnected`));continue}let ne=h===A?F("\u25B6 "):" ",ye=j.userId??g("anonymous"),Re=Bt(j.connectedAt),Yt=v.get(V(j)),Vt=Jt(Yt);T(`${ne}${P(j.roomId)} ${g("\xB7")} actor=${j.actor} ${g("\xB7")} ${ye} ${g("\xB7")} ${g(Re)}${Vt}`)}},Gt=()=>{O="sockets",A=0,Se(),K(),I=setInterval(()=>K(),1e3)},$t=()=>{if(l)l(),l=null;else{let{promise:R,resolve:v}=os();at(R),l=v}};process.stdout.write("\x1B[2J\x1B[H"),T(C()),T(B()),T(),d&&e.verbose&&console.log(g(`Ephemeral mode, using ${d}`)),process.stdin.setRawMode?.(!0),process.stdin.resume(),process.stdin.on("data",R=>{let v=R.toString();if(v===""||v==="q"){c.stop(!0).then(()=>{Le(),process.exit(0)});return}if(v==="m"){$t(),O==="sockets"?K():(process.stdout.write("\x1B[s\x1B[H\x1B[2K"),T(C()),process.stdout.write("\x1B[u"));return}if((v==="s"||v==="\x1B[C")&&O!=="sockets"){Gt();return}if((v==="l"||v==="\x1B[D")&&O!=="logs"){be();return}if(O==="sockets"){if(v==="\x1B[A")A=me(A,-1),K();else if(v==="\x1B[B")A=me(A,1),K();else if(v==="k"){let h=x[A];h?.alive&&(ct(h.roomId,h.actor),K())}else v==="r"&&(Se(),A=0,K());return}if(v==="!")m!==null?(clearTimeout(m),m=null,S()):(console.log("Simulating crash in 2.5s... (press ! again to crash now)"),m=setTimeout(()=>{m=null,S()},2500));else if(v==="c")M.length=0,process.stdout.write("\x1B[2J\x1B[H"),T(C()),T(B()),T();else if(v==="v")f=!f,process.stdout.write("\x1B[s\x1B[H\x1B[2K"),T(C()),process.stdout.write("\x1B[2K"),T(B()),process.stdout.write("\x1B[u"),console.log(g(f?"Verbose mode on":"Verbose mode off"));else if(v==="p")if(b.length>0){let h=bt(b,p);St(h),console.log(g("Copied AI fix prompt to clipboard"))}else console.log(g("No setup issues detected"))})}}},Ar=as;export{Ar as default};
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{i as r}from"./chunk-27HMDMOH.js";import{execFileSync as l,spawnSync as c}from"node:child_process";function a(){try{return l("bun",["--version"],{stdio:"ignore"}),!0}catch{return!1}}function d(){if(a()){let e=c("bun",process.argv.slice(1),{stdio:"inherit"});process.exit(e.status??1)}else console.error("The Liveblocks local dev server requires Bun."),console.error("See https://liveblocks.io/docs/get-started/dev-server for more information."),process.exit(1)}var s=process.argv.slice(2),o=s.findIndex(e=>!e.startsWith("-")),{options:t}=r(o>=0?s.slice(0,o):s,{help:{type:"boolean",short:"h",default:!1},version:{type:"boolean",default:!1}}),n=o>=0?s[o]:void 0,u=o>=0?s.slice(o+1):[];async function p(e){switch(e){case"dev":return typeof Bun>"u"&&d(),(await import("./dev-server-6J6UWSVZ.js")).default;case"upgrade":return(await import("./upgrade-4WWSF4S5.js")).default;default:return}}var m={dev:"Start the local Liveblocks dev server",upgrade:"Upgrade all Liveblocks packages"};function f(){console.log("liveblocks v1.2.1"),console.log(),console.log("Usage: liveblocks <command> [options]"),console.log(),console.log("Commands:");for(let[e,i]of Object.entries(m))console.log(` ${e.padEnd(12)} ${i}`);console.log(),console.log("Options:"),console.log(" --help, -h Show this help message"),console.log(" --version Show version number")}async function v(){t.version&&(console.log("1.2.1"),process.exit(0)),(t.help||!n)&&(f(),process.exit(n?0:1));let e=await p(n);e?await e.run(u):(console.error(`Unknown command: ${n}`),console.error('Run "liveblocks --help" for usage.'),process.exit(1))}v();
2
+ import{i as r}from"./chunk-27HMDMOH.js";import{execFileSync as l,spawnSync as c}from"node:child_process";function a(){try{return l("bun",["--version"],{stdio:"ignore"}),!0}catch{return!1}}function d(){if(a()){let e=c("bun",process.argv.slice(1),{stdio:"inherit"});process.exit(e.status??1)}else console.error("The Liveblocks local dev server requires Bun."),console.error("See https://liveblocks.io/docs/get-started/dev-server for more information."),process.exit(1)}var s=process.argv.slice(2),o=s.findIndex(e=>!e.startsWith("-")),{options:t}=r(o>=0?s.slice(0,o):s,{help:{type:"boolean",short:"h",default:!1},version:{type:"boolean",default:!1}}),n=o>=0?s[o]:void 0,u=o>=0?s.slice(o+1):[];async function p(e){switch(e){case"dev":return typeof Bun>"u"&&d(),(await import("./dev-server-QE4U22NI.js")).default;case"upgrade":return(await import("./upgrade-4WWSF4S5.js")).default;default:return}}var m={dev:"Start the local Liveblocks dev server",upgrade:"Upgrade all Liveblocks packages"};function f(){console.log("liveblocks v1.3.0"),console.log(),console.log("Usage: liveblocks <command> [options]"),console.log(),console.log("Commands:");for(let[e,i]of Object.entries(m))console.log(` ${e.padEnd(12)} ${i}`);console.log(),console.log("Options:"),console.log(" --help, -h Show this help message"),console.log(" --version Show version number")}async function v(){t.version&&(console.log("1.3.0"),process.exit(0)),(t.help||!n)&&(f(),process.exit(n?0:1));let e=await p(n);e?await e.run(u):(console.error(`Unknown command: ${n}`),console.error('Run "liveblocks --help" for usage.'),process.exit(1))}v();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "liveblocks",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "Liveblocks command line interface",
5
5
  "type": "module",
6
6
  "bin": {
@@ -44,7 +44,7 @@
44
44
  "js-base64": "^3.7.5",
45
45
  "yjs": "^13.6.10",
46
46
  "@liveblocks/query-parser": "^0.1.1",
47
- "@liveblocks/server": "^1.2.1"
47
+ "@liveblocks/server": "^1.3.0"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsup",