@liveblocks/core 3.20.0-exp6 → 3.20.0-perm2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
 
7
7
  // src/version.ts
8
8
  var PKG_NAME = "@liveblocks/core";
9
- var PKG_VERSION = "3.20.0-exp6";
9
+ var PKG_VERSION = "3.20.0-perm2";
10
10
  var PKG_FORMAT = "esm";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -1570,7 +1570,6 @@ function isUrl(string) {
1570
1570
  function createApiClient({
1571
1571
  baseUrl,
1572
1572
  authManager,
1573
- currentUserId,
1574
1573
  fetchPolyfill
1575
1574
  }) {
1576
1575
  const httpClient = new HttpClient(baseUrl, fetchPolyfill);
@@ -1578,8 +1577,9 @@ function createApiClient({
1578
1577
  const result = await httpClient.get(
1579
1578
  url`/v2/c/rooms/${options.roomId}/threads/delta`,
1580
1579
  await authManager.getAuthValue({
1581
- requestedScope: "comments:read",
1582
- roomId: options.roomId
1580
+ roomId: options.roomId,
1581
+ resource: "comments",
1582
+ access: "read"
1583
1583
  }),
1584
1584
  {
1585
1585
  since: options.since.toISOString()
@@ -1617,8 +1617,9 @@ function createApiClient({
1617
1617
  const result = await httpClient.get(
1618
1618
  url`/v2/c/rooms/${options.roomId}/threads`,
1619
1619
  await authManager.getAuthValue({
1620
- requestedScope: "comments:read",
1621
- roomId: options.roomId
1620
+ roomId: options.roomId,
1621
+ resource: "comments",
1622
+ access: "read"
1622
1623
  }),
1623
1624
  {
1624
1625
  cursor: options.cursor,
@@ -1662,8 +1663,9 @@ function createApiClient({
1662
1663
  const result = await httpClient.get(
1663
1664
  url`/v2/c/rooms/${options.roomId}/threads/comments/search`,
1664
1665
  await authManager.getAuthValue({
1665
- requestedScope: "comments:read",
1666
- roomId: options.roomId
1666
+ roomId: options.roomId,
1667
+ resource: "comments",
1668
+ access: "read"
1667
1669
  }),
1668
1670
  {
1669
1671
  text: options.query.text,
@@ -1684,8 +1686,9 @@ function createApiClient({
1684
1686
  const thread = await httpClient.post(
1685
1687
  url`/v2/c/rooms/${options.roomId}/threads`,
1686
1688
  await authManager.getAuthValue({
1687
- requestedScope: "comments:read",
1688
- roomId: options.roomId
1689
+ roomId: options.roomId,
1690
+ resource: "comments",
1691
+ access: "write"
1689
1692
  }),
1690
1693
  {
1691
1694
  id: threadId,
@@ -1704,8 +1707,9 @@ function createApiClient({
1704
1707
  await httpClient.delete(
1705
1708
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}`,
1706
1709
  await authManager.getAuthValue({
1707
- requestedScope: "comments:read",
1708
- roomId: options.roomId
1710
+ roomId: options.roomId,
1711
+ resource: "comments",
1712
+ access: "write"
1709
1713
  })
1710
1714
  );
1711
1715
  }
@@ -1713,8 +1717,9 @@ function createApiClient({
1713
1717
  const response = await httpClient.rawGet(
1714
1718
  url`/v2/c/rooms/${options.roomId}/thread-with-notification/${options.threadId}`,
1715
1719
  await authManager.getAuthValue({
1716
- requestedScope: "comments:read",
1717
- roomId: options.roomId
1720
+ roomId: options.roomId,
1721
+ resource: "comments",
1722
+ access: "read"
1718
1723
  })
1719
1724
  );
1720
1725
  if (response.ok) {
@@ -1740,8 +1745,9 @@ function createApiClient({
1740
1745
  return await httpClient.post(
1741
1746
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/metadata`,
1742
1747
  await authManager.getAuthValue({
1743
- requestedScope: "comments:read",
1744
- roomId: options.roomId
1748
+ roomId: options.roomId,
1749
+ resource: "comments",
1750
+ access: "write"
1745
1751
  }),
1746
1752
  options.metadata
1747
1753
  );
@@ -1750,8 +1756,9 @@ function createApiClient({
1750
1756
  return await httpClient.post(
1751
1757
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/metadata`,
1752
1758
  await authManager.getAuthValue({
1753
- requestedScope: "comments:read",
1754
- roomId: options.roomId
1759
+ roomId: options.roomId,
1760
+ resource: "comments",
1761
+ access: "write"
1755
1762
  }),
1756
1763
  options.metadata
1757
1764
  );
@@ -1761,8 +1768,9 @@ function createApiClient({
1761
1768
  const comment = await httpClient.post(
1762
1769
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments`,
1763
1770
  await authManager.getAuthValue({
1764
- requestedScope: "comments:read",
1765
- roomId: options.roomId
1771
+ roomId: options.roomId,
1772
+ resource: "comments",
1773
+ access: "write"
1766
1774
  }),
1767
1775
  {
1768
1776
  id: commentId,
@@ -1777,8 +1785,9 @@ function createApiClient({
1777
1785
  const comment = await httpClient.post(
1778
1786
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}`,
1779
1787
  await authManager.getAuthValue({
1780
- requestedScope: "comments:read",
1781
- roomId: options.roomId
1788
+ roomId: options.roomId,
1789
+ resource: "comments",
1790
+ access: "write"
1782
1791
  }),
1783
1792
  {
1784
1793
  body: options.body,
@@ -1792,8 +1801,9 @@ function createApiClient({
1792
1801
  await httpClient.delete(
1793
1802
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}`,
1794
1803
  await authManager.getAuthValue({
1795
- requestedScope: "comments:read",
1796
- roomId: options.roomId
1804
+ roomId: options.roomId,
1805
+ resource: "comments",
1806
+ access: "write"
1797
1807
  })
1798
1808
  );
1799
1809
  }
@@ -1801,8 +1811,9 @@ function createApiClient({
1801
1811
  const reaction = await httpClient.post(
1802
1812
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/reactions`,
1803
1813
  await authManager.getAuthValue({
1804
- requestedScope: "comments:read",
1805
- roomId: options.roomId
1814
+ roomId: options.roomId,
1815
+ resource: "comments",
1816
+ access: "write"
1806
1817
  }),
1807
1818
  { emoji: options.emoji }
1808
1819
  );
@@ -1812,8 +1823,9 @@ function createApiClient({
1812
1823
  await httpClient.delete(
1813
1824
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/reactions/${options.emoji}`,
1814
1825
  await authManager.getAuthValue({
1815
- requestedScope: "comments:read",
1816
- roomId: options.roomId
1826
+ roomId: options.roomId,
1827
+ resource: "comments",
1828
+ access: "write"
1817
1829
  })
1818
1830
  );
1819
1831
  }
@@ -1821,8 +1833,9 @@ function createApiClient({
1821
1833
  await httpClient.post(
1822
1834
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/mark-as-resolved`,
1823
1835
  await authManager.getAuthValue({
1824
- requestedScope: "comments:read",
1825
- roomId: options.roomId
1836
+ roomId: options.roomId,
1837
+ resource: "comments",
1838
+ access: "write"
1826
1839
  })
1827
1840
  );
1828
1841
  }
@@ -1830,8 +1843,9 @@ function createApiClient({
1830
1843
  await httpClient.post(
1831
1844
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/mark-as-unresolved`,
1832
1845
  await authManager.getAuthValue({
1833
- requestedScope: "comments:read",
1834
- roomId: options.roomId
1846
+ roomId: options.roomId,
1847
+ resource: "comments",
1848
+ access: "write"
1835
1849
  })
1836
1850
  );
1837
1851
  }
@@ -1839,8 +1853,9 @@ function createApiClient({
1839
1853
  const subscription = await httpClient.post(
1840
1854
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/subscribe`,
1841
1855
  await authManager.getAuthValue({
1842
- requestedScope: "comments:read",
1843
- roomId: options.roomId
1856
+ roomId: options.roomId,
1857
+ resource: "comments",
1858
+ access: "read"
1844
1859
  })
1845
1860
  );
1846
1861
  return convertToSubscriptionData(subscription);
@@ -1849,8 +1864,9 @@ function createApiClient({
1849
1864
  await httpClient.post(
1850
1865
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/unsubscribe`,
1851
1866
  await authManager.getAuthValue({
1852
- requestedScope: "comments:read",
1853
- roomId: options.roomId
1867
+ roomId: options.roomId,
1868
+ resource: "comments",
1869
+ access: "read"
1854
1870
  })
1855
1871
  );
1856
1872
  }
@@ -1906,8 +1922,9 @@ function createApiClient({
1906
1922
  async () => httpClient.putBlob(
1907
1923
  url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/upload/${encodeURIComponent(attachment.name)}`,
1908
1924
  await authManager.getAuthValue({
1909
- requestedScope: "comments:read",
1910
- roomId
1925
+ roomId,
1926
+ resource: "comments",
1927
+ access: "write"
1911
1928
  }),
1912
1929
  attachment.file,
1913
1930
  { fileSize: attachment.size },
@@ -1924,8 +1941,9 @@ function createApiClient({
1924
1941
  async () => httpClient.post(
1925
1942
  url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${encodeURIComponent(attachment.name)}`,
1926
1943
  await authManager.getAuthValue({
1927
- requestedScope: "comments:read",
1928
- roomId
1944
+ roomId,
1945
+ resource: "comments",
1946
+ access: "write"
1929
1947
  }),
1930
1948
  void 0,
1931
1949
  { signal: abortSignal },
@@ -1950,8 +1968,9 @@ function createApiClient({
1950
1968
  async () => httpClient.putBlob(
1951
1969
  url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${createMultiPartUpload.uploadId}/${String(partNumber)}`,
1952
1970
  await authManager.getAuthValue({
1953
- requestedScope: "comments:read",
1954
- roomId
1971
+ roomId,
1972
+ resource: "comments",
1973
+ access: "write"
1955
1974
  }),
1956
1975
  part,
1957
1976
  void 0,
@@ -1974,8 +1993,9 @@ function createApiClient({
1974
1993
  return httpClient.post(
1975
1994
  url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${uploadId}/complete`,
1976
1995
  await authManager.getAuthValue({
1977
- requestedScope: "comments:read",
1978
- roomId
1996
+ roomId,
1997
+ resource: "comments",
1998
+ access: "write"
1979
1999
  }),
1980
2000
  { parts: sortedUploadedParts },
1981
2001
  { signal: abortSignal }
@@ -1986,8 +2006,9 @@ function createApiClient({
1986
2006
  await httpClient.rawDelete(
1987
2007
  url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${uploadId}`,
1988
2008
  await authManager.getAuthValue({
1989
- requestedScope: "comments:read",
1990
- roomId
2009
+ roomId,
2010
+ resource: "comments",
2011
+ access: "write"
1991
2012
  })
1992
2013
  );
1993
2014
  } catch {
@@ -2004,8 +2025,9 @@ function createApiClient({
2004
2025
  const { urls } = await httpClient.post(
2005
2026
  url`/v2/c/rooms/${roomId}/attachments/presigned-urls`,
2006
2027
  await authManager.getAuthValue({
2007
- requestedScope: "comments:read",
2008
- roomId
2028
+ roomId,
2029
+ resource: "comments",
2030
+ access: "read"
2009
2031
  }),
2010
2032
  { attachmentIds }
2011
2033
  );
@@ -2024,109 +2046,13 @@ function createApiClient({
2024
2046
  const batch2 = getOrCreateAttachmentUrlsStore(options.roomId).batch;
2025
2047
  return batch2.get(options.attachmentId);
2026
2048
  }
2027
- async function uploadChatAttachment(options) {
2028
- const { chatId, attachment, signal } = options;
2029
- const userId = currentUserId.get();
2030
- if (userId === void 0) {
2031
- throw new Error("Attachment upload requires an authenticated user.");
2032
- }
2033
- const ATTACHMENT_PART_SIZE = 5 * 1024 * 1024;
2034
- if (options.attachment.file.size <= ATTACHMENT_PART_SIZE) {
2035
- await httpClient.putBlob(
2036
- url`/v2/c/chats/${chatId}/attachments/${attachment.id}/upload/${encodeURIComponent(attachment.file.name)}`,
2037
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2038
- attachment.file,
2039
- { fileSize: attachment.file.size },
2040
- { signal }
2041
- );
2042
- } else {
2043
- const multipartUpload = await httpClient.post(
2044
- url`/v2/c/chats/${chatId}/attachments/${attachment.id}/multipart/${encodeURIComponent(attachment.file.name)}`,
2045
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2046
- void 0,
2047
- { signal },
2048
- { fileSize: attachment.file.size }
2049
- );
2050
- try {
2051
- const uploadedParts = [];
2052
- const parts = [];
2053
- let start = 0;
2054
- while (start < attachment.file.size) {
2055
- const end = Math.min(
2056
- start + ATTACHMENT_PART_SIZE,
2057
- attachment.file.size
2058
- );
2059
- parts.push({
2060
- number: parts.length + 1,
2061
- part: attachment.file.slice(start, end)
2062
- });
2063
- start = end;
2064
- }
2065
- uploadedParts.push(
2066
- ...await Promise.all(
2067
- parts.map(async ({ number, part }) => {
2068
- return await httpClient.putBlob(
2069
- url`/v2/c/chats/${chatId}/attachments/${attachment.id}/multipart/${multipartUpload.uploadId}/${String(number)}`,
2070
- await authManager.getAuthValue({
2071
- requestedScope: "comments:read"
2072
- }),
2073
- part,
2074
- void 0,
2075
- { signal }
2076
- );
2077
- })
2078
- )
2079
- );
2080
- await httpClient.post(
2081
- url`/v2/c/chats/${chatId}/attachments/${attachment.id}/multipart/${multipartUpload.uploadId}/complete`,
2082
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2083
- { parts: uploadedParts.sort((a, b) => a.number - b.number) },
2084
- { signal }
2085
- );
2086
- } catch (err) {
2087
- try {
2088
- await httpClient.delete(
2089
- url`/v2/c/chats/${chatId}/attachments/${attachment.id}/multipart/${multipartUpload.uploadId}`,
2090
- await authManager.getAuthValue({ requestedScope: "comments:read" })
2091
- );
2092
- } catch {
2093
- }
2094
- throw err;
2095
- }
2096
- }
2097
- }
2098
- const attachmentUrlsBatchStoresByChat = new DefaultMap((chatId) => {
2099
- const batch2 = new Batch(
2100
- async (batchedAttachmentIds) => {
2101
- const attachmentIds = batchedAttachmentIds.flat();
2102
- const { urls } = await httpClient.post(
2103
- url`/v2/c/chats/${chatId}/attachments/presigned-urls`,
2104
- await authManager.getAuthValue({
2105
- requestedScope: "comments:read"
2106
- }),
2107
- { attachmentIds }
2108
- );
2109
- return urls.map(
2110
- (url2) => url2 ?? new Error("There was an error while getting this attachment's URL")
2111
- );
2112
- },
2113
- { delay: 50 }
2114
- );
2115
- return createBatchStore(batch2);
2116
- });
2117
- function getOrCreateChatAttachmentUrlsStore(chatId) {
2118
- return attachmentUrlsBatchStoresByChat.getOrCreate(chatId);
2119
- }
2120
- function getChatAttachmentUrl(options) {
2121
- const batch2 = getOrCreateChatAttachmentUrlsStore(options.chatId).batch;
2122
- return batch2.get(options.attachmentId);
2123
- }
2124
2049
  async function getSubscriptionSettings(options) {
2125
2050
  return httpClient.get(
2126
2051
  url`/v2/c/rooms/${options.roomId}/subscription-settings`,
2127
2052
  await authManager.getAuthValue({
2128
- requestedScope: "comments:read",
2129
- roomId: options.roomId
2053
+ roomId: options.roomId,
2054
+ resource: "comments",
2055
+ access: "read"
2130
2056
  }),
2131
2057
  void 0,
2132
2058
  {
@@ -2138,8 +2064,9 @@ function createApiClient({
2138
2064
  return httpClient.post(
2139
2065
  url`/v2/c/rooms/${options.roomId}/subscription-settings`,
2140
2066
  await authManager.getAuthValue({
2141
- requestedScope: "comments:read",
2142
- roomId: options.roomId
2067
+ roomId: options.roomId,
2068
+ resource: "comments",
2069
+ access: "read"
2143
2070
  }),
2144
2071
  options.settings
2145
2072
  );
@@ -2151,8 +2078,9 @@ function createApiClient({
2151
2078
  await httpClient.post(
2152
2079
  url`/v2/c/rooms/${roomId}/inbox-notifications/read`,
2153
2080
  await authManager.getAuthValue({
2154
- requestedScope: "comments:read",
2155
- roomId
2081
+ roomId,
2082
+ resource: "comments",
2083
+ access: "read"
2156
2084
  }),
2157
2085
  { inboxNotificationIds }
2158
2086
  );
@@ -2172,8 +2100,9 @@ function createApiClient({
2172
2100
  await httpClient.rawPost(
2173
2101
  url`/v2/c/rooms/${options.roomId}/text-mentions`,
2174
2102
  await authManager.getAuthValue({
2175
- requestedScope: "comments:read",
2176
- roomId: options.roomId
2103
+ roomId: options.roomId,
2104
+ resource: "storage",
2105
+ access: "write"
2177
2106
  }),
2178
2107
  {
2179
2108
  userId: options.mention.kind === "user" ? options.mention.id : void 0,
@@ -2187,8 +2116,9 @@ function createApiClient({
2187
2116
  await httpClient.rawDelete(
2188
2117
  url`/v2/c/rooms/${options.roomId}/text-mentions/${options.mentionId}`,
2189
2118
  await authManager.getAuthValue({
2190
- requestedScope: "comments:read",
2191
- roomId: options.roomId
2119
+ roomId: options.roomId,
2120
+ resource: "storage",
2121
+ access: "write"
2192
2122
  })
2193
2123
  );
2194
2124
  }
@@ -2196,8 +2126,9 @@ function createApiClient({
2196
2126
  return httpClient.rawGet(
2197
2127
  url`/v2/c/rooms/${options.roomId}/y-version/${options.versionId}`,
2198
2128
  await authManager.getAuthValue({
2199
- requestedScope: "comments:read",
2200
- roomId: options.roomId
2129
+ roomId: options.roomId,
2130
+ resource: "storage",
2131
+ access: "read"
2201
2132
  })
2202
2133
  );
2203
2134
  }
@@ -2205,8 +2136,9 @@ function createApiClient({
2205
2136
  await httpClient.rawPost(
2206
2137
  url`/v2/c/rooms/${options.roomId}/version`,
2207
2138
  await authManager.getAuthValue({
2208
- requestedScope: "comments:read",
2209
- roomId: options.roomId
2139
+ roomId: options.roomId,
2140
+ resource: "storage",
2141
+ access: "write"
2210
2142
  })
2211
2143
  );
2212
2144
  }
@@ -2214,8 +2146,9 @@ function createApiClient({
2214
2146
  await httpClient.rawPost(
2215
2147
  url`/v2/c/rooms/${options.roomId}/text-metadata`,
2216
2148
  await authManager.getAuthValue({
2217
- requestedScope: "comments:read",
2218
- roomId: options.roomId
2149
+ roomId: options.roomId,
2150
+ resource: "storage",
2151
+ access: "read"
2219
2152
  }),
2220
2153
  {
2221
2154
  type: options.type,
@@ -2227,8 +2160,9 @@ function createApiClient({
2227
2160
  const result = await httpClient.post(
2228
2161
  url`/v2/c/rooms/${options.roomId}/ai/contextual-prompt`,
2229
2162
  await authManager.getAuthValue({
2230
- requestedScope: "room:read",
2231
- roomId: options.roomId
2163
+ roomId: options.roomId,
2164
+ resource: "storage",
2165
+ access: "read"
2232
2166
  }),
2233
2167
  {
2234
2168
  prompt: options.prompt,
@@ -2250,8 +2184,9 @@ function createApiClient({
2250
2184
  const result = await httpClient.get(
2251
2185
  url`/v2/c/rooms/${options.roomId}/versions`,
2252
2186
  await authManager.getAuthValue({
2253
- requestedScope: "comments:read",
2254
- roomId: options.roomId
2187
+ roomId: options.roomId,
2188
+ resource: "storage",
2189
+ access: "read"
2255
2190
  })
2256
2191
  );
2257
2192
  return {
@@ -2268,8 +2203,9 @@ function createApiClient({
2268
2203
  const result = await httpClient.get(
2269
2204
  url`/v2/c/rooms/${options.roomId}/versions/delta`,
2270
2205
  await authManager.getAuthValue({
2271
- requestedScope: "comments:read",
2272
- roomId: options.roomId
2206
+ roomId: options.roomId,
2207
+ resource: "storage",
2208
+ access: "read"
2273
2209
  }),
2274
2210
  { since: options.since.toISOString() },
2275
2211
  { signal: options.signal }
@@ -2288,8 +2224,9 @@ function createApiClient({
2288
2224
  const result = await httpClient.rawGet(
2289
2225
  url`/v2/c/rooms/${options.roomId}/storage`,
2290
2226
  await authManager.getAuthValue({
2291
- requestedScope: "room:read",
2292
- roomId: options.roomId
2227
+ roomId: options.roomId,
2228
+ resource: "storage",
2229
+ access: "read"
2293
2230
  })
2294
2231
  );
2295
2232
  return await result.json();
@@ -2302,7 +2239,7 @@ function createApiClient({
2302
2239
  }
2303
2240
  const json = await httpClient.get(
2304
2241
  url`/v2/c/inbox-notifications`,
2305
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2242
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2306
2243
  {
2307
2244
  cursor: options?.cursor,
2308
2245
  limit: PAGE_SIZE,
@@ -2328,7 +2265,7 @@ function createApiClient({
2328
2265
  }
2329
2266
  const json = await httpClient.get(
2330
2267
  url`/v2/c/inbox-notifications/delta`,
2331
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2268
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2332
2269
  { since: options.since.toISOString(), query },
2333
2270
  { signal: options.signal }
2334
2271
  );
@@ -2357,7 +2294,7 @@ function createApiClient({
2357
2294
  }
2358
2295
  const { count } = await httpClient.get(
2359
2296
  url`/v2/c/inbox-notifications/count`,
2360
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2297
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2361
2298
  { query },
2362
2299
  { signal: options?.signal }
2363
2300
  );
@@ -2366,7 +2303,7 @@ function createApiClient({
2366
2303
  async function markAllInboxNotificationsAsRead() {
2367
2304
  await httpClient.post(
2368
2305
  url`/v2/c/inbox-notifications/read`,
2369
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2306
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2370
2307
  {
2371
2308
  inboxNotificationIds: "all"
2372
2309
  }
@@ -2375,7 +2312,7 @@ function createApiClient({
2375
2312
  async function markInboxNotificationsAsRead(inboxNotificationIds) {
2376
2313
  await httpClient.post(
2377
2314
  url`/v2/c/inbox-notifications/read`,
2378
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2315
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2379
2316
  {
2380
2317
  inboxNotificationIds
2381
2318
  }
@@ -2395,19 +2332,19 @@ function createApiClient({
2395
2332
  async function deleteAllInboxNotifications() {
2396
2333
  await httpClient.delete(
2397
2334
  url`/v2/c/inbox-notifications`,
2398
- await authManager.getAuthValue({ requestedScope: "comments:read" })
2335
+ await authManager.getAuthValue({ resource: "personal", access: "write" })
2399
2336
  );
2400
2337
  }
2401
2338
  async function deleteInboxNotification(inboxNotificationId) {
2402
2339
  await httpClient.delete(
2403
2340
  url`/v2/c/inbox-notifications/${inboxNotificationId}`,
2404
- await authManager.getAuthValue({ requestedScope: "comments:read" })
2341
+ await authManager.getAuthValue({ resource: "personal", access: "write" })
2405
2342
  );
2406
2343
  }
2407
2344
  async function getNotificationSettings(options) {
2408
2345
  return httpClient.get(
2409
2346
  url`/v2/c/notification-settings`,
2410
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2347
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2411
2348
  void 0,
2412
2349
  { signal: options?.signal }
2413
2350
  );
@@ -2415,7 +2352,7 @@ function createApiClient({
2415
2352
  async function updateNotificationSettings(settings) {
2416
2353
  return httpClient.post(
2417
2354
  url`/v2/c/notification-settings`,
2418
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2355
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2419
2356
  settings
2420
2357
  );
2421
2358
  }
@@ -2427,7 +2364,7 @@ function createApiClient({
2427
2364
  const PAGE_SIZE = 50;
2428
2365
  const json = await httpClient.get(
2429
2366
  url`/v2/c/threads`,
2430
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2367
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2431
2368
  {
2432
2369
  cursor: options?.cursor,
2433
2370
  query,
@@ -2448,7 +2385,7 @@ function createApiClient({
2448
2385
  async function getUserThreadsSince_experimental(options) {
2449
2386
  const json = await httpClient.get(
2450
2387
  url`/v2/c/threads/delta`,
2451
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2388
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2452
2389
  { since: options.since.toISOString() },
2453
2390
  { signal: options.signal }
2454
2391
  );
@@ -2477,7 +2414,8 @@ function createApiClient({
2477
2414
  const { groups: plainGroups } = await httpClient.post(
2478
2415
  url`/v2/c/groups/find`,
2479
2416
  await authManager.getAuthValue({
2480
- requestedScope: "comments:read"
2417
+ resource: "personal",
2418
+ access: "write"
2481
2419
  }),
2482
2420
  { groupIds }
2483
2421
  );
@@ -2496,7 +2434,7 @@ function createApiClient({
2496
2434
  async function getUrlMetadata(_url) {
2497
2435
  const { metadata } = await httpClient.get(
2498
2436
  url`/v2/c/urls/metadata`,
2499
- await authManager.getAuthValue({ requestedScope: "comments:read" }),
2437
+ await authManager.getAuthValue({ resource: "personal", access: "write" }),
2500
2438
  { url: _url }
2501
2439
  );
2502
2440
  return metadata;
@@ -2536,10 +2474,6 @@ function createApiClient({
2536
2474
  getAttachmentUrl,
2537
2475
  uploadAttachment,
2538
2476
  getOrCreateAttachmentUrlsStore,
2539
- // User attachments
2540
- uploadChatAttachment,
2541
- getOrCreateChatAttachmentUrlsStore,
2542
- getChatAttachmentUrl,
2543
2477
  // Room storage
2544
2478
  streamStorage,
2545
2479
  // Notifications
@@ -5233,22 +5167,291 @@ function createReceivingToolInvocation(invocationId, name, partialArgsText = "")
5233
5167
  };
5234
5168
  }
5235
5169
 
5236
- // src/protocol/AuthToken.ts
5237
- var Permission = /* @__PURE__ */ ((Permission2) => {
5238
- Permission2["Read"] = "room:read";
5239
- Permission2["Write"] = "room:write";
5240
- Permission2["PresenceWrite"] = "room:presence:write";
5241
- Permission2["CommentsWrite"] = "comments:write";
5242
- Permission2["CommentsRead"] = "comments:read";
5243
- Permission2["FeedsWrite"] = "feeds:write";
5244
- return Permission2;
5245
- })(Permission || {});
5246
- function canWriteStorage(scopes) {
5247
- return scopes.includes("room:write" /* Write */);
5248
- }
5249
- function canComment(scopes) {
5250
- return scopes.includes("comments:write" /* CommentsWrite */) || scopes.includes("room:write" /* Write */);
5170
+ // src/protocol/Permissions.ts
5171
+ var Permission = {
5172
+ /**
5173
+ * Default permission for a room
5174
+ */
5175
+ RoomWrite: "room:write",
5176
+ RoomRead: "room:read",
5177
+ /**
5178
+ * Presence (LiveRoom Websocket access)
5179
+ */
5180
+ RoomPresenceRead: "room:presence:read",
5181
+ RoomPresenceNone: "room:presence:none",
5182
+ /**
5183
+ * Storage
5184
+ */
5185
+ RoomStorageRead: "room:storage:read",
5186
+ RoomStorageWrite: "room:storage:write",
5187
+ RoomStorageNone: "room:storage:none",
5188
+ /**
5189
+ * Comments
5190
+ */
5191
+ RoomCommentsWrite: "room:comments:write",
5192
+ RoomCommentsRead: "room:comments:read",
5193
+ RoomCommentsNone: "room:comments:none",
5194
+ /**
5195
+ * Feeds
5196
+ */
5197
+ RoomFeedsRead: "room:feeds:read",
5198
+ RoomFeedsWrite: "room:feeds:write",
5199
+ RoomFeedsNone: "room:feeds:none",
5200
+ /**
5201
+ * Legacy
5202
+ */
5203
+ LegacyRoomPresenceWrite: "room:presence:write",
5204
+ LegacyCommentsWrite: "comments:write",
5205
+ LegacyCommentsRead: "comments:read",
5206
+ LegacyFeedsWrite: "feeds:write"
5207
+ };
5208
+ var ACCESS_LEVELS = [
5209
+ "none",
5210
+ "read",
5211
+ "write"
5212
+ ];
5213
+ var ACCESS_RANKS = {
5214
+ none: 0,
5215
+ read: 1,
5216
+ write: 2
5217
+ };
5218
+ var NO_PERMISSION_CAPABILITIES = {
5219
+ creation: "none",
5220
+ presence: "none",
5221
+ storage: "none",
5222
+ comments: "none",
5223
+ feeds: "none",
5224
+ personal: "write"
5225
+ };
5226
+ var RESOURCE_PERMISSIONS = {
5227
+ creation: {
5228
+ read: [Permission.RoomRead],
5229
+ write: [Permission.RoomWrite]
5230
+ },
5231
+ personal: {
5232
+ write: []
5233
+ },
5234
+ presence: {
5235
+ write: [Permission.LegacyRoomPresenceWrite],
5236
+ read: [Permission.RoomPresenceRead],
5237
+ none: [Permission.RoomPresenceNone]
5238
+ },
5239
+ storage: {
5240
+ write: [Permission.RoomStorageWrite],
5241
+ read: [Permission.RoomStorageRead],
5242
+ none: [Permission.RoomStorageNone]
5243
+ },
5244
+ comments: {
5245
+ write: [Permission.RoomCommentsWrite, Permission.LegacyCommentsWrite],
5246
+ read: [Permission.RoomCommentsRead, Permission.LegacyCommentsRead],
5247
+ none: [Permission.RoomCommentsNone]
5248
+ },
5249
+ feeds: {
5250
+ write: [Permission.RoomFeedsWrite, Permission.LegacyFeedsWrite],
5251
+ read: [Permission.RoomFeedsRead],
5252
+ none: [Permission.RoomFeedsNone]
5253
+ }
5254
+ };
5255
+ var DEFAULT_PERMISSION_RESOURCE = "creation";
5256
+ var ROOM_PERMISSION_RESOURCES = [
5257
+ "presence",
5258
+ "storage",
5259
+ "comments",
5260
+ "feeds"
5261
+ ];
5262
+ function resolveResourceAccess(scopes, resource) {
5263
+ const permissions = RESOURCE_PERMISSIONS[resource];
5264
+ let resourceAccess;
5265
+ for (const access of ACCESS_LEVELS) {
5266
+ const scopedPermissions = permissions[access];
5267
+ if (scopedPermissions !== void 0 && scopedPermissions.some((permission) => scopes.includes(permission))) {
5268
+ resourceAccess = access;
5269
+ }
5270
+ }
5271
+ return resourceAccess;
5272
+ }
5273
+ function resolveFullPermissionCapabilities(resolved) {
5274
+ if (!resolved.hasDefaultPermission) {
5275
+ return { ...NO_PERMISSION_CAPABILITIES, ...resolved.capabilities };
5276
+ }
5277
+ const capabilities = {
5278
+ ...NO_PERMISSION_CAPABILITIES,
5279
+ [DEFAULT_PERMISSION_RESOURCE]: resolved.baseAccess
5280
+ };
5281
+ for (const resource of ROOM_PERMISSION_RESOURCES) {
5282
+ capabilities[resource] = resolved.capabilities[resource] ?? resolved.baseAccess;
5283
+ }
5284
+ return capabilities;
5285
+ }
5286
+ function permissionCapabilitiesFromScopes(scopes) {
5287
+ return resolveFullPermissionCapabilities(
5288
+ resolvePermissionCapabilities(scopes)
5289
+ );
5290
+ }
5291
+ function resolvePermissionCapabilities(scopes) {
5292
+ const hasDefaultPermission = scopes.includes(Permission.RoomWrite) || scopes.includes(Permission.RoomRead);
5293
+ const baseAccess = scopes.includes(Permission.RoomWrite) ? "write" : scopes.includes(Permission.RoomRead) ? "read" : "none";
5294
+ const capabilities = {};
5295
+ for (const resource of ROOM_PERMISSION_RESOURCES) {
5296
+ const access = resolveResourceAccess(scopes, resource);
5297
+ if (access !== void 0) {
5298
+ capabilities[resource] = access;
5299
+ }
5300
+ }
5301
+ return { hasDefaultPermission, baseAccess, capabilities };
5302
+ }
5303
+ function hasPermissionCapability(scopes, resource, requiredAccess) {
5304
+ const access = permissionCapabilitiesFromScopes(scopes)[resource];
5305
+ return ACCESS_RANKS[access] >= ACCESS_RANKS[requiredAccess];
5306
+ }
5307
+ function hasPermissionCapabilityAccess(capabilities, resource, requiredAccess) {
5308
+ const access = capabilities[resource] ?? "none";
5309
+ return ACCESS_RANKS[access] >= ACCESS_RANKS[requiredAccess];
5310
+ }
5311
+
5312
+ // src/permissions.ts
5313
+ var VALID_PERMISSIONS = new Set(Object.values(Permission));
5314
+ var DEFAULT_PERMISSIONS = [
5315
+ Permission.RoomRead,
5316
+ Permission.RoomWrite
5317
+ ];
5318
+ var ROOM_PERMISSION_OBJECT_KEYS = /* @__PURE__ */ new Set([
5319
+ "default",
5320
+ ...ROOM_PERMISSION_RESOURCES
5321
+ ]);
5322
+ var RESOURCE_SPECIFIC_PERMISSIONS_BY_RESOURCE = {
5323
+ presence: Object.values(RESOURCE_PERMISSIONS.presence).flat(),
5324
+ storage: Object.values(RESOURCE_PERMISSIONS.storage).flat(),
5325
+ comments: Object.values(RESOURCE_PERMISSIONS.comments).flat(),
5326
+ feeds: Object.values(RESOURCE_PERMISSIONS.feeds).flat()
5327
+ };
5328
+ var RESOURCE_SPECIFIC_PERMISSIONS = ROOM_PERMISSION_RESOURCES.flatMap(
5329
+ (resource) => RESOURCE_SPECIFIC_PERMISSIONS_BY_RESOURCE[resource]
5330
+ );
5331
+ function permissionForAccessLevel(resource, access) {
5332
+ const levels = RESOURCE_PERMISSIONS[resource];
5333
+ const permissions = levels[access];
5334
+ if (permissions === void 0 || permissions.length === 0) {
5335
+ throw new Error(
5336
+ `Invalid permission level for ${resource}: ${String(access)}`
5337
+ );
5338
+ }
5339
+ return permissions[0];
5340
+ }
5341
+ function resolveRoomPermissionCapabilities(permissions, roomId) {
5342
+ const matchedPermissions = permissions.filter(
5343
+ (permission) => resourceMatchesRoomId(permission.resource, roomId)
5344
+ );
5345
+ if (matchedPermissions.length === 0) {
5346
+ return void 0;
5347
+ }
5348
+ let hasDefaultPermission = false;
5349
+ let baseAccess = "none";
5350
+ const explicitCapabilities = {};
5351
+ for (const permission of matchedPermissions) {
5352
+ const resolved = resolvePermissionCapabilities(permission.scopes);
5353
+ if (resolved.hasDefaultPermission) {
5354
+ hasDefaultPermission = true;
5355
+ baseAccess = strongestAccess(baseAccess, resolved.baseAccess);
5356
+ }
5357
+ for (const resource of ROOM_PERMISSION_RESOURCES) {
5358
+ const access = resolved.capabilities[resource];
5359
+ if (access !== void 0) {
5360
+ explicitCapabilities[resource] = strongestAccess(
5361
+ explicitCapabilities[resource] ?? "none",
5362
+ access
5363
+ );
5364
+ }
5365
+ }
5366
+ }
5367
+ return resolveFullPermissionCapabilities({
5368
+ hasDefaultPermission,
5369
+ baseAccess,
5370
+ capabilities: explicitCapabilities
5371
+ });
5372
+ }
5373
+ function isRoomPermissionArray(input) {
5374
+ return Array.isArray(input);
5375
+ }
5376
+ function normalizeRoomPermissionInput(input) {
5377
+ if (isRoomPermissionArray(input)) {
5378
+ return input.map((permission) => {
5379
+ if (!VALID_PERMISSIONS.has(permission)) {
5380
+ throw new Error(`Not a valid permission: ${permission}`);
5381
+ }
5382
+ return permission;
5383
+ });
5384
+ }
5385
+ return normalizeRoomPermissionObject(input);
5386
+ }
5387
+ function normalizeRoomPermissionObject(objectInput) {
5388
+ for (const key of Object.keys(objectInput)) {
5389
+ if (!ROOM_PERMISSION_OBJECT_KEYS.has(key)) {
5390
+ throw new Error(`Unknown permission field: ${key}`);
5391
+ }
5392
+ }
5393
+ const permissions = [];
5394
+ if (objectInput.default !== void 0) {
5395
+ permissions.push(
5396
+ permissionForAccessLevel(DEFAULT_PERMISSION_RESOURCE, objectInput.default)
5397
+ );
5398
+ }
5399
+ for (const resource of ROOM_PERMISSION_RESOURCES) {
5400
+ const access = objectInput[resource];
5401
+ if (access !== void 0) {
5402
+ permissions.push(permissionForAccessLevel(resource, access));
5403
+ }
5404
+ }
5405
+ if (permissions.length === 0) {
5406
+ throw new Error("Permission object cannot be empty");
5407
+ }
5408
+ return permissions;
5409
+ }
5410
+ function normalizeRoomAccessesInput(input) {
5411
+ if (input === void 0) {
5412
+ return void 0;
5413
+ }
5414
+ return Object.fromEntries(
5415
+ Object.entries(input).map(([id, permissions]) => [
5416
+ id,
5417
+ normalizeRoomPermissionInput(permissions)
5418
+ ])
5419
+ );
5420
+ }
5421
+ function normalizeRoomAccessesUpdateInput(input) {
5422
+ if (input === void 0) {
5423
+ return void 0;
5424
+ }
5425
+ return Object.fromEntries(
5426
+ Object.entries(input).map(([id, permissions]) => [
5427
+ id,
5428
+ permissions === null ? null : normalizeRoomPermissionInput(permissions)
5429
+ ])
5430
+ );
5431
+ }
5432
+ function getRoomPermissionConflicts(permission) {
5433
+ if (DEFAULT_PERMISSIONS.includes(permission)) {
5434
+ return [...DEFAULT_PERMISSIONS, ...RESOURCE_SPECIFIC_PERMISSIONS];
5435
+ }
5436
+ for (const resource of ROOM_PERMISSION_RESOURCES) {
5437
+ const permissions = RESOURCE_SPECIFIC_PERMISSIONS_BY_RESOURCE[resource];
5438
+ if (permissions.includes(permission)) {
5439
+ return permissions;
5440
+ }
5441
+ }
5442
+ return [];
5443
+ }
5444
+ function strongestAccess(left, right) {
5445
+ return ACCESS_RANKS[right] > ACCESS_RANKS[left] ? right : left;
5446
+ }
5447
+ function resourceMatchesRoomId(resource, roomId) {
5448
+ if (resource.includes("*")) {
5449
+ return roomId.startsWith(resource.replace("*", ""));
5450
+ }
5451
+ return resource === roomId;
5251
5452
  }
5453
+
5454
+ // src/protocol/AuthToken.ts
5252
5455
  function isValidAuthTokenPayload(data) {
5253
5456
  return isPlainObject(data) && (data.k === "acc" /* ACCESS_TOKEN */ || data.k === "id" /* ID_TOKEN */);
5254
5457
  }
@@ -5287,47 +5490,22 @@ function createAuthManager(authOptions, onAuthenticate) {
5287
5490
  const authentication = prepareAuthentication(authOptions);
5288
5491
  const seenTokens = /* @__PURE__ */ new Set();
5289
5492
  const tokens = [];
5290
- const expiryTimes = [];
5291
5493
  const requestPromises = /* @__PURE__ */ new Map();
5292
5494
  function reset() {
5293
5495
  seenTokens.clear();
5294
5496
  tokens.length = 0;
5295
- expiryTimes.length = 0;
5296
5497
  requestPromises.clear();
5297
5498
  }
5298
- function hasCorrespondingScopes(requestedScope, scopes) {
5299
- if (requestedScope === "comments:read") {
5300
- return scopes.includes("comments:read" /* CommentsRead */) || scopes.includes("comments:write" /* CommentsWrite */) || scopes.includes("room:read" /* Read */) || scopes.includes("room:write" /* Write */);
5301
- } else if (requestedScope === "room:read") {
5302
- return scopes.includes("room:read" /* Read */) || scopes.includes("room:write" /* Write */);
5303
- }
5304
- return false;
5305
- }
5306
5499
  function getCachedToken(requestOptions) {
5307
5500
  const now2 = Math.ceil(Date.now() / 1e3);
5308
5501
  for (let i = tokens.length - 1; i >= 0; i--) {
5309
- const token = tokens[i];
5310
- const expiresAt = expiryTimes[i];
5311
- if (expiresAt <= now2) {
5502
+ const cachedToken = tokens[i];
5503
+ if (cachedToken.expiresAt <= now2) {
5312
5504
  tokens.splice(i, 1);
5313
- expiryTimes.splice(i, 1);
5314
5505
  continue;
5315
5506
  }
5316
- if (token.parsed.k === "id" /* ID_TOKEN */) {
5317
- return token;
5318
- } else if (token.parsed.k === "acc" /* ACCESS_TOKEN */) {
5319
- if (!requestOptions.roomId && Object.entries(token.parsed.perms).length === 0) {
5320
- return token;
5321
- }
5322
- for (const [resource, scopes] of Object.entries(token.parsed.perms)) {
5323
- if (!requestOptions.roomId) {
5324
- if (resource.includes("*") && hasCorrespondingScopes(requestOptions.requestedScope, scopes)) {
5325
- return token;
5326
- }
5327
- } else if (resource.includes("*") && requestOptions.roomId.startsWith(resource.replace("*", "")) || requestOptions.roomId === resource && hasCorrespondingScopes(requestOptions.requestedScope, scopes)) {
5328
- return token;
5329
- }
5330
- }
5507
+ if (cachedTokenSatisfiesRequest(cachedToken, requestOptions)) {
5508
+ return cachedToken.token;
5331
5509
  }
5332
5510
  }
5333
5511
  return void 0;
@@ -5385,11 +5563,12 @@ function createAuthManager(authOptions, onAuthenticate) {
5385
5563
  return { type: "secret", token: cachedToken };
5386
5564
  }
5387
5565
  let currentPromise;
5388
- if (requestOptions.roomId) {
5389
- currentPromise = requestPromises.get(requestOptions.roomId);
5566
+ const requestKey = getAuthRequestKey(requestOptions);
5567
+ if (requestKey !== void 0) {
5568
+ currentPromise = requestPromises.get(requestKey);
5390
5569
  if (currentPromise === void 0) {
5391
5570
  currentPromise = makeAuthRequest(requestOptions);
5392
- requestPromises.set(requestOptions.roomId, currentPromise);
5571
+ requestPromises.set(requestKey, currentPromise);
5393
5572
  }
5394
5573
  } else {
5395
5574
  currentPromise = requestPromises.get("liveblocks-user-token");
@@ -5403,12 +5582,12 @@ function createAuthManager(authOptions, onAuthenticate) {
5403
5582
  const BUFFER = 30;
5404
5583
  const expiresAt = Math.floor(Date.now() / 1e3) + (token.parsed.exp - token.parsed.iat) - BUFFER;
5405
5584
  seenTokens.add(token.raw);
5406
- tokens.push(token);
5407
- expiryTimes.push(expiresAt);
5585
+ const cachedToken2 = makeCachedToken(token, expiresAt);
5586
+ tokens.push(cachedToken2);
5408
5587
  return { type: "secret", token };
5409
5588
  } finally {
5410
- if (requestOptions.roomId) {
5411
- requestPromises.delete(requestOptions.roomId);
5589
+ if (requestKey !== void 0) {
5590
+ requestPromises.delete(requestKey);
5412
5591
  } else {
5413
5592
  requestPromises.delete("liveblocks-user-token");
5414
5593
  }
@@ -5419,6 +5598,48 @@ function createAuthManager(authOptions, onAuthenticate) {
5419
5598
  getAuthValue
5420
5599
  };
5421
5600
  }
5601
+ function getAuthRequestKey(request) {
5602
+ if (request.roomId === void 0) {
5603
+ return void 0;
5604
+ }
5605
+ return `${request.roomId}:${request.resource}:${request.access}`;
5606
+ }
5607
+ function makeCachedToken(token, expiresAt) {
5608
+ if (token.parsed.k === "acc" /* ACCESS_TOKEN */) {
5609
+ return {
5610
+ token,
5611
+ expiresAt,
5612
+ permissions: getAuthTokenPermissionScopes(token.parsed.perms)
5613
+ };
5614
+ }
5615
+ return { token, expiresAt };
5616
+ }
5617
+ function getAuthTokenPermissionScopes(permissions) {
5618
+ return Object.entries(permissions).map(([resource, scopes]) => ({
5619
+ resource,
5620
+ scopes
5621
+ }));
5622
+ }
5623
+ function cachedTokenSatisfiesRequest(cachedToken, request) {
5624
+ if (cachedToken.token.parsed.k === "id" /* ID_TOKEN */) {
5625
+ return true;
5626
+ }
5627
+ if (request.resource === "personal") {
5628
+ return true;
5629
+ }
5630
+ if (request.roomId === void 0) {
5631
+ return false;
5632
+ }
5633
+ const capabilities = resolveRoomPermissionCapabilities(
5634
+ cachedToken.permissions ?? [],
5635
+ request.roomId
5636
+ );
5637
+ return capabilities !== void 0 && hasPermissionCapabilityAccess(
5638
+ capabilities,
5639
+ request.resource,
5640
+ request.access
5641
+ );
5642
+ }
5422
5643
  function prepareAuthentication(authOptions) {
5423
5644
  const { publicApiKey, authEndpoint } = authOptions;
5424
5645
  if (authEndpoint !== void 0 && publicApiKey !== void 0) {
@@ -5511,9 +5732,7 @@ var OpCode = Object.freeze({
5511
5732
  DELETE_CRDT: 5,
5512
5733
  DELETE_OBJECT_KEY: 6,
5513
5734
  CREATE_MAP: 7,
5514
- CREATE_REGISTER: 8,
5515
- CREATE_TEXT: 9,
5516
- UPDATE_TEXT: 10
5735
+ CREATE_REGISTER: 8
5517
5736
  });
5518
5737
  function isIgnoredOp(op) {
5519
5738
  return op.type === OpCode.DELETE_CRDT && op.id === "ACK";
@@ -5527,8 +5746,7 @@ var CrdtType = Object.freeze({
5527
5746
  OBJECT: 0,
5528
5747
  LIST: 1,
5529
5748
  MAP: 2,
5530
- REGISTER: 3,
5531
- TEXT: 4
5749
+ REGISTER: 3
5532
5750
  });
5533
5751
  function isRootStorageNode(node) {
5534
5752
  return node[0] === "root";
@@ -5545,9 +5763,6 @@ function isMapStorageNode(node) {
5545
5763
  function isRegisterStorageNode(node) {
5546
5764
  return node[1].type === CrdtType.REGISTER;
5547
5765
  }
5548
- function isTextStorageNode(node) {
5549
- return node[1].type === CrdtType.TEXT;
5550
- }
5551
5766
  function isCompactRootNode(node) {
5552
5767
  return node[0] === "root";
5553
5768
  }
@@ -5570,9 +5785,6 @@ function* compactNodesToNodeStream(compactNodes) {
5570
5785
  case CrdtType.REGISTER:
5571
5786
  yield [cnode[0], { type: CrdtType.REGISTER, parentId: cnode[2], parentKey: cnode[3], data: cnode[4] }];
5572
5787
  break;
5573
- case CrdtType.TEXT:
5574
- yield [cnode[0], { type: CrdtType.TEXT, parentId: cnode[2], parentKey: cnode[3], data: cnode[4], version: cnode[5] }];
5575
- break;
5576
5788
  default:
5577
5789
  }
5578
5790
  }
@@ -5601,17 +5813,6 @@ function* nodeStreamToCompactNodes(nodes) {
5601
5813
  const id = node[0];
5602
5814
  const crdt = node[1];
5603
5815
  yield [id, CrdtType.REGISTER, crdt.parentId, crdt.parentKey, crdt.data];
5604
- } else if (isTextStorageNode(node)) {
5605
- const id = node[0];
5606
- const crdt = node[1];
5607
- yield [
5608
- id,
5609
- CrdtType.TEXT,
5610
- crdt.parentId,
5611
- crdt.parentKey,
5612
- crdt.data,
5613
- crdt.version
5614
- ];
5615
5816
  } else {
5616
5817
  }
5617
5818
  }
@@ -8474,580 +8675,6 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
8474
8675
  }
8475
8676
  };
8476
8677
 
8477
- // src/crdts/liveTextOps.ts
8478
- function attributesEqual(left, right) {
8479
- if (left === right) {
8480
- return true;
8481
- }
8482
- if (left === void 0 || right === void 0) {
8483
- return false;
8484
- }
8485
- const leftKeys = Object.keys(left);
8486
- const rightKeys = Object.keys(right);
8487
- if (leftKeys.length !== rightKeys.length) {
8488
- return false;
8489
- }
8490
- for (const key of leftKeys) {
8491
- if (left[key] !== right[key]) {
8492
- return false;
8493
- }
8494
- }
8495
- return true;
8496
- }
8497
- function cloneAttributes(attributes) {
8498
- return attributes === void 0 ? void 0 : freeze({ ...attributes });
8499
- }
8500
- function normalizeSegments(segments) {
8501
- const normalized = [];
8502
- for (const segment of segments) {
8503
- if (segment.text.length === 0) {
8504
- continue;
8505
- }
8506
- const last = normalized.at(-1);
8507
- const attributes = cloneAttributes(segment.attributes);
8508
- if (last !== void 0 && attributesEqual(last.attributes, attributes)) {
8509
- last.text += segment.text;
8510
- } else {
8511
- normalized.push({ text: segment.text, attributes });
8512
- }
8513
- }
8514
- return normalized;
8515
- }
8516
- function dataToSegments(data) {
8517
- return normalizeSegments(
8518
- data.map(([text, attributes]) => ({
8519
- text,
8520
- attributes
8521
- }))
8522
- );
8523
- }
8524
- function segmentsToData(segments) {
8525
- return segments.map(
8526
- (segment) => segment.attributes === void 0 ? [segment.text] : [segment.text, { ...segment.attributes }]
8527
- );
8528
- }
8529
- function textLength(segments) {
8530
- return segments.reduce((sum, segment) => sum + segment.text.length, 0);
8531
- }
8532
- function splitSegmentsAt(segments, index) {
8533
- const result = [];
8534
- let offset = 0;
8535
- for (const segment of segments) {
8536
- const end = offset + segment.text.length;
8537
- if (index > offset && index < end) {
8538
- const before2 = segment.text.slice(0, index - offset);
8539
- const after2 = segment.text.slice(index - offset);
8540
- result.push({ text: before2, attributes: segment.attributes });
8541
- result.push({ text: after2, attributes: segment.attributes });
8542
- } else {
8543
- result.push({ text: segment.text, attributes: segment.attributes });
8544
- }
8545
- offset = end;
8546
- }
8547
- return result;
8548
- }
8549
- function clipRange(index, length, contentLength) {
8550
- const clippedIndex = Math.max(0, Math.min(index, contentLength));
8551
- const clippedEnd = Math.max(
8552
- clippedIndex,
8553
- Math.min(index + length, contentLength)
8554
- );
8555
- return { index: clippedIndex, length: clippedEnd - clippedIndex };
8556
- }
8557
- function applyInsert(segments, index, text, attributes) {
8558
- if (text.length === 0) {
8559
- return normalizeSegments(segments);
8560
- }
8561
- const split = splitSegmentsAt(segments, index);
8562
- const result = [];
8563
- let offset = 0;
8564
- let inserted = false;
8565
- for (const segment of split) {
8566
- if (!inserted && offset === index) {
8567
- result.push({ text, attributes });
8568
- inserted = true;
8569
- }
8570
- result.push(segment);
8571
- offset += segment.text.length;
8572
- }
8573
- if (!inserted) {
8574
- result.push({ text, attributes });
8575
- }
8576
- return normalizeSegments(result);
8577
- }
8578
- function extractDeletedSegments(segments, index, length) {
8579
- const split = splitSegmentsAt(
8580
- splitSegmentsAt(segments, index),
8581
- index + length
8582
- );
8583
- const deleted = [];
8584
- let offset = 0;
8585
- for (const segment of split) {
8586
- const end = offset + segment.text.length;
8587
- if (offset >= index && end <= index + length) {
8588
- deleted.push({
8589
- text: segment.text,
8590
- attributes: segment.attributes
8591
- });
8592
- }
8593
- offset = end;
8594
- }
8595
- return normalizeSegments(deleted);
8596
- }
8597
- function applyDelete(segments, index, length) {
8598
- const deletedSegments = extractDeletedSegments(segments, index, length);
8599
- const split = splitSegmentsAt(
8600
- splitSegmentsAt(segments, index),
8601
- index + length
8602
- );
8603
- const result = [];
8604
- let offset = 0;
8605
- let deletedText = "";
8606
- for (const segment of split) {
8607
- const end = offset + segment.text.length;
8608
- if (offset >= index && end <= index + length) {
8609
- deletedText += segment.text;
8610
- } else {
8611
- result.push(segment);
8612
- }
8613
- offset = end;
8614
- }
8615
- return {
8616
- segments: normalizeSegments(result),
8617
- deletedText,
8618
- deletedSegments
8619
- };
8620
- }
8621
- function applyFormat(segments, index, length, attributes) {
8622
- const split = splitSegmentsAt(
8623
- splitSegmentsAt(segments, index),
8624
- index + length
8625
- );
8626
- const result = [];
8627
- let offset = 0;
8628
- for (const segment of split) {
8629
- const end = offset + segment.text.length;
8630
- if (offset >= index && end <= index + length) {
8631
- const nextAttributes = {
8632
- ...segment.attributes ?? {}
8633
- };
8634
- for (const [key, value] of Object.entries(attributes)) {
8635
- if (value === null) {
8636
- delete nextAttributes[key];
8637
- } else {
8638
- nextAttributes[key] = value;
8639
- }
8640
- }
8641
- result.push({
8642
- text: segment.text,
8643
- attributes: Object.keys(nextAttributes).length === 0 ? void 0 : freeze(nextAttributes)
8644
- });
8645
- } else {
8646
- result.push(segment);
8647
- }
8648
- offset = end;
8649
- }
8650
- return normalizeSegments(result);
8651
- }
8652
- function formatReverseOperations(segments, index, length, patch) {
8653
- const split = splitSegmentsAt(
8654
- splitSegmentsAt(segments, index),
8655
- index + length
8656
- );
8657
- const result = [];
8658
- let offset = 0;
8659
- for (const segment of split) {
8660
- const end = offset + segment.text.length;
8661
- if (offset >= index && end <= index + length) {
8662
- const attributes = {};
8663
- for (const key of Object.keys(patch)) {
8664
- attributes[key] = segment.attributes?.[key] ?? null;
8665
- }
8666
- result.push({
8667
- type: "format",
8668
- index: offset,
8669
- length: segment.text.length,
8670
- attributes
8671
- });
8672
- }
8673
- offset = end;
8674
- }
8675
- return result;
8676
- }
8677
- function mapIndexThroughOperation(index, op) {
8678
- if (op.type === "insert") {
8679
- return op.index <= index ? index + op.text.length : index;
8680
- } else if (op.type === "delete") {
8681
- if (op.index >= index) {
8682
- return index;
8683
- }
8684
- return Math.max(op.index, index - op.length);
8685
- } else {
8686
- return index;
8687
- }
8688
- }
8689
- function mapTextIndexThroughOperations(index, ops) {
8690
- let mapped = index;
8691
- for (const op of ops) {
8692
- mapped = mapIndexThroughOperation(mapped, op);
8693
- }
8694
- return mapped;
8695
- }
8696
- function rebaseTextOperations(ops, acceptedOps) {
8697
- return ops.map((op) => {
8698
- if (op.type === "insert") {
8699
- return {
8700
- ...op,
8701
- index: mapTextIndexThroughOperations(op.index, acceptedOps)
8702
- };
8703
- } else if (op.type === "delete" || op.type === "format") {
8704
- const start = mapTextIndexThroughOperations(op.index, acceptedOps);
8705
- const end = mapTextIndexThroughOperations(
8706
- op.index + op.length,
8707
- acceptedOps
8708
- );
8709
- return { ...op, index: start, length: Math.max(0, end - start) };
8710
- } else {
8711
- return op;
8712
- }
8713
- });
8714
- }
8715
- function applyTextOperationsToSegments(segments, ops) {
8716
- let next = [...segments];
8717
- for (const op of ops) {
8718
- if (op.type === "insert") {
8719
- const index = Math.max(0, Math.min(op.index, textLength(next)));
8720
- next = applyInsert(next, index, op.text, op.attributes);
8721
- } else if (op.type === "delete") {
8722
- const index = Math.max(0, Math.min(op.index, textLength(next)));
8723
- const clipped = clipRange(index, op.length, textLength(next));
8724
- next = applyDelete(next, clipped.index, clipped.length).segments;
8725
- } else {
8726
- const index = Math.max(0, Math.min(op.index, textLength(next)));
8727
- const clipped = clipRange(index, op.length, textLength(next));
8728
- next = applyFormat(next, clipped.index, clipped.length, op.attributes);
8729
- }
8730
- }
8731
- return next;
8732
- }
8733
- function applyLiveTextOperations(data, ops) {
8734
- return segmentsToData(
8735
- applyTextOperationsToSegments(dataToSegments(data), ops)
8736
- );
8737
- }
8738
- function invertTextOperations(segments, ops) {
8739
- let shadow = [...segments];
8740
- const reverse = [];
8741
- for (const op of ops) {
8742
- if (op.type === "insert") {
8743
- shadow = applyInsert(shadow, op.index, op.text, op.attributes);
8744
- reverse.unshift({
8745
- type: "delete",
8746
- index: op.index,
8747
- length: op.text.length
8748
- });
8749
- } else if (op.type === "delete") {
8750
- const deletedSegments = extractDeletedSegments(
8751
- shadow,
8752
- op.index,
8753
- op.length
8754
- );
8755
- shadow = applyDelete(shadow, op.index, op.length).segments;
8756
- const inserts = [];
8757
- let insertIndex = op.index;
8758
- for (const segment of deletedSegments) {
8759
- inserts.push({
8760
- type: "insert",
8761
- index: insertIndex,
8762
- text: segment.text,
8763
- attributes: segment.attributes
8764
- });
8765
- insertIndex += segment.text.length;
8766
- }
8767
- for (let index = inserts.length - 1; index >= 0; index--) {
8768
- reverse.unshift(inserts[index]);
8769
- }
8770
- } else {
8771
- const inverse = formatReverseOperations(
8772
- shadow,
8773
- op.index,
8774
- op.length,
8775
- op.attributes
8776
- );
8777
- shadow = applyFormat(shadow, op.index, op.length, op.attributes);
8778
- reverse.unshift(...inverse.reverse());
8779
- }
8780
- }
8781
- return reverse;
8782
- }
8783
-
8784
- // src/crdts/LiveText.ts
8785
- var LiveText = class _LiveText extends AbstractCrdt {
8786
- #segments;
8787
- #version;
8788
- #pendingOps;
8789
- constructor(textOrData = "", version = 0) {
8790
- super();
8791
- this.#segments = typeof textOrData === "string" ? textOrData.length === 0 ? [] : [{ text: textOrData }] : dataToSegments(textOrData);
8792
- this.#version = version;
8793
- this.#pendingOps = /* @__PURE__ */ new Map();
8794
- }
8795
- get version() {
8796
- return this.#version;
8797
- }
8798
- get length() {
8799
- return this.toString().length;
8800
- }
8801
- /** @internal */
8802
- static _deserialize([id, item], _parentToChildren, pool) {
8803
- const text = new _LiveText(item.data, item.version);
8804
- text._attach(id, pool);
8805
- return text;
8806
- }
8807
- /** @internal */
8808
- _toOps(parentId, parentKey) {
8809
- if (this._id === void 0) {
8810
- throw new Error("Cannot serialize LiveText if it is not attached");
8811
- }
8812
- return [
8813
- {
8814
- type: OpCode.CREATE_TEXT,
8815
- id: this._id,
8816
- parentId,
8817
- parentKey,
8818
- data: this.toJSON(),
8819
- version: this.#version
8820
- }
8821
- ];
8822
- }
8823
- /** @internal */
8824
- _serialize() {
8825
- if (this.parent.type !== "HasParent") {
8826
- throw new Error("Cannot serialize LiveText if parent is missing");
8827
- }
8828
- return {
8829
- type: CrdtType.TEXT,
8830
- parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
8831
- parentKey: this.parent.key,
8832
- data: this.toJSON(),
8833
- version: this.#version
8834
- };
8835
- }
8836
- /** @internal */
8837
- _attachChild(_op) {
8838
- throw new Error("LiveText cannot contain child nodes");
8839
- }
8840
- /** @internal */
8841
- _detachChild(_crdt) {
8842
- throw new Error("LiveText cannot contain child nodes");
8843
- }
8844
- /** @internal */
8845
- _apply(op, isLocal) {
8846
- if (op.type !== OpCode.UPDATE_TEXT) {
8847
- return super._apply(op, isLocal);
8848
- }
8849
- if (isLocal) {
8850
- this.#pendingOps.set(nn(op.opId), op.ops);
8851
- return this.#applyOperations(op.ops, op.version ?? this.#version);
8852
- }
8853
- if (op.opId !== void 0) {
8854
- const pending2 = this.#pendingOps.get(op.opId);
8855
- this.#pendingOps.delete(op.opId);
8856
- const otherPending = Array.from(this.#pendingOps.values()).flat();
8857
- if (pending2 !== void 0 && otherPending.length > 0) {
8858
- this.#segments = applyTextOperationsToSegments(
8859
- this.#segments,
8860
- invertTextOperations(this.#segments, pending2)
8861
- );
8862
- const ops2 = rebaseTextOperations(op.ops, otherPending);
8863
- return this.#applyOperations(
8864
- ops2,
8865
- op.version ?? Math.max(this.#version, op.baseVersion + 1)
8866
- );
8867
- }
8868
- this.#version = op.version ?? Math.max(this.#version, op.baseVersion + 1);
8869
- return { modified: false };
8870
- }
8871
- const pending = Array.from(this.#pendingOps.values()).flat();
8872
- const ops = pending.length > 0 ? rebaseTextOperations(op.ops, pending) : op.ops;
8873
- return this.#applyOperations(ops, op.version ?? this.#version + 1);
8874
- }
8875
- insert(index, text, attributes) {
8876
- const clippedIndex = Math.max(0, Math.min(index, this.length));
8877
- this.#dispatch([{ type: "insert", index: clippedIndex, text, attributes }]);
8878
- }
8879
- delete(index, length) {
8880
- const clipped = clipRange(index, length, this.length);
8881
- if (clipped.length === 0) {
8882
- return;
8883
- }
8884
- this.#dispatch([
8885
- { type: "delete", index: clipped.index, length: clipped.length }
8886
- ]);
8887
- }
8888
- replace(index, length, text, attributes) {
8889
- const clipped = clipRange(index, length, this.length);
8890
- const ops = [];
8891
- if (clipped.length > 0) {
8892
- ops.push({
8893
- type: "delete",
8894
- index: clipped.index,
8895
- length: clipped.length
8896
- });
8897
- }
8898
- if (text.length > 0) {
8899
- ops.push({ type: "insert", index: clipped.index, text, attributes });
8900
- }
8901
- this.#dispatch(ops);
8902
- }
8903
- format(index, length, attributes) {
8904
- const clipped = clipRange(index, length, this.length);
8905
- if (clipped.length === 0) {
8906
- return;
8907
- }
8908
- this.#dispatch([
8909
- {
8910
- type: "format",
8911
- index: clipped.index,
8912
- length: clipped.length,
8913
- attributes
8914
- }
8915
- ]);
8916
- }
8917
- #dispatch(ops) {
8918
- if (ops.length === 0) {
8919
- return;
8920
- }
8921
- this._pool?.assertStorageIsWritable();
8922
- const baseVersion = this.#version;
8923
- const reverse = this._pool !== void 0 && this._id !== void 0 ? this.#invertOperations(ops) : [];
8924
- const changes = this.#applyOperationsLocally(ops);
8925
- if (this._pool !== void 0 && this._id !== void 0) {
8926
- const opId = this._pool.generateOpId();
8927
- this.#pendingOps.set(opId, ops);
8928
- this._pool.dispatch(
8929
- [
8930
- {
8931
- type: OpCode.UPDATE_TEXT,
8932
- id: this._id,
8933
- opId,
8934
- baseVersion,
8935
- ops: [...ops]
8936
- }
8937
- ],
8938
- reverse,
8939
- /* @__PURE__ */ new Map([
8940
- [
8941
- this._id,
8942
- {
8943
- type: "LiveText",
8944
- node: this,
8945
- version: this.#version,
8946
- updates: changes
8947
- }
8948
- ]
8949
- ])
8950
- );
8951
- }
8952
- }
8953
- #applyOperations(ops, version) {
8954
- const reverse = this.#invertOperations(ops);
8955
- const changes = this.#applyOperationsLocally(ops);
8956
- this.#version = Math.max(this.#version, version);
8957
- return {
8958
- reverse,
8959
- modified: {
8960
- type: "LiveText",
8961
- node: this,
8962
- version: this.#version,
8963
- updates: changes
8964
- }
8965
- };
8966
- }
8967
- #applyOperationsLocally(ops) {
8968
- const changes = [];
8969
- for (const op of ops) {
8970
- if (op.type === "insert") {
8971
- this.#segments = applyInsert(
8972
- this.#segments,
8973
- op.index,
8974
- op.text,
8975
- op.attributes
8976
- );
8977
- changes.push({
8978
- type: "insert",
8979
- index: op.index,
8980
- text: op.text,
8981
- attributes: op.attributes
8982
- });
8983
- } else if (op.type === "delete") {
8984
- const result = applyDelete(this.#segments, op.index, op.length);
8985
- this.#segments = result.segments;
8986
- changes.push({
8987
- type: "delete",
8988
- index: op.index,
8989
- length: op.length,
8990
- deletedText: result.deletedText
8991
- });
8992
- } else {
8993
- this.#segments = applyFormat(
8994
- this.#segments,
8995
- op.index,
8996
- op.length,
8997
- op.attributes
8998
- );
8999
- changes.push({
9000
- type: "format",
9001
- index: op.index,
9002
- length: op.length,
9003
- attributes: op.attributes
9004
- });
9005
- }
9006
- }
9007
- this.invalidate();
9008
- return changes;
9009
- }
9010
- #invertOperations(ops) {
9011
- return [
9012
- {
9013
- type: OpCode.UPDATE_TEXT,
9014
- id: nn(this._id),
9015
- baseVersion: this.#version,
9016
- ops: invertTextOperations(this.#segments, ops)
9017
- }
9018
- ];
9019
- }
9020
- toString() {
9021
- return this.#segments.map((segment) => segment.text).join("");
9022
- }
9023
- toJSON() {
9024
- return super.toJSON();
9025
- }
9026
- /** @internal */
9027
- _toJSON() {
9028
- return segmentsToData(this.#segments);
9029
- }
9030
- /** @internal */
9031
- _toTreeNode(key) {
9032
- return {
9033
- type: "LiveText",
9034
- id: this._id ?? nanoid(),
9035
- key,
9036
- payload: [
9037
- {
9038
- type: "Json",
9039
- id: `${this._id ?? nanoid()}:text`,
9040
- key: "text",
9041
- payload: this.toString()
9042
- }
9043
- ]
9044
- };
9045
- }
9046
- clone() {
9047
- return new _LiveText(this.toJSON(), this.#version);
9048
- }
9049
- };
9050
-
9051
8678
  // src/crdts/liveblocks-helpers.ts
9052
8679
  function creationOpToLiveNode(op) {
9053
8680
  return lsonToLiveNode(creationOpToLson(op));
@@ -9062,8 +8689,6 @@ function creationOpToLson(op) {
9062
8689
  return new LiveMap();
9063
8690
  case OpCode.CREATE_LIST:
9064
8691
  return new LiveList([]);
9065
- case OpCode.CREATE_TEXT:
9066
- return new LiveText(op.data, op.version);
9067
8692
  default:
9068
8693
  return assertNever(op, "Unknown creation Op");
9069
8694
  }
@@ -9086,8 +8711,6 @@ function deserialize(node, parentToChildren, pool) {
9086
8711
  return LiveMap._deserialize(node, parentToChildren, pool);
9087
8712
  } else if (isRegisterStorageNode(node)) {
9088
8713
  return LiveRegister._deserialize(node, parentToChildren, pool);
9089
- } else if (isTextStorageNode(node)) {
9090
- return LiveText._deserialize(node, parentToChildren, pool);
9091
8714
  } else {
9092
8715
  throw new Error("Unexpected CRDT type");
9093
8716
  }
@@ -9101,14 +8724,12 @@ function deserializeToLson(node, parentToChildren, pool) {
9101
8724
  return LiveMap._deserialize(node, parentToChildren, pool);
9102
8725
  } else if (isRegisterStorageNode(node)) {
9103
8726
  return node[1].data;
9104
- } else if (isTextStorageNode(node)) {
9105
- return LiveText._deserialize(node, parentToChildren, pool);
9106
8727
  } else {
9107
8728
  throw new Error("Unexpected CRDT type");
9108
8729
  }
9109
8730
  }
9110
8731
  function isLiveStructure(value) {
9111
- return isLiveList(value) || isLiveMap(value) || isLiveObject(value) || isLiveText(value);
8732
+ return isLiveList(value) || isLiveMap(value) || isLiveObject(value);
9112
8733
  }
9113
8734
  function isLiveNode(value) {
9114
8735
  return isLiveStructure(value) || isLiveRegister(value);
@@ -9122,9 +8743,6 @@ function isLiveMap(value) {
9122
8743
  function isLiveObject(value) {
9123
8744
  return value instanceof LiveObject;
9124
8745
  }
9125
- function isLiveText(value) {
9126
- return value instanceof LiveText;
9127
- }
9128
8746
  function isLiveRegister(value) {
9129
8747
  return value instanceof LiveRegister;
9130
8748
  }
@@ -9134,14 +8752,14 @@ function cloneLson(value) {
9134
8752
  function liveNodeToLson(obj) {
9135
8753
  if (obj instanceof LiveRegister) {
9136
8754
  return obj.data;
9137
- } else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject || obj instanceof LiveText) {
8755
+ } else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject) {
9138
8756
  return obj;
9139
8757
  } else {
9140
8758
  return assertNever(obj, "Unknown AbstractCrdt");
9141
8759
  }
9142
8760
  }
9143
8761
  function lsonToLiveNode(value) {
9144
- if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList || value instanceof LiveText) {
8762
+ if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList) {
9145
8763
  return value;
9146
8764
  } else {
9147
8765
  return new LiveRegister(value);
@@ -9236,40 +8854,6 @@ function getTreesDiffOperations(currentItems, newItems) {
9236
8854
  }
9237
8855
  }
9238
8856
  }
9239
- if (crdt.type === CrdtType.TEXT) {
9240
- if (currentCrdt.type !== CrdtType.TEXT || stringifyOrLog(crdt.data) !== stringifyOrLog(currentCrdt.data) || crdt.version !== currentCrdt.version) {
9241
- ops.push({
9242
- type: OpCode.UPDATE_TEXT,
9243
- id,
9244
- baseVersion: currentCrdt.type === CrdtType.TEXT ? currentCrdt.version : 0,
9245
- version: crdt.version,
9246
- ops: [
9247
- {
9248
- type: "delete",
9249
- index: 0,
9250
- length: currentCrdt.type === CrdtType.TEXT ? currentCrdt.data.reduce(
9251
- (sum, segment) => sum + segment[0].length,
9252
- 0
9253
- ) : 0
9254
- },
9255
- ...crdt.data.map((segment, index, items) => {
9256
- const [text, attributes] = segment;
9257
- const insertIndex = items.slice(0, index).reduce((sum, item) => sum + item[0].length, 0);
9258
- return attributes === void 0 ? {
9259
- type: "insert",
9260
- index: insertIndex,
9261
- text
9262
- } : {
9263
- type: "insert",
9264
- index: insertIndex,
9265
- text,
9266
- attributes
9267
- };
9268
- })
9269
- ]
9270
- });
9271
- }
9272
- }
9273
8857
  if (crdt.parentKey !== currentCrdt.parentKey) {
9274
8858
  ops.push({
9275
8859
  type: OpCode.SET_PARENT_KEY,
@@ -9318,16 +8902,6 @@ function getTreesDiffOperations(currentItems, newItems) {
9318
8902
  parentKey: crdt.parentKey
9319
8903
  });
9320
8904
  break;
9321
- case CrdtType.TEXT:
9322
- ops.push({
9323
- type: OpCode.CREATE_TEXT,
9324
- id,
9325
- parentId: crdt.parentId,
9326
- parentKey: crdt.parentKey,
9327
- data: crdt.data,
9328
- version: crdt.version
9329
- });
9330
- break;
9331
8905
  }
9332
8906
  }
9333
8907
  });
@@ -9360,12 +8934,6 @@ function mergeListStorageUpdates(first, second) {
9360
8934
  updates: updates.concat(second.updates)
9361
8935
  };
9362
8936
  }
9363
- function mergeTextStorageUpdates(first, second) {
9364
- return {
9365
- ...second,
9366
- updates: first.updates.concat(second.updates)
9367
- };
9368
- }
9369
8937
  function mergeStorageUpdates(first, second) {
9370
8938
  if (first === void 0) {
9371
8939
  return second;
@@ -9376,8 +8944,6 @@ function mergeStorageUpdates(first, second) {
9376
8944
  return mergeMapStorageUpdates(first, second);
9377
8945
  } else if (first.type === "LiveList" && second.type === "LiveList") {
9378
8946
  return mergeListStorageUpdates(first, second);
9379
- } else if (first.type === "LiveText" && second.type === "LiveText") {
9380
- return mergeTextStorageUpdates(first, second);
9381
8947
  } else {
9382
8948
  }
9383
8949
  return second;
@@ -9964,14 +9530,14 @@ var ClientMsgCode = Object.freeze({
9964
9530
  // src/refs/ManagedOthers.ts
9965
9531
  function makeUser(conn, presence) {
9966
9532
  const { connectionId, id, info } = conn;
9967
- const canWrite = canWriteStorage(conn.scopes);
9533
+ const canWrite = hasPermissionCapability(conn.scopes, "storage", "write");
9968
9534
  return freeze(
9969
9535
  compactObject({
9970
9536
  connectionId,
9971
9537
  id,
9972
9538
  info,
9973
9539
  canWrite,
9974
- canComment: canComment(conn.scopes),
9540
+ canComment: hasPermissionCapability(conn.scopes, "comments", "write"),
9975
9541
  isReadOnly: !canWrite,
9976
9542
  // Deprecated, kept for backward-compatibility
9977
9543
  presence
@@ -10428,7 +9994,7 @@ function createRoom(options, config) {
10428
9994
  }
10429
9995
  function isStorageWritable() {
10430
9996
  const scopes = context.dynamicSessionInfoSig.get()?.scopes;
10431
- return scopes !== void 0 ? canWriteStorage(scopes) : true;
9997
+ return scopes !== void 0 ? hasPermissionCapability(scopes, "storage", "write") : true;
10432
9998
  }
10433
9999
  const eventHub = {
10434
10000
  status: makeEventSource(),
@@ -10489,14 +10055,22 @@ function createRoom(options, config) {
10489
10055
  if (staticSession === null || dynamicSession === null) {
10490
10056
  return null;
10491
10057
  } else {
10492
- const canWrite = canWriteStorage(dynamicSession.scopes);
10058
+ const canWrite = hasPermissionCapability(
10059
+ dynamicSession.scopes,
10060
+ "storage",
10061
+ "write"
10062
+ );
10493
10063
  return {
10494
10064
  connectionId: dynamicSession.actor,
10495
10065
  id: staticSession.userId,
10496
10066
  info: staticSession.userInfo,
10497
10067
  presence: myPresence,
10498
10068
  canWrite,
10499
- canComment: canComment(dynamicSession.scopes)
10069
+ canComment: hasPermissionCapability(
10070
+ dynamicSession.scopes,
10071
+ "comments",
10072
+ "write"
10073
+ )
10500
10074
  };
10501
10075
  }
10502
10076
  }
@@ -10662,7 +10236,7 @@ function createRoom(options, config) {
10662
10236
  );
10663
10237
  output.reverse.pushLeft(applyOpResult.reverse);
10664
10238
  }
10665
- if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_TEXT) {
10239
+ if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
10666
10240
  createdNodeIds.add(op.id);
10667
10241
  }
10668
10242
  }
@@ -10682,7 +10256,6 @@ function createRoom(options, config) {
10682
10256
  switch (op.type) {
10683
10257
  case OpCode.DELETE_OBJECT_KEY:
10684
10258
  case OpCode.UPDATE_OBJECT:
10685
- case OpCode.UPDATE_TEXT:
10686
10259
  case OpCode.DELETE_CRDT: {
10687
10260
  const node = context.pool.nodes.get(op.id);
10688
10261
  if (node === void 0) {
@@ -10707,7 +10280,6 @@ function createRoom(options, config) {
10707
10280
  case OpCode.CREATE_OBJECT:
10708
10281
  case OpCode.CREATE_LIST:
10709
10282
  case OpCode.CREATE_MAP:
10710
- case OpCode.CREATE_TEXT:
10711
10283
  case OpCode.CREATE_REGISTER: {
10712
10284
  if (op.parentId === void 0) {
10713
10285
  return { modified: false };
@@ -12098,7 +11670,11 @@ function isRoomEventName(value) {
12098
11670
  }
12099
11671
  function makeAuthDelegateForRoom(roomId, authManager) {
12100
11672
  return async () => {
12101
- return authManager.getAuthValue({ requestedScope: "room:read", roomId });
11673
+ return authManager.getAuthValue({
11674
+ roomId,
11675
+ resource: "presence",
11676
+ access: "read"
11677
+ });
12102
11678
  };
12103
11679
  }
12104
11680
  function makeCreateSocketDelegateForRoom(roomId, baseUrl, WebSocketPolyfill) {
@@ -12188,7 +11764,9 @@ function createClient(options) {
12188
11764
  ),
12189
11765
  authenticate: async () => {
12190
11766
  const resp = await authManager.getAuthValue({
12191
- requestedScope: "room:read"
11767
+ // TODO: Should we have permissions for AI Copilots?
11768
+ resource: "personal",
11769
+ access: "write"
12192
11770
  });
12193
11771
  if (resp.type === "public") {
12194
11772
  throw new StopRetrying(
@@ -12867,12 +12445,6 @@ function toPlainLson(lson) {
12867
12445
  liveblocksType: "LiveList",
12868
12446
  data: [...lson].map((item) => toPlainLson(item))
12869
12447
  };
12870
- } else if (lson instanceof LiveText) {
12871
- return {
12872
- liveblocksType: "LiveText",
12873
- data: lson.toJSON(),
12874
- version: lson.version
12875
- };
12876
12448
  } else {
12877
12449
  return lson;
12878
12450
  }
@@ -13054,7 +12626,6 @@ export {
13054
12626
  LiveList,
13055
12627
  LiveMap,
13056
12628
  LiveObject,
13057
- LiveText,
13058
12629
  LiveblocksError,
13059
12630
  MENTION_CHARACTER,
13060
12631
  MutableSignal,
@@ -13066,7 +12637,6 @@ export {
13066
12637
  SortedList,
13067
12638
  TextEditorType,
13068
12639
  WebsocketCloseCodes,
13069
- applyLiveTextOperations,
13070
12640
  asPos,
13071
12641
  assert,
13072
12642
  assertNever,
@@ -13104,7 +12674,10 @@ export {
13104
12674
  freeze,
13105
12675
  generateUrl,
13106
12676
  getMentionsFromCommentBody,
12677
+ getRoomPermissionConflicts,
13107
12678
  getSubscriptionKey,
12679
+ hasPermissionCapability,
12680
+ hasPermissionCapabilityAccess,
13108
12681
  html,
13109
12682
  htmlSafe,
13110
12683
  isCommentBodyLink,
@@ -13123,7 +12696,6 @@ export {
13123
12696
  isRegisterStorageNode,
13124
12697
  isRootStorageNode,
13125
12698
  isStartsWithOperator,
13126
- isTextStorageNode,
13127
12699
  isUrl,
13128
12700
  kInternal,
13129
12701
  keys,
@@ -13136,8 +12708,12 @@ export {
13136
12708
  nanoid,
13137
12709
  nn,
13138
12710
  nodeStreamToCompactNodes,
12711
+ normalizeRoomAccessesInput,
12712
+ normalizeRoomAccessesUpdateInput,
12713
+ normalizeRoomPermissionInput,
13139
12714
  objectToQuery,
13140
12715
  patchNotificationSettings,
12716
+ permissionCapabilitiesFromScopes,
13141
12717
  raise,
13142
12718
  resolveMentionsInCommentBody,
13143
12719
  sanitizeUrl,