liveblocks 1.4.2-pre2 → 1.5.0-rc2
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/README.md +10 -9
- package/dist/dev-server-2XWU56GJ.js +406 -0
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/dist/dev-server-3TFNGSK6.js +0 -406
package/README.md
CHANGED
|
@@ -14,15 +14,16 @@ npx liveblocks dev
|
|
|
14
14
|
|
|
15
15
|
Options:
|
|
16
16
|
|
|
17
|
-
| Flag
|
|
18
|
-
|
|
|
19
|
-
| `--port`, `-p
|
|
20
|
-
| `--
|
|
21
|
-
| `--
|
|
22
|
-
| `--
|
|
23
|
-
| `--
|
|
24
|
-
| `--
|
|
25
|
-
| `--
|
|
17
|
+
| Flag | Description | Default |
|
|
18
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------- |
|
|
19
|
+
| `--port`, `-p <port>` | Port to listen on. | `1153` |
|
|
20
|
+
| `--random-port`, `-P` | Bind a random free port. The chosen port is exposed via the `LIVEBLOCKS_DEV_SERVER_PORT` env var. Ideal for CI. | |
|
|
21
|
+
| `--host <hostname>` | Host to bind to. | `localhost` |
|
|
22
|
+
| `--cmd`, `-c <command>` | Run a one-off command against a fresh server instance, then shut down. Does not affect your local data in `.liveblocks/`. | |
|
|
23
|
+
| `--ci` | Start a fresh server instance on every boot, ideal for CI. | |
|
|
24
|
+
| `--no-check` | Skip project setup check on start. | Checks by default |
|
|
25
|
+
| `--verbose`, `-v` | Show verbose output. | |
|
|
26
|
+
| `--help`, `-h` | Show help. | |
|
|
26
27
|
|
|
27
28
|
By default, the dev server scans your project on startup for common Liveblocks
|
|
28
29
|
call sites (`<LiveblocksProvider>`, `createClient()`, `new Liveblocks()`) and
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import{a as ee,b as Ve,c as H,d as J,e as de,f as D,g as p,h as Ce,i as Ye}from"./chunk-ZFPKG3IB.js";import{Promise_withResolvers as fr,tryParseJson as Gt,WebsocketCloseCodes as $t}from"@liveblocks/core";import{ZenRelay as pr}from"@liveblocks/zenrouter";import Ge from"bun";import{join as gr}from"path";import{nanoid as Lo}from"@liveblocks/core";import{ProtocolVersion as yt}from"@liveblocks/server";import{nanoid as ao,WebsocketCloseCodes as Qe}from"@liveblocks/core";import{DefaultMap as co,Room as uo}from"@liveblocks/server";import{Database as lo}from"bun:sqlite";import{mkdirSync as et,mkdtempSync as mo,rmSync as fo}from"fs";import{tmpdir as po}from"os";import{dirname as go,join as ve,resolve as Ze}from"path";import{asPos as Ke,CrdtType as V,nn as Zt,nodeStreamToCompactNodes as Qt}from"@liveblocks/core";import{makeInMemorySnapshot as eo,NestedMap as to,plainLsonToNodeStream as oo,quote as $}from"@liveblocks/server";import{Database as ro}from"bun:sqlite";function q(t){try{return t!==void 0?JSON.parse(t):void 0}catch{return}}function We(t){if(t>512)throw new Error("More than 512 params not supported");return new Array(t).fill("?").join(",")}function so(t){return Array.isArray(t)?t:Array.from(t)}function no(t){return t.query("SELECT node_id, crdt_json FROM nodes").values().map(([e,o])=>[e,q(o)])}function ce(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 qe(t,e){let o=so(e),r=o.length;t.query(`DELETE FROM nodes WHERE node_id IN (${We(r)})`).run(...o)}function He(t){let e=new to;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 io(t,e){let o=new Map(no(t));o.has("root")||o.set("root",{type:V.OBJECT,data:{}});let r=new Set,i=["root"],a=new Map,d=He(o);for(;i.length>0;){let v=i.pop(),b=Zt(o.get(v));if(b.type===V.OBJECT)for(let g of d.keysAt(v))Object.prototype.hasOwnProperty.call(b.data,g)&&(delete b.data[g],r.add(v),e.warn(`[integrity] Found data key ${$(g)} from ${$(v)} (conflicted with child node)`));if(b.type!==V.REGISTER)i.push(...d.valuesAt(v));else if(o.get(b.parentId)?.type===V.OBJECT)continue;a.set(v,b)}let c=new Set;for(let[v,b]of o)a.has(v)||(b.parentId!==void 0&&a.has(b.parentId)?a.get(b.parentId)?.type===V.REGISTER?e.warn(`[integrity] Found unreachable node ${$(v)} (child of live register)`):e.warn(`[integrity] Found conflicting sibling ${$(v)} (conflicted with ${$(d.get(b.parentId,b.parentKey))} at ${$(b.parentKey)})`):e.warn(`[integrity] Found orphan ${$(v)}`),c.add(v),r.delete(v));if(r.size>0||c.size>0){if(r.size>0){let v=new Map;for(let b of r){let g=a.get(b);g!==void 0&&v.set(b,g)}ce(t,v)}c.size>0&&qe(t,c)}let f=c.size===0?d:He(a);return{nodes:a,revNodes:f}}function Xe(t,e){return t?.type===V.OBJECT&&Object.prototype.hasOwnProperty.call(t.data,e)&&t.data[e]!==void 0}var he=class{db;constructor(e){let o=new ro(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}=io(o,e),a=l=>r.get(l),d=(l,u)=>i.get(l,u),c=(l,u)=>i.has(l,u);function f(l,u){let h;for(let y of i.keysAt(l)){let S=Ke(y);S>u&&(h===void 0||S<h)&&(h=S)}return h}function v(l){let u;for(let h of i.keysAt(l)){let y=Ke(h);(u===void 0||y>u)&&(u=y)}return u}function b(l,u,h=!1){let y=a(u.parentId);if(y===void 0)throw new Error(`No such parent ${$(u.parentId)}`);if(u.type===V.REGISTER&&y.type===V.OBJECT)throw new Error("Cannot add register under object");let S=d(u.parentId,u.parentKey);if(S!==l){let U=Xe(y,u.parentKey);if(S!==void 0||U)if(h)T(u.parentId,u.parentKey);else throw new Error(`Key ${$(u.parentKey)} already exists`);i.set(u.parentId,u.parentKey,l)}r.set(l,u),ce(o,[[l,u]])}function g(l,u){let h=a(l);if(h?.parentId===void 0)return;if(c(h.parentId,u))throw new Error(`Pos ${$(u)} already taken`);i.delete(h.parentId,h.parentKey);let y={...h,parentKey:u};r.set(l,y),i.set(h.parentId,u,l),ce(o,[[l,y]])}function L(l,u,h=!1){let y=a(l);if(y?.type!==V.OBJECT)return;for(let U of Object.keys(u)){let _=d(l,U);if(_!==void 0)if(h)O(_);else throw new Error(`Child node already exists under ${U}`)}let S={...y,data:{...y.data,...u}};r.set(l,S),ce(o,[[l,S]])}function O(l){let u=a(l);if(u?.parentId===void 0)return;i.delete(u.parentId,u.parentKey);let h=[],y=[l];for(;y.length>0;){let S=y.pop();y.push(...i.valuesAt(S)),r.delete(S),i.deleteAll(S),h.push(S)}qe(o,h)}function T(l,u){let h=a(l);if(Xe(h,u)){let{[u]:S,...U}=h.data,_={...h,data:U};r.set(l,_),ce(o,[[l,_]])}let y=d(l,u);y!==void 0&&O(y)}return{get_node:a,iter_nodes:()=>r.entries(),*iter_nodes_optimized(){for(let l of Qt(r.entries()))yield JSON.stringify(l)},has_node:l=>r.has(l),get_child_at:d,has_child_at:c,get_next_sibling:f,get_last_sibling:v,set_child:b,move_sibling:g,delete_node:O,delete_child_key:T,set_object_data:L,get_snapshot(l){return eo(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 oo(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,q(o)])}get_meta(e){let r=this.db.query("SELECT jval FROM metadata WHERE key = ?").get(e)?.jval;if(r!==void 0)return q(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 (${We(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:q(o.jpresence)??null,updatedAt:o.updated_at,info:q(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:q(o.jpresence)??null,updatedAt:o.updated_at,info:q(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[g,L]of Object.entries(a)){let O=typeof L=="boolean"?Number(L):L;d+=" AND json_extract(jmetadata, '$.' || ?) = ?",c.push(g,O)}if(r!==void 0&&(d+=" AND created_at >= ?",c.push(r)),i!==void 0)try{let g=JSON.parse(Buffer.from(i.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[L,O]=g;d+=" AND (created_at < ? OR (created_at = ? AND feed_id < ?))",c.push(O,O,L)}catch{}d+=" ORDER BY created_at DESC, feed_id DESC LIMIT ?",c.push(o+1);let f=this.db.query(d).all(...c),v;if(f.length>o){f.pop();let g=f[f.length-1];if(g){let L=[g.feed_id,g.created_at];v=Buffer.from(JSON.stringify(L),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}return{feeds:f.map(g=>({feedId:g.feed_id,metadata:JSON.parse(g.jmetadata),createdAt:g.created_at,updatedAt:g.updated_at})),nextCursor:v}}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 g=JSON.parse(Buffer.from(a.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[L,O]=g;d+=" AND (created_at < ? OR (created_at = ? AND message_id < ?))",c.push(O,O,L)}catch{}d+=" ORDER BY created_at DESC, message_id DESC LIMIT ?",c.push(r+1);let f=this.db.query(d).all(...c),v;if(f.length>r){f.pop();let g=f[f.length-1];if(g){let L=[g.message_id,g.created_at];v=Buffer.from(JSON.stringify(L),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}}return{messages:f.map(g=>({id:g.message_id,data:JSON.parse(g.jdata),createdAt:g.created_at,updatedAt:g.updated_at})),nextCursor:v}}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 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 ho=".liveblocks/v1",Ee=ho,tt=!1,Z=null;function ot(){return ve(Ee,"rooms")}function oe(){if(Z)return;let t=ve(Ee,"db.sql");et(go(t),{recursive:!0});let e=new lo(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`),Z=e}function re(){if(!Z)throw new Error("Rooms DB not initialized");return Z}function rt(t){let e=re(),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 te(t){let e=re().query("SELECT room_id, internal_id, organization_id, default_permissions, metadata, created_at FROM rooms WHERE room_id = ?").get(t);if(e)return rt(e)}var vo="default";function st(t,e){let o=re(),r=ao(),i=new Date().toISOString(),a=e?.organizationId??vo,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[f,v]of Object.entries(e.usersAccesses))o.run("INSERT INTO room_user_permissions (room_id, user_id, scopes) VALUES (?, ?, ?)",[t,f,JSON.stringify(v)]);if(e?.groupsAccesses)for(let[f,v]of Object.entries(e.groupsAccesses))o.run("INSERT INTO room_group_permissions (room_id, group_id, scopes) VALUES (?, ?, ?)",[t,f,JSON.stringify(v)]);return{id:t,internalId:r,organizationId:a,defaultAccesses:d,usersAccesses:e?.usersAccesses??{},groupsAccesses:e?.groupsAccesses??{},metadata:c,createdAt:i}}function Eo(t,e){let o=re(),r=te(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 te(t)}}function Io(t){re().run("DELETE FROM rooms WHERE room_id = ?",[t])}function nt(t){let e=ot(),o=Ze(e,`${t}.sql`);if(!o.startsWith(Ze(e)+"/"))throw new Error("Invalid internal ID");return o}var B=new co(t=>{let e=te(t)??st(t);et(ot(),{recursive:!0});let o=new he(nt(e.internalId));return new uo(t,{storage:o})});function it(){let t=mo(ve(po(),"liveblocks-dev-"));return Ee=ve(t,"data"),tt=!0,t}function C(t){return oe(),te(t)}function Ie(t,e){oe();let o=te(t);if(o)return o;let r=st(t,e);return B.getOrCreate(t),r}function at(t){oe();let e=re(),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(rt)}function dt(t,e){return oe(),Eo(t,e)}async function ct(t){oe();let e=te(t),o=B.get(t);if(o&&(o.endSessionBy(()=>!0,Qe.KICKED,"Deliberately disconnected"),o.unload(),o.driver.close(),B.delete(t)),e){let r=nt(e.internalId);try{await Bun.write(r,""),await Bun.file(r).unlink()}catch{}Io(t)}}function F(t){return oe(),B.getOrCreate(t)}var Le=null;function ut(t){Le=t;for(let e of B.values())e.runInMaintenanceMode(()=>t).catch(()=>{});t.then(()=>{Le=null})}function lt(t){if(Le!==null)return!0;let e=B.get(t);return e!==void 0&&e.isInMaintenance}function ue(){let t=[];for(let[e,o]of B)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 mt(t,e){let o=B.get(t);return o?o.endSessionBy(r=>r.actor===e,Qe.KICKED,"Deliberately disconnected")>0:!1}function ft(){for(let t of B.values())t.unload();B.clear()}function xe(){for(let t of B.values())t.unload(),t.driver.close();B.clear(),Z&&(Z.close(),Z=null),tt&&fo(Ee,{recursive:!0,force:!0})}import{nanoid as yo,tryParseJson as ht}from"@liveblocks/core";import{array as It,constant as le,enum_ as _o,number as Tt,object as Pe,optional as Ae,record as bo,string as ke,taggedUnion as So}from"decoders";import{inexact as To,optional as pt,string as gt}from"decoders";var se=To({name:pt(gt),avatar:pt(gt)}).refineType();var Q={RoomRead:"room:read",RoomWrite:"room:write",CommentsWrite:"comments:write",FeedsWrite:"feeds:write",RoomPresenceWrite:"room:presence:write",CommentsRead:"comments:read"};var Ro=Pe({alg:le("none")}),Oo=Pe({k:le("acc"),pid:le("localdev"),uid:ke,ui:Ae(se),perms:bo(It(_o(Q))),exp:Tt}),wo=Pe({k:le("id"),pid:le("localdev"),uid:ke,ui:Ae(se),gids:Ae(It(ke)),exp:Tt}),Co=So("k",{acc:Oo,id:wo});function vt(t){return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Et(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),o=e+"=".repeat((4-e.length%4)%4);return atob(o)}function De(t){let e=Math.floor(Date.now()/1e3),o={...t,iat:e,exp:e+3600,jti:yo(12)},r=vt(JSON.stringify({alg:"none",typ:"JWT"})),i=vt(JSON.stringify(o));return`${r}.${i}.`}function Te(t){let e=t.split(".");if(e.length!==3)return null;let[o,r,i]=e;if(i!==""||!Ro.value(ht(Et(o))))return null;let a=Co.value(ht(Et(r)));return!a||a.exp<Math.floor(Date.now()/1e3)?null:a}function xo(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 No(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 Ao(t,e){return t.k==="acc"?xo(t,e):No(t,e)}function _t(t){let e=new URL(t.url),o=e.pathname==="/v7"?yt.V7:e.pathname==="/v8"?yt.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=Te(i);if(!d)return{ok:!1};let c=Ao(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"}:(Ie(r,{defaultAccesses:[Q.RoomWrite]}),{ok:!0,roomId:r,ticketData:{version:o,anonymousId:Lo(),scopes:[Q.RoomWrite]}}):{ok:!1}}function ko(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 bt(...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,ko(r)}catch{return[]}}function Po(t){let e=t.trim();return e.startsWith("#")||e.startsWith("//")||e.startsWith("*")||e.startsWith("/*")}var je=[{pattern:"<LiveblocksProvider",expected:"baseUrl=",fixSnippet:t=>`${H("baseUrl")}=${J(`"${t}"`)}`,closePattern:">"},{pattern:"createClient(",expected:"baseUrl:",fixSnippet:t=>`${H("baseUrl")}: ${J(`"${t}"`)}`,closePattern:")"},{pattern:"new Liveblocks(",expected:"baseUrl:",fixSnippet:t=>`${H("baseUrl")}: ${J(`"${t}"`)}`,closePattern:")"}];async function St(t){let e=je.map(c=>c.pattern),o=[...new Set(je.map(c=>c.expected))],[r,i]=await Promise.all([bt(...e),bt(...o)]);if(r.length===0)return[];let a=new Set(i.map(c=>c.file)),d=[];for(let c of r){if(Po(c.text)||a.has(c.file))continue;let f=je.find(v=>c.text.includes(v.pattern));f&&d.push({match:c,check:f})}if(d.length>0){console.log(),console.warn(ee("\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(` ${Ve(`${c.file}:${c.line}`)}`),console.log(` To fix, add ${f.fixSnippet(t)} to ${H(f.pattern)}${H(f.closePattern)}`),console.log();console.log(p(" \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(p(" \u2502 \u{1F4A1} ")+"Press "+D("p")+" to copy an AI fix prompt to your clipboard"+p(" \u2502")),console.log(p(" \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(p(" To skip this check, use --no-check")),console.log()}return d}var Do={"<LiveblocksProvider":"baseUrl={...}","createClient(":"baseUrl: ...","new Liveblocks(":"baseUrl: ..."};function Rt(t,e){let o=t.map(({match:r,check:i})=>{let a=Do[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 jo}from"child_process";function Ot(t){let e=process.platform==="darwin"?"pbcopy":process.platform==="win32"?"clip.exe":"xclip -selection clipboard";jo(e,{input:t})}import Mo from"bun";function wt(t,e){let{promise:o,resolve:r}=Promise.withResolvers();return Mo.connect({hostname:e,port:t,socket:{data(){},open(i){i.end(),r(!0)},error(){r(!1)},connectError(){r(!1)}}}),o}function Me(t,e=!1){t&&console.log((e?de:ee)(` \u26A0 ${t}`))}import{ZenRouter as Bo}from"@liveblocks/zenrouter";import{array as Lt,enum_ as Fo,object as xt,optional as Be,record as Jo,string as Fe}from"decoders";import{json as Uo}from"@liveblocks/zenrouter";import{json as Ct}from"@liveblocks/zenrouter";function Ue(t,e,o){return Ct(t,e,{"X-LB-Warn":o})}function P(t,e,o="This is a dummy response."){return Ue(t,e,o)}function s(t="This endpoint isn't implemented in the Liveblocks dev server."){return Ct({error:"Not implemented",message:t},501,{"X-LB-Warn":t})}function ye(t){let e=t.headers.get("Authorization");if(e==="Bearer sk_localdev")return!0;if(!e)throw Uo({error:"Unauthorized",message:"Missing secret key"},401);if(e.startsWith("Bearer "))throw Ue({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 Go=Fo(Q),me=new Bo({authorize:({req:t})=>ye(t)});me.route("POST /v2/authorize-user",xt({userId:Fe,userInfo:Be(se),permissions:Jo(Lt(Go))}),({body:t})=>({token:De({k:"acc",pid:"localdev",uid:t.userId,perms:t.permissions,ui:t.userInfo})}));me.route("POST /v2/identify-user",xt({userId:Fe,userInfo:Be(se),groupIds:Be(Lt(Fe))}),({body:t})=>({token:De({k:"id",pid:"localdev",uid:t.userId,ui:t.userInfo,gids:t.groupIds})}));import{ZenRouter as $o}from"@liveblocks/zenrouter";var m=new $o({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 Te(o)!==null}});m.route("GET /v2/c/threads",()=>P({threads:[],inboxNotifications:[],subscriptions:[],meta:{nextCursor:null,requestedAt:new Date().toISOString(),permissionHints:{}}}));m.route("GET /v2/c/threads/delta",()=>P({threads:[],inboxNotifications:[],subscriptions:[],meta:{requestedAt:new Date().toISOString(),permissionHints:{}}}));m.route("GET /v2/c/inbox-notifications",()=>P({inboxNotifications:[],threads:[],subscriptions:[],groups:[],meta:{nextCursor:null,requestedAt:new Date().toISOString()}}));m.route("GET /v2/c/inbox-notifications/count",()=>P({count:0}));m.route("GET /v2/c/inbox-notifications/delta",()=>P({inboxNotifications:[],threads:[],subscriptions:[],groups:[],deletedInboxNotifications:[],deletedThreads:[],deletedSubscriptions:[],meta:{requestedAt:new Date().toISOString()}}));m.route("GET /v2/c/rooms/<roomId>/threads",()=>P({data:[],inboxNotifications:[],subscriptions:[],meta:{nextCursor:null,requestedAt:new Date().toISOString(),permissionHints:{}}}));m.route("GET /v2/c/rooms/<roomId>/threads/delta",()=>P({data:[],inboxNotifications:[],subscriptions:[],deletedThreads:[],deletedInboxNotifications:[],deletedSubscriptions:[],meta:{requestedAt:new Date().toISOString(),permissionHints:{}}}));m.route("POST /v2/c/rooms/<roomId>/text-metadata",()=>P({status:"ok"}));m.route("PUT /v2/c/rooms/<roomId>/attachments/<attachmentId>/upload/<name>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<name>",()=>s()),m.route("PUT /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>/<partNumber>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>/complete",()=>s()),m.route("DELETE /v2/c/rooms/<roomId>/attachments/<attachmentId>/multipart/<uploadId>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/attachments/presigned-urls",()=>s()),m.route("POST /v2/c/rooms/<roomId>/send-message",()=>s()),m.route("GET /v2/c/rooms/<roomId>/storage",()=>s()),m.route("POST /v2/c/rooms/<roomId>/version",()=>s()),m.route("GET /v2/c/rooms/<roomId>/y-version/<version>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/ai/contextual-prompt",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/search",()=>s()),m.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/metadata",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/mark-as-resolved",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/mark-as-unresolved",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/subscribe",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/unsubscribe",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments",()=>s()),m.route("GET /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/metadata",()=>s()),m.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/reactions",()=>s()),m.route("DELETE /v2/c/rooms/<roomId>/threads/<threadId>/comments/<commentId>/reactions/<emoji>",()=>s()),m.route("GET /v2/c/rooms/<roomId>/threads/comments/search",()=>s()),m.route("GET /v2/c/rooms/<roomId>/threads/<threadId>/participants",()=>s()),m.route("GET /v2/c/rooms/<roomId>/notification-settings",()=>s()),m.route("GET /v2/c/rooms/<roomId>/subscription-settings",()=>s()),m.route("POST /v2/c/rooms/<roomId>/notification-settings",()=>s()),m.route("POST /v2/c/rooms/<roomId>/subscription-settings",()=>s()),m.route("DELETE /v2/c/inbox-notifications",()=>s()),m.route("POST /v2/c/inbox-notifications/read",()=>s()),m.route("DELETE /v2/c/inbox-notifications/<inboxNotificationId>",()=>s()),m.route("POST /v2/c/rooms/<roomId>/inbox-notifications/read",()=>s()),m.route("POST /v2/c/rooms/<roomId>/text-mentions",()=>s()),m.route("DELETE /v2/c/rooms/<roomId>/text-mentions/<mentionId>",()=>s()),m.route("GET /v2/c/notification-settings",()=>s()),m.route("POST /v2/c/notification-settings",()=>s()),m.route("GET /v2/c/rooms/<roomId>/thread-with-notification/<threadId>",()=>s()),m.route("GET /v2/c/urls/metadata",()=>s()),m.route("GET /v2/c/rooms/<roomId>/versions",()=>s()),m.route("GET /v2/c/rooms/<roomId>/versions/delta",()=>s()),m.route("POST /v2/c/groups/find",()=>s());import{abort as At,html as Vo,json as Yo,ZenRouter as Ko}from"@liveblocks/zenrouter";var Nt=`<!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 ne=new Ko({authorize:()=>!0});ne.route("GET /v7",()=>At(426));ne.route("GET /v8",()=>At(426));ne.route("GET /health",()=>Yo({status:"ok"}));ne.route("GET /",()=>Vo(Nt.replace("__VERSION__","1.5.0-rc2")));import{ServerMsgCode as Zo}from"@liveblocks/core";import{QueryParser as Qo}from"@liveblocks/query-parser";import{ConsoleTarget as Mt,jsonObjectYolo as er,Logger as Ut,ROOT_YDOC_ID as Je,snapshotToLossyJson_eager as tr,snapshotToNodeStream as or,snapshotToPlainLson_eager as Bt,transientClientMsgDecoder as rr}from"@liveblocks/server";import{json as _e,ndjsonStream as sr,ZenRouter as nr}from"@liveblocks/zenrouter";import{array as X,constant as ir,either as ar,enum_ as dr,nullable as jt,object as be,optional as Y,record as fe,string as j}from"decoders";function*Ho(t){for(let e of t)for(let o of e)yield o}function kt(...t){return Ho(t)}import{Base64 as cr}from"js-base64";import*as Se from"yjs";import*as x from"yjs";function Xo(t){return t.content instanceof x.ContentFormat||t.content instanceof x.ContentEmbed?"text":"arr"in t.content?"array":"str"in t.content?"text":"type"in t.content?"xml":"unknown"}function Wo(t){let e=[],o=t;for(;o!==null;){if(!o.deleted)if(o.content instanceof x.ContentType)e.push(o.content.type.toJSON());else if(o.content instanceof x.ContentString)e.push(o.content.str);else if(o.content instanceof x.ContentFormat){let{key:r,value:i}=o.content;e.push({key:r,value:i})}else o.content instanceof x.ContentEmbed&&e.push(o.content.embed);o=o.right}return e}function Pt(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=Xo(e._first);if(i==="text")return r?Wo(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 qo={ytext:x.Text,yxmlfragment:x.XmlFragment,yxmltext:x.XmlText,ymap:x.Map,yarray:x.Array};function Dt(t,e="",o=!1,r=""){let i={};if(e.length){if(t.share.has(e)){if(r.length){let a=qo[r];if(a)return t.get(e,a).toJSON()}return{[e]:Pt(t,t.share.get(e),e,o)}}return{[e]:""}}for(let[a,d]of t.share)i[a]=Pt(t,d,a,o);return i}var Ft=(o=>(o.PlainLson="plain-lson",o.LossyJson="json",o))(Ft||{}),ur=dr(Ft),Jt=fe(j,ar(j,X(j))),n=new nr({authorize:({req:t})=>ye(t)});function N(t){return _e({error:"ROOM_NOT_FOUND",message:`Room with id "${t}" not found.`},404)}var lr=new Qo({fields:{roomId:"string"},indexableFields:{metadata:"token"}});function mr(t){let e=lr.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 Re(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 N(t.roomId);return Re(e)});n.route("GET /v2/rooms",({url:t})=>{let e,o=t.searchParams.get("query");if(o)try{e=mr(o)}catch(d){return _e({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 r=t.searchParams.get("organizationId")??void 0;return r&&(e={...e,organizationId:r}),{data:at(e).map(Re),nextPage:null,nextCursor:null}});n.route("POST /v2/rooms",be({id:j,organizationId:Y(j),defaultAccesses:Y(X(j)),metadata:Y(Jt),usersAccesses:Y(fe(j,X(j))),groupsAccesses:Y(fe(j,X(j)))}),({body:t,url:e})=>{if(!e.searchParams.has("idempotent")&&C(t.id))return _e({error:"ROOM_ALREADY_EXISTS",message:`Room with id "${t.id}" already exists.`},409);let r=Ie(t.id,{organizationId:t.organizationId,defaultAccesses:t.defaultAccesses,metadata:t.metadata,usersAccesses:t.usersAccesses,groupsAccesses:t.groupsAccesses});return Re(r)});n.route("POST /v2/rooms/<roomId>",be({defaultAccesses:Y(X(j)),metadata:Y(Jt),usersAccesses:Y(fe(j,jt(X(j)))),groupsAccesses:Y(fe(j,jt(X(j))))}),({p:t,body:e})=>{let o=dt(t.roomId,{defaultAccesses:e.defaultAccesses,metadata:e.metadata,usersAccesses:e.usersAccesses,groupsAccesses:e.groupsAccesses});if(!o)throw N(t.roomId);return Re(o)});n.route("DELETE /v2/rooms/<roomId>",async({p:t})=>(await ct(t.roomId),new Response(null,{status:204})));n.route("GET /v2/rooms/<roomId>/storage",async({url:t,p:e})=>{if(!C(e.roomId))throw N(e.roomId);let o=ur.value(t.searchParams.get("format"))??"plain-lson",r=F(e.roomId);await r.load();let i=r.storage.loadedDriver.get_snapshot(!1),a=o==="json"?tr(i):Bt(i);return new Response(JSON.stringify(a),{status:200,headers:{"Content-Type":"application/json"}})});n.route("POST /v2/rooms/<roomId>/storage",be({liveblocksType:ir("LiveObject"),data:er}).refineType(),async({p:t,body:e})=>{if(!C(t.roomId))throw N(t.roomId);let o=F(t.roomId);await o.load();let r=o.storage.loadedDriver.get_snapshot(!1),i=Bt(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 N(t.roomId);let e=F(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 N(e.roomId);let o=F(e.roomId);await o.load();let r=t.searchParams.get("key")??"",i=t.searchParams.get("type")??"",a=t.searchParams.get("guid")??Je,d=t.searchParams.get("formatting")!==null,c=new Ut(new Mt("warning")),f=await o.yjsStorage.getYDoc(c,a),v=Dt(f,r,d,i);return new Response(JSON.stringify(v),{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 N(o.roomId);let r=F(o.roomId);await r.load();let i=await t.arrayBuffer(),a=cr.fromUint8Array(new Uint8Array(i)),d=e.searchParams.get("guid"),f=e.searchParams.get("encoder")==="v2",v=d&&d!==Je?d:void 0;try{let b=await r.mutex.runExclusive(()=>r.yjsStorage.addYDocUpdate({},a,v,f)),g=L=>{};return r.sendToAll({type:Zo.UPDATE_YDOC,update:a,isSync:!1,stateVector:null,guid:v,v2:f,remoteSnapshotHash:b.snapshotHash},void 0,g),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 N(e.roomId);let o=F(e.roomId);await o.load();let r=t.searchParams.get("guid")??Je,i=t.searchParams.get("encoder"),a=new Ut(new Mt("warning")),d=await o.yjsStorage.getYDoc(a,r),c=i==="v2"?Se.encodeStateAsUpdateV2(d):Se.encodeStateAsUpdate(d);return new Response(c,{status:200,headers:{"Content-Type":"application/octet-stream"}})});n.route("GET /v2/rooms/<roomId>/active_users",({p:t})=>{if(!C(t.roomId))throw N(t.roomId);let o=F(t.roomId).listSessions().map(r=>({type:"user",connectionId:r.actor,id:r.user.id,info:r.user.info}));return _e({data:o})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!C(t.roomId))throw N(t.roomId);return P({ok:!0})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>/messages/<messageId>",({p:t})=>{if(!C(t.roomId))throw N(t.roomId);return P({ok:!0})});n.route("GET /v2/rooms/<roomId>/feeds",({p:t})=>{if(!C(t.roomId))throw N(t.roomId);return P({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 N(t.roomId);return P({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 N(t.roomId);return P({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 N(t.roomId);let e=Date.now();return P({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 N(t.roomId);let e=Date.now();return P({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 N(t.roomId);return P({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 N(t.roomId);return P({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 N(t.roomId);let e=F(t.roomId);await e.load();let o=await e.driver.next_actor(),r=e.storage.loadedDriver.get_snapshot(!1);return sr(kt([{actor:o}],or(r)))});n.route("POST /v2/rooms/<roomId>/send-message",be({messages:X(rr)}),async({p:t,body:e})=>{if(!C(t.roomId))throw N(t.roomId);let o=F(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 zt(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 ie=new pr;ie.relay("/v2/authorize-user/*",me);ie.relay("/v2/identify-user/*",me);ie.relay("/v2/c/*",m);ie.relay("/v2/*",n);ie.relay("/*",ne);var $e=1153;function Vt(t){if(t===void 0)return;let e=Number(t);return Number.isInteger(e)&&e>0&&e<=65535?e:void 0}function hr(t){return process.platform==="win32"?[process.env.COMSPEC||"cmd.exe","/c",t]:["sh","-c",t]}function vr(t){return"'"+t.replace(/'/g,"'\\''")+"'"}var Er={description:"Start the local Liveblocks dev server",async run(t){let{options:e,args:o}=Ye(t,{port:{type:"string",short:"p",default:$e.toString()},"random-port":{type:"boolean",short:"P",default:!1},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(de("Extra arguments are only supported with --cmd (-c)")),process.exit(1)),o.length>0&&e.cmd){let O=o.map(vr).join(" ");e.cmd.includes("{}")?e.cmd=e.cmd.replaceAll("{}",O):e.cmd+=" "+O}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: ${$e})`),console.log(" --random-port, -P Bind a random free port instead of --port (no collisions,"),console.log(" ever). With --cmd, the chosen port is exposed to the command"),console.log(" via LIVEBLOCKS_DEV_SERVER_PORT. Ideal for CI."),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=e["random-port"]?0:Vt(e.port)??Vt(process.env.LIVEBLOCKS_DEVSERVER_PORT)??$e,a=e.host||process.env.LIVEBLOCKS_DEVSERVER_HOST||"localhost",d=r?it():null;i!==0&&await wt(i,a)&&(console.error(`Port ${i} is already in use.
|
|
398
|
+
Is another dev server already running?`),process.exit(1));let c,f=!1,v=i;function b(){let O=Ge.serve({hostname:a,port:v,async fetch(T,w){if(T.headers.get("Upgrade")==="websocket"){let G=_t(T);if(!G.ok)return Me(G.xwarn,!0),zt(w,T,$t.NOT_ALLOWED,"You have no access to this room");let{roomId:K,ticketData:A}=G;if(lt(K))return zt(w,T,$t.TRY_AGAIN_LATER,"Server is undergoing maintenance, try again later");let k=F(K);await k.load();let z=await k.createTicket(A),pe=z.sessionKey;if(w.upgrade(T,{data:{room:k,ticket:z,sessionKey:pe}})){console.log(`${J("101")} WS ${new URL(T.url).pathname}${p(` - ${K}`)}`);return}return new Response("Could not upgrade to WebSocket",{status:426})}let l=new URL(T.url);if(T.method==="POST"&&l.pathname==="/crash")return console.log(`${J("204")} POST /crash`),setTimeout(()=>{g()},0),new Response(null,{status:204});let u=`${T.method} ${l.pathname}`,h;if(f)try{h=await T.clone().text()}catch{}let y=await ie.fetch(T),S=y.status,U=S>=500?de(S):S>=400?ee(S):J(S);console.log(`${U} ${u}`);let _=y.headers.get("X-LB-Warn")??void 0;if(Me(_,!y.ok),f){if(h){let A=Gt(h);A!==void 0&&console.log(p(` \u2192 ${JSON.stringify(A)}`))}let G=await y.clone().text(),K=Gt(G);K!==void 0&&console.log(p(` \u2190 ${JSON.stringify(K)}`))}return y},error(T){return console.error(T),new Response("An unknown error occurred",{status:500})},websocket:{async open(T){let{refuseConnection:w,room:l,ticket:u}=T.data;if(w){T.close(w.code,w.message);return}l&&u&&await l.startBrowserSession(u,T)},async message(T,w){let{room:l,sessionKey:u}=T.data;l&&u&&await l.handleData(u,w)},close(T,w,l){let{room:u,sessionKey:h}=T.data;u&&h&&u.endBrowserSession(h,w,l)}}});return v=O.port,O}c=b();async function g(){ft(),await c.stop(!0),c=b(),console.log("Crash \u{1F4A5}")}let L=O=>process.stderr.write(O+`
|
|
399
|
+
`);if(e.cmd){L(`Liveblocks dev server ${p("v1.5.0-rc2")} running at http://${c.hostname}:${c.port}`),d&&e.verbose&&L(p(`Ephemeral mode, using ${d}`));let O=gr(d,"server.log");L(p(`Server logs: ${O}`));let T=Ge.file(O).writer(),w=(...u)=>{T.write(u.map(String).join(" ")+`
|
|
400
|
+
`),T.flush()};console.log=w,console.error=w;let l=1;try{let u=Ge.spawn(hr(e.cmd),{stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LIVEBLOCKS_DEV_SERVER_HOST:a,LIVEBLOCKS_DEV_SERVER_PORT:String(c.port)}}),h=()=>{u.kill()};process.on("SIGTERM",h),process.on("SIGINT",h),l=await u.exited}finally{T.end(),await c.stop(),xe(),L(p("Liveblocks dev server shut down"))}process.exit(l)}else{let O=`http://${a}:${c.port}`,T=e["no-check"]?[]:await St(O),w="logs",l=null,u=null,h=null,y=`http://${c.hostname}:${c.port}`,S=()=>{let R=w==="logs"?D(" Logs "):p(" Logs "),I=w==="sockets"?D(" Sockets "):p(" Sockets "),E=R+p("|")+I,ae=(u?H("\u23F8 maintenance")+" ":"")+p(`Liveblocks running at ${y}`),Oe=process.stdout.columns??80,we=Math.max(1,Oe-Ce(E).length-Ce(ae).length);return E+" ".repeat(we)+ae},U=[],_=console.log.bind(console);console.log=(...R)=>{let I=R.map(String).join(" ");U.push(I),w==="logs"&&_(I)};let G=()=>p(" ")+D("q")+p(" quit, ")+D("!")+p(" crash, ")+D("c")+p(" clear, ")+D("v")+p(f?" verbose (on)":" verbose"),K=()=>{h&&(clearInterval(h),h=null),w="logs",process.stdout.write("\x1B[2J\x1B[H"),_(S()),_(G()),_();for(let R of U)_(R)},A=0,k=[],z=R=>`${R.roomId}:${R.actor}`,pe=()=>{k=ue().map(R=>({...R,alive:!0}))},ze=()=>{let R=new Set(ue().map(z));for(let E of k)E.alive=R.has(z(E));let I=new Set(k.map(z));for(let E of ue())I.has(z(E))||k.push({...E,alive:!0})},Yt=R=>{let I=Date.now()-R,E=Math.floor(I/1e3);if(E<60)return`${E}s`;let M=Math.floor(E/60);return M<60?`${M}m`:`${Math.floor(M/60)}h`},Kt=R=>{if(!R)return"";let I=Date.now()-R;return I<1e3?" "+J("\u25CF"):I<3e3?" "+p(J("\u25CF")):I<5e3?" "+p("\u25CF"):""},ge=(R,I)=>{let E=R+I;for(;E>=0&&E<k.length;){if(k[E].alive)return E;E+=I}return R},W=()=>{ze();let R=k.filter(E=>E.alive).length;if(process.stdout.write("\x1B[2J\x1B[H"),_(S()),_(p(" ")+D("\u2191\u2193")+p(" navigate, ")+D("k")+p(" kill, ")+D("m")+p(u?" maintenance off, ":" maintenance on, ")+D("r")+p(" refresh")),_(),_(" "+D("Connections")+p(` (${R} alive)`)),_(),k.length===0){_(p(" No active connections"));return}if(A>=k.length&&(A=k.length-1),!k[A]?.alive){let E=ge(A,-1);A=k[E]?.alive?E:ge(A,1)}let I=new Map;for(let E of ue())I.set(z(E),E.lastActiveAt);for(let E=0;E<k.length;E++){let M=k[E];if(!M.alive){_(p(` ${M.roomId} \xB7 actor=${M.actor} \xB7 disconnected`));continue}let ae=E===A?J("\u25B6 "):" ",Oe=M.userId??p("anonymous"),we=Yt(M.connectedAt),Wt=I.get(z(M)),qt=Kt(Wt);_(`${ae}${D(M.roomId)} ${p("\xB7")} actor=${M.actor} ${p("\xB7")} ${Oe} ${p("\xB7")} ${p(we)}${qt}`)}},Ht=()=>{w="sockets",A=0,pe(),W(),h=setInterval(()=>W(),1e3)},Xt=()=>{if(u)u(),u=null;else{let{promise:R,resolve:I}=fr();ut(R),u=I}};process.stdout.write("\x1B[2J\x1B[H"),_(S()),_(G()),_(),d&&e.verbose&&console.log(p(`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(()=>{xe(),process.exit(0)});return}if(I==="m"){Xt(),w==="sockets"?W():(process.stdout.write("\x1B[s\x1B[H\x1B[2K"),_(S()),process.stdout.write("\x1B[u"));return}if((I==="s"||I==="\x1B[C")&&w!=="sockets"){Ht();return}if((I==="l"||I==="\x1B[D")&&w!=="logs"){K();return}if(w==="sockets"){if(I==="\x1B[A")A=ge(A,-1),W();else if(I==="\x1B[B")A=ge(A,1),W();else if(I==="k"){let E=k[A];E?.alive&&(mt(E.roomId,E.actor),W())}else I==="r"&&(pe(),A=0,W());return}if(I==="!")l!==null?(clearTimeout(l),l=null,g()):(console.log("Simulating crash in 2.5s... (press ! again to crash now)"),l=setTimeout(()=>{l=null,g()},2500));else if(I==="c")U.length=0,process.stdout.write("\x1B[2J\x1B[H"),_(S()),_(G()),_();else if(I==="v")f=!f,process.stdout.write("\x1B[s\x1B[H\x1B[2K"),_(S()),process.stdout.write("\x1B[2K"),_(G()),process.stdout.write("\x1B[u"),console.log(p(f?"Verbose mode on":"Verbose mode off"));else if(I==="p")if(T.length>0){let E=Rt(T,O);Ot(E),console.log(p("Copied AI fix prompt to clipboard"))}else console.log(p("No setup issues detected"))})}}},Vs=Er;export{Vs 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-ZFPKG3IB.js";import{execFileSync as l,spawnSync as c}from"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-ZFPKG3IB.js";import{execFileSync as l,spawnSync as c}from"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-2XWU56GJ.js")).default;case"upgrade":return(await import("./upgrade-QCUVOTDV.js")).default;default:return}}var m={dev:"Start the local Liveblocks dev server",upgrade:"Upgrade all Liveblocks packages"};function f(){console.log("liveblocks v1.5.0-rc2"),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.5.0-rc2"),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.5.0-rc2",
|
|
4
4
|
"description": "Liveblocks command line interface",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"decoders": "^2.9.0",
|
|
42
42
|
"js-base64": "^3.7.5",
|
|
43
43
|
"yjs": "^13.6.10",
|
|
44
|
-
"@liveblocks/
|
|
45
|
-
"@liveblocks/
|
|
44
|
+
"@liveblocks/query-parser": "^0.1.1",
|
|
45
|
+
"@liveblocks/server": "^1.5.0-rc2"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsup",
|
|
@@ -1,406 +0,0 @@
|
|
|
1
|
-
import{a as Q,b as $e,c as V,d as J,e as ae,f as j,g,h as we,i as ze}from"./chunk-ZFPKG3IB.js";import{Promise_withResolvers as ms,tryParseJson as Ft,WebsocketCloseCodes as Jt}from"@liveblocks/core";import{ZenRelay as fs}from"@liveblocks/zenrouter";import Je from"bun";import{join as ps}from"path";import{nanoid as Co}from"@liveblocks/core";import{ProtocolVersion as It}from"@liveblocks/server";import{nanoid as io,WebsocketCloseCodes as qe}from"@liveblocks/core";import{DefaultMap as ao,Room as co}from"@liveblocks/server";import{Database as uo}from"bun:sqlite";import{mkdirSync as Ze,mkdtempSync as lo,rmSync as mo}from"fs";import{tmpdir as fo}from"os";import{dirname as po,join as ge,resolve as We}from"path";import{asPos as Ye,CrdtType as $,nn as qt,nodeStreamToCompactNodes as Zt}from"@liveblocks/core";import{makeInMemorySnapshot as Qt,NestedMap as eo,plainLsonToNodeStream as to,quote as G}from"@liveblocks/server";import{Database as oo}from"bun:sqlite";function X(t){try{return t!==void 0?JSON.parse(t):void 0}catch{return}}function He(t){if(t>512)throw new Error("More than 512 params not supported");return new Array(t).fill("?").join(",")}function so(t){return Array.isArray(t)?t:Array.from(t)}function ro(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 Xe(t,e){let o=so(e),s=o.length;t.query(`DELETE FROM nodes WHERE node_id IN (${He(s)})`).run(...o)}function Ve(t){let e=new eo;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 no(t,e){let o=new Map(ro(t));o.has("root")||o.set("root",{type:$.OBJECT,data:{}});let s=new Set,i=["root"],a=new Map,d=Ve(o);for(;i.length>0;){let v=i.pop(),S=qt(o.get(v));if(S.type===$.OBJECT)for(let h of d.keysAt(v))Object.prototype.hasOwnProperty.call(S.data,h)&&(delete S.data[h],s.add(v),e.warn(`[integrity] Found data key ${G(h)} from ${G(v)} (conflicted with child node)`));if(S.type!==$.REGISTER)i.push(...d.valuesAt(v));else if(o.get(S.parentId)?.type===$.OBJECT)continue;a.set(v,S)}let c=new Set;for(let[v,S]of o)a.has(v)||(S.parentId!==void 0&&a.has(S.parentId)?a.get(S.parentId)?.type===$.REGISTER?e.warn(`[integrity] Found unreachable node ${G(v)} (child of live register)`):e.warn(`[integrity] Found conflicting sibling ${G(v)} (conflicted with ${G(d.get(S.parentId,S.parentKey))} at ${G(S.parentKey)})`):e.warn(`[integrity] Found orphan ${G(v)}`),c.add(v),s.delete(v));if(s.size>0||c.size>0){if(s.size>0){let v=new Map;for(let S of s){let h=a.get(S);h!==void 0&&v.set(S,h)}de(t,v)}c.size>0&&Xe(t,c)}let p=c.size===0?d:Ve(a);return{nodes:a,revNodes:p}}function Ke(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 oo(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}=no(o,e),a=u=>s.get(u),d=(u,m)=>i.get(u,m),c=(u,m)=>i.has(u,m);function p(u,m){let y;for(let _ of i.keysAt(u)){let C=Ye(_);C>m&&(y===void 0||C<y)&&(y=C)}return y}function v(u){let m;for(let y of i.keysAt(u)){let _=Ye(y);(m===void 0||_>m)&&(m=_)}return m}function S(u,m,y=!1){let _=a(m.parentId);if(_===void 0)throw new Error(`No such parent ${G(m.parentId)}`);if(m.type===$.REGISTER&&_.type===$.OBJECT)throw new Error("Cannot add register under object");let C=d(m.parentId,m.parentKey);if(C!==u){let T=Ke(_,m.parentKey);if(C!==void 0||T)if(y)R(m.parentId,m.parentKey);else throw new Error(`Key ${G(m.parentKey)} already exists`);i.set(m.parentId,m.parentKey,u)}s.set(u,m),de(o,[[u,m]])}function h(u,m){let y=a(u);if(y?.parentId===void 0)return;if(c(y.parentId,m))throw new Error(`Pos ${G(m)} already taken`);i.delete(y.parentId,y.parentKey);let _={...y,parentKey:m};s.set(u,_),i.set(y.parentId,m,u),de(o,[[u,_]])}function f(u,m,y=!1){let _=a(u);if(_?.type!==$.OBJECT)return;for(let T of Object.keys(m)){let D=d(u,T);if(D!==void 0)if(y)b(D);else throw new Error(`Child node already exists under ${T}`)}let C={..._,data:{..._.data,...m}};s.set(u,C),de(o,[[u,C]])}function b(u){let m=a(u);if(m?.parentId===void 0)return;i.delete(m.parentId,m.parentKey);let y=[],_=[u];for(;_.length>0;){let C=_.pop();_.push(...i.valuesAt(C)),s.delete(C),i.deleteAll(C),y.push(C)}Xe(o,y)}function R(u,m){let y=a(u);if(Ke(y,m)){let{[m]:C,...T}=y.data,D={...y,data:T};s.set(u,D),de(o,[[u,D]])}let _=d(u,m);_!==void 0&&b(_)}return{get_node:a,iter_nodes:()=>s.entries(),*iter_nodes_optimized(){for(let u of Zt(s.entries()))yield JSON.stringify(u)},has_node:u=>s.has(u),get_child_at:d,has_child_at:c,get_next_sibling:p,get_last_sibling:v,set_child:S,move_sibling:h,delete_node:b,delete_child_key:R,set_object_data:f,get_snapshot(u){return Qt(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 to(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,X(o)])}get_meta(e){let s=this.db.query("SELECT jval FROM metadata WHERE key = ?").get(e)?.jval;if(s!==void 0)return X(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 (${He(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: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),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[h,f]of Object.entries(a)){let b=typeof f=="boolean"?Number(f):f;d+=" AND json_extract(jmetadata, '$.' || ?) = ?",c.push(h,b)}if(s!==void 0&&(d+=" AND created_at >= ?",c.push(s)),i!==void 0)try{let h=JSON.parse(Buffer.from(i.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[f,b]=h;d+=" AND (created_at < ? OR (created_at = ? AND feed_id < ?))",c.push(b,b,f)}catch{}d+=" ORDER BY created_at DESC, feed_id DESC LIMIT ?",c.push(o+1);let p=this.db.query(d).all(...c),v;if(p.length>o){p.pop();let h=p[p.length-1];if(h){let f=[h.feed_id,h.created_at];v=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:v}}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 h=JSON.parse(Buffer.from(a.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf8")),[f,b]=h;d+=" AND (created_at < ? OR (created_at = ? AND message_id < ?))",c.push(b,b,f)}catch{}d+=" ORDER BY created_at DESC, message_id DESC LIMIT ?",c.push(s+1);let p=this.db.query(d).all(...c),v;if(p.length>s){p.pop();let h=p[p.length-1];if(h){let f=[h.message_id,h.created_at];v=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:v}}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 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 go=".liveblocks/v1",he=go,Qe=!1,W=null;function et(){return ge(he,"rooms")}function te(){if(W)return;let t=ge(he,"db.sql");Ze(po(t),{recursive:!0});let e=new uo(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 tt(t){let e=oe(),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 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 tt(e)}var ho="default";function ot(t,e){let o=oe(),s=io(),i=new Date().toISOString(),a=e?.organizationId??ho,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[p,v]of Object.entries(e.usersAccesses))o.run("INSERT INTO room_user_permissions (room_id, user_id, scopes) VALUES (?, ?, ?)",[t,p,JSON.stringify(v)]);if(e?.groupsAccesses)for(let[p,v]of Object.entries(e.groupsAccesses))o.run("INSERT INTO room_group_permissions (room_id, group_id, scopes) VALUES (?, ?, ?)",[t,p,JSON.stringify(v)]);return{id:t,internalId:s,organizationId:a,defaultAccesses:d,usersAccesses:e?.usersAccesses??{},groupsAccesses:e?.groupsAccesses??{},metadata:c,createdAt:i}}function vo(t,e){let o=oe(),s=ee(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 ee(t)}}function Eo(t){oe().run("DELETE FROM rooms WHERE room_id = ?",[t])}function st(t){let e=et(),o=We(e,`${t}.sql`);if(!o.startsWith(We(e)+"/"))throw new Error("Invalid internal ID");return o}var B=new ao(t=>{let e=ee(t)??ot(t);Ze(et(),{recursive:!0});let o=new pe(st(e.internalId));return new co(t,{storage:o})});function rt(){let t=lo(ge(fo(),"liveblocks-dev-"));return he=ge(t,"data"),Qe=!0,t}function w(t){return te(),ee(t)}function ve(t,e){te();let o=ee(t);if(o)return o;let s=ot(t,e);return B.getOrCreate(t),s}function nt(t){te();let e=oe(),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(tt)}function it(t,e){return te(),vo(t,e)}async function at(t){te();let e=ee(t),o=B.get(t);if(o&&(o.endSessionBy(()=>!0,qe.KICKED,"Deliberately disconnected"),o.unload(),o.driver.close(),B.delete(t)),e){let s=st(e.internalId);try{await Bun.write(s,""),await Bun.file(s).unlink()}catch{}Eo(t)}}function F(t){return te(),B.getOrCreate(t)}var Ce=null;function dt(t){Ce=t;for(let e of B.values())e.runInMaintenanceMode(()=>t).catch(()=>{});t.then(()=>{Ce=null})}function ct(t){if(Ce!==null)return!0;let e=B.get(t);return e!==void 0&&e.isInMaintenance}function ce(){let t=[];for(let[e,o]of B)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 ut(t,e){let o=B.get(t);return o?o.endSessionBy(s=>s.actor===e,qe.KICKED,"Deliberately disconnected")>0:!1}function lt(){for(let t of B.values())t.unload();B.clear()}function Le(){for(let t of B.values())t.unload(),t.driver.close();B.clear(),W&&(W.close(),W=null),Qe&&mo(he,{recursive:!0,force:!0})}import{nanoid as To,tryParseJson as pt}from"@liveblocks/core";import{array as vt,constant as ue,enum_ as yo,number as Et,object as ke,optional as Ne,record as _o,string as Ae,taggedUnion as bo}from"decoders";import{inexact as Io,optional as mt,string as ft}from"decoders";var se=Io({name:mt(ft),avatar:mt(ft)}).refineType();var q={RoomRead:"room:read",RoomWrite:"room:write",CommentsWrite:"comments:write",FeedsWrite:"feeds:write",RoomPresenceWrite:"room:presence:write",CommentsRead:"comments:read"};var So=ke({alg:ue("none")}),Ro=ke({k:ue("acc"),pid:ue("localdev"),uid:Ae,ui:Ne(se),perms:_o(vt(yo(q))),exp:Et}),Oo=ke({k:ue("id"),pid:ue("localdev"),uid:Ae,ui:Ne(se),gids:Ne(vt(Ae)),exp:Et}),wo=bo("k",{acc:Ro,id:Oo});function gt(t){return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ht(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+3600,jti:To(12)},s=gt(JSON.stringify({alg:"none",typ:"JWT"})),i=gt(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!==""||!So.value(pt(ht(o))))return null;let a=wo.value(pt(ht(s)));return!a||a.exp<Math.floor(Date.now()/1e3)?null:a}function Lo(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 xo(t,e){let o=w(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 No(t,e){return t.k==="acc"?Lo(t,e):xo(t,e)}function Tt(t){let e=new URL(t.url),o=e.pathname==="/v7"?It.V7:e.pathname==="/v8"?It.V8:null;if(o===null)return{ok:!1};let s=e.searchParams.get("roomId");if(!s)return{ok:!1};let i=e.searchParams.get("tok");if(i!==null){let d=Ee(i);if(!d)return{ok:!1};let c=No(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"}:(ve(s,{defaultAccesses:[q.RoomWrite]}),{ok:!0,roomId:s,ticketData:{version:o,anonymousId:Co(),scopes:[q.RoomWrite]}}):{ok:!1}}function Ao(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 yt(...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,Ao(s)}catch{return[]}}function ko(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 _t(t){let e=De.map(c=>c.pattern),o=[...new Set(De.map(c=>c.expected))],[s,i]=await Promise.all([yt(...e),yt(...o)]);if(s.length===0)return[];let a=new Set(i.map(c=>c.file)),d=[];for(let c of s){if(ko(c.text)||a.has(c.file))continue;let p=De.find(v=>c.text.includes(v.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 "+j("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 Po={"<LiveblocksProvider":"baseUrl={...}","createClient(":"baseUrl: ...","new Liveblocks(":"baseUrl: ..."};function bt(t,e){let o=t.map(({match:s,check:i})=>{let a=Po[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 Do}from"child_process";function St(t){let e=process.platform==="darwin"?"pbcopy":process.platform==="win32"?"clip.exe":"xclip -selection clipboard";Do(e,{input:t})}import jo from"bun";function Rt(t,e){let{promise:o,resolve:s}=Promise.withResolvers();return jo.connect({hostname:e,port:t,socket:{data(){},open(i){i.end(),s(!0)},error(){s(!1)},connectError(){s(!1)}}}),o}function je(t,e=!1){t&&console.log((e?ae:Q)(` \u26A0 ${t}`))}import{ZenRouter as Uo}from"@liveblocks/zenrouter";import{array as wt,enum_ as Bo,object as Ct,optional as Ue,record as Fo,string as Be}from"decoders";import{json as Mo}from"@liveblocks/zenrouter";import{json as Ot}from"@liveblocks/zenrouter";function Me(t,e,o){return Ot(t,e,{"X-LB-Warn":o})}function A(t,e,o="This is a dummy response."){return Me(t,e,o)}function r(t="This endpoint isn't implemented in the Liveblocks dev server."){return Ot({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 Mo({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 Jo=Bo(q),le=new Uo({authorize:({req:t})=>Ie(t)});le.route("POST /v2/authorize-user",Ct({userId:Be,userInfo:Ue(se),permissions:Fo(wt(Jo))}),({body:t})=>({token:Pe({k:"acc",pid:"localdev",uid:t.userId,perms:t.permissions,ui:t.userInfo})}));le.route("POST /v2/identify-user",Ct({userId:Be,userInfo:Ue(se),groupIds:Ue(wt(Be))}),({body:t})=>({token:Pe({k:"id",pid:"localdev",uid:t.userId,ui:t.userInfo,gids:t.groupIds})}));import{ZenRouter as Go}from"@liveblocks/zenrouter";var l=new Go({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",()=>A({threads:[],inboxNotifications:[],subscriptions:[],meta:{nextCursor:null,requestedAt:new Date().toISOString(),permissionHints:{}}}));l.route("GET /v2/c/threads/delta",()=>A({threads:[],inboxNotifications:[],subscriptions:[],meta:{requestedAt:new Date().toISOString(),permissionHints:{}}}));l.route("GET /v2/c/inbox-notifications",()=>A({inboxNotifications:[],threads:[],subscriptions:[],groups:[],meta:{nextCursor:null,requestedAt:new Date().toISOString()}}));l.route("GET /v2/c/inbox-notifications/count",()=>A({count:0}));l.route("GET /v2/c/inbox-notifications/delta",()=>A({inboxNotifications:[],threads:[],subscriptions:[],groups:[],deletedInboxNotifications:[],deletedThreads:[],deletedSubscriptions:[],meta:{requestedAt:new Date().toISOString()}}));l.route("GET /v2/c/rooms/<roomId>/threads",()=>A({data:[],inboxNotifications:[],subscriptions:[],meta:{nextCursor:null,requestedAt:new Date().toISOString(),permissionHints:{}}}));l.route("GET /v2/c/rooms/<roomId>/threads/delta",()=>A({data:[],inboxNotifications:[],subscriptions:[],deletedThreads:[],deletedInboxNotifications:[],deletedSubscriptions:[],meta:{requestedAt:new Date().toISOString(),permissionHints:{}}}));l.route("POST /v2/c/rooms/<roomId>/text-metadata",()=>A({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 xt,html as zo,json as Yo,ZenRouter as Vo}from"@liveblocks/zenrouter";var Lt=`<!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 re=new Vo({authorize:()=>!0});re.route("GET /v7",()=>xt(426));re.route("GET /v8",()=>xt(426));re.route("GET /health",()=>Yo({status:"ok"}));re.route("GET /",()=>zo(Lt.replace("__VERSION__","1.4.2-pre2")));import{ServerMsgCode as qo}from"@liveblocks/core";import{QueryParser as Zo}from"@liveblocks/query-parser";import{ConsoleTarget as Dt,jsonObjectYolo as Qo,Logger as jt,ROOT_YDOC_ID as Fe,snapshotToLossyJson_eager as es,snapshotToNodeStream as ts,snapshotToPlainLson_eager as Mt,transientClientMsgDecoder as os}from"@liveblocks/server";import{json as Te,ndjsonStream as ss,ZenRouter as rs}from"@liveblocks/zenrouter";import{array as K,constant as ns,either as is,enum_ as as,nullable as Pt,object as ye,optional as z,record as me,string as M}from"decoders";function*Ko(t){for(let e of t)for(let o of e)yield o}function Nt(...t){return Ko(t)}import{Base64 as ds}from"js-base64";import*as _e from"yjs";import*as x from"yjs";function Ho(t){return t.content instanceof x.ContentFormat||t.content instanceof x.ContentEmbed?"text":"arr"in t.content?"array":"str"in t.content?"text":"type"in t.content?"xml":"unknown"}function Xo(t){let e=[],o=t;for(;o!==null;){if(!o.deleted)if(o.content instanceof x.ContentType)e.push(o.content.type.toJSON());else if(o.content instanceof x.ContentString)e.push(o.content.str);else if(o.content instanceof x.ContentFormat){let{key:s,value:i}=o.content;e.push({key:s,value:i})}else o.content instanceof x.ContentEmbed&&e.push(o.content.embed);o=o.right}return e}function At(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=Ho(e._first);if(i==="text")return s?Xo(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 Wo={ytext:x.Text,yxmlfragment:x.XmlFragment,yxmltext:x.XmlText,ymap:x.Map,yarray:x.Array};function kt(t,e="",o=!1,s=""){let i={};if(e.length){if(t.share.has(e)){if(s.length){let a=Wo[s];if(a)return t.get(e,a).toJSON()}return{[e]:At(t,t.share.get(e),e,o)}}return{[e]:""}}for(let[a,d]of t.share)i[a]=At(t,d,a,o);return i}var Ut=(o=>(o.PlainLson="plain-lson",o.LossyJson="json",o))(Ut||{}),cs=as(Ut),Bt=me(M,is(M,K(M))),n=new rs({authorize:({req:t})=>Ie(t)});function N(t){return Te({error:"ROOM_NOT_FOUND",message:`Room with id "${t}" not found.`},404)}var us=new Zo({fields:{roomId:"string"},indexableFields:{metadata:"token"}});function ls(t){let e=us.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 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=w(t.roomId);if(!e)throw N(t.roomId);return be(e)});n.route("GET /v2/rooms",({url:t})=>{let e,o=t.searchParams.get("query");if(o)try{e=ls(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 s=t.searchParams.get("organizationId")??void 0;return s&&(e={...e,organizationId:s}),{data:nt(e).map(be),nextPage:null,nextCursor:null}});n.route("POST /v2/rooms",ye({id:M,organizationId:z(M),defaultAccesses:z(K(M)),metadata:z(Bt),usersAccesses:z(me(M,K(M))),groupsAccesses:z(me(M,K(M)))}),({body:t,url:e})=>{if(!e.searchParams.has("idempotent")&&w(t.id))return Te({error:"ROOM_ALREADY_EXISTS",message:`Room with id "${t.id}" already exists.`},409);let s=ve(t.id,{organizationId:t.organizationId,defaultAccesses:t.defaultAccesses,metadata:t.metadata,usersAccesses:t.usersAccesses,groupsAccesses:t.groupsAccesses});return be(s)});n.route("POST /v2/rooms/<roomId>",ye({defaultAccesses:z(K(M)),metadata:z(Bt),usersAccesses:z(me(M,Pt(K(M)))),groupsAccesses:z(me(M,Pt(K(M))))}),({p:t,body:e})=>{let o=it(t.roomId,{defaultAccesses:e.defaultAccesses,metadata:e.metadata,usersAccesses:e.usersAccesses,groupsAccesses:e.groupsAccesses});if(!o)throw N(t.roomId);return be(o)});n.route("DELETE /v2/rooms/<roomId>",async({p:t})=>(await at(t.roomId),new Response(null,{status:204})));n.route("GET /v2/rooms/<roomId>/storage",async({url:t,p:e})=>{if(!w(e.roomId))throw N(e.roomId);let o=cs.value(t.searchParams.get("format"))??"plain-lson",s=F(e.roomId);await s.load();let i=s.storage.loadedDriver.get_snapshot(!1),a=o==="json"?es(i):Mt(i);return new Response(JSON.stringify(a),{status:200,headers:{"Content-Type":"application/json"}})});n.route("POST /v2/rooms/<roomId>/storage",ye({liveblocksType:ns("LiveObject"),data:Qo}).refineType(),async({p:t,body:e})=>{if(!w(t.roomId))throw N(t.roomId);let o=F(t.roomId);await o.load();let s=o.storage.loadedDriver.get_snapshot(!1),i=Mt(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(!w(t.roomId))throw N(t.roomId);let e=F(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(!w(e.roomId))throw N(e.roomId);let o=F(e.roomId);await o.load();let s=t.searchParams.get("key")??"",i=t.searchParams.get("type")??"",a=t.searchParams.get("guid")??Fe,d=t.searchParams.get("formatting")!==null,c=new jt(new Dt("warning")),p=await o.yjsStorage.getYDoc(c,a),v=kt(p,s,d,i);return new Response(JSON.stringify(v),{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(!w(o.roomId))throw N(o.roomId);let s=F(o.roomId);await s.load();let i=await t.arrayBuffer(),a=ds.fromUint8Array(new Uint8Array(i)),d=e.searchParams.get("guid"),p=e.searchParams.get("encoder")==="v2",v=d&&d!==Fe?d:void 0;try{let S=await s.mutex.runExclusive(()=>s.yjsStorage.addYDocUpdate({},a,v,p)),h=f=>{};return s.sendToAll({type:qo.UPDATE_YDOC,update:a,isSync:!1,stateVector:null,guid:v,v2:p,remoteSnapshotHash:S.snapshotHash},void 0,h),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(!w(e.roomId))throw N(e.roomId);let o=F(e.roomId);await o.load();let s=t.searchParams.get("guid")??Fe,i=t.searchParams.get("encoder"),a=new jt(new Dt("warning")),d=await o.yjsStorage.getYDoc(a,s),c=i==="v2"?_e.encodeStateAsUpdateV2(d):_e.encodeStateAsUpdate(d);return new Response(c,{status:200,headers:{"Content-Type":"application/octet-stream"}})});n.route("GET /v2/rooms/<roomId>/active_users",({p:t})=>{if(!w(t.roomId))throw N(t.roomId);let o=F(t.roomId).listSessions().map(s=>({type:"user",connectionId:s.actor,id:s.user.id,info:s.user.info}));return Te({data:o})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!w(t.roomId))throw N(t.roomId);return A({ok:!0})});n.route("DELETE /v2/rooms/<roomId>/feeds/<feedId>/messages/<messageId>",({p:t})=>{if(!w(t.roomId))throw N(t.roomId);return A({ok:!0})});n.route("GET /v2/rooms/<roomId>/feeds",({p:t})=>{if(!w(t.roomId))throw N(t.roomId);return A({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(!w(t.roomId))throw N(t.roomId);return A({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(!w(t.roomId))throw N(t.roomId);return A({messages:[{messageId:"123",data:{content:"This is a test message"}}],nextCursor:null})});n.route("PATCH /v2/rooms/<roomId>/feeds/<feedId>",({p:t})=>{if(!w(t.roomId))throw N(t.roomId);let e=Date.now();return A({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(!w(t.roomId))throw N(t.roomId);let e=Date.now();return A({id:t.messageId,createdAt:e,updatedAt:e,data:{content:"This is a test message"}})});n.route("POST /v2/rooms/<roomId>/feeds",({p:t})=>{if(!w(t.roomId))throw N(t.roomId);return A({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(!w(t.roomId))throw N(t.roomId);return A({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(!w(t.roomId))throw N(t.roomId);let e=F(t.roomId);await e.load();let o=await e.driver.next_actor(),s=e.storage.loadedDriver.get_snapshot(!1);return ss(Nt([{actor:o}],ts(s)))});n.route("POST /v2/rooms/<roomId>/send-message",ye({messages:K(os)}),async({p:t,body:e})=>{if(!w(t.roomId))throw N(t.roomId);let o=F(t.roomId);await o.load();let[s,i]=await o.createBackendSession_experimental();return await o.processClientMsgFromBackendSession(s,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",()=>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 Gt(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 ne=new fs;ne.relay("/v2/authorize-user/*",le);ne.relay("/v2/identify-user/*",le);ne.relay("/v2/c/*",l);ne.relay("/v2/*",n);ne.relay("/*",re);var Ge=1153;function $t(t){if(t===void 0)return;let e=Number(t);return Number.isInteger(e)&&e>0&&e<=65535?e:void 0}function gs(t){return process.platform==="win32"?[process.env.COMSPEC||"cmd.exe","/c",t]:["sh","-c",t]}function hs(t){return"'"+t.replace(/'/g,"'\\''")+"'"}var vs={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(hs).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 s=!1;e.ci&&(s=!0,e["no-check"]=!0),e.cmd&&(s=!0,e["no-check"]=!0);let i=$t(e.port)??$t(process.env.LIVEBLOCKS_DEVSERVER_PORT)??Ge,a=e.host||process.env.LIVEBLOCKS_DEVSERVER_HOST||"localhost",d=s?rt():null;await Rt(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 v(){return Je.serve({hostname:a,port:i,async fetch(f,b){if(f.headers.get("Upgrade")==="websocket"){let T=Tt(f);if(!T.ok)return je(T.xwarn,!0),Gt(b,f,Jt.NOT_ALLOWED,"You have no access to this room");let{roomId:D,ticketData:Z}=T;if(ct(D))return Gt(b,f,Jt.TRY_AGAIN_LATER,"Server is undergoing maintenance, try again later");let k=F(D);await k.load();let P=await k.createTicket(Z),Y=P.sessionKey;if(b.upgrade(f,{data:{room:k,ticket:P,sessionKey:Y}})){console.log(`${J("101")} WS ${new URL(f.url).pathname}${g(` - ${D}`)}`);return}return new Response("Could not upgrade to WebSocket",{status:426})}let R=new URL(f.url);if(f.method==="POST"&&R.pathname==="/crash")return console.log(`${J("204")} POST /crash`),setTimeout(()=>{S()},0),new Response(null,{status:204});let L=`${f.method} ${R.pathname}`,u;if(p)try{u=await f.clone().text()}catch{}let m=await ne.fetch(f),y=m.status,_=y>=500?ae(y):y>=400?Q(y):J(y);console.log(`${_} ${L}`);let C=m.headers.get("X-LB-Warn")??void 0;if(je(C,!m.ok),p){if(u){let Z=Ft(u);Z!==void 0&&console.log(g(` \u2192 ${JSON.stringify(Z)}`))}let T=await m.clone().text(),D=Ft(T);D!==void 0&&console.log(g(` \u2190 ${JSON.stringify(D)}`))}return m},error(f){return console.error(f),new Response("An unknown error occurred",{status:500})},websocket:{async open(f){let{refuseConnection:b,room:R,ticket:L}=f.data;if(b){f.close(b.code,b.message);return}R&&L&&await R.startBrowserSession(L,f)},async message(f,b){let{room:R,sessionKey:L}=f.data;R&&L&&await R.handleData(L,b)},close(f,b,R){let{room:L,sessionKey:u}=f.data;L&&u&&L.endBrowserSession(u,b,R)}}})}c=v();async function S(){lt(),await c.stop(!0),c=v(),console.log("Crash \u{1F4A5}")}let h=f=>process.stderr.write(f+`
|
|
399
|
-
`);if(e.cmd){h(`Liveblocks dev server ${g("v1.4.2-pre2")} running at http://${c.hostname}:${c.port}`),d&&e.verbose&&h(g(`Ephemeral mode, using ${d}`));let f=ps(d,"server.log");h(g(`Server logs: ${f}`));let b=Je.file(f).writer(),R=(...u)=>{b.write(u.map(String).join(" ")+`
|
|
400
|
-
`),b.flush()};console.log=R,console.error=R;let L=1;try{let u=Je.spawn(gs(e.cmd),{stdin:"inherit",stdout:"inherit",stderr:"inherit",env:{...process.env,LIVEBLOCKS_DEV_SERVER_HOST:a,LIVEBLOCKS_DEV_SERVER_PORT:String(i)}}),m=()=>{u.kill()};process.on("SIGTERM",m),process.on("SIGINT",m),L=await u.exited}finally{b.end(),await c.stop(),Le(),h(g("Liveblocks dev server shut down"))}process.exit(L)}else{let f=`http://${a}:${i}`,b=e["no-check"]?[]:await _t(f),R="logs",L=null,u=null,m=null,y=`http://${c.hostname}:${c.port}`,_=()=>{let O=R==="logs"?j(" Logs "):g(" Logs "),I=R==="sockets"?j(" Sockets "):g(" Sockets "),E=O+g("|")+I,ie=(u?V("\u23F8 maintenance")+" ":"")+g(`Liveblocks running at ${y}`),Re=process.stdout.columns??80,Oe=Math.max(1,Re-we(E).length-we(ie).length);return E+" ".repeat(Oe)+ie},C=[],T=console.log.bind(console);console.log=(...O)=>{let I=O.map(String).join(" ");C.push(I),R==="logs"&&T(I)};let D=()=>g(" ")+j("q")+g(" quit, ")+j("!")+g(" crash, ")+j("c")+g(" clear, ")+j("v")+g(p?" verbose (on)":" verbose"),Z=()=>{m&&(clearInterval(m),m=null),R="logs",process.stdout.write("\x1B[2J\x1B[H"),T(_()),T(D()),T();for(let O of C)T(O)},k=0,P=[],Y=O=>`${O.roomId}:${O.actor}`,Se=()=>{P=ce().map(O=>({...O,alive:!0}))},zt=()=>{let O=new Set(ce().map(Y));for(let E of P)E.alive=O.has(Y(E));let I=new Set(P.map(Y));for(let E of ce())I.has(Y(E))||P.push({...E,alive:!0})},Yt=O=>{let I=Date.now()-O,E=Math.floor(I/1e3);if(E<60)return`${E}s`;let U=Math.floor(E/60);return U<60?`${U}m`:`${Math.floor(U/60)}h`},Vt=O=>{if(!O)return"";let I=Date.now()-O;return I<1e3?" "+J("\u25CF"):I<3e3?" "+g(J("\u25CF")):I<5e3?" "+g("\u25CF"):""},fe=(O,I)=>{let E=O+I;for(;E>=0&&E<P.length;){if(P[E].alive)return E;E+=I}return O},H=()=>{zt();let O=P.filter(E=>E.alive).length;if(process.stdout.write("\x1B[2J\x1B[H"),T(_()),T(g(" ")+j("\u2191\u2193")+g(" navigate, ")+j("k")+g(" kill, ")+j("m")+g(u?" maintenance off, ":" maintenance on, ")+j("r")+g(" refresh")),T(),T(" "+j("Connections")+g(` (${O} alive)`)),T(),P.length===0){T(g(" No active connections"));return}if(k>=P.length&&(k=P.length-1),!P[k]?.alive){let E=fe(k,-1);k=P[E]?.alive?E:fe(k,1)}let I=new Map;for(let E of ce())I.set(Y(E),E.lastActiveAt);for(let E=0;E<P.length;E++){let U=P[E];if(!U.alive){T(g(` ${U.roomId} \xB7 actor=${U.actor} \xB7 disconnected`));continue}let ie=E===k?J("\u25B6 "):" ",Re=U.userId??g("anonymous"),Oe=Yt(U.connectedAt),Xt=I.get(Y(U)),Wt=Vt(Xt);T(`${ie}${j(U.roomId)} ${g("\xB7")} actor=${U.actor} ${g("\xB7")} ${Re} ${g("\xB7")} ${g(Oe)}${Wt}`)}},Kt=()=>{R="sockets",k=0,Se(),H(),m=setInterval(()=>H(),1e3)},Ht=()=>{if(u)u(),u=null;else{let{promise:O,resolve:I}=ms();dt(O),u=I}};process.stdout.write("\x1B[2J\x1B[H"),T(_()),T(D()),T(),d&&e.verbose&&console.log(g(`Ephemeral mode, using ${d}`)),process.stdin.setRawMode?.(!0),process.stdin.resume(),process.stdin.on("data",O=>{let I=O.toString();if(I===""||I==="q"){c.stop(!0).then(()=>{Le(),process.exit(0)});return}if(I==="m"){Ht(),R==="sockets"?H():(process.stdout.write("\x1B[s\x1B[H\x1B[2K"),T(_()),process.stdout.write("\x1B[u"));return}if((I==="s"||I==="\x1B[C")&&R!=="sockets"){Kt();return}if((I==="l"||I==="\x1B[D")&&R!=="logs"){Z();return}if(R==="sockets"){if(I==="\x1B[A")k=fe(k,-1),H();else if(I==="\x1B[B")k=fe(k,1),H();else if(I==="k"){let E=P[k];E?.alive&&(ut(E.roomId,E.actor),H())}else I==="r"&&(Se(),k=0,H());return}if(I==="!")L!==null?(clearTimeout(L),L=null,S()):(console.log("Simulating crash in 2.5s... (press ! again to crash now)"),L=setTimeout(()=>{L=null,S()},2500));else if(I==="c")C.length=0,process.stdout.write("\x1B[2J\x1B[H"),T(_()),T(D()),T();else if(I==="v")p=!p,process.stdout.write("\x1B[s\x1B[H\x1B[2K"),T(_()),process.stdout.write("\x1B[2K"),T(D()),process.stdout.write("\x1B[u"),console.log(g(p?"Verbose mode on":"Verbose mode off"));else if(I==="p")if(b.length>0){let E=bt(b,f);St(E),console.log(g("Copied AI fix prompt to clipboard"))}else console.log(g("No setup issues detected"))})}}},zr=vs;export{zr as default};
|
|
401
|
-
/*! Bundled license information:
|
|
402
|
-
|
|
403
|
-
itertools/dist/index.js:
|
|
404
|
-
(* istanbul ignore else -- @preserve *)
|
|
405
|
-
(* istanbul ignore if -- @preserve *)
|
|
406
|
-
*/
|