liveblocks 1.2.1 → 1.4.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.
- package/dist/dev-server-Q637N3GN.js +406 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/dist/dev-server-6J6UWSVZ.js +0 -400
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import{a as Q,b as $e,c as V,d as J,e as ae,f as P,g,h as we,i as ze}from"./chunk-27HMDMOH.js";import{Promise_withResolvers as dr,tryParseJson as Mt,WebsocketCloseCodes as Ut}from"@liveblocks/core";import{ZenRelay as cr}from"@liveblocks/zenrouter";import Je from"bun";import{join as ur}from"path";import{nanoid as Ro}from"@liveblocks/core";import{ProtocolVersion as Et}from"@liveblocks/server";import{nanoid as ro,WebsocketCloseCodes as We}from"@liveblocks/core";import{DefaultMap as so,Room as no}from"@liveblocks/server";import{Database as io}from"bun:sqlite";import{mkdirSync as qe,mkdtempSync as ao,rmSync as co}from"fs";import{tmpdir as uo}from"os";import{dirname as lo,join as ge,resolve as Xe}from"path";import{asPos as Ht,CrdtType as $,nn as Xt}from"@liveblocks/core";import{makeInMemorySnapshot as Wt,NestedMap as qt,plainLsonToNodeStream as Zt,quote as G}from"@liveblocks/server";import{Database as Qt}from"bun:sqlite";function X(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 eo(t){return Array.isArray(t)?t:Array.from(t)}function to(t){return t.query("SELECT node_id, crdt_json FROM nodes").values().map(([e,o])=>[e,X(o)])}function de(t,e){let o=t.prepare(`INSERT INTO nodes (node_id, crdt_json)
|
|
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 He(t,e){let o=eo(e),r=o.length;t.query(`DELETE FROM nodes WHERE node_id IN (${Ke(r)})`).run(...o)}function Ye(t){let e=new qt;for(let[o,r]of t){if(r.parentId===void 0)continue;let i=e.get(r.parentId,r.parentKey);(i===void 0||o>i)&&e.set(r.parentId,r.parentKey,o)}return e}function oo(t,e){let o=new Map(to(t));o.has("root")||o.set("root",{type:$.OBJECT,data:{}});let r=new Set,i=["root"],a=new Map,d=Ye(o);for(;i.length>0;){let T=i.pop(),b=Xt(o.get(T));if(b.type===$.OBJECT)for(let h of d.keysAt(T))Object.prototype.hasOwnProperty.call(b.data,h)&&(delete b.data[h],r.add(T),e.warn(`[integrity] Found data key ${G(h)} from ${G(T)} (conflicted with child node)`));if(b.type!==$.REGISTER)i.push(...d.valuesAt(T));else if(o.get(b.parentId)?.type===$.OBJECT)continue;a.set(T,b)}let c=new Set;for(let[T,b]of o)a.has(T)||(b.parentId!==void 0&&a.has(b.parentId)?a.get(b.parentId)?.type===$.REGISTER?e.warn(`[integrity] Found unreachable node ${G(T)} (child of live register)`):e.warn(`[integrity] Found conflicting sibling ${G(T)} (conflicted with ${G(d.get(b.parentId,b.parentKey))} at ${G(b.parentKey)})`):e.warn(`[integrity] Found orphan ${G(T)}`),c.add(T),r.delete(T));if(r.size>0||c.size>0){if(r.size>0){let T=new Map;for(let b of r){let h=a.get(b);h!==void 0&&T.set(b,h)}de(t,T)}c.size>0&&He(t,c)}let p=c.size===0?d:Ye(a);return{nodes:a,revNodes:p}}function Ve(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
|
+
setting TEXT NOT NULL,
|
|
5
|
+
jval TEXT NOT NULL,
|
|
6
|
+
PRIMARY KEY (setting)
|
|
7
|
+
)`),o.run(`CREATE TABLE IF NOT EXISTS nodes (
|
|
8
|
+
node_id TEXT NOT NULL,
|
|
9
|
+
crdt_json TEXT NOT NULL,
|
|
10
|
+
PRIMARY KEY (node_id)
|
|
11
|
+
)`),o.run(`CREATE TABLE IF NOT EXISTS metadata (
|
|
12
|
+
key TEXT NOT NULL,
|
|
13
|
+
jval TEXT NOT NULL,
|
|
14
|
+
PRIMARY KEY (key)
|
|
15
|
+
)`),o.run(`CREATE TABLE IF NOT EXISTS ydocs (
|
|
16
|
+
doc_id TEXT NOT NULL,
|
|
17
|
+
key TEXT NOT NULL,
|
|
18
|
+
data BLOB NOT NULL,
|
|
19
|
+
PRIMARY KEY (doc_id, key)
|
|
20
|
+
)`),o.run(`CREATE TABLE IF NOT EXISTS leased_sessions (
|
|
21
|
+
session_id TEXT NOT NULL PRIMARY KEY,
|
|
22
|
+
jpresence TEXT NOT NULL,
|
|
23
|
+
updated_at INTEGER NOT NULL,
|
|
24
|
+
juserinfo TEXT NOT NULL,
|
|
25
|
+
ttl INTEGER NOT NULL,
|
|
26
|
+
actor_id INTEGER NOT NULL
|
|
27
|
+
)`),o.run("CREATE INDEX IF NOT EXISTS idx_leased_sessions_expiry ON leased_sessions(updated_at, ttl)"),o.run(`CREATE TABLE IF NOT EXISTS feeds (
|
|
28
|
+
feed_id TEXT NOT NULL PRIMARY KEY,
|
|
29
|
+
jmetadata TEXT NOT NULL,
|
|
30
|
+
created_at INTEGER NOT NULL,
|
|
31
|
+
updated_at INTEGER NOT NULL
|
|
32
|
+
)`),o.run("CREATE INDEX IF NOT EXISTS idx_feeds_created_at ON feeds(created_at DESC, feed_id DESC)"),o.run(`CREATE TABLE IF NOT EXISTS feed_messages (
|
|
33
|
+
feed_id TEXT NOT NULL,
|
|
34
|
+
message_id TEXT NOT NULL,
|
|
35
|
+
jdata TEXT NOT NULL,
|
|
36
|
+
created_at INTEGER NOT NULL,
|
|
37
|
+
updated_at INTEGER NOT NULL,
|
|
38
|
+
PRIMARY KEY (feed_id, message_id),
|
|
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:r,revNodes:i}=oo(o,e),a=m=>r.get(m),d=(m,l)=>i.get(m,l),c=(m,l)=>i.has(m,l);function p(m,l){let E;for(let S of i.keysAt(m)){let w=Ht(S);w>l&&(E===void 0||w<E)&&(E=w)}return E}function T(m,l,E=!1){let S=a(l.parentId);if(S===void 0)throw new Error(`No such parent ${G(l.parentId)}`);if(l.type===$.REGISTER&&S.type===$.OBJECT)throw new Error("Cannot add register under object");let w=d(l.parentId,l.parentKey);if(w!==m){let M=Ve(S,l.parentKey);if(w!==void 0||M)if(E)_(l.parentId,l.parentKey);else throw new Error(`Key ${G(l.parentKey)} already exists`);i.set(l.parentId,l.parentKey,m)}r.set(m,l),de(o,[[m,l]])}function b(m,l){let E=a(m);if(E?.parentId===void 0)return;if(c(E.parentId,l))throw new Error(`Pos ${G(l)} already taken`);i.delete(E.parentId,E.parentKey);let S={...E,parentKey:l};r.set(m,S),i.set(E.parentId,l,m),de(o,[[m,S]])}function h(m,l,E=!1){let S=a(m);if(S?.type!==$.OBJECT)return;for(let M of Object.keys(l)){let y=d(m,M);if(y!==void 0)if(E)f(y);else throw new Error(`Child node already exists under ${M}`)}let w={...S,data:{...S.data,...l}};r.set(m,w),de(o,[[m,w]])}function f(m){let l=a(m);if(l?.parentId===void 0)return;i.delete(l.parentId,l.parentKey);let E=[],S=[m];for(;S.length>0;){let w=S.pop();S.push(...i.valuesAt(w)),r.delete(w),i.deleteAll(w),E.push(w)}He(o,E)}function _(m,l){let E=a(m);if(Ve(E,l)){let{[l]:w,...M}=E.data,y={...E,data:M};r.set(m,y),de(o,[[m,y]])}let S=d(m,l);S!==void 0&&f(S)}return{get_node:a,iter_nodes:()=>r.entries(),has_node:m=>r.has(m),get_child_at:d,has_child_at:c,get_next_sibling:p,set_child:T,move_sibling:b,delete_node:f,delete_child_key:_,set_object_data:h,get_snapshot(m){return Wt(r)}}}DANGEROUSLY_reset_nodes(e){let o=this.db.prepare("DELETE FROM nodes"),r=this.db.prepare("INSERT INTO nodes (node_id, crdt_json) VALUES (?, ?)");this.db.transaction(()=>{o.run();for(let[a,d]of Zt(e))r.run(a,JSON.stringify(d))})()}raw_iter_nodes(){return this.db.query("SELECT node_id, crdt_json FROM nodes").values().map(([e,o])=>[e,X(o)])}get_meta(e){let r=this.db.query("SELECT jval FROM metadata WHERE key = ?").get(e)?.jval;if(r!==void 0)return X(r)??null}put_meta(e,o){let r=JSON.stringify(o);this.db.run(`INSERT INTO metadata (key, jval)
|
|
41
|
+
VALUES (?, ?)
|
|
42
|
+
ON CONFLICT (key) DO UPDATE SET jval = ?
|
|
43
|
+
`,[e,r,r])}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)
|
|
44
|
+
VALUES ('last_actor_id', '0')
|
|
45
|
+
ON CONFLICT (setting) DO UPDATE SET jval = json(CAST(jval AS INTEGER) + 1)
|
|
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,r){this.db.query(`INSERT INTO ydocs
|
|
47
|
+
VALUES (?, ?, ?)
|
|
48
|
+
ON CONFLICT (doc_id, key) DO UPDATE SET data = ?`).run(e,o,r,r)}delete_y_updates(e,o){let r=o.length;this.db.query(`DELETE FROM ydocs WHERE doc_id = ? AND key IN (${Ke(r)})`).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:X(o.jpresence)??null,updatedAt:o.updated_at,info:X(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:X(o.jpresence)??null,updatedAt:o.updated_at,info:X(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
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
50
|
+
ON CONFLICT (session_id) DO UPDATE SET
|
|
51
|
+
jpresence = excluded.jpresence,
|
|
52
|
+
updated_at = excluded.updated_at,
|
|
53
|
+
juserinfo = excluded.juserinfo,
|
|
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),r=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[h,f]of Object.entries(a)){let _=typeof f=="boolean"?Number(f):f;d+=" AND json_extract(jmetadata, '$.' || ?) = ?",c.push(h,_)}if(r!==void 0&&(d+=" AND created_at >= ?",c.push(r)),i!==void 0)try{let h=JSON.parse(Buffer.from(i.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[f,_]=h;d+=" AND (created_at < ? OR (created_at = ? AND feed_id < ?))",c.push(_,_,f)}catch{}d+=" ORDER BY created_at DESC, feed_id DESC LIMIT ?",c.push(o+1);let p=this.db.query(d).all(...c),T;if(p.length>o){p.pop();let h=p[p.length-1];if(h){let f=[h.feed_id,h.created_at];T=Buffer.from(JSON.stringify(f),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}return{feeds:p.map(h=>({feedId:h.feed_id,metadata:JSON.parse(h.jmetadata),createdAt:h.created_at,updatedAt:h.updated_at})),nextCursor:T}}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 r=this.db.query("UPDATE feeds SET jmetadata = ? WHERE feed_id = ? RETURNING feed_id, jmetadata, created_at, updated_at").get(JSON.stringify(o),e);if(r==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 r=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 h=JSON.parse(Buffer.from(a.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[f,_]=h;d+=" AND (created_at < ? OR (created_at = ? AND message_id < ?))",c.push(_,_,f)}catch{}d+=" ORDER BY created_at DESC, message_id DESC LIMIT ?",c.push(r+1);let p=this.db.query(d).all(...c),T;if(p.length>r){p.pop();let h=p[p.length-1];if(h){let f=[h.message_id,h.created_at];T=Buffer.from(JSON.stringify(f),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}return{messages:p.map(h=>({id:h.message_id,data:JSON.parse(h.jdata),createdAt:h.created_at,updatedAt:h.updated_at})),nextCursor:T}}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,r,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(r),d,e,o,d);if(c==null){let p=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(p==null)throw new Error(`Feed message ${o} not found in feed ${e}`);return{id:p.message_id,data:JSON.parse(p.jdata),createdAt:p.created_at,updatedAt:p.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 mo=".liveblocks/v1",he=mo,Ze=!1,W=null;function Qe(){return ge(he,"rooms")}function te(){if(W)return;let t=ge(he,"db.sql");qe(lo(t),{recursive:!0});let e=new io(t,{create:!0});e.run("PRAGMA journal_mode = WAL"),e.run("PRAGMA foreign_keys = ON"),e.run(`CREATE TABLE IF NOT EXISTS rooms (
|
|
56
|
+
room_id TEXT NOT NULL PRIMARY KEY,
|
|
57
|
+
internal_id TEXT NOT NULL UNIQUE,
|
|
58
|
+
organization_id TEXT NOT NULL,
|
|
59
|
+
default_permissions TEXT NOT NULL,
|
|
60
|
+
metadata TEXT NOT NULL,
|
|
61
|
+
created_at TEXT NOT NULL
|
|
62
|
+
) STRICT`),e.run(`CREATE TABLE IF NOT EXISTS room_user_permissions (
|
|
63
|
+
room_id TEXT NOT NULL,
|
|
64
|
+
user_id TEXT NOT NULL,
|
|
65
|
+
scopes TEXT NOT NULL,
|
|
66
|
+
PRIMARY KEY (room_id, user_id),
|
|
67
|
+
FOREIGN KEY (room_id) REFERENCES rooms(room_id) ON DELETE CASCADE
|
|
68
|
+
) STRICT`),e.run(`CREATE TABLE IF NOT EXISTS room_group_permissions (
|
|
69
|
+
room_id TEXT NOT NULL,
|
|
70
|
+
group_id TEXT NOT NULL,
|
|
71
|
+
scopes TEXT NOT NULL,
|
|
72
|
+
PRIMARY KEY (room_id, group_id),
|
|
73
|
+
FOREIGN KEY (room_id) REFERENCES rooms(room_id) ON DELETE CASCADE
|
|
74
|
+
) STRICT`),W=e}function oe(){if(!W)throw new Error("Rooms DB not initialized");return W}function et(t){let e=oe(),o=e.query("SELECT user_id, scopes FROM room_user_permissions WHERE room_id = ?").all(t.room_id),r=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 r)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 ee(t){let e=oe().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 fo="default";function tt(t,e){let o=oe(),r=ro(),i=new Date().toISOString(),a=e?.organizationId??fo,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,r,a,JSON.stringify(d),JSON.stringify(c),i]),e?.usersAccesses)for(let[p,T]of Object.entries(e.usersAccesses))o.run("INSERT INTO room_user_permissions (room_id, user_id, scopes) VALUES (?, ?, ?)",[t,p,JSON.stringify(T)]);if(e?.groupsAccesses)for(let[p,T]of Object.entries(e.groupsAccesses))o.run("INSERT INTO room_group_permissions (room_id, group_id, scopes) VALUES (?, ?, ?)",[t,p,JSON.stringify(T)]);return{id:t,internalId:r,organizationId:a,defaultAccesses:d,usersAccesses:e?.usersAccesses??{},groupsAccesses:e?.groupsAccesses??{},metadata:c,createdAt:i}}function po(t,e){let o=oe(),r=ee(t);if(r){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={...r.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
|
+
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 ee(t)}}function go(t){oe().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 so(t=>{let e=ee(t)??tt(t);qe(Qe(),{recursive:!0});let o=new pe(ot(e.internalId));return new no(t,{storage:o})});function rt(){let t=ao(ge(uo(),"liveblocks-dev-"));return he=ge(t,"data"),Ze=!0,t}function C(t){return te(),ee(t)}function ve(t,e){te();let o=ee(t);if(o)return o;let r=tt(t,e);return U.getOrCreate(t),r}function st(t){te();let e=oe(),o=[],r=[];if(t?.organizationId&&(o.push("organization_id = ?"),r.push(t.organizationId)),t?.roomId){o.push("room_id LIKE ? ESCAPE '\\'");let d=t.roomId.value.replace(/[%_\\]/g,"\\$&");r.push(`${d}%`)}if(t?.metadata)for(let[d,c]of Object.entries(t.metadata))o.push("JSON_EXTRACT(metadata, ?) = ?"),r.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
|
+
FROM rooms
|
|
78
|
+
${i}`).all(...r).map(et)}function nt(t,e){return te(),po(t,e)}async function it(t){te();let e=ee(t),o=U.get(t);if(o&&(o.endSessionBy(()=>!0,We.KICKED,"Deliberately disconnected"),o.unload(),o.driver.close(),U.delete(t)),e){let r=ot(e.internalId);try{await Bun.write(r,""),await Bun.file(r).unlink()}catch{}go(t)}}function B(t){return te(),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 ce(){let t=[];for(let[e,o]of U)for(let r of o.listSessions())t.push({roomId:e,actor:r.actor,userId:r.user.id??r.user.anonymousId,connectedAt:r.createdAt,lastActiveAt:r.lastActiveAt});return t}function ct(t,e){let o=U.get(t);return o?o.endSessionBy(r=>r.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(),W&&(W.close(),W=null),Ze&&co(he,{recursive:!0,force:!0})}import{nanoid as vo,tryParseJson as ft}from"@liveblocks/core";import{array as ht,constant as ue,enum_ as Eo,number as vt,object as ke,optional as Ne,record as Io,string as Ae,taggedUnion as To}from"decoders";import{inexact as ho,optional as lt,string as mt}from"decoders";var re=ho({name:lt(mt),avatar:lt(mt)}).refineType();var q={RoomRead:"room:read",RoomWrite:"room:write",CommentsWrite:"comments:write",FeedsWrite:"feeds:write",RoomPresenceWrite:"room:presence:write",CommentsRead:"comments:read"};var yo=ke({alg:ue("none")}),_o=ke({k:ue("acc"),pid:ue("localdev"),uid:Ae,ui:Ne(re),perms:Io(ht(Eo(q))),exp:vt}),bo=ke({k:ue("id"),pid:ue("localdev"),uid:Ae,ui:Ne(re),gids:Ne(ht(Ae)),exp:vt}),So=To("k",{acc:_o,id:bo});function pt(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 Pe(t){let e=Math.floor(Date.now()/1e3),o={...t,iat:e,exp:e+60*60,jti:vo(12)},r=pt(JSON.stringify({alg:"none",typ:"JWT"})),i=pt(JSON.stringify(o));return`${r}.${i}.`}function Ee(t){let e=t.split(".");if(e.length!==3)return null;let[o,r,i]=e;if(i!==""||!yo.value(ft(gt(o))))return null;let a=So.value(ft(gt(r)));return!a||a.exp<Math.floor(Date.now()/1e3)?null:a}function Oo(t,e){if(t.perms[e])return t.perms[e];for(let[o,r]of Object.entries(t.perms))if(o.endsWith("*")){let i=o.slice(0,-1);if(e.startsWith(i))return r}return[]}function wo(t,e){let o=C(e);if(!o)return[];let r=new Set(o.defaultAccesses);if(t.gids)for(let i of t.gids)for(let a of o.groupsAccesses[i]??[])r.add(a);for(let i of o.usersAccesses[t.uid]??[])r.add(i);return Array.from(r)}function Co(t,e){return t.k==="acc"?Oo(t,e):wo(t,e)}function It(t){let e=new URL(t.url),o=e.pathname==="/v7"?Et.V7:e.pathname==="/v8"?Et.V8:null;if(o===null)return{ok:!1};let r=e.searchParams.get("roomId");if(!r)return{ok:!1};let i=e.searchParams.get("tok");if(i!==null){let d=Ee(i);if(!d)return{ok:!1};let c=Co(d,r);return c.length===0?{ok:!1}:{ok:!0,roomId:r,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"}:(ve(r,{defaultAccesses:[q.RoomWrite]}),{ok:!0,roomId:r,ticketData:{version:o,anonymousId:Ro(),scopes:[q.RoomWrite]}}):{ok:!1}}function Lo(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"}),r=await new Response(o.stdout).text();return await o.exited,Lo(r)}catch{return[]}}function xo(t){let e=t.trim();return e.startsWith("#")||e.startsWith("//")||e.startsWith("*")||e.startsWith("/*")}var De=[{pattern:"<LiveblocksProvider",expected:"baseUrl=",fixSnippet:t=>`${V("baseUrl")}=${J(`"${t}"`)}`,closePattern:">"},{pattern:"createClient(",expected:"baseUrl:",fixSnippet:t=>`${V("baseUrl")}: ${J(`"${t}"`)}`,closePattern:")"},{pattern:"new Liveblocks(",expected:"baseUrl:",fixSnippet:t=>`${V("baseUrl")}: ${J(`"${t}"`)}`,closePattern:")"}];async function yt(t){let e=De.map(c=>c.pattern),o=[...new Set(De.map(c=>c.expected))],[r,i]=await Promise.all([Tt(...e),Tt(...o)]);if(r.length===0)return[];let a=new Set(i.map(c=>c.file)),d=[];for(let c of r){if(xo(c.text)||a.has(c.file))continue;let p=De.find(T=>c.text.includes(T.pattern));p&&d.push({match:c,check:p})}if(d.length>0){console.log(),console.warn(Q("\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:p}of d)console.log(` ${$e(`${c.file}:${c.line}`)}`),console.log(` To fix, add ${p.fixSnippet(t)} to ${V(p.pattern)}${V(p.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 No={"<LiveblocksProvider":"baseUrl={...}","createClient(":"baseUrl: ...","new Liveblocks(":"baseUrl: ..."};function _t(t,e){let o=t.map(({match:r,check:i})=>{let a=No[i.pattern]??"baseUrl: ...";return` - In \`${r.file}\` at line ${r.line}, add \`${a}\` to the \`${i.pattern}\` call`}).join(`
|
|
81
|
+
`);return`# Set up Liveblocks dev server
|
|
82
|
+
|
|
83
|
+
1. Check which system the application is using for environment variables, then
|
|
84
|
+
add a new environment variable called \`USE_LIVEBLOCKS_DEV_SERVER="true"\`.
|
|
85
|
+
This will be used to enable the dev server. It needs to be available on the client, so it may need to be called
|
|
86
|
+
\`NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER\` or similar. Do not rename or modify existing variables.
|
|
87
|
+
2. You must use \`"${e}"\` as a \`baseUrl\` when the dev server is
|
|
88
|
+
enabled. In the following files add a \`baseUrl\` property for this when the
|
|
89
|
+
dev server is enabled, otherwise set \`baseUrl\` to \`undefined\`:
|
|
90
|
+
${o}
|
|
91
|
+
|
|
92
|
+
3. Identify if the user is using \`publicApiKey\` in \`LiveblocksProvider\` or
|
|
93
|
+
\`secret\` in \`new Liveblocks\`. Edit the existing property to use "pk_localdev"
|
|
94
|
+
(for \`publicApikey\`) or "sk_localdev" (for \`secret\`) when the dev server is
|
|
95
|
+
enabled.
|
|
96
|
+
|
|
97
|
+
## Examples
|
|
98
|
+
|
|
99
|
+
Remember to keep the user's current system for environment variables and names.
|
|
100
|
+
In the following snippets, I have given the following names, but the user's
|
|
101
|
+
system may work differently: \`process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_KEY\`
|
|
102
|
+
and \`process.env.LIVEBLOCKS_SECRET_KEY\`.
|
|
103
|
+
|
|
104
|
+
### Public key example
|
|
105
|
+
|
|
106
|
+
If the user is already using the public key with \`publicApKey\`:
|
|
107
|
+
|
|
108
|
+
\`\`\`env file=".env.local"
|
|
109
|
+
NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER="true"
|
|
110
|
+
\`\`\`
|
|
111
|
+
|
|
112
|
+
\`\`\`tsx file="src/app/Providers.tsx"
|
|
113
|
+
<LiveblocksProvider
|
|
114
|
+
baseUrl={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "${e}" : undefined}
|
|
115
|
+
publicApiKey={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "pk_localdev" : process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_KEY}
|
|
116
|
+
\`\`\`
|
|
117
|
+
|
|
118
|
+
### Secret key example
|
|
119
|
+
|
|
120
|
+
If the user is already using their secret key with \`secret\`:
|
|
121
|
+
|
|
122
|
+
\`\`\`env file=".env.local"
|
|
123
|
+
NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER="true"
|
|
124
|
+
\`\`\`
|
|
125
|
+
|
|
126
|
+
\`\`\`tsx file="src/app/Providers.tsx"
|
|
127
|
+
<LiveblocksProvider
|
|
128
|
+
baseUrl={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "${e}" : undefined}
|
|
129
|
+
\`\`\`
|
|
130
|
+
|
|
131
|
+
\`\`\`ts file="src/app/api/liveblocks-auth/route.ts"
|
|
132
|
+
new Liveblocks({
|
|
133
|
+
baseUrl={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "${e}" : undefined}
|
|
134
|
+
secret={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "sk_localdev" : process.env.LIVEBLOCKS_SECRET_KEY}
|
|
135
|
+
\`\`\`
|
|
136
|
+
|
|
137
|
+
## Follow up
|
|
138
|
+
|
|
139
|
+
Explain to the user that you've enabled the Liveblocks dev server by adding a an
|
|
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 Ao}from"node:child_process";function bt(t){let e=process.platform==="darwin"?"pbcopy":process.platform==="win32"?"clip.exe":"xclip -selection clipboard";Ao(e,{input:t})}import ko from"bun";function St(t,e){let{promise:o,resolve:r}=Promise.withResolvers();return ko.connect({hostname:e,port:t,socket:{data(){},open(i){i.end(),r(!0)},error(){r(!1)},connectError(){r(!1)}}}),o}function je(t,e=!1){t&&console.log((e?ae:Q)(` \u26A0 ${t}`))}import{ZenRouter as Do}from"@liveblocks/zenrouter";import{array as Ot,enum_ as jo,object as wt,optional as Ue,record as Mo,string as Be}from"decoders";import{json as Po}from"@liveblocks/zenrouter";import{json as Rt}from"@liveblocks/zenrouter";function Me(t,e,o){return Rt(t,e,{"X-LB-Warn":o})}function N(t,e,o="This is a dummy response."){return Me(t,e,o)}function s(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 Po({error:"Unauthorized",message:"Missing secret key"},401);if(e.startsWith("Bearer "))throw Me({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 Uo=jo(q),le=new Do({authorize:({req:t})=>Ie(t)});le.route("POST /v2/authorize-user",wt({userId:Be,userInfo:Ue(re),permissions:Mo(Ot(Uo))}),({body:t})=>({token:Pe({k:"acc",pid:"localdev",uid:t.userId,perms:t.permissions,ui:t.userInfo})}));le.route("POST /v2/identify-user",wt({userId:Be,userInfo:Ue(re),groupIds:Ue(Ot(Be))}),({body:t})=>({token:Pe({k:"id",pid:"localdev",uid:t.userId,ui:t.userInfo,gids:t.groupIds})}));import{ZenRouter as Bo}from"@liveblocks/zenrouter";var u=new Bo({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}});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>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<name>",()=>s()),u.route("PUT /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>/<partNumber>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>/complete",()=>s()),u.route("DELETE /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/attachments/presigned-urls",()=>s()),u.route("POST /v2/c/rooms/<roomId>/send-message",()=>s()),u.route("GET /v2/c/rooms/<roomId>/storage",()=>s()),u.route("POST /v2/c/rooms/<roomId>/version",()=>s()),u.route("GET /v2/c/rooms/<roomId>/y-version/<version>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/ai/contextual-prompt",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/search",()=>s()),u.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/metadata",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/mark-as-resolved",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/mark-as-unresolved",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/subscribe",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/unsubscribe",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments",()=>s()),u.route("GET /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/metadata",()=>s()),u.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/reactions",()=>s()),u.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/reactions/<emoji>",()=>s()),u.route("GET /v2/c/rooms/<roomId>/threads/comments/search",()=>s()),u.route("GET /v2/c/rooms/<roomId>/threads/<threadId>/participants",()=>s()),u.route("GET /v2/c/rooms/<roomId>/notification-settings",()=>s()),u.route("GET /v2/c/rooms/<roomId>/subscription-settings",()=>s()),u.route("POST /v2/c/rooms/<roomId>/notification-settings",()=>s()),u.route("POST /v2/c/rooms/<roomId>/subscription-settings",()=>s()),u.route("DELETE /v2/c/inbox-notifications",()=>s()),u.route("POST /v2/c/inbox-notifications/read",()=>s()),u.route("DELETE /v2/c/inbox-notifications/<inboxNotificationId>",()=>s()),u.route("POST /v2/c/rooms/<roomId>/inbox-notifications/read",()=>s()),u.route("POST /v2/c/rooms/<roomId>/text-mentions",()=>s()),u.route("DELETE /v2/c/rooms/<roomId>/text-mentions/<mentionId>",()=>s()),u.route("GET /v2/c/notification-settings",()=>s()),u.route("POST /v2/c/notification-settings",()=>s()),u.route("GET /v2/c/rooms/<roomId>/thread-with-notification/<threadId>",()=>s()),u.route("GET /v2/c/urls/metadata",()=>s()),u.route("GET /v2/c/rooms/<roomId>/versions",()=>s()),u.route("GET /v2/c/rooms/<roomId>/versions/delta",()=>s()),u.route("POST /v2/c/groups/find",()=>s());import{abort as Lt,html as Jo,json as Go,ZenRouter as $o}from"@liveblocks/zenrouter";var Ct=`<!doctype html>
|
|
142
|
+
<html lang="en">
|
|
143
|
+
<head>
|
|
144
|
+
<meta charset="UTF-8" />
|
|
145
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
146
|
+
<title>Liveblocks dev server</title>
|
|
147
|
+
<style>
|
|
148
|
+
* {
|
|
149
|
+
box-sizing: border-box;
|
|
150
|
+
margin: 0;
|
|
151
|
+
padding: 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
:root {
|
|
155
|
+
--bg: #f9f9f9;
|
|
156
|
+
--fg: #202020;
|
|
157
|
+
--fg-secondary: #646464;
|
|
158
|
+
--code-bg: #fcfcfc;
|
|
159
|
+
--shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.06),
|
|
160
|
+
0px 1px 2px -1px rgba(0, 0, 0, 0.06),
|
|
161
|
+
0px 2px 4px 0px rgba(0, 0, 0, 0.04);
|
|
162
|
+
--shadow-hover: 0px 0px 0px 1px rgba(0, 0, 0, 0.08),
|
|
163
|
+
0px 1px 2px -1px rgba(0, 0, 0, 0.08),
|
|
164
|
+
0px 2px 4px 0px rgba(0, 0, 0, 0.06);
|
|
165
|
+
--pill-bg: #171717;
|
|
166
|
+
--pill-fg: #e5e7eb;
|
|
167
|
+
--green: #05df72;
|
|
168
|
+
--green-glow: rgba(5, 223, 114, 0.4);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@media (prefers-color-scheme: dark) {
|
|
172
|
+
:root {
|
|
173
|
+
--bg: #111;
|
|
174
|
+
--fg: #e5e5e5;
|
|
175
|
+
--fg-secondary: #a0a0a0;
|
|
176
|
+
--code-bg: #1a1a1a;
|
|
177
|
+
--shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.08),
|
|
178
|
+
0px 1px 2px -1px rgba(0, 0, 0, 0.4),
|
|
179
|
+
0px 2px 4px 0px rgba(0, 0, 0, 0.3);
|
|
180
|
+
--shadow-hover: 0px 0px 0px 1px rgba(255, 255, 255, 0.12),
|
|
181
|
+
0px 1px 2px -1px rgba(0, 0, 0, 0.5),
|
|
182
|
+
0px 2px 4px 0px rgba(0, 0, 0, 0.4);
|
|
183
|
+
--pill-bg: #f5f5f5;
|
|
184
|
+
--pill-fg: #202020;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
body {
|
|
189
|
+
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
|
|
190
|
+
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
191
|
+
background: var(--bg);
|
|
192
|
+
color: var(--fg);
|
|
193
|
+
min-height: 100vh;
|
|
194
|
+
-webkit-font-smoothing: antialiased;
|
|
195
|
+
-moz-osx-font-smoothing: grayscale;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
main {
|
|
199
|
+
position: relative;
|
|
200
|
+
min-height: 100vh;
|
|
201
|
+
overflow: hidden;
|
|
202
|
+
padding: 2rem 1.5rem;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.logo {
|
|
206
|
+
position: absolute;
|
|
207
|
+
left: 50%;
|
|
208
|
+
top: 2rem;
|
|
209
|
+
transform: translateX(-50%);
|
|
210
|
+
animation: fade-in 0.6s ease-out both;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.logo svg {
|
|
214
|
+
height: 1.5rem;
|
|
215
|
+
width: auto;
|
|
216
|
+
color: var(--fg);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.center {
|
|
220
|
+
position: absolute;
|
|
221
|
+
inset: 0;
|
|
222
|
+
z-index: 10;
|
|
223
|
+
display: flex;
|
|
224
|
+
flex-direction: column;
|
|
225
|
+
align-items: center;
|
|
226
|
+
justify-content: center;
|
|
227
|
+
text-align: center;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
h1 {
|
|
231
|
+
margin-bottom: 0.25rem;
|
|
232
|
+
font-weight: 500;
|
|
233
|
+
font-size: 1rem;
|
|
234
|
+
animation: fade-in 0.6s ease-out 0.1s both;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.description {
|
|
238
|
+
margin-bottom: 1rem;
|
|
239
|
+
max-width: 20rem;
|
|
240
|
+
font-size: 0.875rem;
|
|
241
|
+
line-height: 1.625;
|
|
242
|
+
color: var(--fg-secondary);
|
|
243
|
+
animation: fade-in 0.6s ease-out 0.2s both;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.description code {
|
|
247
|
+
white-space: nowrap;
|
|
248
|
+
border-radius: 0.25rem;
|
|
249
|
+
background: var(--code-bg);
|
|
250
|
+
padding: 0.125rem 0.375rem;
|
|
251
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
|
252
|
+
monospace;
|
|
253
|
+
box-shadow: var(--shadow);
|
|
254
|
+
font-size: 0.75rem;
|
|
255
|
+
color: var(--fg);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.docs-link {
|
|
259
|
+
display: inline-flex;
|
|
260
|
+
align-items: center;
|
|
261
|
+
justify-content: center;
|
|
262
|
+
border-radius: 0.375rem;
|
|
263
|
+
font-size: 0.875rem;
|
|
264
|
+
font-weight: 500;
|
|
265
|
+
background: var(--code-bg);
|
|
266
|
+
box-shadow: var(--shadow);
|
|
267
|
+
height: 2.25rem;
|
|
268
|
+
padding: 0.5rem 1rem;
|
|
269
|
+
color: var(--fg);
|
|
270
|
+
text-decoration: none;
|
|
271
|
+
transition: box-shadow 0.15s;
|
|
272
|
+
animation: fade-in 0.6s ease-out 0.3s both;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.docs-link:hover {
|
|
276
|
+
box-shadow: var(--shadow-hover);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.status {
|
|
280
|
+
position: absolute;
|
|
281
|
+
bottom: 2rem;
|
|
282
|
+
left: 50%;
|
|
283
|
+
transform: translateX(-50%);
|
|
284
|
+
animation: fade-in 0.6s ease-out 0.4s both;
|
|
285
|
+
display: inline-flex;
|
|
286
|
+
align-items: center;
|
|
287
|
+
gap: 0.5rem;
|
|
288
|
+
border-radius: 9999px;
|
|
289
|
+
background: var(--pill-bg);
|
|
290
|
+
color: var(--pill-fg);
|
|
291
|
+
box-shadow: var(--shadow);
|
|
292
|
+
padding: 0.5rem 0.75rem 0.5rem 0.625rem;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.status-dot {
|
|
296
|
+
position: relative;
|
|
297
|
+
width: 0.75rem;
|
|
298
|
+
height: 0.75rem;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.status-dot .glow {
|
|
302
|
+
position: absolute;
|
|
303
|
+
inset: 0;
|
|
304
|
+
background: var(--green-glow);
|
|
305
|
+
border-radius: 9999px;
|
|
306
|
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.status-dot .dot {
|
|
310
|
+
position: absolute;
|
|
311
|
+
width: 0.25rem;
|
|
312
|
+
height: 0.25rem;
|
|
313
|
+
left: 50%;
|
|
314
|
+
top: 50%;
|
|
315
|
+
transform: translate(-50%, -50%);
|
|
316
|
+
background: var(--green);
|
|
317
|
+
border-radius: 9999px;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.status-text {
|
|
321
|
+
font-size: 0.75rem;
|
|
322
|
+
font-weight: 500;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
@keyframes fade-in {
|
|
326
|
+
from {
|
|
327
|
+
opacity: 0;
|
|
328
|
+
}
|
|
329
|
+
to {
|
|
330
|
+
opacity: 1;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
@keyframes pulse {
|
|
335
|
+
50% {
|
|
336
|
+
opacity: 0.5;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
</style>
|
|
340
|
+
</head>
|
|
341
|
+
<body>
|
|
342
|
+
<main>
|
|
343
|
+
<div class="logo">
|
|
344
|
+
<svg
|
|
345
|
+
width="384"
|
|
346
|
+
height="72"
|
|
347
|
+
viewBox="0 0 128 24"
|
|
348
|
+
fill="none"
|
|
349
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
350
|
+
>
|
|
351
|
+
<path
|
|
352
|
+
fill-rule="evenodd"
|
|
353
|
+
clip-rule="evenodd"
|
|
354
|
+
d="M28.8316 3.21884H26L26.0007 19.9974H28.8316V3.21884ZM34.0855 8.01549H31.2547V19.9974H34.0855V8.01549ZM34.0855 3.08984H31.2547V6.14356H34.0855V3.08984ZM38.2401 8.01549H35.1978L39.4807 19.9974H42.6398L46.9226 8.01549H43.9269L42.1367 13.6908C42.0901 13.8384 41.9224 14.416 41.6336 15.4222L41.0602 17.3529C40.7213 16.1277 40.3665 14.9069 39.996 13.6908L38.2401 8.01549ZM58.5185 11.7601C58.2841 10.9567 57.9408 10.2737 57.4879 9.71184C56.9805 9.08118 56.3376 8.59313 55.5579 8.24984C54.7853 7.89868 53.9274 7.72381 52.9836 7.72381C51.1897 7.72381 49.7542 8.28496 48.6778 9.40798C48.1408 9.9882 47.7303 10.6737 47.4723 11.4211C47.2072 12.1929 47.0746 13.0472 47.0746 13.9832C47.0746 15.9877 47.6092 17.5364 48.6785 18.6286C49.7621 19.7359 51.2055 20.2898 53.0072 20.2898C54.5517 20.2898 55.803 19.943 56.7633 19.2485C57.723 18.5541 58.3586 17.5249 58.6704 16.1597L55.909 15.949C55.7765 16.69 55.4719 17.244 54.996 17.6102C54.5201 17.9693 53.8493 18.1492 52.9836 18.1492C51.0027 18.1492 49.9886 17.0333 49.942 14.8023H58.8575L58.8696 14.4046C58.8696 13.445 58.7521 12.5635 58.5185 11.7601ZM50.5734 10.918C51.0729 10.2157 51.8763 9.86449 52.9836 9.86449C53.5218 9.86449 53.9747 9.93831 54.341 10.0867C54.7079 10.235 55.024 10.4729 55.2891 10.8005C55.4953 11.0547 55.6539 11.3441 55.7571 11.6547C55.8734 11.9788 55.9443 12.3174 55.9678 12.6609H49.9649C50.0352 11.9665 50.238 11.3853 50.5734 10.918ZM69.8685 8.48419C69.0651 7.96103 68.137 7.70016 67.0842 7.70016H67.0827C66.3188 7.70016 65.6207 7.85568 64.9886 8.16814C64.3667 8.4713 63.8342 8.9309 63.4435 9.50186V3.21884H60.6126V19.9974H63.4442V18.3477C63.8031 18.9405 64.3115 19.4286 64.9184 19.7631C65.5505 20.1143 66.2485 20.2898 67.0125 20.2898C68.0739 20.2898 69.0135 20.0361 69.8341 19.5295C70.6525 19.0228 71.2882 18.2968 71.7404 17.3529C72.2005 16.4012 72.4313 15.2861 72.4313 14.0068C72.4313 12.7584 72.2041 11.659 71.7526 10.7073C71.3076 9.74768 70.6797 9.00664 69.8685 8.48419ZM68.663 17.1774C68.2108 17.8639 67.4389 18.2065 66.346 18.2065C65.3627 18.2065 64.6224 17.8517 64.1236 17.1422C63.6241 16.4327 63.3747 15.395 63.3747 14.0298C63.3747 12.7111 63.5968 11.682 64.0412 10.9409C64.4941 10.192 65.2545 9.81791 66.3231 9.81791C67.4153 9.81791 68.1914 10.1612 68.6516 10.847C69.1124 11.5257 69.3417 12.5792 69.3417 14.0068C69.3417 15.4337 69.116 16.4908 68.663 17.1774ZM77.0302 3.21884H74.1986V19.9974H77.0302V3.21884ZM81.6169 19.5409C82.5379 20.0404 83.6294 20.2898 84.8936 20.2898C86.1105 20.2898 87.1791 20.0283 88.0993 19.5065C89.0131 18.9985 89.7576 18.2335 90.2407 17.3064C90.7474 16.3546 91.0011 15.2545 91.0011 14.0068C91.0011 12.8057 90.7517 11.7285 90.2522 10.7775C89.7734 9.83933 89.0341 9.05921 88.1229 8.53078C87.202 7.99256 86.1256 7.72309 84.8936 7.72309C83.653 7.72309 82.5687 7.99256 81.6406 8.53078C80.7318 9.05692 79.9926 9.83235 79.5106 10.7653C79.0197 11.7092 78.7739 12.7899 78.7739 14.0068C78.7739 15.3018 79.0154 16.4206 79.4992 17.3644C79.9697 18.2867 80.7079 19.0453 81.6169 19.5409ZM87.245 17.1895C86.7691 17.8603 85.9851 18.1957 84.8936 18.1957C84.1525 18.1957 83.5556 18.0474 83.1033 17.7507C82.6504 17.4468 82.3229 16.9903 82.12 16.3819C81.9172 15.7655 81.8162 14.9736 81.8162 14.0061C81.8162 12.5556 82.0541 11.4949 82.53 10.8241C83.0137 10.1533 83.8014 9.81791 84.8936 9.81791C85.9779 9.81791 86.7577 10.1533 87.2335 10.8241C87.7173 11.4949 87.9588 12.5556 87.9588 14.0068C87.9588 15.4574 87.7209 16.518 87.245 17.1895ZM94.8626 19.5409C95.7756 20.0404 96.8635 20.2898 98.1277 20.2898C99.1103 20.2898 99.9882 20.1186 100.76 19.7753C101.533 19.432 102.16 18.9525 102.644 18.3362C103.129 17.708 103.447 16.967 103.568 16.1826L100.842 15.9024C100.655 16.6506 100.343 17.2089 99.9058 17.5751C99.4693 17.942 98.8759 18.1255 98.1277 18.1255C97.363 18.1255 96.7625 17.9693 96.3253 17.6568C95.8888 17.3372 95.5842 16.8814 95.413 16.288C95.241 15.6874 95.1557 14.927 95.1557 14.0068C95.1557 13.1017 95.241 12.3528 95.413 11.7601C95.5842 11.1595 95.8845 10.6994 96.3138 10.3791C96.751 10.0515 97.3552 9.88814 98.1277 9.88814C98.9541 9.88814 99.5668 10.1182 99.9646 10.5783C100.37 11.0305 100.659 11.6504 100.83 12.4388L103.51 11.9586C103.253 10.6793 102.671 9.65379 101.766 8.88194C100.869 8.10938 99.6564 7.72381 98.1277 7.72381C96.8793 7.72381 95.7992 7.98898 94.8862 8.51931C93.9847 9.03823 93.2562 9.81153 92.7921 10.7424C92.3083 11.6863 92.0661 12.7742 92.0661 14.0068C92.0661 15.309 92.304 16.4327 92.7799 17.3766C93.2637 18.3204 93.9581 19.0421 94.8626 19.5409ZM107.91 15.5512L109.232 14.287L112.742 19.9974H116.007L111.151 12.4732L115.855 8.01549H112.18L107.91 12.3922V3.21884H105.078V19.9974H107.91V15.5512ZM118.488 19.8569C119.284 20.1457 120.169 20.2897 121.144 20.2897C122.634 20.2897 123.862 19.993 124.83 19.4011C125.805 18.8077 126.293 17.8402 126.293 16.4986C126.293 15.6249 126.066 14.9384 125.614 14.4396C125.162 13.9322 124.623 13.5695 123.999 13.351C123.383 13.1252 122.544 12.8952 121.484 12.6608C120.867 12.5282 120.38 12.4035 120.021 12.2867C119.662 12.1692 119.373 12.0172 119.155 11.8302C118.945 11.6424 118.839 11.4009 118.839 11.1049C118.839 10.6678 119.034 10.3367 119.424 10.1102C119.814 9.88373 120.298 9.77049 120.875 9.77049C121.639 9.77049 122.236 9.95396 122.666 10.3209C123.102 10.6878 123.336 11.2375 123.367 11.9707L125.988 11.5378C125.863 10.1962 125.337 9.22511 124.408 8.62383C123.488 8.02398 122.31 7.72298 120.875 7.72298C120.032 7.72298 119.253 7.85126 118.535 8.10926C117.825 8.35866 117.252 8.75283 116.815 9.29176C116.378 9.82926 116.16 10.5079 116.16 11.3271C116.16 12.0839 116.347 12.6959 116.721 13.1639C117.102 13.6369 117.592 14.0102 118.149 14.2518C118.726 14.5019 119.451 14.7399 120.325 14.9656L121.051 15.1412C121.535 15.256 122.015 15.3887 122.49 15.5389C122.817 15.6407 123.086 15.7812 123.297 15.9603C123.508 16.1395 123.613 16.3739 123.613 16.6627C123.613 17.1694 123.402 17.5599 122.981 17.8323C122.568 18.106 121.963 18.2422 121.168 18.2422C120.356 18.2422 119.709 18.0394 119.225 17.6338C118.742 17.2281 118.496 16.6433 118.488 15.8786L115.821 16.1825C115.851 17.1034 116.105 17.8717 116.581 18.488C117.065 19.1044 117.7 19.5602 118.488 19.8569Z"
|
|
355
|
+
fill="currentColor"
|
|
356
|
+
></path>
|
|
357
|
+
<path
|
|
358
|
+
fill-rule="evenodd"
|
|
359
|
+
clip-rule="evenodd"
|
|
360
|
+
d="M13.5 9H0L4 13V18.5L13.5 9Z"
|
|
361
|
+
fill="currentColor"
|
|
362
|
+
></path>
|
|
363
|
+
<path
|
|
364
|
+
fill-rule="evenodd"
|
|
365
|
+
clip-rule="evenodd"
|
|
366
|
+
d="M6.5 20H20L16 16V10.5L6.5 20Z"
|
|
367
|
+
fill="currentColor"
|
|
368
|
+
></path>
|
|
369
|
+
</svg>
|
|
370
|
+
</div>
|
|
371
|
+
|
|
372
|
+
<div class="center">
|
|
373
|
+
<p class="description">
|
|
374
|
+
This is the Liveblocks dev server. Point your app to
|
|
375
|
+
<code>http://localhost:1153</code> and start building. This page is
|
|
376
|
+
not meant to be used directly.
|
|
377
|
+
</p>
|
|
378
|
+
<a
|
|
379
|
+
href="https://liveblocks.io/docs/tools/dev-server?from=__VERSION__"
|
|
380
|
+
target="_blank"
|
|
381
|
+
rel="noopener noreferrer"
|
|
382
|
+
class="docs-link"
|
|
383
|
+
>Read the docs</a
|
|
384
|
+
>
|
|
385
|
+
</div>
|
|
386
|
+
|
|
387
|
+
<div class="status">
|
|
388
|
+
<span class="status-dot">
|
|
389
|
+
<span class="glow" aria-hidden="true"></span>
|
|
390
|
+
<span class="dot" aria-hidden="true"></span>
|
|
391
|
+
</span>
|
|
392
|
+
<span class="status-text">Dev server is running</span>
|
|
393
|
+
</div>
|
|
394
|
+
</main>
|
|
395
|
+
</body>
|
|
396
|
+
</html>
|
|
397
|
+
`;var se=new $o({authorize:()=>!0});se.route("GET /v7",()=>Lt(426));se.route("GET /v8",()=>Lt(426));se.route("GET /health",()=>Go({status:"ok"}));se.route("GET /",()=>Jo(Ct.replace("__VERSION__","1.4.0")));import{QueryParser as Ho}from"@liveblocks/query-parser";import{jsonObjectYolo as Xo,ROOT_YDOC_ID as Fe,snapshotToLossyJson_eager as Wo,snapshotToNodeStream as qo,snapshotToPlainLson_eager as Pt,transientClientMsgDecoder as Zo}from"@liveblocks/server";import{json as Te,ndjsonStream as Qo,ZenRouter as er}from"@liveblocks/zenrouter";import{array as K,constant as tr,either as or,enum_ as rr,nullable as kt,object as ye,optional as z,record as me,string as D}from"decoders";function*zo(t){for(let e of t)for(let o of e)yield o}var ms=Symbol();function xt(...t){return zo(t)}import{Base64 as sr}from"js-base64";import*as _e from"yjs";import*as L from"yjs";function Yo(t){return t.content instanceof L.ContentFormat||t.content instanceof L.ContentEmbed?"text":"arr"in t.content?"array":"str"in t.content?"text":"type"in t.content?"xml":"unknown"}function Vo(t){let e=[],o=t;for(;o!==null;){if(!o.deleted)if(o.content instanceof L.ContentType)e.push(o.content.type.toJSON());else if(o.content instanceof L.ContentString)e.push(o.content.str);else if(o.content instanceof L.ContentFormat){let{key:r,value:i}=o.content;e.push({key:r,value:i})}else o.content instanceof L.ContentEmbed&&e.push(o.content.embed);o=o.right}return e}function Nt(t,e,o,r=!1){if(!e._first&&e._map instanceof Map&&e._map.size>0)return t.getMap(o).toJSON();if(e._first!==null){let i=Yo(e._first);if(i==="text")return r?Vo(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 Ko={ytext:L.Text,yxmlfragment:L.XmlFragment,yxmltext:L.XmlText,ymap:L.Map,yarray:L.Array};function At(t,e="",o=!1,r=""){let i={};if(e.length){if(t.share.has(e)){if(r.length){let a=Ko[r];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 Dt=(o=>(o.PlainLson="plain-lson",o.LossyJson="json",o))(Dt||{}),nr=rr(Dt),jt=me(D,or(D,K(D))),n=new er({authorize:({req:t})=>Ie(t)});function x(t){return Te({error:"ROOM_NOT_FOUND",message:`Room with id "${t}" not found.`},404)}var ir=new Ho({fields:{roomId:"string"},indexableFields:{metadata:"token"}});function ar(t){let e=ir.parse(t),o={};for(let r of e.query.allOf)switch(r.type){case"PrefixCondition":{r.field.type==="DirectField"&&r.field.ref.name==="roomId"&&(o.roomId={value:r.prefix.value,operator:"^"});break}case"ExactCondition":{r.field.type==="KeyedField"&&r.field.base.name==="metadata"&&r.value.type==="LiteralString"&&(o.metadata??={},o.metadata[r.field.key]=r.value.value);break}}return o}function be(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 x(t.roomId);return be(e)});n.route("GET /v2/rooms",({url:t})=>{let e,o=t.searchParams.get("query");if(o)try{e=ar(o)}catch(d){return Te({error:"INVALID_QUERY",message:d instanceof Error?d.message:String(d)},422)}else{let d={};for(let[c,p]of t.searchParams.entries())c.startsWith("metadata.")&&(d[c.slice(9)]=p);Object.keys(d).length>0&&(e={metadata:d})}let r=t.searchParams.get("organizationId")??void 0;return r&&(e={...e,organizationId:r}),{data:st(e).map(be),nextPage:null,nextCursor:null}});n.route("POST /v2/rooms",ye({id:D,organizationId:z(D),defaultAccesses:z(K(D)),metadata:z(jt),usersAccesses:z(me(D,K(D))),groupsAccesses:z(me(D,K(D)))}),({body:t})=>{if(C(t.id))return Te({error:"ROOM_ALREADY_EXISTS",message:`Room with id "${t.id}" already exists.`},409);let e=ve(t.id,{organizationId:t.organizationId,defaultAccesses:t.defaultAccesses,metadata:t.metadata,usersAccesses:t.usersAccesses,groupsAccesses:t.groupsAccesses});return be(e)});n.route("POST /v2/rooms/<roomId>",ye({defaultAccesses:z(K(D)),metadata:z(jt),usersAccesses:z(me(D,kt(K(D)))),groupsAccesses:z(me(D,kt(K(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 x(t.roomId);return be(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(!C(e.roomId))throw x(e.roomId);let o=nr.value(t.searchParams.get("format"))??"plain-lson",r=B(e.roomId);await r.load();let i=r.storage.loadedDriver.get_snapshot(!1),a=o==="json"?Wo(i):Pt(i);return new Response(JSON.stringify(a),{status:200,headers:{"Content-Type":"application/json"}})});n.route("POST /v2/rooms/<roomId>/storage",ye({liveblocksType:tr("LiveObject"),data:Xo}).refineType(),async({p:t,body:e})=>{if(!C(t.roomId))throw x(t.roomId);let o=B(t.roomId);await o.load();let r=o.storage.loadedDriver.get_snapshot(!1),i=Pt(r);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 x(t.roomId);let e=B(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 x(e.roomId);let o=B(e.roomId);await o.load();let r=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),p=At(c,r,d,i);return new Response(JSON.stringify(p),{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 x(o.roomId);let r=B(o.roomId);await r.load();let i=await t.arrayBuffer(),a=sr.fromUint8Array(new Uint8Array(i)),d=e.searchParams.get("guid"),p=e.searchParams.get("encoder")==="v2",T=d&&d!==Fe?d:void 0;try{return await r.mutex.runExclusive(()=>r.yjsStorage.addYDocUpdate({},a,T,p)),new Response(JSON.stringify({success:!0}),{status:200,headers:{"Content-Type":"application/json"}})}catch(b){return new Response(JSON.stringify({error:"UNPROCESSABLE_ENTITY",message:b instanceof Error?b.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 x(e.roomId);let o=B(e.roomId);await o.load();let r=t.searchParams.get("guid")??Fe,i=t.searchParams.get("encoder"),a=await o.yjsStorage.getYDoc(r),d=i==="v2"?_e.encodeStateAsUpdateV2(a):_e.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 x(t.roomId);let o=B(t.roomId).listSessions().map(r=>({type:"user",connectionId:r.actor,id:r.user.id,info:r.user.info}));return Te({data:o})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!C(t.roomId))throw x(t.roomId);return N({ok:!0})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>/messages/<messageId>",({p:t})=>{if(!C(t.roomId))throw x(t.roomId);return N({ok:!0})});n.route("GET /v2/rooms/<roomId>/feeds",({p:t})=>{if(!C(t.roomId))throw x(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 x(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 x(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 x(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 x(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 x(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 x(t.roomId);return N({id:"123",timestamp:new Date().getTime(),data:{content:"This is a test message"}})});n.route("POST /v2/rooms/<roomId>/request-storage-mutation",async({p:t})=>{if(!C(t.roomId))throw x(t.roomId);let e=B(t.roomId);await e.load();let o=await e.driver.next_actor(),r=e.storage.loadedDriver.get_snapshot(!1);return Qo(xt([{actor:o}],qo(r)))});n.route("POST /v2/rooms/<roomId>/send-message",ye({messages:K(Zo)}),async({p:t,body:e})=>{if(!C(t.roomId))throw x(t.roomId);let o=B(t.roomId);await o.load();let[r,i]=await o.createBackendSession_experimental();return await o.processClientMsgFromBackendSession(r,e.messages),new Response(`{"messages":[${i.join(",")}]}`,{status:200,headers:{"Content-Type":"application/json; charset=utf-8"}})});n.route("PATCH /v2/rooms/<roomId>/storage/json-patch",()=>s()),n.route("POST /v2/rooms/<roomId>/presence",()=>s()),n.route("GET /v2/rooms/<roomId>/threads",()=>s()),n.route("POST /v2/rooms/<roomId>/upsert",()=>s()),n.route("POST /v2/rooms/<roomId>/update-room-id",()=>s()),n.route("POST /v2/rooms/<roomId>/update-organization-id",()=>s()),n.route("GET /v2/rooms/<roomId>/prewarm",()=>s()),n.route("POST /v2/rooms/<roomId>/broadcast_event",()=>s()),n.route("GET /v2/rooms/<roomId>/versions",()=>s()),n.route("GET /v2/rooms/<roomId>/version/<version>",()=>s()),n.route("POST /v2/rooms/<roomId>/version",()=>s()),n.route("POST /v2/rooms/<roomId>/threads",()=>s()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/mark-as-resolved",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/mark-as-unresolved",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/subscribe",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/unsubscribe",()=>s()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/subscriptions",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/metadata",()=>s()),n.route("DELETE /v2/rooms/<roomId>/threads/<threadId>",()=>s()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/participants",()=>s()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/inbox-notifications",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments",()=>s()),n.route("GET /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/metadata",()=>s()),n.route("DELETE /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/add-reaction",()=>s()),n.route("POST /v2/rooms/<roomId>/threads/<threadId>/comments/<commentId>/remove-reaction",()=>s()),n.route("GET /v2/rooms/<roomId>/attachments/<attachmentId>",()=>s()),n.route("GET /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>s()),n.route("GET /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>s()),n.route("POST /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>s()),n.route("POST /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>s()),n.route("DELETE /v2/rooms/<roomId>/users/<userId>/notification-settings",()=>s()),n.route("DELETE /v2/rooms/<roomId>/users/<userId>/subscription-settings",()=>s()),n.route("GET /v2/users/<userId>/inbox-notifications/<inboxNotificationId>",()=>s()),n.route("DELETE /v2/users/<userId>/inbox-notifications/<inboxNotificationId>",()=>s()),n.route("GET /v2/users/<userId>/inbox-notifications",()=>s()),n.route("DELETE /v2/users/<userId>/inbox-notifications",()=>s()),n.route("GET /v2/users/<userId>/notification-settings",()=>s()),n.route("POST /v2/users/<userId>/notification-settings",()=>s()),n.route("DELETE /v2/users/<userId>/notification-settings",()=>s()),n.route("GET /v2/users/<userId>/room-subscription-settings",()=>s()),n.route("POST /v2/inbox-notifications/trigger",()=>s()),n.route("POST /v2/inbox-notifications/<inboxNotificationId>/read",()=>s()),n.route("POST /v2/groups",()=>s()),n.route("GET /v2/groups/<groupId>",()=>s()),n.route("POST /v2/groups/<groupId>/add-members",()=>s()),n.route("POST /v2/groups/<groupId>/remove-members",()=>s()),n.route("DELETE /v2/groups/<groupId>",()=>s()),n.route("GET /v2/groups",()=>s()),n.route("GET /v2/users/<userId>/groups",()=>s()),n.route("GET /v2/ai/copilots",()=>s()),n.route("GET /v2/ai/copilots/<copilotId>",()=>s()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge",()=>s()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/<knowledgeSourceId>",()=>s()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/file/<knowledgeSourceId>",()=>s()),n.route("GET /v2/ai/copilots/<copilotId>/knowledge/web/<knowledgeSourceId>/links",()=>s()),n.route("POST /v2/ai/copilots",()=>s()),n.route("POST /v2/ai/copilots/<copilotId>",()=>s()),n.route("POST /v2/ai/copilots/<copilotId>/knowledge/web",()=>s()),n.route("DELETE /v2/ai/copilots/<copilotId>",()=>s()),n.route("DELETE /v2/ai/copilots/<copilotId>/knowledge/file/<knowledgeSourceId>",()=>s()),n.route("DELETE /v2/ai/copilots/<copilotId>/knowledge/web/<knowledgeSourceId>",()=>s()),n.route("PUT /v2/ai/copilots/<copilotId>/knowledge/file/<fileName>",()=>s()),n.route("GET /v2/management/projects",()=>s()),n.route("GET /v2/management/projects/<projectId>",()=>s()),n.route("POST /v2/management/projects",()=>s()),n.route("POST /v2/management/projects/<projectId>",()=>s()),n.route("DELETE /v2/management/projects/<projectId>",()=>s()),n.route("GET /v2/management/projects/<projectId>/webhooks",()=>s()),n.route("GET /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>s()),n.route("GET /v2/management/projects/<projectId>/webhooks/<webhookId>/additional-headers",()=>s()),n.route("POST /v2/management/projects/<projectId>/webhooks",()=>s()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>s()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/additional-headers",()=>s()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/delete-additional-headers",()=>s()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/recover-failed-messages",()=>s()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/secret/roll",()=>s()),n.route("POST /v2/management/projects/<projectId>/webhooks/<webhookId>/test",()=>s()),n.route("DELETE /v2/management/projects/<projectId>/webhooks/<webhookId>",()=>s()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/activate",()=>s()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/deactivate",()=>s()),n.route("POST /v2/management/projects/<projectId>/api-keys/public/roll",()=>s()),n.route("POST /v2/management/projects/<projectId>/api-keys/secret/roll",()=>s());function Bt(t,e,o,r){if(!t.upgrade(e,{data:{refuseConnection:{code:o,message:r}}}))return new Response("Could not upgrade to WebSocket",{status:426})}var ne=new cr;ne.relay("/v2/authorize-user/*",le);ne.relay("/v2/identify-user/*",le);ne.relay("/v2/c/*",u);ne.relay("/v2/*",n);ne.relay("/*",se);var Ge=1153;function Ft(t){if(t===void 0)return;let e=Number(t);return Number.isInteger(e)&&e>0&&e<=65535?e:void 0}function lr(t){return process.platform==="win32"?[process.env.COMSPEC||"cmd.exe","/c",t]:["sh","-c",t]}function mr(t){return"'"+t.replace(/'/g,"'\\''")+"'"}var fr={description:"Start the local Liveblocks dev server",async run(t){let{options:e,args:o}=ze(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(ae("Extra arguments are only supported with --cmd (-c)")),process.exit(1)),o.length>0&&e.cmd){let f=o.map(mr).join(" ");e.cmd.includes("{}")?e.cmd=e.cmd.replaceAll("{}",f):e.cmd+=" "+f}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 r=!1;e.ci&&(r=!0,e["no-check"]=!0),e.cmd&&(r=!0,e["no-check"]=!0);let i=Ft(e.port)??Ft(process.env.LIVEBLOCKS_DEVSERVER_PORT)??Ge,a=e.host||process.env.LIVEBLOCKS_DEVSERVER_HOST||"localhost",d=r?rt():null;await St(i,a)&&(console.error(`Port ${i} is already in use.
|
|
398
|
+
Is another dev server already running?`),process.exit(1));let c,p=!1;function T(){return Je.serve({hostname:a,port:i,async fetch(f,_){if(f.headers.get("Upgrade")==="websocket"){let y=It(f);if(!y.ok)return je(y.xwarn,!0),Bt(_,f,Ut.NOT_ALLOWED,"You have no access to this room");let{roomId:F,ticketData:Z}=y;if(dt(F))return Bt(_,f,Ut.TRY_AGAIN_LATER,"Server is undergoing maintenance, try again later");let A=B(F);await A.load();let k=await A.createTicket(Z),Y=k.sessionKey;if(_.upgrade(f,{data:{room:A,ticket:k,sessionKey:Y}})){console.log(`${J("101")} WS ${new URL(f.url).pathname}${g(` - ${F}`)}`);return}return new Response("Could not upgrade to WebSocket",{status:426})}let O=new URL(f.url);if(f.method==="POST"&&O.pathname==="/crash")return console.log(`${J("204")} POST /crash`),setTimeout(()=>void b(),0),new Response(null,{status:204});let m=`${f.method} ${O.pathname}`,l;if(p)try{l=await f.clone().text()}catch{}let E=await ne.fetch(f),S=E.status,w=S>=500?ae(S):S>=400?Q(S):J(S);console.log(`${w} ${m}`);let M=E.headers.get("X-LB-Warn")??void 0;if(je(M,!E.ok),p){if(l){let Z=Mt(l);Z!==void 0&&console.log(g(` \u2192 ${JSON.stringify(Z)}`))}let y=await E.clone().text(),F=Mt(y);F!==void 0&&console.log(g(` \u2190 ${JSON.stringify(F)}`))}return E},error(f){return console.error(f),new Response("An unknown error occurred",{status:500})},websocket:{async open(f){let{refuseConnection:_,room:O,ticket:m}=f.data;if(_){f.close(_.code,_.message);return}O&&m&&await O.startBrowserSession(m,f)},async message(f,_){let{room:O,sessionKey:m}=f.data;O&&m&&await O.handleData(m,_)},close(f,_,O){let{room:m,sessionKey:l}=f.data;m&&l&&m.endBrowserSession(l,_,O)}}})}c=T();async function b(){ut(),await c.stop(!0),c=T(),console.log("Crash \u{1F4A5}")}let h=f=>process.stderr.write(f+`
|
|
399
|
+
`);if(e.cmd){h(`Liveblocks dev server ${g("v1.4.0")} running at http://${c.hostname}:${c.port}`),d&&e.verbose&&h(g(`Ephemeral mode, using ${d}`));let f=ur(d,"server.log");h(g(`Server logs: ${f}`));let _=Je.file(f).writer(),O=(...l)=>{_.write(l.map(String).join(" ")+`
|
|
400
|
+
`),_.flush()};console.log=O,console.error=O;let m=1;try{let l=Je.spawn(lr(e.cmd),{stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LIVEBLOCKS_DEV_SERVER_HOST:a,LIVEBLOCKS_DEV_SERVER_PORT:String(i)}}),E=()=>{l.kill()};process.on("SIGTERM",E),process.on("SIGINT",E),m=await l.exited}finally{_.end(),await c.stop(),Le(),h(g("Liveblocks dev server shut down"))}process.exit(m)}else{let f=`http://${a}:${i}`,_=e["no-check"]?[]:await yt(f),O="logs",m=null,l=null,E=null,S=`http://${c.hostname}:${c.port}`,w=()=>{let R=O==="logs"?P(" Logs "):g(" Logs "),I=O==="sockets"?P(" Sockets "):g(" Sockets "),v=R+g("|")+I,ie=(l?V("\u23F8 maintenance")+" ":"")+g(`Liveblocks running at ${S}`),Re=process.stdout.columns??80,Oe=Math.max(1,Re-we(v).length-we(ie).length);return v+" ".repeat(Oe)+ie},M=[],y=console.log.bind(console);console.log=(...R)=>{let I=R.map(String).join(" ");M.push(I),O==="logs"&&y(I)};let F=()=>g(" ")+P("q")+g(" quit, ")+P("!")+g(" crash, ")+P("c")+g(" clear, ")+P("v")+g(p?" verbose (on)":" verbose"),Z=()=>{E&&(clearInterval(E),E=null),O="logs",process.stdout.write("\x1B[2J\x1B[H"),y(w()),y(F()),y();for(let R of M)y(R)},A=0,k=[],Y=R=>`${R.roomId}:${R.actor}`,Se=()=>{k=ce().map(R=>({...R,alive:!0}))},Jt=()=>{let R=new Set(ce().map(Y));for(let v of k)v.alive=R.has(Y(v));let I=new Set(k.map(Y));for(let v of ce())I.has(Y(v))||k.push({...v,alive:!0})},Gt=R=>{let I=Date.now()-R,v=Math.floor(I/1e3);if(v<60)return`${v}s`;let j=Math.floor(v/60);return j<60?`${j}m`:`${Math.floor(j/60)}h`},$t=R=>{if(!R)return"";let I=Date.now()-R;return I<1e3?" "+J("\u25CF"):I<3e3?" "+g(J("\u25CF")):I<5e3?" "+g("\u25CF"):""},fe=(R,I)=>{let v=R+I;for(;v>=0&&v<k.length;){if(k[v].alive)return v;v+=I}return R},H=()=>{Jt();let R=k.filter(v=>v.alive).length;if(process.stdout.write("\x1B[2J\x1B[H"),y(w()),y(g(" ")+P("\u2191\u2193")+g(" navigate, ")+P("k")+g(" kill, ")+P("m")+g(l?" maintenance off, ":" maintenance on, ")+P("r")+g(" refresh")),y(),y(" "+P("Connections")+g(` (${R} alive)`)),y(),k.length===0){y(g(" No active connections"));return}if(A>=k.length&&(A=k.length-1),!k[A]?.alive){let v=fe(A,-1);A=k[v]?.alive?v:fe(A,1)}let I=new Map;for(let v of ce())I.set(Y(v),v.lastActiveAt);for(let v=0;v<k.length;v++){let j=k[v];if(!j.alive){y(g(` ${j.roomId} \xB7 actor=${j.actor} \xB7 disconnected`));continue}let ie=v===A?J("\u25B6 "):" ",Re=j.userId??g("anonymous"),Oe=Gt(j.connectedAt),Vt=I.get(Y(j)),Kt=$t(Vt);y(`${ie}${P(j.roomId)} ${g("\xB7")} actor=${j.actor} ${g("\xB7")} ${Re} ${g("\xB7")} ${g(Oe)}${Kt}`)}},zt=()=>{O="sockets",A=0,Se(),H(),E=setInterval(()=>H(),1e3)},Yt=()=>{if(l)l(),l=null;else{let{promise:R,resolve:I}=dr();at(R),l=I}};process.stdout.write("\x1B[2J\x1B[H"),y(w()),y(F()),y(),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(()=>{Le(),process.exit(0)});return}if(I==="m"){Yt(),O==="sockets"?H():(process.stdout.write("\x1B[s\x1B[H\x1B[2K"),y(w()),process.stdout.write("\x1B[u"));return}if((I==="s"||I==="\x1B[C")&&O!=="sockets"){zt();return}if((I==="l"||I==="\x1B[D")&&O!=="logs"){Z();return}if(O==="sockets"){if(I==="\x1B[A")A=fe(A,-1),H();else if(I==="\x1B[B")A=fe(A,1),H();else if(I==="k"){let v=k[A];v?.alive&&(ct(v.roomId,v.actor),H())}else I==="r"&&(Se(),A=0,H());return}if(I==="!")m!==null?(clearTimeout(m),m=null,b()):(console.log("Simulating crash in 2.5s... (press ! again to crash now)"),m=setTimeout(()=>{m=null,b()},2500));else if(I==="c")M.length=0,process.stdout.write("\x1B[2J\x1B[H"),y(w()),y(F()),y();else if(I==="v")p=!p,process.stdout.write("\x1B[s\x1B[H\x1B[2K"),y(w()),process.stdout.write("\x1B[2K"),y(F()),process.stdout.write("\x1B[u"),console.log(g(p?"Verbose mode on":"Verbose mode off"));else if(I==="p")if(_.length>0){let v=_t(_,f);bt(v),console.log(g("Copied AI fix prompt to clipboard"))}else console.log(g("No setup issues detected"))})}}},Fs=fr;export{Fs as default};
|
|
401
|
+
/*! Bundled license information:
|
|
402
|
+
|
|
403
|
+
itertools/dist/index.js:
|
|
404
|
+
(* istanbul ignore else -- @preserve *)
|
|
405
|
+
(* istanbul ignore if -- @preserve *)
|
|
406
|
+
*/
|
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-
|
|
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-Q637N3GN.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.4.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.4.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.
|
|
3
|
+
"version": "1.4.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.
|
|
47
|
+
"@liveblocks/server": "^1.4.0"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsup",
|
|
@@ -1,400 +0,0 @@
|
|
|
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)
|
|
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 (
|
|
4
|
-
setting TEXT NOT NULL,
|
|
5
|
-
jval TEXT NOT NULL,
|
|
6
|
-
PRIMARY KEY (setting)
|
|
7
|
-
)`),o.run(`CREATE TABLE IF NOT EXISTS nodes (
|
|
8
|
-
node_id TEXT NOT NULL,
|
|
9
|
-
crdt_json TEXT NOT NULL,
|
|
10
|
-
PRIMARY KEY (node_id)
|
|
11
|
-
)`),o.run(`CREATE TABLE IF NOT EXISTS metadata (
|
|
12
|
-
key TEXT NOT NULL,
|
|
13
|
-
jval TEXT NOT NULL,
|
|
14
|
-
PRIMARY KEY (key)
|
|
15
|
-
)`),o.run(`CREATE TABLE IF NOT EXISTS ydocs (
|
|
16
|
-
doc_id TEXT NOT NULL,
|
|
17
|
-
key TEXT NOT NULL,
|
|
18
|
-
data BLOB NOT NULL,
|
|
19
|
-
PRIMARY KEY (doc_id, key)
|
|
20
|
-
)`),o.run(`CREATE TABLE IF NOT EXISTS leased_sessions (
|
|
21
|
-
session_id TEXT NOT NULL PRIMARY KEY,
|
|
22
|
-
jpresence TEXT NOT NULL,
|
|
23
|
-
updated_at INTEGER NOT NULL,
|
|
24
|
-
juserinfo TEXT NOT NULL,
|
|
25
|
-
ttl INTEGER NOT NULL,
|
|
26
|
-
actor_id INTEGER NOT NULL
|
|
27
|
-
)`),o.run("CREATE INDEX IF NOT EXISTS idx_leased_sessions_expiry ON leased_sessions(updated_at, ttl)"),o.run(`CREATE TABLE IF NOT EXISTS feeds (
|
|
28
|
-
feed_id TEXT NOT NULL PRIMARY KEY,
|
|
29
|
-
jmetadata TEXT NOT NULL,
|
|
30
|
-
created_at INTEGER NOT NULL,
|
|
31
|
-
updated_at INTEGER NOT NULL
|
|
32
|
-
)`),o.run("CREATE INDEX IF NOT EXISTS idx_feeds_created_at ON feeds(created_at DESC, feed_id DESC)"),o.run(`CREATE TABLE IF NOT EXISTS feed_messages (
|
|
33
|
-
feed_id TEXT NOT NULL,
|
|
34
|
-
message_id TEXT NOT NULL,
|
|
35
|
-
jdata TEXT NOT NULL,
|
|
36
|
-
created_at INTEGER NOT NULL,
|
|
37
|
-
updated_at INTEGER NOT NULL,
|
|
38
|
-
PRIMARY KEY (feed_id, message_id),
|
|
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)
|
|
41
|
-
VALUES (?, ?)
|
|
42
|
-
ON CONFLICT (key) DO UPDATE SET jval = ?
|
|
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)
|
|
44
|
-
VALUES ('last_actor_id', '0')
|
|
45
|
-
ON CONFLICT (setting) DO UPDATE SET jval = json(CAST(jval AS INTEGER) + 1)
|
|
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
|
-
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)
|
|
49
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
50
|
-
ON CONFLICT (session_id) DO UPDATE SET
|
|
51
|
-
jpresence = excluded.jpresence,
|
|
52
|
-
updated_at = excluded.updated_at,
|
|
53
|
-
juserinfo = excluded.juserinfo,
|
|
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 (
|
|
56
|
-
room_id TEXT NOT NULL PRIMARY KEY,
|
|
57
|
-
internal_id TEXT NOT NULL UNIQUE,
|
|
58
|
-
organization_id TEXT NOT NULL,
|
|
59
|
-
default_permissions TEXT NOT NULL,
|
|
60
|
-
metadata TEXT NOT NULL,
|
|
61
|
-
created_at TEXT NOT NULL
|
|
62
|
-
) STRICT`),e.run(`CREATE TABLE IF NOT EXISTS room_user_permissions (
|
|
63
|
-
room_id TEXT NOT NULL,
|
|
64
|
-
user_id TEXT NOT NULL,
|
|
65
|
-
scopes TEXT NOT NULL,
|
|
66
|
-
PRIMARY KEY (room_id, user_id),
|
|
67
|
-
FOREIGN KEY (room_id) REFERENCES rooms(room_id) ON DELETE CASCADE
|
|
68
|
-
) STRICT`),e.run(`CREATE TABLE IF NOT EXISTS room_group_permissions (
|
|
69
|
-
room_id TEXT NOT NULL,
|
|
70
|
-
group_id TEXT NOT NULL,
|
|
71
|
-
scopes TEXT NOT NULL,
|
|
72
|
-
PRIMARY KEY (room_id, group_id),
|
|
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 (?, ?, ?)
|
|
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
|
|
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(`
|
|
81
|
-
`);return`# Set up Liveblocks dev server
|
|
82
|
-
|
|
83
|
-
1. Check which system the application is using for environment variables, then
|
|
84
|
-
add a new environment variable called \`USE_LIVEBLOCKS_DEV_SERVER="true"\`.
|
|
85
|
-
This will be used to enable the dev server. It needs to be available on the client, so it may need to be called
|
|
86
|
-
\`NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER\` or similar. Do not rename or modify existing variables.
|
|
87
|
-
2. You must use \`"${e}"\` as a \`baseUrl\` when the dev server is
|
|
88
|
-
enabled. In the following files add a \`baseUrl\` property for this when the
|
|
89
|
-
dev server is enabled, otherwise set \`baseUrl\` to \`undefined\`:
|
|
90
|
-
${o}
|
|
91
|
-
|
|
92
|
-
3. Identify if the user is using \`publicApiKey\` in \`LiveblocksProvider\` or
|
|
93
|
-
\`secret\` in \`new Liveblocks\`. Edit the existing property to use "pk_localdev"
|
|
94
|
-
(for \`publicApikey\`) or "sk_localdev" (for \`secret\`) when the dev server is
|
|
95
|
-
enabled.
|
|
96
|
-
|
|
97
|
-
## Examples
|
|
98
|
-
|
|
99
|
-
Remember to keep the user's current system for environment variables and names.
|
|
100
|
-
In the following snippets, I have given the following names, but the user's
|
|
101
|
-
system may work differently: \`process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_KEY\`
|
|
102
|
-
and \`process.env.LIVEBLOCKS_SECRET_KEY\`.
|
|
103
|
-
|
|
104
|
-
### Public key example
|
|
105
|
-
|
|
106
|
-
If the user is already using the public key with \`publicApKey\`:
|
|
107
|
-
|
|
108
|
-
\`\`\`env file=".env.local"
|
|
109
|
-
NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER="true"
|
|
110
|
-
\`\`\`
|
|
111
|
-
|
|
112
|
-
\`\`\`tsx file="src/app/Providers.tsx"
|
|
113
|
-
<LiveblocksProvider
|
|
114
|
-
baseUrl={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "${e}" : undefined}
|
|
115
|
-
publicApiKey={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "pk_localdev" : process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_KEY}
|
|
116
|
-
\`\`\`
|
|
117
|
-
|
|
118
|
-
### Secret key example
|
|
119
|
-
|
|
120
|
-
If the user is already using their secret key with \`secret\`:
|
|
121
|
-
|
|
122
|
-
\`\`\`env file=".env.local"
|
|
123
|
-
NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER="true"
|
|
124
|
-
\`\`\`
|
|
125
|
-
|
|
126
|
-
\`\`\`tsx file="src/app/Providers.tsx"
|
|
127
|
-
<LiveblocksProvider
|
|
128
|
-
baseUrl={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "${e}" : undefined}
|
|
129
|
-
\`\`\`
|
|
130
|
-
|
|
131
|
-
\`\`\`ts file="src/app/api/liveblocks-auth/route.ts"
|
|
132
|
-
new Liveblocks({
|
|
133
|
-
baseUrl={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "${e}" : undefined}
|
|
134
|
-
secret={process.env.NEXT_PUBLIC_USE_LIVEBLOCKS_DEV_SERVER === "true" ? "sk_localdev" : process.env.LIVEBLOCKS_SECRET_KEY}
|
|
135
|
-
\`\`\`
|
|
136
|
-
|
|
137
|
-
## Follow up
|
|
138
|
-
|
|
139
|
-
Explain to the user that you've enabled the Liveblocks dev server by adding a an
|
|
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>
|
|
142
|
-
<html lang="en">
|
|
143
|
-
<head>
|
|
144
|
-
<meta charset="UTF-8" />
|
|
145
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
146
|
-
<title>Liveblocks dev server</title>
|
|
147
|
-
<style>
|
|
148
|
-
* {
|
|
149
|
-
box-sizing: border-box;
|
|
150
|
-
margin: 0;
|
|
151
|
-
padding: 0;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
:root {
|
|
155
|
-
--bg: #f9f9f9;
|
|
156
|
-
--fg: #202020;
|
|
157
|
-
--fg-secondary: #646464;
|
|
158
|
-
--code-bg: #fcfcfc;
|
|
159
|
-
--shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.06),
|
|
160
|
-
0px 1px 2px -1px rgba(0, 0, 0, 0.06),
|
|
161
|
-
0px 2px 4px 0px rgba(0, 0, 0, 0.04);
|
|
162
|
-
--shadow-hover: 0px 0px 0px 1px rgba(0, 0, 0, 0.08),
|
|
163
|
-
0px 1px 2px -1px rgba(0, 0, 0, 0.08),
|
|
164
|
-
0px 2px 4px 0px rgba(0, 0, 0, 0.06);
|
|
165
|
-
--pill-bg: #171717;
|
|
166
|
-
--pill-fg: #e5e7eb;
|
|
167
|
-
--green: #05df72;
|
|
168
|
-
--green-glow: rgba(5, 223, 114, 0.4);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
@media (prefers-color-scheme: dark) {
|
|
172
|
-
:root {
|
|
173
|
-
--bg: #111;
|
|
174
|
-
--fg: #e5e5e5;
|
|
175
|
-
--fg-secondary: #a0a0a0;
|
|
176
|
-
--code-bg: #1a1a1a;
|
|
177
|
-
--shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.08),
|
|
178
|
-
0px 1px 2px -1px rgba(0, 0, 0, 0.4),
|
|
179
|
-
0px 2px 4px 0px rgba(0, 0, 0, 0.3);
|
|
180
|
-
--shadow-hover: 0px 0px 0px 1px rgba(255, 255, 255, 0.12),
|
|
181
|
-
0px 1px 2px -1px rgba(0, 0, 0, 0.5),
|
|
182
|
-
0px 2px 4px 0px rgba(0, 0, 0, 0.4);
|
|
183
|
-
--pill-bg: #f5f5f5;
|
|
184
|
-
--pill-fg: #202020;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
body {
|
|
189
|
-
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
|
|
190
|
-
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
191
|
-
background: var(--bg);
|
|
192
|
-
color: var(--fg);
|
|
193
|
-
min-height: 100vh;
|
|
194
|
-
-webkit-font-smoothing: antialiased;
|
|
195
|
-
-moz-osx-font-smoothing: grayscale;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
main {
|
|
199
|
-
position: relative;
|
|
200
|
-
min-height: 100vh;
|
|
201
|
-
overflow: hidden;
|
|
202
|
-
padding: 2rem 1.5rem;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.logo {
|
|
206
|
-
position: absolute;
|
|
207
|
-
left: 50%;
|
|
208
|
-
top: 2rem;
|
|
209
|
-
transform: translateX(-50%);
|
|
210
|
-
animation: fade-in 0.6s ease-out both;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.logo svg {
|
|
214
|
-
height: 1.5rem;
|
|
215
|
-
width: auto;
|
|
216
|
-
color: var(--fg);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.center {
|
|
220
|
-
position: absolute;
|
|
221
|
-
inset: 0;
|
|
222
|
-
z-index: 10;
|
|
223
|
-
display: flex;
|
|
224
|
-
flex-direction: column;
|
|
225
|
-
align-items: center;
|
|
226
|
-
justify-content: center;
|
|
227
|
-
text-align: center;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
h1 {
|
|
231
|
-
margin-bottom: 0.25rem;
|
|
232
|
-
font-weight: 500;
|
|
233
|
-
font-size: 1rem;
|
|
234
|
-
animation: fade-in 0.6s ease-out 0.1s both;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.description {
|
|
238
|
-
margin-bottom: 1rem;
|
|
239
|
-
max-width: 20rem;
|
|
240
|
-
font-size: 0.875rem;
|
|
241
|
-
line-height: 1.625;
|
|
242
|
-
color: var(--fg-secondary);
|
|
243
|
-
animation: fade-in 0.6s ease-out 0.2s both;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
.description code {
|
|
247
|
-
white-space: nowrap;
|
|
248
|
-
border-radius: 0.25rem;
|
|
249
|
-
background: var(--code-bg);
|
|
250
|
-
padding: 0.125rem 0.375rem;
|
|
251
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
|
252
|
-
monospace;
|
|
253
|
-
box-shadow: var(--shadow);
|
|
254
|
-
font-size: 0.75rem;
|
|
255
|
-
color: var(--fg);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
.docs-link {
|
|
259
|
-
display: inline-flex;
|
|
260
|
-
align-items: center;
|
|
261
|
-
justify-content: center;
|
|
262
|
-
border-radius: 0.375rem;
|
|
263
|
-
font-size: 0.875rem;
|
|
264
|
-
font-weight: 500;
|
|
265
|
-
background: var(--code-bg);
|
|
266
|
-
box-shadow: var(--shadow);
|
|
267
|
-
height: 2.25rem;
|
|
268
|
-
padding: 0.5rem 1rem;
|
|
269
|
-
color: var(--fg);
|
|
270
|
-
text-decoration: none;
|
|
271
|
-
transition: box-shadow 0.15s;
|
|
272
|
-
animation: fade-in 0.6s ease-out 0.3s both;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
.docs-link:hover {
|
|
276
|
-
box-shadow: var(--shadow-hover);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
.status {
|
|
280
|
-
position: absolute;
|
|
281
|
-
bottom: 2rem;
|
|
282
|
-
left: 50%;
|
|
283
|
-
transform: translateX(-50%);
|
|
284
|
-
animation: fade-in 0.6s ease-out 0.4s both;
|
|
285
|
-
display: inline-flex;
|
|
286
|
-
align-items: center;
|
|
287
|
-
gap: 0.5rem;
|
|
288
|
-
border-radius: 9999px;
|
|
289
|
-
background: var(--pill-bg);
|
|
290
|
-
color: var(--pill-fg);
|
|
291
|
-
box-shadow: var(--shadow);
|
|
292
|
-
padding: 0.5rem 0.75rem 0.5rem 0.625rem;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
.status-dot {
|
|
296
|
-
position: relative;
|
|
297
|
-
width: 0.75rem;
|
|
298
|
-
height: 0.75rem;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
.status-dot .glow {
|
|
302
|
-
position: absolute;
|
|
303
|
-
inset: 0;
|
|
304
|
-
background: var(--green-glow);
|
|
305
|
-
border-radius: 9999px;
|
|
306
|
-
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
.status-dot .dot {
|
|
310
|
-
position: absolute;
|
|
311
|
-
width: 0.25rem;
|
|
312
|
-
height: 0.25rem;
|
|
313
|
-
left: 50%;
|
|
314
|
-
top: 50%;
|
|
315
|
-
transform: translate(-50%, -50%);
|
|
316
|
-
background: var(--green);
|
|
317
|
-
border-radius: 9999px;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
.status-text {
|
|
321
|
-
font-size: 0.75rem;
|
|
322
|
-
font-weight: 500;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
@keyframes fade-in {
|
|
326
|
-
from {
|
|
327
|
-
opacity: 0;
|
|
328
|
-
}
|
|
329
|
-
to {
|
|
330
|
-
opacity: 1;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
@keyframes pulse {
|
|
335
|
-
50% {
|
|
336
|
-
opacity: 0.5;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
</style>
|
|
340
|
-
</head>
|
|
341
|
-
<body>
|
|
342
|
-
<main>
|
|
343
|
-
<div class="logo">
|
|
344
|
-
<svg
|
|
345
|
-
width="384"
|
|
346
|
-
height="72"
|
|
347
|
-
viewBox="0 0 128 24"
|
|
348
|
-
fill="none"
|
|
349
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
350
|
-
>
|
|
351
|
-
<path
|
|
352
|
-
fill-rule="evenodd"
|
|
353
|
-
clip-rule="evenodd"
|
|
354
|
-
d="M28.8316 3.21884H26L26.0007 19.9974H28.8316V3.21884ZM34.0855 8.01549H31.2547V19.9974H34.0855V8.01549ZM34.0855 3.08984H31.2547V6.14356H34.0855V3.08984ZM38.2401 8.01549H35.1978L39.4807 19.9974H42.6398L46.9226 8.01549H43.9269L42.1367 13.6908C42.0901 13.8384 41.9224 14.416 41.6336 15.4222L41.0602 17.3529C40.7213 16.1277 40.3665 14.9069 39.996 13.6908L38.2401 8.01549ZM58.5185 11.7601C58.2841 10.9567 57.9408 10.2737 57.4879 9.71184C56.9805 9.08118 56.3376 8.59313 55.5579 8.24984C54.7853 7.89868 53.9274 7.72381 52.9836 7.72381C51.1897 7.72381 49.7542 8.28496 48.6778 9.40798C48.1408 9.9882 47.7303 10.6737 47.4723 11.4211C47.2072 12.1929 47.0746 13.0472 47.0746 13.9832C47.0746 15.9877 47.6092 17.5364 48.6785 18.6286C49.7621 19.7359 51.2055 20.2898 53.0072 20.2898C54.5517 20.2898 55.803 19.943 56.7633 19.2485C57.723 18.5541 58.3586 17.5249 58.6704 16.1597L55.909 15.949C55.7765 16.69 55.4719 17.244 54.996 17.6102C54.5201 17.9693 53.8493 18.1492 52.9836 18.1492C51.0027 18.1492 49.9886 17.0333 49.942 14.8023H58.8575L58.8696 14.4046C58.8696 13.445 58.7521 12.5635 58.5185 11.7601ZM50.5734 10.918C51.0729 10.2157 51.8763 9.86449 52.9836 9.86449C53.5218 9.86449 53.9747 9.93831 54.341 10.0867C54.7079 10.235 55.024 10.4729 55.2891 10.8005C55.4953 11.0547 55.6539 11.3441 55.7571 11.6547C55.8734 11.9788 55.9443 12.3174 55.9678 12.6609H49.9649C50.0352 11.9665 50.238 11.3853 50.5734 10.918ZM69.8685 8.48419C69.0651 7.96103 68.137 7.70016 67.0842 7.70016H67.0827C66.3188 7.70016 65.6207 7.85568 64.9886 8.16814C64.3667 8.4713 63.8342 8.9309 63.4435 9.50186V3.21884H60.6126V19.9974H63.4442V18.3477C63.8031 18.9405 64.3115 19.4286 64.9184 19.7631C65.5505 20.1143 66.2485 20.2898 67.0125 20.2898C68.0739 20.2898 69.0135 20.0361 69.8341 19.5295C70.6525 19.0228 71.2882 18.2968 71.7404 17.3529C72.2005 16.4012 72.4313 15.2861 72.4313 14.0068C72.4313 12.7584 72.2041 11.659 71.7526 10.7073C71.3076 9.74768 70.6797 9.00664 69.8685 8.48419ZM68.663 17.1774C68.2108 17.8639 67.4389 18.2065 66.346 18.2065C65.3627 18.2065 64.6224 17.8517 64.1236 17.1422C63.6241 16.4327 63.3747 15.395 63.3747 14.0298C63.3747 12.7111 63.5968 11.682 64.0412 10.9409C64.4941 10.192 65.2545 9.81791 66.3231 9.81791C67.4153 9.81791 68.1914 10.1612 68.6516 10.847C69.1124 11.5257 69.3417 12.5792 69.3417 14.0068C69.3417 15.4337 69.116 16.4908 68.663 17.1774ZM77.0302 3.21884H74.1986V19.9974H77.0302V3.21884ZM81.6169 19.5409C82.5379 20.0404 83.6294 20.2898 84.8936 20.2898C86.1105 20.2898 87.1791 20.0283 88.0993 19.5065C89.0131 18.9985 89.7576 18.2335 90.2407 17.3064C90.7474 16.3546 91.0011 15.2545 91.0011 14.0068C91.0011 12.8057 90.7517 11.7285 90.2522 10.7775C89.7734 9.83933 89.0341 9.05921 88.1229 8.53078C87.202 7.99256 86.1256 7.72309 84.8936 7.72309C83.653 7.72309 82.5687 7.99256 81.6406 8.53078C80.7318 9.05692 79.9926 9.83235 79.5106 10.7653C79.0197 11.7092 78.7739 12.7899 78.7739 14.0068C78.7739 15.3018 79.0154 16.4206 79.4992 17.3644C79.9697 18.2867 80.7079 19.0453 81.6169 19.5409ZM87.245 17.1895C86.7691 17.8603 85.9851 18.1957 84.8936 18.1957C84.1525 18.1957 83.5556 18.0474 83.1033 17.7507C82.6504 17.4468 82.3229 16.9903 82.12 16.3819C81.9172 15.7655 81.8162 14.9736 81.8162 14.0061C81.8162 12.5556 82.0541 11.4949 82.53 10.8241C83.0137 10.1533 83.8014 9.81791 84.8936 9.81791C85.9779 9.81791 86.7577 10.1533 87.2335 10.8241C87.7173 11.4949 87.9588 12.5556 87.9588 14.0068C87.9588 15.4574 87.7209 16.518 87.245 17.1895ZM94.8626 19.5409C95.7756 20.0404 96.8635 20.2898 98.1277 20.2898C99.1103 20.2898 99.9882 20.1186 100.76 19.7753C101.533 19.432 102.16 18.9525 102.644 18.3362C103.129 17.708 103.447 16.967 103.568 16.1826L100.842 15.9024C100.655 16.6506 100.343 17.2089 99.9058 17.5751C99.4693 17.942 98.8759 18.1255 98.1277 18.1255C97.363 18.1255 96.7625 17.9693 96.3253 17.6568C95.8888 17.3372 95.5842 16.8814 95.413 16.288C95.241 15.6874 95.1557 14.927 95.1557 14.0068C95.1557 13.1017 95.241 12.3528 95.413 11.7601C95.5842 11.1595 95.8845 10.6994 96.3138 10.3791C96.751 10.0515 97.3552 9.88814 98.1277 9.88814C98.9541 9.88814 99.5668 10.1182 99.9646 10.5783C100.37 11.0305 100.659 11.6504 100.83 12.4388L103.51 11.9586C103.253 10.6793 102.671 9.65379 101.766 8.88194C100.869 8.10938 99.6564 7.72381 98.1277 7.72381C96.8793 7.72381 95.7992 7.98898 94.8862 8.51931C93.9847 9.03823 93.2562 9.81153 92.7921 10.7424C92.3083 11.6863 92.0661 12.7742 92.0661 14.0068C92.0661 15.309 92.304 16.4327 92.7799 17.3766C93.2637 18.3204 93.9581 19.0421 94.8626 19.5409ZM107.91 15.5512L109.232 14.287L112.742 19.9974H116.007L111.151 12.4732L115.855 8.01549H112.18L107.91 12.3922V3.21884H105.078V19.9974H107.91V15.5512ZM118.488 19.8569C119.284 20.1457 120.169 20.2897 121.144 20.2897C122.634 20.2897 123.862 19.993 124.83 19.4011C125.805 18.8077 126.293 17.8402 126.293 16.4986C126.293 15.6249 126.066 14.9384 125.614 14.4396C125.162 13.9322 124.623 13.5695 123.999 13.351C123.383 13.1252 122.544 12.8952 121.484 12.6608C120.867 12.5282 120.38 12.4035 120.021 12.2867C119.662 12.1692 119.373 12.0172 119.155 11.8302C118.945 11.6424 118.839 11.4009 118.839 11.1049C118.839 10.6678 119.034 10.3367 119.424 10.1102C119.814 9.88373 120.298 9.77049 120.875 9.77049C121.639 9.77049 122.236 9.95396 122.666 10.3209C123.102 10.6878 123.336 11.2375 123.367 11.9707L125.988 11.5378C125.863 10.1962 125.337 9.22511 124.408 8.62383C123.488 8.02398 122.31 7.72298 120.875 7.72298C120.032 7.72298 119.253 7.85126 118.535 8.10926C117.825 8.35866 117.252 8.75283 116.815 9.29176C116.378 9.82926 116.16 10.5079 116.16 11.3271C116.16 12.0839 116.347 12.6959 116.721 13.1639C117.102 13.6369 117.592 14.0102 118.149 14.2518C118.726 14.5019 119.451 14.7399 120.325 14.9656L121.051 15.1412C121.535 15.256 122.015 15.3887 122.49 15.5389C122.817 15.6407 123.086 15.7812 123.297 15.9603C123.508 16.1395 123.613 16.3739 123.613 16.6627C123.613 17.1694 123.402 17.5599 122.981 17.8323C122.568 18.106 121.963 18.2422 121.168 18.2422C120.356 18.2422 119.709 18.0394 119.225 17.6338C118.742 17.2281 118.496 16.6433 118.488 15.8786L115.821 16.1825C115.851 17.1034 116.105 17.8717 116.581 18.488C117.065 19.1044 117.7 19.5602 118.488 19.8569Z"
|
|
355
|
-
fill="currentColor"
|
|
356
|
-
></path>
|
|
357
|
-
<path
|
|
358
|
-
fill-rule="evenodd"
|
|
359
|
-
clip-rule="evenodd"
|
|
360
|
-
d="M13.5 9H0L4 13V18.5L13.5 9Z"
|
|
361
|
-
fill="currentColor"
|
|
362
|
-
></path>
|
|
363
|
-
<path
|
|
364
|
-
fill-rule="evenodd"
|
|
365
|
-
clip-rule="evenodd"
|
|
366
|
-
d="M6.5 20H20L16 16V10.5L6.5 20Z"
|
|
367
|
-
fill="currentColor"
|
|
368
|
-
></path>
|
|
369
|
-
</svg>
|
|
370
|
-
</div>
|
|
371
|
-
|
|
372
|
-
<div class="center">
|
|
373
|
-
<p class="description">
|
|
374
|
-
This is the Liveblocks dev server. Point your app to
|
|
375
|
-
<code>http://localhost:1153</code> and start building. This page is
|
|
376
|
-
not meant to be used directly.
|
|
377
|
-
</p>
|
|
378
|
-
<a
|
|
379
|
-
href="https://liveblocks.io/docs/tools/dev-server?from=__VERSION__"
|
|
380
|
-
target="_blank"
|
|
381
|
-
rel="noopener noreferrer"
|
|
382
|
-
class="docs-link"
|
|
383
|
-
>Read the docs</a
|
|
384
|
-
>
|
|
385
|
-
</div>
|
|
386
|
-
|
|
387
|
-
<div class="status">
|
|
388
|
-
<span class="status-dot">
|
|
389
|
-
<span class="glow" aria-hidden="true"></span>
|
|
390
|
-
<span class="dot" aria-hidden="true"></span>
|
|
391
|
-
</span>
|
|
392
|
-
<span class="status-text">Dev server is running</span>
|
|
393
|
-
</div>
|
|
394
|
-
</main>
|
|
395
|
-
</body>
|
|
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};
|