@liveblocks/core 3.20.0-pre1 → 3.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +994 -423
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +228 -126
- package/dist/index.d.ts +228 -126
- package/dist/index.js +891 -320
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
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
|
|
9
|
+
var PKG_VERSION = "3.20.0";
|
|
10
10
|
var PKG_FORMAT = "cjs";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -701,6 +701,20 @@ var SortedList = class _SortedList {
|
|
|
701
701
|
get length() {
|
|
702
702
|
return this.#data.length;
|
|
703
703
|
}
|
|
704
|
+
/**
|
|
705
|
+
* Whether the given value is present, by identity. O(log n) plus the length
|
|
706
|
+
* of any run of items that share its sort key (normally 1). Bisects on the
|
|
707
|
+
* value's own key, so it only finds values sitting at their sorted position,
|
|
708
|
+
* which is true for any item currently in the list.
|
|
709
|
+
*/
|
|
710
|
+
includes(value) {
|
|
711
|
+
for (let i = bisectRight(this.#data, value, this.#lt) - 1; i >= 0 && !this.#lt(this.#data[i], value); i--) {
|
|
712
|
+
if (this.#data[i] === value) {
|
|
713
|
+
return true;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
704
718
|
*filter(predicate) {
|
|
705
719
|
for (const item of this.#data) {
|
|
706
720
|
if (predicate(item)) {
|
|
@@ -1556,7 +1570,6 @@ function isUrl(string) {
|
|
|
1556
1570
|
function createApiClient({
|
|
1557
1571
|
baseUrl,
|
|
1558
1572
|
authManager,
|
|
1559
|
-
currentUserId,
|
|
1560
1573
|
fetchPolyfill
|
|
1561
1574
|
}) {
|
|
1562
1575
|
const httpClient = new HttpClient(baseUrl, fetchPolyfill);
|
|
@@ -1564,8 +1577,9 @@ function createApiClient({
|
|
|
1564
1577
|
const result = await httpClient.get(
|
|
1565
1578
|
url`/v2/c/rooms/${options.roomId}/threads/delta`,
|
|
1566
1579
|
await authManager.getAuthValue({
|
|
1567
|
-
|
|
1568
|
-
|
|
1580
|
+
roomId: options.roomId,
|
|
1581
|
+
resource: "comments",
|
|
1582
|
+
access: "read"
|
|
1569
1583
|
}),
|
|
1570
1584
|
{
|
|
1571
1585
|
since: options.since.toISOString()
|
|
@@ -1603,8 +1617,9 @@ function createApiClient({
|
|
|
1603
1617
|
const result = await httpClient.get(
|
|
1604
1618
|
url`/v2/c/rooms/${options.roomId}/threads`,
|
|
1605
1619
|
await authManager.getAuthValue({
|
|
1606
|
-
|
|
1607
|
-
|
|
1620
|
+
roomId: options.roomId,
|
|
1621
|
+
resource: "comments",
|
|
1622
|
+
access: "read"
|
|
1608
1623
|
}),
|
|
1609
1624
|
{
|
|
1610
1625
|
cursor: options.cursor,
|
|
@@ -1648,8 +1663,9 @@ function createApiClient({
|
|
|
1648
1663
|
const result = await httpClient.get(
|
|
1649
1664
|
url`/v2/c/rooms/${options.roomId}/threads/comments/search`,
|
|
1650
1665
|
await authManager.getAuthValue({
|
|
1651
|
-
|
|
1652
|
-
|
|
1666
|
+
roomId: options.roomId,
|
|
1667
|
+
resource: "comments",
|
|
1668
|
+
access: "read"
|
|
1653
1669
|
}),
|
|
1654
1670
|
{
|
|
1655
1671
|
text: options.query.text,
|
|
@@ -1670,8 +1686,9 @@ function createApiClient({
|
|
|
1670
1686
|
const thread = await httpClient.post(
|
|
1671
1687
|
url`/v2/c/rooms/${options.roomId}/threads`,
|
|
1672
1688
|
await authManager.getAuthValue({
|
|
1673
|
-
|
|
1674
|
-
|
|
1689
|
+
roomId: options.roomId,
|
|
1690
|
+
resource: "comments",
|
|
1691
|
+
access: "write"
|
|
1675
1692
|
}),
|
|
1676
1693
|
{
|
|
1677
1694
|
id: threadId,
|
|
@@ -1690,8 +1707,9 @@ function createApiClient({
|
|
|
1690
1707
|
await httpClient.delete(
|
|
1691
1708
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}`,
|
|
1692
1709
|
await authManager.getAuthValue({
|
|
1693
|
-
|
|
1694
|
-
|
|
1710
|
+
roomId: options.roomId,
|
|
1711
|
+
resource: "comments",
|
|
1712
|
+
access: "write"
|
|
1695
1713
|
})
|
|
1696
1714
|
);
|
|
1697
1715
|
}
|
|
@@ -1699,8 +1717,9 @@ function createApiClient({
|
|
|
1699
1717
|
const response = await httpClient.rawGet(
|
|
1700
1718
|
url`/v2/c/rooms/${options.roomId}/thread-with-notification/${options.threadId}`,
|
|
1701
1719
|
await authManager.getAuthValue({
|
|
1702
|
-
|
|
1703
|
-
|
|
1720
|
+
roomId: options.roomId,
|
|
1721
|
+
resource: "comments",
|
|
1722
|
+
access: "read"
|
|
1704
1723
|
})
|
|
1705
1724
|
);
|
|
1706
1725
|
if (response.ok) {
|
|
@@ -1726,8 +1745,9 @@ function createApiClient({
|
|
|
1726
1745
|
return await httpClient.post(
|
|
1727
1746
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/metadata`,
|
|
1728
1747
|
await authManager.getAuthValue({
|
|
1729
|
-
|
|
1730
|
-
|
|
1748
|
+
roomId: options.roomId,
|
|
1749
|
+
resource: "comments",
|
|
1750
|
+
access: "write"
|
|
1731
1751
|
}),
|
|
1732
1752
|
options.metadata
|
|
1733
1753
|
);
|
|
@@ -1736,8 +1756,9 @@ function createApiClient({
|
|
|
1736
1756
|
return await httpClient.post(
|
|
1737
1757
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/metadata`,
|
|
1738
1758
|
await authManager.getAuthValue({
|
|
1739
|
-
|
|
1740
|
-
|
|
1759
|
+
roomId: options.roomId,
|
|
1760
|
+
resource: "comments",
|
|
1761
|
+
access: "write"
|
|
1741
1762
|
}),
|
|
1742
1763
|
options.metadata
|
|
1743
1764
|
);
|
|
@@ -1747,8 +1768,9 @@ function createApiClient({
|
|
|
1747
1768
|
const comment = await httpClient.post(
|
|
1748
1769
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments`,
|
|
1749
1770
|
await authManager.getAuthValue({
|
|
1750
|
-
|
|
1751
|
-
|
|
1771
|
+
roomId: options.roomId,
|
|
1772
|
+
resource: "comments",
|
|
1773
|
+
access: "write"
|
|
1752
1774
|
}),
|
|
1753
1775
|
{
|
|
1754
1776
|
id: commentId,
|
|
@@ -1763,8 +1785,9 @@ function createApiClient({
|
|
|
1763
1785
|
const comment = await httpClient.post(
|
|
1764
1786
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}`,
|
|
1765
1787
|
await authManager.getAuthValue({
|
|
1766
|
-
|
|
1767
|
-
|
|
1788
|
+
roomId: options.roomId,
|
|
1789
|
+
resource: "comments",
|
|
1790
|
+
access: "write"
|
|
1768
1791
|
}),
|
|
1769
1792
|
{
|
|
1770
1793
|
body: options.body,
|
|
@@ -1778,8 +1801,9 @@ function createApiClient({
|
|
|
1778
1801
|
await httpClient.delete(
|
|
1779
1802
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}`,
|
|
1780
1803
|
await authManager.getAuthValue({
|
|
1781
|
-
|
|
1782
|
-
|
|
1804
|
+
roomId: options.roomId,
|
|
1805
|
+
resource: "comments",
|
|
1806
|
+
access: "write"
|
|
1783
1807
|
})
|
|
1784
1808
|
);
|
|
1785
1809
|
}
|
|
@@ -1787,8 +1811,9 @@ function createApiClient({
|
|
|
1787
1811
|
const reaction = await httpClient.post(
|
|
1788
1812
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/reactions`,
|
|
1789
1813
|
await authManager.getAuthValue({
|
|
1790
|
-
|
|
1791
|
-
|
|
1814
|
+
roomId: options.roomId,
|
|
1815
|
+
resource: "comments",
|
|
1816
|
+
access: "write"
|
|
1792
1817
|
}),
|
|
1793
1818
|
{ emoji: options.emoji }
|
|
1794
1819
|
);
|
|
@@ -1798,8 +1823,9 @@ function createApiClient({
|
|
|
1798
1823
|
await httpClient.delete(
|
|
1799
1824
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/reactions/${options.emoji}`,
|
|
1800
1825
|
await authManager.getAuthValue({
|
|
1801
|
-
|
|
1802
|
-
|
|
1826
|
+
roomId: options.roomId,
|
|
1827
|
+
resource: "comments",
|
|
1828
|
+
access: "write"
|
|
1803
1829
|
})
|
|
1804
1830
|
);
|
|
1805
1831
|
}
|
|
@@ -1807,8 +1833,9 @@ function createApiClient({
|
|
|
1807
1833
|
await httpClient.post(
|
|
1808
1834
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/mark-as-resolved`,
|
|
1809
1835
|
await authManager.getAuthValue({
|
|
1810
|
-
|
|
1811
|
-
|
|
1836
|
+
roomId: options.roomId,
|
|
1837
|
+
resource: "comments",
|
|
1838
|
+
access: "write"
|
|
1812
1839
|
})
|
|
1813
1840
|
);
|
|
1814
1841
|
}
|
|
@@ -1816,8 +1843,9 @@ function createApiClient({
|
|
|
1816
1843
|
await httpClient.post(
|
|
1817
1844
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/mark-as-unresolved`,
|
|
1818
1845
|
await authManager.getAuthValue({
|
|
1819
|
-
|
|
1820
|
-
|
|
1846
|
+
roomId: options.roomId,
|
|
1847
|
+
resource: "comments",
|
|
1848
|
+
access: "write"
|
|
1821
1849
|
})
|
|
1822
1850
|
);
|
|
1823
1851
|
}
|
|
@@ -1825,8 +1853,9 @@ function createApiClient({
|
|
|
1825
1853
|
const subscription = await httpClient.post(
|
|
1826
1854
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/subscribe`,
|
|
1827
1855
|
await authManager.getAuthValue({
|
|
1828
|
-
|
|
1829
|
-
|
|
1856
|
+
roomId: options.roomId,
|
|
1857
|
+
resource: "comments",
|
|
1858
|
+
access: "read"
|
|
1830
1859
|
})
|
|
1831
1860
|
);
|
|
1832
1861
|
return convertToSubscriptionData(subscription);
|
|
@@ -1835,8 +1864,9 @@ function createApiClient({
|
|
|
1835
1864
|
await httpClient.post(
|
|
1836
1865
|
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/unsubscribe`,
|
|
1837
1866
|
await authManager.getAuthValue({
|
|
1838
|
-
|
|
1839
|
-
|
|
1867
|
+
roomId: options.roomId,
|
|
1868
|
+
resource: "comments",
|
|
1869
|
+
access: "read"
|
|
1840
1870
|
})
|
|
1841
1871
|
);
|
|
1842
1872
|
}
|
|
@@ -1892,8 +1922,9 @@ function createApiClient({
|
|
|
1892
1922
|
async () => httpClient.putBlob(
|
|
1893
1923
|
url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/upload/${encodeURIComponent(attachment.name)}`,
|
|
1894
1924
|
await authManager.getAuthValue({
|
|
1895
|
-
|
|
1896
|
-
|
|
1925
|
+
roomId,
|
|
1926
|
+
resource: "comments",
|
|
1927
|
+
access: "write"
|
|
1897
1928
|
}),
|
|
1898
1929
|
attachment.file,
|
|
1899
1930
|
{ fileSize: attachment.size },
|
|
@@ -1910,8 +1941,9 @@ function createApiClient({
|
|
|
1910
1941
|
async () => httpClient.post(
|
|
1911
1942
|
url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${encodeURIComponent(attachment.name)}`,
|
|
1912
1943
|
await authManager.getAuthValue({
|
|
1913
|
-
|
|
1914
|
-
|
|
1944
|
+
roomId,
|
|
1945
|
+
resource: "comments",
|
|
1946
|
+
access: "write"
|
|
1915
1947
|
}),
|
|
1916
1948
|
void 0,
|
|
1917
1949
|
{ signal: abortSignal },
|
|
@@ -1936,8 +1968,9 @@ function createApiClient({
|
|
|
1936
1968
|
async () => httpClient.putBlob(
|
|
1937
1969
|
url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${createMultiPartUpload.uploadId}/${String(partNumber)}`,
|
|
1938
1970
|
await authManager.getAuthValue({
|
|
1939
|
-
|
|
1940
|
-
|
|
1971
|
+
roomId,
|
|
1972
|
+
resource: "comments",
|
|
1973
|
+
access: "write"
|
|
1941
1974
|
}),
|
|
1942
1975
|
part,
|
|
1943
1976
|
void 0,
|
|
@@ -1960,8 +1993,9 @@ function createApiClient({
|
|
|
1960
1993
|
return httpClient.post(
|
|
1961
1994
|
url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${uploadId}/complete`,
|
|
1962
1995
|
await authManager.getAuthValue({
|
|
1963
|
-
|
|
1964
|
-
|
|
1996
|
+
roomId,
|
|
1997
|
+
resource: "comments",
|
|
1998
|
+
access: "write"
|
|
1965
1999
|
}),
|
|
1966
2000
|
{ parts: sortedUploadedParts },
|
|
1967
2001
|
{ signal: abortSignal }
|
|
@@ -1972,8 +2006,9 @@ function createApiClient({
|
|
|
1972
2006
|
await httpClient.rawDelete(
|
|
1973
2007
|
url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${uploadId}`,
|
|
1974
2008
|
await authManager.getAuthValue({
|
|
1975
|
-
|
|
1976
|
-
|
|
2009
|
+
roomId,
|
|
2010
|
+
resource: "comments",
|
|
2011
|
+
access: "write"
|
|
1977
2012
|
})
|
|
1978
2013
|
);
|
|
1979
2014
|
} catch (e8) {
|
|
@@ -1990,8 +2025,9 @@ function createApiClient({
|
|
|
1990
2025
|
const { urls } = await httpClient.post(
|
|
1991
2026
|
url`/v2/c/rooms/${roomId}/attachments/presigned-urls`,
|
|
1992
2027
|
await authManager.getAuthValue({
|
|
1993
|
-
|
|
1994
|
-
|
|
2028
|
+
roomId,
|
|
2029
|
+
resource: "comments",
|
|
2030
|
+
access: "read"
|
|
1995
2031
|
}),
|
|
1996
2032
|
{ attachmentIds }
|
|
1997
2033
|
);
|
|
@@ -2010,109 +2046,13 @@ function createApiClient({
|
|
|
2010
2046
|
const batch2 = getOrCreateAttachmentUrlsStore(options.roomId).batch;
|
|
2011
2047
|
return batch2.get(options.attachmentId);
|
|
2012
2048
|
}
|
|
2013
|
-
async function uploadChatAttachment(options) {
|
|
2014
|
-
const { chatId, attachment, signal } = options;
|
|
2015
|
-
const userId = currentUserId.get();
|
|
2016
|
-
if (userId === void 0) {
|
|
2017
|
-
throw new Error("Attachment upload requires an authenticated user.");
|
|
2018
|
-
}
|
|
2019
|
-
const ATTACHMENT_PART_SIZE = 5 * 1024 * 1024;
|
|
2020
|
-
if (options.attachment.file.size <= ATTACHMENT_PART_SIZE) {
|
|
2021
|
-
await httpClient.putBlob(
|
|
2022
|
-
url`/v2/c/chats/${chatId}/attachments/${attachment.id}/upload/${encodeURIComponent(attachment.file.name)}`,
|
|
2023
|
-
await authManager.getAuthValue({ requestedScope: "comments:read" }),
|
|
2024
|
-
attachment.file,
|
|
2025
|
-
{ fileSize: attachment.file.size },
|
|
2026
|
-
{ signal }
|
|
2027
|
-
);
|
|
2028
|
-
} else {
|
|
2029
|
-
const multipartUpload = await httpClient.post(
|
|
2030
|
-
url`/v2/c/chats/${chatId}/attachments/${attachment.id}/multipart/${encodeURIComponent(attachment.file.name)}`,
|
|
2031
|
-
await authManager.getAuthValue({ requestedScope: "comments:read" }),
|
|
2032
|
-
void 0,
|
|
2033
|
-
{ signal },
|
|
2034
|
-
{ fileSize: attachment.file.size }
|
|
2035
|
-
);
|
|
2036
|
-
try {
|
|
2037
|
-
const uploadedParts = [];
|
|
2038
|
-
const parts = [];
|
|
2039
|
-
let start = 0;
|
|
2040
|
-
while (start < attachment.file.size) {
|
|
2041
|
-
const end = Math.min(
|
|
2042
|
-
start + ATTACHMENT_PART_SIZE,
|
|
2043
|
-
attachment.file.size
|
|
2044
|
-
);
|
|
2045
|
-
parts.push({
|
|
2046
|
-
number: parts.length + 1,
|
|
2047
|
-
part: attachment.file.slice(start, end)
|
|
2048
|
-
});
|
|
2049
|
-
start = end;
|
|
2050
|
-
}
|
|
2051
|
-
uploadedParts.push(
|
|
2052
|
-
...await Promise.all(
|
|
2053
|
-
parts.map(async ({ number, part }) => {
|
|
2054
|
-
return await httpClient.putBlob(
|
|
2055
|
-
url`/v2/c/chats/${chatId}/attachments/${attachment.id}/multipart/${multipartUpload.uploadId}/${String(number)}`,
|
|
2056
|
-
await authManager.getAuthValue({
|
|
2057
|
-
requestedScope: "comments:read"
|
|
2058
|
-
}),
|
|
2059
|
-
part,
|
|
2060
|
-
void 0,
|
|
2061
|
-
{ signal }
|
|
2062
|
-
);
|
|
2063
|
-
})
|
|
2064
|
-
)
|
|
2065
|
-
);
|
|
2066
|
-
await httpClient.post(
|
|
2067
|
-
url`/v2/c/chats/${chatId}/attachments/${attachment.id}/multipart/${multipartUpload.uploadId}/complete`,
|
|
2068
|
-
await authManager.getAuthValue({ requestedScope: "comments:read" }),
|
|
2069
|
-
{ parts: uploadedParts.sort((a, b) => a.number - b.number) },
|
|
2070
|
-
{ signal }
|
|
2071
|
-
);
|
|
2072
|
-
} catch (err) {
|
|
2073
|
-
try {
|
|
2074
|
-
await httpClient.delete(
|
|
2075
|
-
url`/v2/c/chats/${chatId}/attachments/${attachment.id}/multipart/${multipartUpload.uploadId}`,
|
|
2076
|
-
await authManager.getAuthValue({ requestedScope: "comments:read" })
|
|
2077
|
-
);
|
|
2078
|
-
} catch (e9) {
|
|
2079
|
-
}
|
|
2080
|
-
throw err;
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
}
|
|
2084
|
-
const attachmentUrlsBatchStoresByChat = new DefaultMap((chatId) => {
|
|
2085
|
-
const batch2 = new Batch(
|
|
2086
|
-
async (batchedAttachmentIds) => {
|
|
2087
|
-
const attachmentIds = batchedAttachmentIds.flat();
|
|
2088
|
-
const { urls } = await httpClient.post(
|
|
2089
|
-
url`/v2/c/chats/${chatId}/attachments/presigned-urls`,
|
|
2090
|
-
await authManager.getAuthValue({
|
|
2091
|
-
requestedScope: "comments:read"
|
|
2092
|
-
}),
|
|
2093
|
-
{ attachmentIds }
|
|
2094
|
-
);
|
|
2095
|
-
return urls.map(
|
|
2096
|
-
(url2) => _nullishCoalesce(url2, () => ( new Error("There was an error while getting this attachment's URL")))
|
|
2097
|
-
);
|
|
2098
|
-
},
|
|
2099
|
-
{ delay: 50 }
|
|
2100
|
-
);
|
|
2101
|
-
return createBatchStore(batch2);
|
|
2102
|
-
});
|
|
2103
|
-
function getOrCreateChatAttachmentUrlsStore(chatId) {
|
|
2104
|
-
return attachmentUrlsBatchStoresByChat.getOrCreate(chatId);
|
|
2105
|
-
}
|
|
2106
|
-
function getChatAttachmentUrl(options) {
|
|
2107
|
-
const batch2 = getOrCreateChatAttachmentUrlsStore(options.chatId).batch;
|
|
2108
|
-
return batch2.get(options.attachmentId);
|
|
2109
|
-
}
|
|
2110
2049
|
async function getSubscriptionSettings(options) {
|
|
2111
2050
|
return httpClient.get(
|
|
2112
2051
|
url`/v2/c/rooms/${options.roomId}/subscription-settings`,
|
|
2113
2052
|
await authManager.getAuthValue({
|
|
2114
|
-
|
|
2115
|
-
|
|
2053
|
+
roomId: options.roomId,
|
|
2054
|
+
resource: "comments",
|
|
2055
|
+
access: "read"
|
|
2116
2056
|
}),
|
|
2117
2057
|
void 0,
|
|
2118
2058
|
{
|
|
@@ -2124,8 +2064,9 @@ function createApiClient({
|
|
|
2124
2064
|
return httpClient.post(
|
|
2125
2065
|
url`/v2/c/rooms/${options.roomId}/subscription-settings`,
|
|
2126
2066
|
await authManager.getAuthValue({
|
|
2127
|
-
|
|
2128
|
-
|
|
2067
|
+
roomId: options.roomId,
|
|
2068
|
+
resource: "comments",
|
|
2069
|
+
access: "read"
|
|
2129
2070
|
}),
|
|
2130
2071
|
options.settings
|
|
2131
2072
|
);
|
|
@@ -2137,8 +2078,9 @@ function createApiClient({
|
|
|
2137
2078
|
await httpClient.post(
|
|
2138
2079
|
url`/v2/c/rooms/${roomId}/inbox-notifications/read`,
|
|
2139
2080
|
await authManager.getAuthValue({
|
|
2140
|
-
|
|
2141
|
-
|
|
2081
|
+
roomId,
|
|
2082
|
+
resource: "comments",
|
|
2083
|
+
access: "read"
|
|
2142
2084
|
}),
|
|
2143
2085
|
{ inboxNotificationIds }
|
|
2144
2086
|
);
|
|
@@ -2158,8 +2100,9 @@ function createApiClient({
|
|
|
2158
2100
|
await httpClient.rawPost(
|
|
2159
2101
|
url`/v2/c/rooms/${options.roomId}/text-mentions`,
|
|
2160
2102
|
await authManager.getAuthValue({
|
|
2161
|
-
|
|
2162
|
-
|
|
2103
|
+
roomId: options.roomId,
|
|
2104
|
+
resource: "storage",
|
|
2105
|
+
access: "write"
|
|
2163
2106
|
}),
|
|
2164
2107
|
{
|
|
2165
2108
|
userId: options.mention.kind === "user" ? options.mention.id : void 0,
|
|
@@ -2173,8 +2116,9 @@ function createApiClient({
|
|
|
2173
2116
|
await httpClient.rawDelete(
|
|
2174
2117
|
url`/v2/c/rooms/${options.roomId}/text-mentions/${options.mentionId}`,
|
|
2175
2118
|
await authManager.getAuthValue({
|
|
2176
|
-
|
|
2177
|
-
|
|
2119
|
+
roomId: options.roomId,
|
|
2120
|
+
resource: "storage",
|
|
2121
|
+
access: "write"
|
|
2178
2122
|
})
|
|
2179
2123
|
);
|
|
2180
2124
|
}
|
|
@@ -2182,8 +2126,9 @@ function createApiClient({
|
|
|
2182
2126
|
return httpClient.rawGet(
|
|
2183
2127
|
url`/v2/c/rooms/${options.roomId}/y-version/${options.versionId}`,
|
|
2184
2128
|
await authManager.getAuthValue({
|
|
2185
|
-
|
|
2186
|
-
|
|
2129
|
+
roomId: options.roomId,
|
|
2130
|
+
resource: "storage",
|
|
2131
|
+
access: "read"
|
|
2187
2132
|
})
|
|
2188
2133
|
);
|
|
2189
2134
|
}
|
|
@@ -2191,8 +2136,9 @@ function createApiClient({
|
|
|
2191
2136
|
await httpClient.rawPost(
|
|
2192
2137
|
url`/v2/c/rooms/${options.roomId}/version`,
|
|
2193
2138
|
await authManager.getAuthValue({
|
|
2194
|
-
|
|
2195
|
-
|
|
2139
|
+
roomId: options.roomId,
|
|
2140
|
+
resource: "storage",
|
|
2141
|
+
access: "write"
|
|
2196
2142
|
})
|
|
2197
2143
|
);
|
|
2198
2144
|
}
|
|
@@ -2200,8 +2146,9 @@ function createApiClient({
|
|
|
2200
2146
|
await httpClient.rawPost(
|
|
2201
2147
|
url`/v2/c/rooms/${options.roomId}/text-metadata`,
|
|
2202
2148
|
await authManager.getAuthValue({
|
|
2203
|
-
|
|
2204
|
-
|
|
2149
|
+
roomId: options.roomId,
|
|
2150
|
+
resource: "storage",
|
|
2151
|
+
access: "read"
|
|
2205
2152
|
}),
|
|
2206
2153
|
{
|
|
2207
2154
|
type: options.type,
|
|
@@ -2213,8 +2160,9 @@ function createApiClient({
|
|
|
2213
2160
|
const result = await httpClient.post(
|
|
2214
2161
|
url`/v2/c/rooms/${options.roomId}/ai/contextual-prompt`,
|
|
2215
2162
|
await authManager.getAuthValue({
|
|
2216
|
-
|
|
2217
|
-
|
|
2163
|
+
roomId: options.roomId,
|
|
2164
|
+
resource: "storage",
|
|
2165
|
+
access: "read"
|
|
2218
2166
|
}),
|
|
2219
2167
|
{
|
|
2220
2168
|
prompt: options.prompt,
|
|
@@ -2236,8 +2184,9 @@ function createApiClient({
|
|
|
2236
2184
|
const result = await httpClient.get(
|
|
2237
2185
|
url`/v2/c/rooms/${options.roomId}/versions`,
|
|
2238
2186
|
await authManager.getAuthValue({
|
|
2239
|
-
|
|
2240
|
-
|
|
2187
|
+
roomId: options.roomId,
|
|
2188
|
+
resource: "storage",
|
|
2189
|
+
access: "read"
|
|
2241
2190
|
})
|
|
2242
2191
|
);
|
|
2243
2192
|
return {
|
|
@@ -2254,8 +2203,9 @@ function createApiClient({
|
|
|
2254
2203
|
const result = await httpClient.get(
|
|
2255
2204
|
url`/v2/c/rooms/${options.roomId}/versions/delta`,
|
|
2256
2205
|
await authManager.getAuthValue({
|
|
2257
|
-
|
|
2258
|
-
|
|
2206
|
+
roomId: options.roomId,
|
|
2207
|
+
resource: "storage",
|
|
2208
|
+
access: "read"
|
|
2259
2209
|
}),
|
|
2260
2210
|
{ since: options.since.toISOString() },
|
|
2261
2211
|
{ signal: options.signal }
|
|
@@ -2274,8 +2224,9 @@ function createApiClient({
|
|
|
2274
2224
|
const result = await httpClient.rawGet(
|
|
2275
2225
|
url`/v2/c/rooms/${options.roomId}/storage`,
|
|
2276
2226
|
await authManager.getAuthValue({
|
|
2277
|
-
|
|
2278
|
-
|
|
2227
|
+
roomId: options.roomId,
|
|
2228
|
+
resource: "storage",
|
|
2229
|
+
access: "read"
|
|
2279
2230
|
})
|
|
2280
2231
|
);
|
|
2281
2232
|
return await result.json();
|
|
@@ -2288,7 +2239,7 @@ function createApiClient({
|
|
|
2288
2239
|
}
|
|
2289
2240
|
const json = await httpClient.get(
|
|
2290
2241
|
url`/v2/c/inbox-notifications`,
|
|
2291
|
-
await authManager.getAuthValue({
|
|
2242
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2292
2243
|
{
|
|
2293
2244
|
cursor: _optionalChain([options, 'optionalAccess', _22 => _22.cursor]),
|
|
2294
2245
|
limit: PAGE_SIZE,
|
|
@@ -2314,7 +2265,7 @@ function createApiClient({
|
|
|
2314
2265
|
}
|
|
2315
2266
|
const json = await httpClient.get(
|
|
2316
2267
|
url`/v2/c/inbox-notifications/delta`,
|
|
2317
|
-
await authManager.getAuthValue({
|
|
2268
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2318
2269
|
{ since: options.since.toISOString(), query },
|
|
2319
2270
|
{ signal: options.signal }
|
|
2320
2271
|
);
|
|
@@ -2343,7 +2294,7 @@ function createApiClient({
|
|
|
2343
2294
|
}
|
|
2344
2295
|
const { count } = await httpClient.get(
|
|
2345
2296
|
url`/v2/c/inbox-notifications/count`,
|
|
2346
|
-
await authManager.getAuthValue({
|
|
2297
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2347
2298
|
{ query },
|
|
2348
2299
|
{ signal: _optionalChain([options, 'optionalAccess', _25 => _25.signal]) }
|
|
2349
2300
|
);
|
|
@@ -2352,7 +2303,7 @@ function createApiClient({
|
|
|
2352
2303
|
async function markAllInboxNotificationsAsRead() {
|
|
2353
2304
|
await httpClient.post(
|
|
2354
2305
|
url`/v2/c/inbox-notifications/read`,
|
|
2355
|
-
await authManager.getAuthValue({
|
|
2306
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2356
2307
|
{
|
|
2357
2308
|
inboxNotificationIds: "all"
|
|
2358
2309
|
}
|
|
@@ -2361,7 +2312,7 @@ function createApiClient({
|
|
|
2361
2312
|
async function markInboxNotificationsAsRead(inboxNotificationIds) {
|
|
2362
2313
|
await httpClient.post(
|
|
2363
2314
|
url`/v2/c/inbox-notifications/read`,
|
|
2364
|
-
await authManager.getAuthValue({
|
|
2315
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2365
2316
|
{
|
|
2366
2317
|
inboxNotificationIds
|
|
2367
2318
|
}
|
|
@@ -2381,19 +2332,19 @@ function createApiClient({
|
|
|
2381
2332
|
async function deleteAllInboxNotifications() {
|
|
2382
2333
|
await httpClient.delete(
|
|
2383
2334
|
url`/v2/c/inbox-notifications`,
|
|
2384
|
-
await authManager.getAuthValue({
|
|
2335
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" })
|
|
2385
2336
|
);
|
|
2386
2337
|
}
|
|
2387
2338
|
async function deleteInboxNotification(inboxNotificationId) {
|
|
2388
2339
|
await httpClient.delete(
|
|
2389
2340
|
url`/v2/c/inbox-notifications/${inboxNotificationId}`,
|
|
2390
|
-
await authManager.getAuthValue({
|
|
2341
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" })
|
|
2391
2342
|
);
|
|
2392
2343
|
}
|
|
2393
2344
|
async function getNotificationSettings(options) {
|
|
2394
2345
|
return httpClient.get(
|
|
2395
2346
|
url`/v2/c/notification-settings`,
|
|
2396
|
-
await authManager.getAuthValue({
|
|
2347
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2397
2348
|
void 0,
|
|
2398
2349
|
{ signal: _optionalChain([options, 'optionalAccess', _26 => _26.signal]) }
|
|
2399
2350
|
);
|
|
@@ -2401,7 +2352,7 @@ function createApiClient({
|
|
|
2401
2352
|
async function updateNotificationSettings(settings) {
|
|
2402
2353
|
return httpClient.post(
|
|
2403
2354
|
url`/v2/c/notification-settings`,
|
|
2404
|
-
await authManager.getAuthValue({
|
|
2355
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2405
2356
|
settings
|
|
2406
2357
|
);
|
|
2407
2358
|
}
|
|
@@ -2413,7 +2364,7 @@ function createApiClient({
|
|
|
2413
2364
|
const PAGE_SIZE = 50;
|
|
2414
2365
|
const json = await httpClient.get(
|
|
2415
2366
|
url`/v2/c/threads`,
|
|
2416
|
-
await authManager.getAuthValue({
|
|
2367
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2417
2368
|
{
|
|
2418
2369
|
cursor: _optionalChain([options, 'optionalAccess', _28 => _28.cursor]),
|
|
2419
2370
|
query,
|
|
@@ -2434,7 +2385,7 @@ function createApiClient({
|
|
|
2434
2385
|
async function getUserThreadsSince_experimental(options) {
|
|
2435
2386
|
const json = await httpClient.get(
|
|
2436
2387
|
url`/v2/c/threads/delta`,
|
|
2437
|
-
await authManager.getAuthValue({
|
|
2388
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2438
2389
|
{ since: options.since.toISOString() },
|
|
2439
2390
|
{ signal: options.signal }
|
|
2440
2391
|
);
|
|
@@ -2463,7 +2414,8 @@ function createApiClient({
|
|
|
2463
2414
|
const { groups: plainGroups } = await httpClient.post(
|
|
2464
2415
|
url`/v2/c/groups/find`,
|
|
2465
2416
|
await authManager.getAuthValue({
|
|
2466
|
-
|
|
2417
|
+
resource: "personal",
|
|
2418
|
+
access: "write"
|
|
2467
2419
|
}),
|
|
2468
2420
|
{ groupIds }
|
|
2469
2421
|
);
|
|
@@ -2482,7 +2434,7 @@ function createApiClient({
|
|
|
2482
2434
|
async function getUrlMetadata(_url) {
|
|
2483
2435
|
const { metadata } = await httpClient.get(
|
|
2484
2436
|
url`/v2/c/urls/metadata`,
|
|
2485
|
-
await authManager.getAuthValue({
|
|
2437
|
+
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2486
2438
|
{ url: _url }
|
|
2487
2439
|
);
|
|
2488
2440
|
return metadata;
|
|
@@ -2522,10 +2474,6 @@ function createApiClient({
|
|
|
2522
2474
|
getAttachmentUrl,
|
|
2523
2475
|
uploadAttachment,
|
|
2524
2476
|
getOrCreateAttachmentUrlsStore,
|
|
2525
|
-
// User attachments
|
|
2526
|
-
uploadChatAttachment,
|
|
2527
|
-
getOrCreateChatAttachmentUrlsStore,
|
|
2528
|
-
getChatAttachmentUrl,
|
|
2529
2477
|
// Room storage
|
|
2530
2478
|
streamStorage,
|
|
2531
2479
|
// Notifications
|
|
@@ -2631,7 +2579,7 @@ var HttpClient = class {
|
|
|
2631
2579
|
let body;
|
|
2632
2580
|
try {
|
|
2633
2581
|
body = await response.json();
|
|
2634
|
-
} catch (
|
|
2582
|
+
} catch (e9) {
|
|
2635
2583
|
body = {};
|
|
2636
2584
|
}
|
|
2637
2585
|
return body;
|
|
@@ -3831,7 +3779,7 @@ var ManagedSocket = class {
|
|
|
3831
3779
|
getStatus() {
|
|
3832
3780
|
try {
|
|
3833
3781
|
return toNewConnectionStatus(this.#machine);
|
|
3834
|
-
} catch (
|
|
3782
|
+
} catch (e10) {
|
|
3835
3783
|
return "initial";
|
|
3836
3784
|
}
|
|
3837
3785
|
}
|
|
@@ -5219,22 +5167,327 @@ function createReceivingToolInvocation(invocationId, name, partialArgsText = "")
|
|
|
5219
5167
|
};
|
|
5220
5168
|
}
|
|
5221
5169
|
|
|
5222
|
-
// src/
|
|
5223
|
-
var Permission =
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5170
|
+
// src/permissions.ts
|
|
5171
|
+
var Permission = {
|
|
5172
|
+
/**
|
|
5173
|
+
* Default permission for a room.
|
|
5174
|
+
*/
|
|
5175
|
+
Read: "*:read",
|
|
5176
|
+
Write: "*:write",
|
|
5177
|
+
/**
|
|
5178
|
+
* Legacy aliases for default room permissions.
|
|
5179
|
+
*/
|
|
5180
|
+
RoomWrite: "room:write",
|
|
5181
|
+
RoomRead: "room:read",
|
|
5182
|
+
/**
|
|
5183
|
+
* Storage
|
|
5184
|
+
*/
|
|
5185
|
+
StorageRead: "storage:read",
|
|
5186
|
+
StorageWrite: "storage:write",
|
|
5187
|
+
StorageNone: "storage:none",
|
|
5188
|
+
/**
|
|
5189
|
+
* Comments
|
|
5190
|
+
*/
|
|
5191
|
+
CommentsWrite: "comments:write",
|
|
5192
|
+
CommentsRead: "comments:read",
|
|
5193
|
+
CommentsNone: "comments:none",
|
|
5194
|
+
/**
|
|
5195
|
+
* Feeds
|
|
5196
|
+
*/
|
|
5197
|
+
FeedsRead: "feeds:read",
|
|
5198
|
+
FeedsWrite: "feeds:write",
|
|
5199
|
+
FeedsNone: "feeds:none",
|
|
5200
|
+
/**
|
|
5201
|
+
* Legacy
|
|
5202
|
+
*/
|
|
5203
|
+
LegacyRoomPresenceWrite: "room:presence:write"
|
|
5204
|
+
};
|
|
5205
|
+
var ACCESS_LEVELS = ["none", "read", "write"];
|
|
5206
|
+
var basePermissionScopes = /* @__PURE__ */ new Set([
|
|
5207
|
+
Permission.Read,
|
|
5208
|
+
Permission.Write,
|
|
5209
|
+
Permission.RoomRead,
|
|
5210
|
+
Permission.RoomWrite
|
|
5211
|
+
]);
|
|
5212
|
+
var ACCESS_LEVEL_RANKS = {
|
|
5213
|
+
none: 0,
|
|
5214
|
+
read: 1,
|
|
5215
|
+
write: 2
|
|
5216
|
+
};
|
|
5217
|
+
var PERMISSIONS_BY_RESOURCE = {
|
|
5218
|
+
room: {
|
|
5219
|
+
read: [Permission.Read, Permission.RoomRead],
|
|
5220
|
+
write: [Permission.Write, Permission.RoomWrite]
|
|
5221
|
+
},
|
|
5222
|
+
personal: {
|
|
5223
|
+
write: []
|
|
5224
|
+
},
|
|
5225
|
+
storage: {
|
|
5226
|
+
write: [Permission.StorageWrite],
|
|
5227
|
+
read: [Permission.StorageRead],
|
|
5228
|
+
none: [Permission.StorageNone]
|
|
5229
|
+
},
|
|
5230
|
+
comments: {
|
|
5231
|
+
write: [Permission.CommentsWrite],
|
|
5232
|
+
read: [Permission.CommentsRead],
|
|
5233
|
+
none: [Permission.CommentsNone]
|
|
5234
|
+
},
|
|
5235
|
+
feeds: {
|
|
5236
|
+
write: [Permission.FeedsWrite],
|
|
5237
|
+
read: [Permission.FeedsRead],
|
|
5238
|
+
none: [Permission.FeedsNone]
|
|
5239
|
+
}
|
|
5240
|
+
};
|
|
5241
|
+
var NO_PERMISSION_MATRIX = {
|
|
5242
|
+
room: "none",
|
|
5243
|
+
storage: "none",
|
|
5244
|
+
comments: "none",
|
|
5245
|
+
feeds: "none",
|
|
5246
|
+
personal: "none"
|
|
5247
|
+
};
|
|
5248
|
+
var BASE_PERMISSION_RESOURCE = "room";
|
|
5249
|
+
var ROOM_PERMISSION_RESOURCES = [
|
|
5250
|
+
"storage",
|
|
5251
|
+
"comments",
|
|
5252
|
+
"feeds"
|
|
5253
|
+
];
|
|
5254
|
+
var VALID_PERMISSIONS = new Set(Object.values(Permission));
|
|
5255
|
+
function isPermission(permission) {
|
|
5256
|
+
return VALID_PERMISSIONS.has(permission);
|
|
5237
5257
|
}
|
|
5258
|
+
function resolveResourceAccess(scopes, resource) {
|
|
5259
|
+
const permissions = PERMISSIONS_BY_RESOURCE[resource];
|
|
5260
|
+
let resourceAccess;
|
|
5261
|
+
for (const access of ACCESS_LEVELS) {
|
|
5262
|
+
const scopedPermissions = permissions[access];
|
|
5263
|
+
if (scopedPermissions !== void 0 && scopedPermissions.some((permission) => scopes.includes(permission))) {
|
|
5264
|
+
resourceAccess = access;
|
|
5265
|
+
}
|
|
5266
|
+
}
|
|
5267
|
+
return resourceAccess;
|
|
5268
|
+
}
|
|
5269
|
+
function permissionMatrixFromResolvedScopes(resolved) {
|
|
5270
|
+
if (!resolved.hasDefaultPermission) {
|
|
5271
|
+
return { ...NO_PERMISSION_MATRIX };
|
|
5272
|
+
}
|
|
5273
|
+
const matrix = {
|
|
5274
|
+
...NO_PERMISSION_MATRIX,
|
|
5275
|
+
[BASE_PERMISSION_RESOURCE]: resolved.baseAccess,
|
|
5276
|
+
personal: "write"
|
|
5277
|
+
};
|
|
5278
|
+
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5279
|
+
matrix[resource] = _nullishCoalesce(resolved.matrix[resource], () => ( resolved.baseAccess));
|
|
5280
|
+
}
|
|
5281
|
+
return matrix;
|
|
5282
|
+
}
|
|
5283
|
+
function permissionMatrixFromScopes(scopes) {
|
|
5284
|
+
return permissionMatrixFromResolvedScopes(resolvePermissionScopes(scopes));
|
|
5285
|
+
}
|
|
5286
|
+
function resolvePermissionScopes(scopes) {
|
|
5287
|
+
const hasDefaultPermission = scopes.includes(Permission.Write) || scopes.includes(Permission.Read) || scopes.includes(Permission.RoomWrite) || scopes.includes(Permission.RoomRead);
|
|
5288
|
+
const baseAccess = scopes.includes(Permission.Write) || scopes.includes(Permission.RoomWrite) ? "write" : scopes.includes(Permission.Read) || scopes.includes(Permission.RoomRead) ? "read" : "none";
|
|
5289
|
+
const matrix = {};
|
|
5290
|
+
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5291
|
+
const access = resolveResourceAccess(scopes, resource);
|
|
5292
|
+
if (access !== void 0) {
|
|
5293
|
+
matrix[resource] = access;
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
return { hasDefaultPermission, baseAccess, matrix };
|
|
5297
|
+
}
|
|
5298
|
+
function hasPermissionAccess(matrix, resource, requiredAccess) {
|
|
5299
|
+
const access = _nullishCoalesce(matrix[resource], () => ( "none"));
|
|
5300
|
+
return ACCESS_LEVEL_RANKS[access] >= ACCESS_LEVEL_RANKS[requiredAccess];
|
|
5301
|
+
}
|
|
5302
|
+
function resolveRoomPermissionMatrix(permissions, roomId) {
|
|
5303
|
+
const matchedPermissions = permissions.filter(
|
|
5304
|
+
(entry) => roomPatternMatches(entry.pattern, roomId)
|
|
5305
|
+
);
|
|
5306
|
+
if (matchedPermissions.length === 0) {
|
|
5307
|
+
return void 0;
|
|
5308
|
+
}
|
|
5309
|
+
let hasDefaultPermission = false;
|
|
5310
|
+
let baseAccess = "none";
|
|
5311
|
+
const explicitMatrix = {};
|
|
5312
|
+
const explicitSpecificity = {};
|
|
5313
|
+
for (const entry of matchedPermissions) {
|
|
5314
|
+
const resolved = resolvePermissionScopes(entry.scopes);
|
|
5315
|
+
const specificity = roomPatternSpecificity(entry.pattern);
|
|
5316
|
+
if (resolved.hasDefaultPermission) {
|
|
5317
|
+
hasDefaultPermission = true;
|
|
5318
|
+
baseAccess = strongestAccess(baseAccess, resolved.baseAccess);
|
|
5319
|
+
}
|
|
5320
|
+
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5321
|
+
const access = resolved.matrix[resource];
|
|
5322
|
+
if (access !== void 0) {
|
|
5323
|
+
const currentSpecificity = _nullishCoalesce(explicitSpecificity[resource], () => ( -1));
|
|
5324
|
+
if (specificity > currentSpecificity) {
|
|
5325
|
+
explicitMatrix[resource] = access;
|
|
5326
|
+
explicitSpecificity[resource] = specificity;
|
|
5327
|
+
} else if (specificity === currentSpecificity) {
|
|
5328
|
+
explicitMatrix[resource] = strongestAccess(
|
|
5329
|
+
_nullishCoalesce(explicitMatrix[resource], () => ( "none")),
|
|
5330
|
+
access
|
|
5331
|
+
);
|
|
5332
|
+
}
|
|
5333
|
+
}
|
|
5334
|
+
}
|
|
5335
|
+
}
|
|
5336
|
+
return permissionMatrixFromResolvedScopes({
|
|
5337
|
+
hasDefaultPermission,
|
|
5338
|
+
baseAccess,
|
|
5339
|
+
matrix: explicitMatrix
|
|
5340
|
+
});
|
|
5341
|
+
}
|
|
5342
|
+
function normalizeRoomPermissions(permissions) {
|
|
5343
|
+
if (!Array.isArray(permissions)) {
|
|
5344
|
+
throw new Error("Permission list must be an array");
|
|
5345
|
+
}
|
|
5346
|
+
const result = [];
|
|
5347
|
+
for (const permission of permissions) {
|
|
5348
|
+
if (!isPermission(permission)) {
|
|
5349
|
+
throw new Error(`Not a valid permission: ${permission}`);
|
|
5350
|
+
}
|
|
5351
|
+
result.push(permission);
|
|
5352
|
+
}
|
|
5353
|
+
return result;
|
|
5354
|
+
}
|
|
5355
|
+
function normalizeRoomAccesses(accesses) {
|
|
5356
|
+
if (accesses === void 0) {
|
|
5357
|
+
return void 0;
|
|
5358
|
+
}
|
|
5359
|
+
return Object.fromEntries(
|
|
5360
|
+
Object.entries(accesses).map(([id, permissions]) => [
|
|
5361
|
+
id,
|
|
5362
|
+
normalizeRoomPermissions(permissions)
|
|
5363
|
+
])
|
|
5364
|
+
);
|
|
5365
|
+
}
|
|
5366
|
+
function normalizeUpdateRoomAccesses(accesses) {
|
|
5367
|
+
if (accesses === void 0) {
|
|
5368
|
+
return void 0;
|
|
5369
|
+
}
|
|
5370
|
+
return Object.fromEntries(
|
|
5371
|
+
Object.entries(accesses).map(([id, permissions]) => [
|
|
5372
|
+
id,
|
|
5373
|
+
permissions === null ? null : normalizeRoomPermissions(permissions)
|
|
5374
|
+
])
|
|
5375
|
+
);
|
|
5376
|
+
}
|
|
5377
|
+
function permissionMatrixToScopes(matrix) {
|
|
5378
|
+
const scopes = [];
|
|
5379
|
+
const baseAccess = matrix.room;
|
|
5380
|
+
if (baseAccess !== "none") {
|
|
5381
|
+
scopes.push(permissionForAccessLevel(BASE_PERMISSION_RESOURCE, baseAccess));
|
|
5382
|
+
}
|
|
5383
|
+
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5384
|
+
const access = matrix[resource];
|
|
5385
|
+
if (access !== baseAccess) {
|
|
5386
|
+
scopes.push(permissionForAccessLevel(resource, access));
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5389
|
+
return scopes;
|
|
5390
|
+
}
|
|
5391
|
+
function mergeRoomPermissionScopes({
|
|
5392
|
+
defaultAccesses,
|
|
5393
|
+
groupsAccesses,
|
|
5394
|
+
userAccesses
|
|
5395
|
+
}) {
|
|
5396
|
+
const sources = [
|
|
5397
|
+
resolvePermissionScopes(defaultAccesses),
|
|
5398
|
+
mergeResolvedScopesByHighestAccess(
|
|
5399
|
+
groupsAccesses.map(resolvePermissionScopes)
|
|
5400
|
+
),
|
|
5401
|
+
resolvePermissionScopes(userAccesses)
|
|
5402
|
+
];
|
|
5403
|
+
const merged = {
|
|
5404
|
+
hasDefaultPermission: false,
|
|
5405
|
+
baseAccess: "none",
|
|
5406
|
+
matrix: {}
|
|
5407
|
+
};
|
|
5408
|
+
for (const source of sources) {
|
|
5409
|
+
if (source.hasDefaultPermission) {
|
|
5410
|
+
merged.hasDefaultPermission = true;
|
|
5411
|
+
merged.baseAccess = source.baseAccess;
|
|
5412
|
+
}
|
|
5413
|
+
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5414
|
+
const access = source.matrix[resource];
|
|
5415
|
+
if (access !== void 0) {
|
|
5416
|
+
merged.matrix[resource] = access;
|
|
5417
|
+
}
|
|
5418
|
+
}
|
|
5419
|
+
}
|
|
5420
|
+
return permissionMatrixToScopes(permissionMatrixFromResolvedScopes(merged));
|
|
5421
|
+
}
|
|
5422
|
+
function mergeResolvedScopesByHighestAccess(sources) {
|
|
5423
|
+
const merged = {
|
|
5424
|
+
hasDefaultPermission: false,
|
|
5425
|
+
baseAccess: "none",
|
|
5426
|
+
matrix: {}
|
|
5427
|
+
};
|
|
5428
|
+
for (const source of sources) {
|
|
5429
|
+
if (source.hasDefaultPermission) {
|
|
5430
|
+
merged.hasDefaultPermission = true;
|
|
5431
|
+
merged.baseAccess = strongestAccess(merged.baseAccess, source.baseAccess);
|
|
5432
|
+
}
|
|
5433
|
+
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5434
|
+
const access = source.matrix[resource];
|
|
5435
|
+
if (access !== void 0) {
|
|
5436
|
+
merged.matrix[resource] = strongestAccess(
|
|
5437
|
+
_nullishCoalesce(merged.matrix[resource], () => ( "none")),
|
|
5438
|
+
access
|
|
5439
|
+
);
|
|
5440
|
+
}
|
|
5441
|
+
}
|
|
5442
|
+
}
|
|
5443
|
+
return merged;
|
|
5444
|
+
}
|
|
5445
|
+
function permissionForAccessLevel(resource, access, field = resource) {
|
|
5446
|
+
const levels = PERMISSIONS_BY_RESOURCE[resource];
|
|
5447
|
+
const permissions = levels[access];
|
|
5448
|
+
if (permissions === void 0 || permissions.length === 0) {
|
|
5449
|
+
throw new Error(
|
|
5450
|
+
`Invalid permission level for ${field}: ${_nullishCoalesce(JSON.stringify(access), () => ( String(access)))}`
|
|
5451
|
+
);
|
|
5452
|
+
}
|
|
5453
|
+
return permissions[0];
|
|
5454
|
+
}
|
|
5455
|
+
function strongestAccess(left, right) {
|
|
5456
|
+
return ACCESS_LEVEL_RANKS[right] > ACCESS_LEVEL_RANKS[left] ? right : left;
|
|
5457
|
+
}
|
|
5458
|
+
function roomPatternMatches(pattern, roomId) {
|
|
5459
|
+
if (pattern.includes("*")) {
|
|
5460
|
+
return roomId.startsWith(pattern.replace("*", ""));
|
|
5461
|
+
}
|
|
5462
|
+
return pattern === roomId;
|
|
5463
|
+
}
|
|
5464
|
+
function roomPatternSpecificity(pattern) {
|
|
5465
|
+
return pattern.replace("*", "").length;
|
|
5466
|
+
}
|
|
5467
|
+
function validatePermissionsSet(scopes) {
|
|
5468
|
+
const unknownScopes = scopes.filter((scope) => !VALID_PERMISSIONS.has(scope));
|
|
5469
|
+
if (unknownScopes.length > 0) {
|
|
5470
|
+
return `Unknown permission scope(s): ${unknownScopes.join(", ")}`;
|
|
5471
|
+
}
|
|
5472
|
+
const baseScopes = scopes.filter((scope) => basePermissionScopes.has(scope));
|
|
5473
|
+
if (baseScopes.length !== 1) {
|
|
5474
|
+
return `Permissions must include exactly one of ${Permission.Read}, ${Permission.Write} (or the legacy aliases ${Permission.RoomRead}, ${Permission.RoomWrite}), got ${baseScopes.length === 0 ? "none" : baseScopes.join(", ")}`;
|
|
5475
|
+
}
|
|
5476
|
+
const seenFeatures = /* @__PURE__ */ new Set();
|
|
5477
|
+
for (const scope of scopes) {
|
|
5478
|
+
if (basePermissionScopes.has(scope) || scope === Permission.LegacyRoomPresenceWrite) {
|
|
5479
|
+
continue;
|
|
5480
|
+
}
|
|
5481
|
+
const feature = scope.slice(0, scope.indexOf(":"));
|
|
5482
|
+
if (seenFeatures.has(feature)) {
|
|
5483
|
+
return `Permissions can include at most one scope per feature, got multiple "${feature}" scopes`;
|
|
5484
|
+
}
|
|
5485
|
+
seenFeatures.add(feature);
|
|
5486
|
+
}
|
|
5487
|
+
return true;
|
|
5488
|
+
}
|
|
5489
|
+
|
|
5490
|
+
// src/protocol/AuthToken.ts
|
|
5238
5491
|
function isValidAuthTokenPayload(data) {
|
|
5239
5492
|
return isPlainObject(data) && (data.k === "acc" /* ACCESS_TOKEN */ || data.k === "id" /* ID_TOKEN */);
|
|
5240
5493
|
}
|
|
@@ -5273,47 +5526,22 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5273
5526
|
const authentication = prepareAuthentication(authOptions);
|
|
5274
5527
|
const seenTokens = /* @__PURE__ */ new Set();
|
|
5275
5528
|
const tokens = [];
|
|
5276
|
-
const expiryTimes = [];
|
|
5277
5529
|
const requestPromises = /* @__PURE__ */ new Map();
|
|
5278
5530
|
function reset() {
|
|
5279
5531
|
seenTokens.clear();
|
|
5280
5532
|
tokens.length = 0;
|
|
5281
|
-
expiryTimes.length = 0;
|
|
5282
5533
|
requestPromises.clear();
|
|
5283
5534
|
}
|
|
5284
|
-
function hasCorrespondingScopes(requestedScope, scopes) {
|
|
5285
|
-
if (requestedScope === "comments:read") {
|
|
5286
|
-
return scopes.includes("comments:read" /* CommentsRead */) || scopes.includes("comments:write" /* CommentsWrite */) || scopes.includes("room:read" /* Read */) || scopes.includes("room:write" /* Write */);
|
|
5287
|
-
} else if (requestedScope === "room:read") {
|
|
5288
|
-
return scopes.includes("room:read" /* Read */) || scopes.includes("room:write" /* Write */);
|
|
5289
|
-
}
|
|
5290
|
-
return false;
|
|
5291
|
-
}
|
|
5292
5535
|
function getCachedToken(requestOptions) {
|
|
5293
5536
|
const now2 = Math.ceil(Date.now() / 1e3);
|
|
5294
5537
|
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
5295
|
-
const
|
|
5296
|
-
|
|
5297
|
-
if (expiresAt <= now2) {
|
|
5538
|
+
const cachedToken = tokens[i];
|
|
5539
|
+
if (cachedToken.expiresAt <= now2) {
|
|
5298
5540
|
tokens.splice(i, 1);
|
|
5299
|
-
expiryTimes.splice(i, 1);
|
|
5300
5541
|
continue;
|
|
5301
5542
|
}
|
|
5302
|
-
if (
|
|
5303
|
-
return token;
|
|
5304
|
-
} else if (token.parsed.k === "acc" /* ACCESS_TOKEN */) {
|
|
5305
|
-
if (!requestOptions.roomId && Object.entries(token.parsed.perms).length === 0) {
|
|
5306
|
-
return token;
|
|
5307
|
-
}
|
|
5308
|
-
for (const [resource, scopes] of Object.entries(token.parsed.perms)) {
|
|
5309
|
-
if (!requestOptions.roomId) {
|
|
5310
|
-
if (resource.includes("*") && hasCorrespondingScopes(requestOptions.requestedScope, scopes)) {
|
|
5311
|
-
return token;
|
|
5312
|
-
}
|
|
5313
|
-
} else if (resource.includes("*") && requestOptions.roomId.startsWith(resource.replace("*", "")) || requestOptions.roomId === resource && hasCorrespondingScopes(requestOptions.requestedScope, scopes)) {
|
|
5314
|
-
return token;
|
|
5315
|
-
}
|
|
5316
|
-
}
|
|
5543
|
+
if (cachedTokenSatisfiesRequest(cachedToken, requestOptions)) {
|
|
5544
|
+
return cachedToken.token;
|
|
5317
5545
|
}
|
|
5318
5546
|
}
|
|
5319
5547
|
return void 0;
|
|
@@ -5331,11 +5559,15 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5331
5559
|
});
|
|
5332
5560
|
const parsed = parseAuthToken(response.token);
|
|
5333
5561
|
if (seenTokens.has(parsed.raw)) {
|
|
5562
|
+
const cachedToken = getCachedToken(options);
|
|
5563
|
+
if (_optionalChain([cachedToken, 'optionalAccess', _109 => _109.raw]) === parsed.raw) {
|
|
5564
|
+
return cachedToken;
|
|
5565
|
+
}
|
|
5334
5566
|
throw new StopRetrying(
|
|
5335
5567
|
"The same Liveblocks auth token was issued from the backend before. Caching Liveblocks tokens is not supported."
|
|
5336
5568
|
);
|
|
5337
5569
|
}
|
|
5338
|
-
_optionalChain([onAuthenticate, 'optionalCall',
|
|
5570
|
+
_optionalChain([onAuthenticate, 'optionalCall', _110 => _110(parsed.parsed)]);
|
|
5339
5571
|
return parsed;
|
|
5340
5572
|
}
|
|
5341
5573
|
if (authentication.type === "custom") {
|
|
@@ -5343,7 +5575,7 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5343
5575
|
if (response && typeof response === "object") {
|
|
5344
5576
|
if (typeof response.token === "string") {
|
|
5345
5577
|
const parsed = parseAuthToken(response.token);
|
|
5346
|
-
_optionalChain([onAuthenticate, 'optionalCall',
|
|
5578
|
+
_optionalChain([onAuthenticate, 'optionalCall', _111 => _111(parsed.parsed)]);
|
|
5347
5579
|
return parsed;
|
|
5348
5580
|
} else if (typeof response.error === "string") {
|
|
5349
5581
|
const reason = `Authentication failed: ${"reason" in response && typeof response.reason === "string" ? response.reason : "Forbidden"}`;
|
|
@@ -5371,11 +5603,12 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5371
5603
|
return { type: "secret", token: cachedToken };
|
|
5372
5604
|
}
|
|
5373
5605
|
let currentPromise;
|
|
5374
|
-
|
|
5375
|
-
|
|
5606
|
+
const requestKey = getAuthRequestKey(requestOptions);
|
|
5607
|
+
if (requestKey !== void 0) {
|
|
5608
|
+
currentPromise = requestPromises.get(requestKey);
|
|
5376
5609
|
if (currentPromise === void 0) {
|
|
5377
5610
|
currentPromise = makeAuthRequest(requestOptions);
|
|
5378
|
-
requestPromises.set(
|
|
5611
|
+
requestPromises.set(requestKey, currentPromise);
|
|
5379
5612
|
}
|
|
5380
5613
|
} else {
|
|
5381
5614
|
currentPromise = requestPromises.get("liveblocks-user-token");
|
|
@@ -5389,12 +5622,12 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5389
5622
|
const BUFFER = 30;
|
|
5390
5623
|
const expiresAt = Math.floor(Date.now() / 1e3) + (token.parsed.exp - token.parsed.iat) - BUFFER;
|
|
5391
5624
|
seenTokens.add(token.raw);
|
|
5392
|
-
|
|
5393
|
-
|
|
5625
|
+
const cachedToken2 = makeCachedToken(token, expiresAt);
|
|
5626
|
+
tokens.push(cachedToken2);
|
|
5394
5627
|
return { type: "secret", token };
|
|
5395
5628
|
} finally {
|
|
5396
|
-
if (
|
|
5397
|
-
requestPromises.delete(
|
|
5629
|
+
if (requestKey !== void 0) {
|
|
5630
|
+
requestPromises.delete(requestKey);
|
|
5398
5631
|
} else {
|
|
5399
5632
|
requestPromises.delete("liveblocks-user-token");
|
|
5400
5633
|
}
|
|
@@ -5405,6 +5638,43 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5405
5638
|
getAuthValue
|
|
5406
5639
|
};
|
|
5407
5640
|
}
|
|
5641
|
+
function getAuthRequestKey(request) {
|
|
5642
|
+
if (request.roomId === void 0) {
|
|
5643
|
+
return void 0;
|
|
5644
|
+
}
|
|
5645
|
+
return `${request.roomId}:${request.resource}:${request.access}`;
|
|
5646
|
+
}
|
|
5647
|
+
function makeCachedToken(token, expiresAt) {
|
|
5648
|
+
if (token.parsed.k === "acc" /* ACCESS_TOKEN */) {
|
|
5649
|
+
return {
|
|
5650
|
+
token,
|
|
5651
|
+
expiresAt,
|
|
5652
|
+
permissions: Object.entries(token.parsed.perms).map(
|
|
5653
|
+
([pattern, scopes]) => ({
|
|
5654
|
+
pattern,
|
|
5655
|
+
scopes: normalizeRoomPermissions(scopes)
|
|
5656
|
+
})
|
|
5657
|
+
)
|
|
5658
|
+
};
|
|
5659
|
+
}
|
|
5660
|
+
return { token, expiresAt };
|
|
5661
|
+
}
|
|
5662
|
+
function cachedTokenSatisfiesRequest(cachedToken, request) {
|
|
5663
|
+
if (cachedToken.token.parsed.k === "id" /* ID_TOKEN */) {
|
|
5664
|
+
return true;
|
|
5665
|
+
}
|
|
5666
|
+
if (request.resource === "personal") {
|
|
5667
|
+
return true;
|
|
5668
|
+
}
|
|
5669
|
+
if (request.roomId === void 0) {
|
|
5670
|
+
return false;
|
|
5671
|
+
}
|
|
5672
|
+
const matrix = resolveRoomPermissionMatrix(
|
|
5673
|
+
_nullishCoalesce(cachedToken.permissions, () => ( [])),
|
|
5674
|
+
request.roomId
|
|
5675
|
+
);
|
|
5676
|
+
return matrix !== void 0 && hasPermissionAccess(matrix, request.resource, request.access);
|
|
5677
|
+
}
|
|
5408
5678
|
function prepareAuthentication(authOptions) {
|
|
5409
5679
|
const { publicApiKey, authEndpoint } = authOptions;
|
|
5410
5680
|
if (authEndpoint !== void 0 && publicApiKey !== void 0) {
|
|
@@ -5502,6 +5772,9 @@ var OpCode = Object.freeze({
|
|
|
5502
5772
|
function isIgnoredOp(op) {
|
|
5503
5773
|
return op.type === OpCode.DELETE_CRDT && op.id === "ACK";
|
|
5504
5774
|
}
|
|
5775
|
+
function isCreateOp(op) {
|
|
5776
|
+
return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST;
|
|
5777
|
+
}
|
|
5505
5778
|
|
|
5506
5779
|
// src/protocol/StorageNode.ts
|
|
5507
5780
|
var CrdtType = Object.freeze({
|
|
@@ -5759,12 +6032,112 @@ function asPos(str) {
|
|
|
5759
6032
|
return isPos(str) ? str : convertToPos(str);
|
|
5760
6033
|
}
|
|
5761
6034
|
|
|
6035
|
+
// src/crdts/UnacknowledgedOps.ts
|
|
6036
|
+
var UnacknowledgedOps = class {
|
|
6037
|
+
// opId -> op
|
|
6038
|
+
#byOpId = /* @__PURE__ */ new Map();
|
|
6039
|
+
// position -> (opId -> Create op)
|
|
6040
|
+
#createOpsByPosition = /* @__PURE__ */ new Map();
|
|
6041
|
+
// parentId -> (opId -> Create op)
|
|
6042
|
+
#createOpsByParent = /* @__PURE__ */ new Map();
|
|
6043
|
+
// opIds of pending ops that were in flight when a connection died, so the
|
|
6044
|
+
// server may already have processed them. See isPossiblyStored().
|
|
6045
|
+
#possiblyStoredOpIds = /* @__PURE__ */ new Set();
|
|
6046
|
+
#posKey(parentId, parentKey) {
|
|
6047
|
+
return `${parentId}
|
|
6048
|
+
${parentKey}`;
|
|
6049
|
+
}
|
|
6050
|
+
get size() {
|
|
6051
|
+
return this.#byOpId.size;
|
|
6052
|
+
}
|
|
6053
|
+
/**
|
|
6054
|
+
* Mark the given Op as still unacknowledged.
|
|
6055
|
+
*/
|
|
6056
|
+
add(op) {
|
|
6057
|
+
this.#byOpId.set(op.opId, op);
|
|
6058
|
+
if (isCreateOp(op)) {
|
|
6059
|
+
const posKey = this.#posKey(op.parentId, op.parentKey);
|
|
6060
|
+
let atPosition = this.#createOpsByPosition.get(posKey);
|
|
6061
|
+
if (atPosition === void 0) {
|
|
6062
|
+
atPosition = /* @__PURE__ */ new Map();
|
|
6063
|
+
this.#createOpsByPosition.set(posKey, atPosition);
|
|
6064
|
+
}
|
|
6065
|
+
atPosition.set(op.opId, op);
|
|
6066
|
+
let inParent = this.#createOpsByParent.get(op.parentId);
|
|
6067
|
+
if (inParent === void 0) {
|
|
6068
|
+
inParent = /* @__PURE__ */ new Map();
|
|
6069
|
+
this.#createOpsByParent.set(op.parentId, inParent);
|
|
6070
|
+
}
|
|
6071
|
+
inParent.set(op.opId, op);
|
|
6072
|
+
}
|
|
6073
|
+
}
|
|
6074
|
+
/**
|
|
6075
|
+
* Drop the op with the given opId from the set, because the server has
|
|
6076
|
+
* acknowledged it (confirmed our own op, or signalled it was seen but
|
|
6077
|
+
* ignored).
|
|
6078
|
+
*/
|
|
6079
|
+
delete(opId) {
|
|
6080
|
+
const op = this.#byOpId.get(opId);
|
|
6081
|
+
if (op === void 0) {
|
|
6082
|
+
return;
|
|
6083
|
+
}
|
|
6084
|
+
this.#byOpId.delete(opId);
|
|
6085
|
+
this.#possiblyStoredOpIds.delete(opId);
|
|
6086
|
+
if (isCreateOp(op)) {
|
|
6087
|
+
const posKey = this.#posKey(op.parentId, op.parentKey);
|
|
6088
|
+
const atPosition = this.#createOpsByPosition.get(posKey);
|
|
6089
|
+
_optionalChain([atPosition, 'optionalAccess', _112 => _112.delete, 'call', _113 => _113(opId)]);
|
|
6090
|
+
if (atPosition !== void 0 && atPosition.size === 0) {
|
|
6091
|
+
this.#createOpsByPosition.delete(posKey);
|
|
6092
|
+
}
|
|
6093
|
+
const inParent = this.#createOpsByParent.get(op.parentId);
|
|
6094
|
+
_optionalChain([inParent, 'optionalAccess', _114 => _114.delete, 'call', _115 => _115(opId)]);
|
|
6095
|
+
if (inParent !== void 0 && inParent.size === 0) {
|
|
6096
|
+
this.#createOpsByParent.delete(op.parentId);
|
|
6097
|
+
}
|
|
6098
|
+
}
|
|
6099
|
+
}
|
|
6100
|
+
/**
|
|
6101
|
+
* The still-unacknowledged Create ops with the given `parentId` and
|
|
6102
|
+
* `parentKey` (targeting one exact position), in dispatch order. O(1) lookup.
|
|
6103
|
+
* Empty if none.
|
|
6104
|
+
*/
|
|
6105
|
+
getByParentIdAndKey(parentId, parentKey) {
|
|
6106
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _116 => _116.#createOpsByPosition, 'access', _117 => _117.get, 'call', _118 => _118(this.#posKey(parentId, parentKey)), 'optionalAccess', _119 => _119.values, 'call', _120 => _120()]), () => ( []));
|
|
6107
|
+
}
|
|
6108
|
+
/**
|
|
6109
|
+
* The still-unacknowledged Create ops with the given `parentId` (across all
|
|
6110
|
+
* positions), in dispatch order. O(1) lookup. Empty if none.
|
|
6111
|
+
*/
|
|
6112
|
+
getByParentId(parentId) {
|
|
6113
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _121 => _121.#createOpsByParent, 'access', _122 => _122.get, 'call', _123 => _123(parentId), 'optionalAccess', _124 => _124.values, 'call', _125 => _125()]), () => ( []));
|
|
6114
|
+
}
|
|
6115
|
+
/** All still-unacknowledged ops, in dispatch order. */
|
|
6116
|
+
values() {
|
|
6117
|
+
return this.#byOpId.values();
|
|
6118
|
+
}
|
|
6119
|
+
isPossiblyStored(opId) {
|
|
6120
|
+
return this.#possiblyStoredOpIds.has(opId);
|
|
6121
|
+
}
|
|
6122
|
+
/**
|
|
6123
|
+
* Mark every currently pending op as possibly stored on the server. Called
|
|
6124
|
+
* when the connection dies: all of these ops were in flight, and their
|
|
6125
|
+
* (possibly lost) acks would have been the only way to know their fate.
|
|
6126
|
+
*/
|
|
6127
|
+
markAllAsPossiblyStored() {
|
|
6128
|
+
for (const opId of this.#byOpId.keys()) {
|
|
6129
|
+
this.#possiblyStoredOpIds.add(opId);
|
|
6130
|
+
}
|
|
6131
|
+
}
|
|
6132
|
+
};
|
|
6133
|
+
|
|
5762
6134
|
// src/crdts/AbstractCrdt.ts
|
|
5763
6135
|
function createManagedPool(roomId, options) {
|
|
5764
6136
|
const {
|
|
5765
6137
|
getCurrentConnectionId,
|
|
5766
6138
|
onDispatch,
|
|
5767
|
-
isStorageWritable = () => true
|
|
6139
|
+
isStorageWritable = () => true,
|
|
6140
|
+
unacknowledgedOps = new UnacknowledgedOps()
|
|
5768
6141
|
} = options;
|
|
5769
6142
|
let clock = 0;
|
|
5770
6143
|
let opClock = 0;
|
|
@@ -5778,7 +6151,7 @@ function createManagedPool(roomId, options) {
|
|
|
5778
6151
|
generateId: () => `${getCurrentConnectionId()}:${clock++}`,
|
|
5779
6152
|
generateOpId: () => `${getCurrentConnectionId()}:${opClock++}`,
|
|
5780
6153
|
dispatch(ops, reverse, storageUpdates) {
|
|
5781
|
-
_optionalChain([onDispatch, 'optionalCall',
|
|
6154
|
+
_optionalChain([onDispatch, 'optionalCall', _126 => _126(ops, reverse, storageUpdates)]);
|
|
5782
6155
|
},
|
|
5783
6156
|
assertStorageIsWritable: () => {
|
|
5784
6157
|
if (!isStorageWritable()) {
|
|
@@ -5786,7 +6159,8 @@ function createManagedPool(roomId, options) {
|
|
|
5786
6159
|
"Cannot write to storage with a read only user, please ensure the user has write permissions"
|
|
5787
6160
|
);
|
|
5788
6161
|
}
|
|
5789
|
-
}
|
|
6162
|
+
},
|
|
6163
|
+
unacknowledgedOps
|
|
5790
6164
|
};
|
|
5791
6165
|
}
|
|
5792
6166
|
function crdtAsLiveNode(value) {
|
|
@@ -6068,11 +6442,9 @@ function childNodeLt(a, b) {
|
|
|
6068
6442
|
var LiveList = class _LiveList extends AbstractCrdt {
|
|
6069
6443
|
#items;
|
|
6070
6444
|
#implicitlyDeletedItems;
|
|
6071
|
-
#unacknowledgedSets;
|
|
6072
6445
|
constructor(items) {
|
|
6073
6446
|
super();
|
|
6074
6447
|
this.#implicitlyDeletedItems = /* @__PURE__ */ new WeakSet();
|
|
6075
|
-
this.#unacknowledgedSets = /* @__PURE__ */ new Map();
|
|
6076
6448
|
const nodes = [];
|
|
6077
6449
|
let lastPos;
|
|
6078
6450
|
for (const item of items) {
|
|
@@ -6102,12 +6474,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6102
6474
|
}
|
|
6103
6475
|
/**
|
|
6104
6476
|
* @internal
|
|
6105
|
-
*
|
|
6106
|
-
*
|
|
6107
|
-
*
|
|
6477
|
+
* Serializes this list (and its children) into Create ops. Each child's
|
|
6478
|
+
* create is tagged with the "set" intent (in the loop below) so that a list
|
|
6479
|
+
* created and immediately mutated doesn't transiently re-show its initial
|
|
6480
|
+
* items (flicker, https://github.com/liveblocks/liveblocks/pull/1177).
|
|
6108
6481
|
*
|
|
6109
|
-
* This is quite unintuitive and should disappear as soon as
|
|
6110
|
-
*
|
|
6482
|
+
* This is quite unintuitive and should disappear as soon as we introduce an
|
|
6483
|
+
* explicit LiveList.Set operation.
|
|
6111
6484
|
*/
|
|
6112
6485
|
_toOps(parentId, parentKey) {
|
|
6113
6486
|
if (this._id === void 0) {
|
|
@@ -6123,7 +6496,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6123
6496
|
ops.push(op);
|
|
6124
6497
|
for (const item of this.#items) {
|
|
6125
6498
|
const parentKey2 = item._getParentKeyOrThrow();
|
|
6126
|
-
const childOps =
|
|
6499
|
+
const childOps = addIntentToRootOp(
|
|
6127
6500
|
item._toOps(this._id, parentKey2),
|
|
6128
6501
|
"set"
|
|
6129
6502
|
);
|
|
@@ -6167,6 +6540,28 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6167
6540
|
(item) => item._getParentKeyOrThrow() === position
|
|
6168
6541
|
);
|
|
6169
6542
|
}
|
|
6543
|
+
/**
|
|
6544
|
+
* The opId of this list's still-unacknowledged "set" op at the given position,
|
|
6545
|
+
* or undefined if none. Derived from the room's unacknowledgedOps (the single
|
|
6546
|
+
* source of truth) rather than tracked in a per-instance map. The pool's
|
|
6547
|
+
* position index already scopes to this list's (parentId, position); the last
|
|
6548
|
+
* match wins, matching the original last-write-wins map semantics.
|
|
6549
|
+
*/
|
|
6550
|
+
#unacknowledgedSetOpIdAt(position) {
|
|
6551
|
+
if (this._pool === void 0 || this._id === void 0) {
|
|
6552
|
+
return void 0;
|
|
6553
|
+
}
|
|
6554
|
+
let opId;
|
|
6555
|
+
for (const op of this._pool.unacknowledgedOps.getByParentIdAndKey(
|
|
6556
|
+
this._id,
|
|
6557
|
+
position
|
|
6558
|
+
)) {
|
|
6559
|
+
if (op.intent === "set") {
|
|
6560
|
+
opId = op.opId;
|
|
6561
|
+
}
|
|
6562
|
+
}
|
|
6563
|
+
return opId;
|
|
6564
|
+
}
|
|
6170
6565
|
/** @internal */
|
|
6171
6566
|
_attach(id, pool) {
|
|
6172
6567
|
super._attach(id, pool);
|
|
@@ -6247,13 +6642,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6247
6642
|
if (deletedDelta) {
|
|
6248
6643
|
delta.push(deletedDelta);
|
|
6249
6644
|
}
|
|
6250
|
-
const unacknowledgedOpId = this.#
|
|
6251
|
-
if (unacknowledgedOpId !== void 0) {
|
|
6252
|
-
|
|
6253
|
-
return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
|
|
6254
|
-
} else {
|
|
6255
|
-
this.#unacknowledgedSets.delete(op.parentKey);
|
|
6256
|
-
}
|
|
6645
|
+
const unacknowledgedOpId = this.#unacknowledgedSetOpIdAt(op.parentKey);
|
|
6646
|
+
if (unacknowledgedOpId !== void 0 && unacknowledgedOpId !== op.opId) {
|
|
6647
|
+
return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
|
|
6257
6648
|
}
|
|
6258
6649
|
const indexOfItemWithSamePosition = this._indexOfPosition(op.parentKey);
|
|
6259
6650
|
const existingItem = this.#items.find((item) => item._id === op.id);
|
|
@@ -6344,11 +6735,92 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6344
6735
|
this.#shiftItemPosition(existingItemIndex, key);
|
|
6345
6736
|
}
|
|
6346
6737
|
const { newItem, newIndex } = this.#createAttachItemAndSort(op, key);
|
|
6738
|
+
const bumpDeltas = this.#bumpUnackedPushesAbove(key);
|
|
6347
6739
|
return {
|
|
6348
|
-
modified: makeUpdate(this, [
|
|
6740
|
+
modified: makeUpdate(this, [
|
|
6741
|
+
insertDelta(newIndex, newItem),
|
|
6742
|
+
...bumpDeltas
|
|
6743
|
+
]),
|
|
6349
6744
|
reverse: []
|
|
6350
6745
|
};
|
|
6351
6746
|
}
|
|
6747
|
+
/**
|
|
6748
|
+
* This list's own still-unacknowledged pushed items (their `intent: "push"`
|
|
6749
|
+
* Create op is still pending in the room's unacknowledgedOps). Derived from
|
|
6750
|
+
* the single source of truth, so an item drops out the instant its op is
|
|
6751
|
+
* acked, with no per-instance membership to leak. Yielded in push order.
|
|
6752
|
+
*
|
|
6753
|
+
* Excludes ops that may already be stored on the server (they were in
|
|
6754
|
+
* flight when a connection died, so their fate is unknown): the bump
|
|
6755
|
+
* prediction assumes the server has not processed the op yet, which is only
|
|
6756
|
+
* guaranteed for ops sent on the current connection. For these excluded
|
|
6757
|
+
* ops, the server's (re-)ack states the authoritative position; predicting
|
|
6758
|
+
* locally could produce a wrong position that no ack would correct.
|
|
6759
|
+
*
|
|
6760
|
+
* Restricted to items currently in `#items`: a pushed node whose op is still
|
|
6761
|
+
* pending may have been pulled out of the list (e.g. implicitly deleted by a
|
|
6762
|
+
* remote set, or removed by an undo) while still living in the pool, and such
|
|
6763
|
+
* a node must not be repositioned.
|
|
6764
|
+
*/
|
|
6765
|
+
*#unackedPushNodes() {
|
|
6766
|
+
if (this._pool === void 0 || this._id === void 0) {
|
|
6767
|
+
return;
|
|
6768
|
+
}
|
|
6769
|
+
for (const op of this._pool.unacknowledgedOps.getByParentId(this._id)) {
|
|
6770
|
+
if (op.intent !== "push") {
|
|
6771
|
+
continue;
|
|
6772
|
+
}
|
|
6773
|
+
if (this._pool.unacknowledgedOps.isPossiblyStored(op.opId)) {
|
|
6774
|
+
continue;
|
|
6775
|
+
}
|
|
6776
|
+
const node = this._pool.getNode(op.id);
|
|
6777
|
+
if (node !== void 0 && this.#items.includes(node)) {
|
|
6778
|
+
yield node;
|
|
6779
|
+
}
|
|
6780
|
+
}
|
|
6781
|
+
}
|
|
6782
|
+
/**
|
|
6783
|
+
* Optimistic no-flip for pushed items. When a remote op lands at or below my
|
|
6784
|
+
* still-unacked pushed items, those items must end up *after* it: FIFO plus
|
|
6785
|
+
* the room's serial processing guarantee the remote was processed first, so
|
|
6786
|
+
* my unacked pushes belong behind it. Re-chain the whole unacked-push block,
|
|
6787
|
+
* in push order, to sit after the highest confirmed sibling, so it keeps
|
|
6788
|
+
* rendering as a contiguous tail instead of getting interleaved. Local-only;
|
|
6789
|
+
* the real acks overwrite these keys with the (identical) server keys.
|
|
6790
|
+
*/
|
|
6791
|
+
#bumpUnackedPushesAbove(remoteKey) {
|
|
6792
|
+
const pending = new Set(this.#unackedPushNodes());
|
|
6793
|
+
if (pending.size === 0) {
|
|
6794
|
+
return [];
|
|
6795
|
+
}
|
|
6796
|
+
let minPending;
|
|
6797
|
+
for (const node of pending) {
|
|
6798
|
+
const pos = node._parentPos;
|
|
6799
|
+
if (minPending === void 0 || pos < minPending) {
|
|
6800
|
+
minPending = pos;
|
|
6801
|
+
}
|
|
6802
|
+
}
|
|
6803
|
+
if (remoteKey < nn(minPending)) {
|
|
6804
|
+
return [];
|
|
6805
|
+
}
|
|
6806
|
+
let base;
|
|
6807
|
+
for (const item of this.#items) {
|
|
6808
|
+
if (!pending.has(item)) {
|
|
6809
|
+
base = item._parentPos;
|
|
6810
|
+
}
|
|
6811
|
+
}
|
|
6812
|
+
const deltas = [];
|
|
6813
|
+
for (const node of pending) {
|
|
6814
|
+
const previousIndex = this.#items.findIndex((item) => item === node);
|
|
6815
|
+
base = makePosition(base);
|
|
6816
|
+
this.#updateItemPosition(node, base);
|
|
6817
|
+
const index = this.#items.findIndex((item) => item === node);
|
|
6818
|
+
if (index !== previousIndex) {
|
|
6819
|
+
deltas.push(moveDelta(previousIndex, index, node));
|
|
6820
|
+
}
|
|
6821
|
+
}
|
|
6822
|
+
return deltas;
|
|
6823
|
+
}
|
|
6352
6824
|
#applyInsertAck(op) {
|
|
6353
6825
|
const existingItem = this.#items.find((item) => item._id === op.id);
|
|
6354
6826
|
const key = asPos(op.parentKey);
|
|
@@ -6403,7 +6875,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6403
6875
|
#applyInsertUndoRedo(op) {
|
|
6404
6876
|
const { id, parentKey: key } = op;
|
|
6405
6877
|
const child = creationOpToLiveNode(op);
|
|
6406
|
-
if (_optionalChain([this, 'access',
|
|
6878
|
+
if (_optionalChain([this, 'access', _127 => _127._pool, 'optionalAccess', _128 => _128.getNode, 'call', _129 => _129(id)]) !== void 0) {
|
|
6407
6879
|
return { modified: false };
|
|
6408
6880
|
}
|
|
6409
6881
|
child._attach(id, nn(this._pool));
|
|
@@ -6411,8 +6883,8 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6411
6883
|
const existingItemIndex = this._indexOfPosition(key);
|
|
6412
6884
|
let newKey = key;
|
|
6413
6885
|
if (existingItemIndex !== -1) {
|
|
6414
|
-
const before2 = _optionalChain([this, 'access',
|
|
6415
|
-
const after2 = _optionalChain([this, 'access',
|
|
6886
|
+
const before2 = _optionalChain([this, 'access', _130 => _130.#items, 'access', _131 => _131.at, 'call', _132 => _132(existingItemIndex), 'optionalAccess', _133 => _133._parentPos]);
|
|
6887
|
+
const after2 = _optionalChain([this, 'access', _134 => _134.#items, 'access', _135 => _135.at, 'call', _136 => _136(existingItemIndex + 1), 'optionalAccess', _137 => _137._parentPos]);
|
|
6416
6888
|
newKey = makePosition(before2, after2);
|
|
6417
6889
|
child._setParentLink(this, newKey);
|
|
6418
6890
|
}
|
|
@@ -6426,10 +6898,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6426
6898
|
#applySetUndoRedo(op) {
|
|
6427
6899
|
const { id, parentKey: key } = op;
|
|
6428
6900
|
const child = creationOpToLiveNode(op);
|
|
6429
|
-
if (_optionalChain([this, 'access',
|
|
6901
|
+
if (_optionalChain([this, 'access', _138 => _138._pool, 'optionalAccess', _139 => _139.getNode, 'call', _140 => _140(id)]) !== void 0) {
|
|
6430
6902
|
return { modified: false };
|
|
6431
6903
|
}
|
|
6432
|
-
this.#unacknowledgedSets.set(key, nn(op.opId));
|
|
6433
6904
|
const indexOfItemWithSameKey = this._indexOfPosition(key);
|
|
6434
6905
|
child._attach(id, nn(this._pool));
|
|
6435
6906
|
child._setParentLink(this, key);
|
|
@@ -6439,7 +6910,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6439
6910
|
existingItem._detach();
|
|
6440
6911
|
this.#items.remove(existingItem);
|
|
6441
6912
|
this.#items.add(child);
|
|
6442
|
-
const reverse =
|
|
6913
|
+
const reverse = addIntentToRootOp(
|
|
6443
6914
|
existingItem._toOps(nn(this._id), key),
|
|
6444
6915
|
"set",
|
|
6445
6916
|
op.id
|
|
@@ -6548,7 +7019,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6548
7019
|
} else {
|
|
6549
7020
|
this.#updateItemPositionAt(
|
|
6550
7021
|
existingItemIndex,
|
|
6551
|
-
makePosition(newKey, _optionalChain([this, 'access',
|
|
7022
|
+
makePosition(newKey, _optionalChain([this, 'access', _141 => _141.#items, 'access', _142 => _142.at, 'call', _143 => _143(existingItemIndex + 1), 'optionalAccess', _144 => _144._parentPos]))
|
|
6552
7023
|
);
|
|
6553
7024
|
const previousIndex = this.#items.findIndex((item) => item === child);
|
|
6554
7025
|
this.#updateItemPosition(child, newKey);
|
|
@@ -6575,7 +7046,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6575
7046
|
this,
|
|
6576
7047
|
makePosition(
|
|
6577
7048
|
newKey,
|
|
6578
|
-
_optionalChain([this, 'access',
|
|
7049
|
+
_optionalChain([this, 'access', _145 => _145.#items, 'access', _146 => _146.at, 'call', _147 => _147(existingItemIndex + 1), 'optionalAccess', _148 => _148._parentPos])
|
|
6579
7050
|
)
|
|
6580
7051
|
);
|
|
6581
7052
|
this.#items.reposition(existingItem);
|
|
@@ -6599,7 +7070,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6599
7070
|
existingItemIndex,
|
|
6600
7071
|
makePosition(
|
|
6601
7072
|
newKey,
|
|
6602
|
-
_optionalChain([this, 'access',
|
|
7073
|
+
_optionalChain([this, 'access', _149 => _149.#items, 'access', _150 => _150.at, 'call', _151 => _151(existingItemIndex + 1), 'optionalAccess', _152 => _152._parentPos])
|
|
6603
7074
|
)
|
|
6604
7075
|
);
|
|
6605
7076
|
}
|
|
@@ -6627,7 +7098,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6627
7098
|
if (existingItemIndex !== -1) {
|
|
6628
7099
|
actualNewKey = makePosition(
|
|
6629
7100
|
newKey,
|
|
6630
|
-
_optionalChain([this, 'access',
|
|
7101
|
+
_optionalChain([this, 'access', _153 => _153.#items, 'access', _154 => _154.at, 'call', _155 => _155(existingItemIndex + 1), 'optionalAccess', _156 => _156._parentPos])
|
|
6631
7102
|
);
|
|
6632
7103
|
}
|
|
6633
7104
|
this.#updateItemPosition(child, actualNewKey);
|
|
@@ -6701,14 +7172,14 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6701
7172
|
* instead of resolving its position against the client's stale view.
|
|
6702
7173
|
*/
|
|
6703
7174
|
#injectAt(element, index, intent) {
|
|
6704
|
-
_optionalChain([this, 'access',
|
|
7175
|
+
_optionalChain([this, 'access', _157 => _157._pool, 'optionalAccess', _158 => _158.assertStorageIsWritable, 'call', _159 => _159()]);
|
|
6705
7176
|
if (index < 0 || index > this.#items.length) {
|
|
6706
7177
|
throw new Error(
|
|
6707
7178
|
`Cannot insert list item at index "${index}". index should be between 0 and ${this.#items.length}`
|
|
6708
7179
|
);
|
|
6709
7180
|
}
|
|
6710
|
-
const before2 = _optionalChain([this, 'access',
|
|
6711
|
-
const after2 = _optionalChain([this, 'access',
|
|
7181
|
+
const before2 = _optionalChain([this, 'access', _160 => _160.#items, 'access', _161 => _161.at, 'call', _162 => _162(index - 1), 'optionalAccess', _163 => _163._parentPos]);
|
|
7182
|
+
const after2 = _optionalChain([this, 'access', _164 => _164.#items, 'access', _165 => _165.at, 'call', _166 => _166(index), 'optionalAccess', _167 => _167._parentPos]);
|
|
6712
7183
|
const position = makePosition(before2, after2);
|
|
6713
7184
|
const value = lsonToLiveNode(element);
|
|
6714
7185
|
value._setParentLink(this, position);
|
|
@@ -6718,7 +7189,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6718
7189
|
value._attach(id, this._pool);
|
|
6719
7190
|
const ops = value._toOpsWithOpId(this._id, position, this._pool);
|
|
6720
7191
|
this._pool.dispatch(
|
|
6721
|
-
intent === "push" ?
|
|
7192
|
+
intent === "push" ? addIntentToRootOp(ops, "push") : ops,
|
|
6722
7193
|
[{ type: OpCode.DELETE_CRDT, id }],
|
|
6723
7194
|
/* @__PURE__ */ new Map([
|
|
6724
7195
|
[this._id, makeUpdate(this, [insertDelta(index, value)])]
|
|
@@ -6732,7 +7203,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6732
7203
|
* @param targetIndex The index where the element should be after moving.
|
|
6733
7204
|
*/
|
|
6734
7205
|
move(index, targetIndex) {
|
|
6735
|
-
_optionalChain([this, 'access',
|
|
7206
|
+
_optionalChain([this, 'access', _168 => _168._pool, 'optionalAccess', _169 => _169.assertStorageIsWritable, 'call', _170 => _170()]);
|
|
6736
7207
|
if (targetIndex < 0) {
|
|
6737
7208
|
throw new Error("targetIndex cannot be less than 0");
|
|
6738
7209
|
}
|
|
@@ -6750,11 +7221,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6750
7221
|
let beforePosition = null;
|
|
6751
7222
|
let afterPosition = null;
|
|
6752
7223
|
if (index < targetIndex) {
|
|
6753
|
-
afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access',
|
|
7224
|
+
afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access', _171 => _171.#items, 'access', _172 => _172.at, 'call', _173 => _173(targetIndex + 1), 'optionalAccess', _174 => _174._parentPos]);
|
|
6754
7225
|
beforePosition = this.#items.at(targetIndex)._parentPos;
|
|
6755
7226
|
} else {
|
|
6756
7227
|
afterPosition = this.#items.at(targetIndex)._parentPos;
|
|
6757
|
-
beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access',
|
|
7228
|
+
beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _175 => _175.#items, 'access', _176 => _176.at, 'call', _177 => _177(targetIndex - 1), 'optionalAccess', _178 => _178._parentPos]);
|
|
6758
7229
|
}
|
|
6759
7230
|
const position = makePosition(beforePosition, afterPosition);
|
|
6760
7231
|
const item = this.#items.at(index);
|
|
@@ -6789,7 +7260,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6789
7260
|
* @param index The index of the element to delete
|
|
6790
7261
|
*/
|
|
6791
7262
|
delete(index) {
|
|
6792
|
-
_optionalChain([this, 'access',
|
|
7263
|
+
_optionalChain([this, 'access', _179 => _179._pool, 'optionalAccess', _180 => _180.assertStorageIsWritable, 'call', _181 => _181()]);
|
|
6793
7264
|
if (index < 0 || index >= this.#items.length) {
|
|
6794
7265
|
throw new Error(
|
|
6795
7266
|
`Cannot delete list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
|
|
@@ -6822,7 +7293,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6822
7293
|
}
|
|
6823
7294
|
}
|
|
6824
7295
|
clear() {
|
|
6825
|
-
_optionalChain([this, 'access',
|
|
7296
|
+
_optionalChain([this, 'access', _182 => _182._pool, 'optionalAccess', _183 => _183.assertStorageIsWritable, 'call', _184 => _184()]);
|
|
6826
7297
|
if (this._pool) {
|
|
6827
7298
|
const ops = [];
|
|
6828
7299
|
const reverseOps = [];
|
|
@@ -6856,7 +7327,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6856
7327
|
}
|
|
6857
7328
|
}
|
|
6858
7329
|
set(index, item) {
|
|
6859
|
-
_optionalChain([this, 'access',
|
|
7330
|
+
_optionalChain([this, 'access', _185 => _185._pool, 'optionalAccess', _186 => _186.assertStorageIsWritable, 'call', _187 => _187()]);
|
|
6860
7331
|
if (index < 0 || index >= this.#items.length) {
|
|
6861
7332
|
throw new Error(
|
|
6862
7333
|
`Cannot set list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
|
|
@@ -6876,13 +7347,12 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6876
7347
|
value._attach(id, this._pool);
|
|
6877
7348
|
const storageUpdates = /* @__PURE__ */ new Map();
|
|
6878
7349
|
storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
|
|
6879
|
-
const ops =
|
|
7350
|
+
const ops = addIntentToRootOp(
|
|
6880
7351
|
value._toOpsWithOpId(this._id, position, this._pool),
|
|
6881
7352
|
"set",
|
|
6882
7353
|
existingId
|
|
6883
7354
|
);
|
|
6884
|
-
|
|
6885
|
-
const reverseOps = addIntentToOpTree(
|
|
7355
|
+
const reverseOps = addIntentToRootOp(
|
|
6886
7356
|
existingItem._toOps(this._id, position),
|
|
6887
7357
|
"set",
|
|
6888
7358
|
id
|
|
@@ -7016,7 +7486,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7016
7486
|
#shiftItemPosition(index, key) {
|
|
7017
7487
|
const shiftedPosition = makePosition(
|
|
7018
7488
|
key,
|
|
7019
|
-
this.#items.length > index + 1 ? _optionalChain([this, 'access',
|
|
7489
|
+
this.#items.length > index + 1 ? _optionalChain([this, 'access', _188 => _188.#items, 'access', _189 => _189.at, 'call', _190 => _190(index + 1), 'optionalAccess', _191 => _191._parentPos]) : void 0
|
|
7020
7490
|
);
|
|
7021
7491
|
this.#updateItemPositionAt(index, shiftedPosition);
|
|
7022
7492
|
}
|
|
@@ -7085,7 +7555,7 @@ function moveDelta(previousIndex, index, item) {
|
|
|
7085
7555
|
previousIndex
|
|
7086
7556
|
};
|
|
7087
7557
|
}
|
|
7088
|
-
function
|
|
7558
|
+
function addIntentToRootOp(ops, intent, deletedId) {
|
|
7089
7559
|
return ops.map((op, index) => {
|
|
7090
7560
|
if (index === 0) {
|
|
7091
7561
|
const firstOp = op;
|
|
@@ -7265,7 +7735,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7265
7735
|
* @param value The value of the element to add. Should be serializable to JSON.
|
|
7266
7736
|
*/
|
|
7267
7737
|
set(key, value) {
|
|
7268
|
-
_optionalChain([this, 'access',
|
|
7738
|
+
_optionalChain([this, 'access', _192 => _192._pool, 'optionalAccess', _193 => _193.assertStorageIsWritable, 'call', _194 => _194()]);
|
|
7269
7739
|
const oldValue = this.#map.get(key);
|
|
7270
7740
|
if (oldValue) {
|
|
7271
7741
|
oldValue._detach();
|
|
@@ -7311,7 +7781,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7311
7781
|
* @returns true if an element existed and has been removed, or false if the element does not exist.
|
|
7312
7782
|
*/
|
|
7313
7783
|
delete(key) {
|
|
7314
|
-
_optionalChain([this, 'access',
|
|
7784
|
+
_optionalChain([this, 'access', _195 => _195._pool, 'optionalAccess', _196 => _196.assertStorageIsWritable, 'call', _197 => _197()]);
|
|
7315
7785
|
const item = this.#map.get(key);
|
|
7316
7786
|
if (item === void 0) {
|
|
7317
7787
|
return false;
|
|
@@ -7741,6 +8211,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
7741
8211
|
const id = nn(this._id);
|
|
7742
8212
|
const parentKey = nn(child._parentKey);
|
|
7743
8213
|
const reverse = child._toOps(id, parentKey);
|
|
8214
|
+
const deletedItem = liveNodeToLson(child);
|
|
7744
8215
|
for (const [key, value] of this.#synced) {
|
|
7745
8216
|
if (value === child) {
|
|
7746
8217
|
this.#synced.delete(key);
|
|
@@ -7752,7 +8223,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
7752
8223
|
node: this,
|
|
7753
8224
|
type: "LiveObject",
|
|
7754
8225
|
updates: {
|
|
7755
|
-
[parentKey]: { type: "delete" }
|
|
8226
|
+
[parentKey]: { type: "delete", deletedItem }
|
|
7756
8227
|
}
|
|
7757
8228
|
};
|
|
7758
8229
|
return { modified: storageUpdate, reverse };
|
|
@@ -7922,20 +8393,20 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
7922
8393
|
* Caveat: this method will not add changes to the undo/redo stack.
|
|
7923
8394
|
*/
|
|
7924
8395
|
setLocal(key, value) {
|
|
7925
|
-
_optionalChain([this, 'access',
|
|
8396
|
+
_optionalChain([this, 'access', _198 => _198._pool, 'optionalAccess', _199 => _199.assertStorageIsWritable, 'call', _200 => _200()]);
|
|
7926
8397
|
const deleteResult = this.#prepareDelete(key);
|
|
7927
8398
|
this.#local.set(key, value);
|
|
7928
8399
|
this.invalidate();
|
|
7929
8400
|
if (this._pool !== void 0 && this._id !== void 0) {
|
|
7930
|
-
const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
7931
|
-
const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
7932
|
-
const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
8401
|
+
const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _201 => _201[0]]), () => ( []));
|
|
8402
|
+
const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _202 => _202[1]]), () => ( []));
|
|
8403
|
+
const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _203 => _203[2]]), () => ( /* @__PURE__ */ new Map()));
|
|
7933
8404
|
const existing = storageUpdates.get(this._id);
|
|
7934
8405
|
storageUpdates.set(this._id, {
|
|
7935
8406
|
node: this,
|
|
7936
8407
|
type: "LiveObject",
|
|
7937
8408
|
updates: {
|
|
7938
|
-
..._optionalChain([existing, 'optionalAccess',
|
|
8409
|
+
..._optionalChain([existing, 'optionalAccess', _204 => _204.updates]),
|
|
7939
8410
|
[key]: { type: "update" }
|
|
7940
8411
|
}
|
|
7941
8412
|
});
|
|
@@ -7955,7 +8426,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
7955
8426
|
* #synced or pool/id are unavailable. Does NOT dispatch.
|
|
7956
8427
|
*/
|
|
7957
8428
|
#prepareDelete(key) {
|
|
7958
|
-
_optionalChain([this, 'access',
|
|
8429
|
+
_optionalChain([this, 'access', _205 => _205._pool, 'optionalAccess', _206 => _206.assertStorageIsWritable, 'call', _207 => _207()]);
|
|
7959
8430
|
const k = key;
|
|
7960
8431
|
if (this.#local.has(k) && !this.#synced.has(k)) {
|
|
7961
8432
|
const oldValue2 = this.#local.get(k);
|
|
@@ -8031,7 +8502,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8031
8502
|
const result = this.#prepareDelete(key);
|
|
8032
8503
|
if (result) {
|
|
8033
8504
|
const [ops, reverse, storageUpdates] = result;
|
|
8034
|
-
_optionalChain([this, 'access',
|
|
8505
|
+
_optionalChain([this, 'access', _208 => _208._pool, 'optionalAccess', _209 => _209.dispatch, 'call', _210 => _210(ops, reverse, storageUpdates)]);
|
|
8035
8506
|
}
|
|
8036
8507
|
}
|
|
8037
8508
|
/**
|
|
@@ -8039,7 +8510,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8039
8510
|
* @param patch The object used to overrides properties
|
|
8040
8511
|
*/
|
|
8041
8512
|
update(patch) {
|
|
8042
|
-
_optionalChain([this, 'access',
|
|
8513
|
+
_optionalChain([this, 'access', _211 => _211._pool, 'optionalAccess', _212 => _212.assertStorageIsWritable, 'call', _213 => _213()]);
|
|
8043
8514
|
if (_LiveObject.detectLargeObjects) {
|
|
8044
8515
|
const data = {};
|
|
8045
8516
|
for (const [key, value] of this.#synced) {
|
|
@@ -8329,23 +8800,93 @@ function lsonToLiveNode(value) {
|
|
|
8329
8800
|
return new LiveRegister(value);
|
|
8330
8801
|
}
|
|
8331
8802
|
}
|
|
8332
|
-
function
|
|
8803
|
+
function dumpPool(pool) {
|
|
8804
|
+
const rows = Array.from(pool.nodes.values(), (node) => {
|
|
8805
|
+
const parent = node.parent;
|
|
8806
|
+
const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
|
|
8807
|
+
let value;
|
|
8808
|
+
if (node instanceof LiveRegister) {
|
|
8809
|
+
value = stringifyOrLog(node.data);
|
|
8810
|
+
} else if (node instanceof LiveList) {
|
|
8811
|
+
value = "<LiveList>";
|
|
8812
|
+
} else if (node instanceof LiveMap) {
|
|
8813
|
+
value = "<LiveMap>";
|
|
8814
|
+
} else {
|
|
8815
|
+
value = "<LiveObject>";
|
|
8816
|
+
}
|
|
8817
|
+
return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
|
|
8818
|
+
});
|
|
8819
|
+
rows.sort((a, b) => {
|
|
8820
|
+
if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
|
|
8821
|
+
if (a.key !== b.key) return a.key < b.key ? -1 : 1;
|
|
8822
|
+
return 0;
|
|
8823
|
+
});
|
|
8824
|
+
return rows.map(
|
|
8825
|
+
(r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
|
|
8826
|
+
).join("\n");
|
|
8827
|
+
}
|
|
8828
|
+
function isJsonEq(a, b) {
|
|
8829
|
+
if (a === b) {
|
|
8830
|
+
return true;
|
|
8831
|
+
}
|
|
8832
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
8833
|
+
return false;
|
|
8834
|
+
}
|
|
8835
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
8836
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
|
|
8837
|
+
return false;
|
|
8838
|
+
}
|
|
8839
|
+
for (let i = 0; i < a.length; i++) {
|
|
8840
|
+
if (!isJsonEq(a[i], b[i])) {
|
|
8841
|
+
return false;
|
|
8842
|
+
}
|
|
8843
|
+
}
|
|
8844
|
+
return true;
|
|
8845
|
+
}
|
|
8846
|
+
const aKeys = Object.keys(a);
|
|
8847
|
+
if (aKeys.length !== Object.keys(b).length) {
|
|
8848
|
+
return false;
|
|
8849
|
+
}
|
|
8850
|
+
for (const key of aKeys) {
|
|
8851
|
+
if (!isJsonEq(a[key], b[key])) {
|
|
8852
|
+
return false;
|
|
8853
|
+
}
|
|
8854
|
+
}
|
|
8855
|
+
return true;
|
|
8856
|
+
}
|
|
8857
|
+
function diffNodeMap(prev, next) {
|
|
8333
8858
|
const ops = [];
|
|
8334
|
-
|
|
8335
|
-
if (!
|
|
8859
|
+
prev.forEach((_, id) => {
|
|
8860
|
+
if (!next.get(id)) {
|
|
8336
8861
|
ops.push({ type: OpCode.DELETE_CRDT, id });
|
|
8337
8862
|
}
|
|
8338
8863
|
});
|
|
8339
|
-
|
|
8340
|
-
const currentCrdt =
|
|
8864
|
+
next.forEach((crdt, id) => {
|
|
8865
|
+
const currentCrdt = prev.get(id);
|
|
8341
8866
|
if (currentCrdt) {
|
|
8342
8867
|
if (crdt.type === CrdtType.OBJECT) {
|
|
8343
|
-
if (currentCrdt.type !== CrdtType.OBJECT
|
|
8344
|
-
ops.push({
|
|
8345
|
-
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8868
|
+
if (currentCrdt.type !== CrdtType.OBJECT) {
|
|
8869
|
+
ops.push({ type: OpCode.UPDATE_OBJECT, id, data: crdt.data });
|
|
8870
|
+
} else {
|
|
8871
|
+
const changed = /* @__PURE__ */ new Map();
|
|
8872
|
+
for (const key of Object.keys(crdt.data)) {
|
|
8873
|
+
const value = crdt.data[key];
|
|
8874
|
+
if (value !== void 0 && !isJsonEq(value, currentCrdt.data[key])) {
|
|
8875
|
+
changed.set(key, value);
|
|
8876
|
+
}
|
|
8877
|
+
}
|
|
8878
|
+
if (changed.size > 0) {
|
|
8879
|
+
ops.push({
|
|
8880
|
+
type: OpCode.UPDATE_OBJECT,
|
|
8881
|
+
id,
|
|
8882
|
+
data: Object.fromEntries(changed)
|
|
8883
|
+
});
|
|
8884
|
+
}
|
|
8885
|
+
for (const key of Object.keys(currentCrdt.data)) {
|
|
8886
|
+
if (!(key in crdt.data)) {
|
|
8887
|
+
ops.push({ type: OpCode.DELETE_OBJECT_KEY, id, key });
|
|
8888
|
+
}
|
|
8889
|
+
}
|
|
8349
8890
|
}
|
|
8350
8891
|
}
|
|
8351
8892
|
if (crdt.parentKey !== currentCrdt.parentKey) {
|
|
@@ -8456,7 +8997,7 @@ function sendToPanel(message, options) {
|
|
|
8456
8997
|
...message,
|
|
8457
8998
|
source: "liveblocks-devtools-client"
|
|
8458
8999
|
};
|
|
8459
|
-
if (!(_optionalChain([options, 'optionalAccess',
|
|
9000
|
+
if (!(_optionalChain([options, 'optionalAccess', _214 => _214.force]) || _bridgeActive)) {
|
|
8460
9001
|
return;
|
|
8461
9002
|
}
|
|
8462
9003
|
window.postMessage(fullMsg, "*");
|
|
@@ -8464,7 +9005,7 @@ function sendToPanel(message, options) {
|
|
|
8464
9005
|
var eventSource = makeEventSource();
|
|
8465
9006
|
if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
|
|
8466
9007
|
window.addEventListener("message", (event) => {
|
|
8467
|
-
if (event.source === window && _optionalChain([event, 'access',
|
|
9008
|
+
if (event.source === window && _optionalChain([event, 'access', _215 => _215.data, 'optionalAccess', _216 => _216.source]) === "liveblocks-devtools-panel") {
|
|
8468
9009
|
eventSource.notify(event.data);
|
|
8469
9010
|
} else {
|
|
8470
9011
|
}
|
|
@@ -8568,7 +9109,7 @@ function partialSyncConnection(room) {
|
|
|
8568
9109
|
});
|
|
8569
9110
|
}
|
|
8570
9111
|
function partialSyncStorage(room) {
|
|
8571
|
-
const root = room.
|
|
9112
|
+
const root = room.getStorageOrNull();
|
|
8572
9113
|
if (root) {
|
|
8573
9114
|
sendToPanel({
|
|
8574
9115
|
msg: "room::sync::partial",
|
|
@@ -8598,7 +9139,7 @@ function partialSyncOthers(room) {
|
|
|
8598
9139
|
}
|
|
8599
9140
|
}
|
|
8600
9141
|
function fullSync(room) {
|
|
8601
|
-
const root = room.
|
|
9142
|
+
const root = room.getStorageOrNull();
|
|
8602
9143
|
const me = room[kInternal].getSelf_forDevTools();
|
|
8603
9144
|
const others = room[kInternal].getOthers_forDevTools();
|
|
8604
9145
|
room.fetchYDoc("");
|
|
@@ -8606,7 +9147,7 @@ function fullSync(room) {
|
|
|
8606
9147
|
msg: "room::sync::full",
|
|
8607
9148
|
roomId: room.id,
|
|
8608
9149
|
status: room.getStatus(),
|
|
8609
|
-
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess',
|
|
9150
|
+
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _217 => _217.toTreeNode, 'call', _218 => _218("root"), 'access', _219 => _219.payload]), () => ( null)),
|
|
8610
9151
|
me,
|
|
8611
9152
|
others
|
|
8612
9153
|
});
|
|
@@ -9023,15 +9564,15 @@ var ClientMsgCode = Object.freeze({
|
|
|
9023
9564
|
|
|
9024
9565
|
// src/refs/ManagedOthers.ts
|
|
9025
9566
|
function makeUser(conn, presence) {
|
|
9026
|
-
const { connectionId, id, info } = conn;
|
|
9027
|
-
const canWrite =
|
|
9567
|
+
const { connectionId, id, info, access } = conn;
|
|
9568
|
+
const { canWrite, canComment } = access;
|
|
9028
9569
|
return freeze(
|
|
9029
9570
|
compactObject({
|
|
9030
9571
|
connectionId,
|
|
9031
9572
|
id,
|
|
9032
9573
|
info,
|
|
9033
9574
|
canWrite,
|
|
9034
|
-
canComment
|
|
9575
|
+
canComment,
|
|
9035
9576
|
isReadOnly: !canWrite,
|
|
9036
9577
|
// Deprecated, kept for backward-compatibility
|
|
9037
9578
|
presence
|
|
@@ -9102,7 +9643,7 @@ var ManagedOthers = class {
|
|
|
9102
9643
|
* Records a known connection. This records the connection ID and the
|
|
9103
9644
|
* associated metadata.
|
|
9104
9645
|
*/
|
|
9105
|
-
setConnection(connectionId, metaUserId, metaUserInfo,
|
|
9646
|
+
setConnection(connectionId, metaUserId, metaUserInfo, access) {
|
|
9106
9647
|
this.#internal.mutate((state) => {
|
|
9107
9648
|
state.connections.set(
|
|
9108
9649
|
connectionId,
|
|
@@ -9110,7 +9651,7 @@ var ManagedOthers = class {
|
|
|
9110
9651
|
connectionId,
|
|
9111
9652
|
id: metaUserId,
|
|
9112
9653
|
info: metaUserInfo,
|
|
9113
|
-
|
|
9654
|
+
access
|
|
9114
9655
|
})
|
|
9115
9656
|
);
|
|
9116
9657
|
if (!state.presences.has(connectionId)) {
|
|
@@ -9263,6 +9804,14 @@ function defaultMessageFromContext(context) {
|
|
|
9263
9804
|
|
|
9264
9805
|
// src/room.ts
|
|
9265
9806
|
var FEEDS_TIMEOUT = 5e3;
|
|
9807
|
+
function connectionAccessFromScopes(scopes) {
|
|
9808
|
+
const roomPermissions = normalizeRoomPermissions(scopes);
|
|
9809
|
+
const matrix = permissionMatrixFromScopes(roomPermissions);
|
|
9810
|
+
return {
|
|
9811
|
+
canWrite: hasPermissionAccess(matrix, "storage", "write"),
|
|
9812
|
+
canComment: hasPermissionAccess(matrix, "comments", "write")
|
|
9813
|
+
};
|
|
9814
|
+
}
|
|
9266
9815
|
function makeIdFactory(connectionId) {
|
|
9267
9816
|
let count = 0;
|
|
9268
9817
|
return () => `${connectionId}:${count++}`;
|
|
@@ -9285,15 +9834,15 @@ function installBackgroundTabSpy() {
|
|
|
9285
9834
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
9286
9835
|
const inBackgroundSince = { current: null };
|
|
9287
9836
|
function onVisibilityChange() {
|
|
9288
|
-
if (_optionalChain([doc, 'optionalAccess',
|
|
9837
|
+
if (_optionalChain([doc, 'optionalAccess', _220 => _220.visibilityState]) === "hidden") {
|
|
9289
9838
|
inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
|
|
9290
9839
|
} else {
|
|
9291
9840
|
inBackgroundSince.current = null;
|
|
9292
9841
|
}
|
|
9293
9842
|
}
|
|
9294
|
-
_optionalChain([doc, 'optionalAccess',
|
|
9843
|
+
_optionalChain([doc, 'optionalAccess', _221 => _221.addEventListener, 'call', _222 => _222("visibilitychange", onVisibilityChange)]);
|
|
9295
9844
|
const unsub = () => {
|
|
9296
|
-
_optionalChain([doc, 'optionalAccess',
|
|
9845
|
+
_optionalChain([doc, 'optionalAccess', _223 => _223.removeEventListener, 'call', _224 => _224("visibilitychange", onVisibilityChange)]);
|
|
9297
9846
|
};
|
|
9298
9847
|
return [inBackgroundSince, unsub];
|
|
9299
9848
|
}
|
|
@@ -9338,6 +9887,7 @@ function createRoom(options, config) {
|
|
|
9338
9887
|
delegates,
|
|
9339
9888
|
config.enableDebugLogging
|
|
9340
9889
|
);
|
|
9890
|
+
const unacknowledgedOps = new UnacknowledgedOps();
|
|
9341
9891
|
const context = {
|
|
9342
9892
|
buffer: {
|
|
9343
9893
|
flushTimerID: void 0,
|
|
@@ -9365,14 +9915,15 @@ function createRoom(options, config) {
|
|
|
9365
9915
|
pool: createManagedPool(roomId, {
|
|
9366
9916
|
getCurrentConnectionId,
|
|
9367
9917
|
onDispatch,
|
|
9368
|
-
isStorageWritable
|
|
9918
|
+
isStorageWritable,
|
|
9919
|
+
unacknowledgedOps
|
|
9369
9920
|
}),
|
|
9370
9921
|
root: void 0,
|
|
9371
9922
|
undoStack: [],
|
|
9372
9923
|
redoStack: [],
|
|
9373
9924
|
pausedHistory: null,
|
|
9374
9925
|
activeBatch: null,
|
|
9375
|
-
unacknowledgedOps
|
|
9926
|
+
unacknowledgedOps
|
|
9376
9927
|
};
|
|
9377
9928
|
const nodeMapBuffer = makeNodeMapBuffer();
|
|
9378
9929
|
const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
|
|
@@ -9433,12 +9984,13 @@ function createRoom(options, config) {
|
|
|
9433
9984
|
)
|
|
9434
9985
|
};
|
|
9435
9986
|
if (_getStorage$ !== null) {
|
|
9436
|
-
refreshStorage(
|
|
9987
|
+
refreshStorage();
|
|
9437
9988
|
}
|
|
9438
9989
|
flushNowOrSoon();
|
|
9439
9990
|
}
|
|
9440
9991
|
function onDidDisconnect() {
|
|
9441
9992
|
clearTimeout(context.buffer.flushTimerID);
|
|
9993
|
+
context.unacknowledgedOps.markAllAsPossiblyStored();
|
|
9442
9994
|
}
|
|
9443
9995
|
managedSocket.events.onMessage.subscribe(handleServerMessage);
|
|
9444
9996
|
managedSocket.events.statusDidChange.subscribe(onStatusDidChange);
|
|
@@ -9484,8 +10036,8 @@ function createRoom(options, config) {
|
|
|
9484
10036
|
}
|
|
9485
10037
|
}
|
|
9486
10038
|
function isStorageWritable() {
|
|
9487
|
-
const
|
|
9488
|
-
return
|
|
10039
|
+
const permissionMatrix = _optionalChain([context, 'access', _225 => _225.dynamicSessionInfoSig, 'access', _226 => _226.get, 'call', _227 => _227(), 'optionalAccess', _228 => _228.permissionMatrix]);
|
|
10040
|
+
return permissionMatrix !== void 0 ? hasPermissionAccess(permissionMatrix, "storage", "write") : true;
|
|
9489
10041
|
}
|
|
9490
10042
|
const eventHub = {
|
|
9491
10043
|
status: makeEventSource(),
|
|
@@ -9546,14 +10098,22 @@ function createRoom(options, config) {
|
|
|
9546
10098
|
if (staticSession === null || dynamicSession === null) {
|
|
9547
10099
|
return null;
|
|
9548
10100
|
} else {
|
|
9549
|
-
const canWrite =
|
|
10101
|
+
const canWrite = hasPermissionAccess(
|
|
10102
|
+
dynamicSession.permissionMatrix,
|
|
10103
|
+
"storage",
|
|
10104
|
+
"write"
|
|
10105
|
+
);
|
|
9550
10106
|
return {
|
|
9551
10107
|
connectionId: dynamicSession.actor,
|
|
9552
10108
|
id: staticSession.userId,
|
|
9553
10109
|
info: staticSession.userInfo,
|
|
9554
10110
|
presence: myPresence,
|
|
9555
10111
|
canWrite,
|
|
9556
|
-
canComment:
|
|
10112
|
+
canComment: hasPermissionAccess(
|
|
10113
|
+
dynamicSession.permissionMatrix,
|
|
10114
|
+
"comments",
|
|
10115
|
+
"write"
|
|
10116
|
+
)
|
|
9557
10117
|
};
|
|
9558
10118
|
}
|
|
9559
10119
|
}
|
|
@@ -9579,7 +10139,7 @@ function createRoom(options, config) {
|
|
|
9579
10139
|
for (const [id, crdt] of context.pool.nodes) {
|
|
9580
10140
|
currentItems.set(id, crdt._serialize());
|
|
9581
10141
|
}
|
|
9582
|
-
const ops =
|
|
10142
|
+
const ops = diffNodeMap(currentItems, nodes);
|
|
9583
10143
|
const result = applyRemoteOps(ops);
|
|
9584
10144
|
notify(result.updates);
|
|
9585
10145
|
} else {
|
|
@@ -9588,7 +10148,7 @@ function createRoom(options, config) {
|
|
|
9588
10148
|
context.pool
|
|
9589
10149
|
);
|
|
9590
10150
|
}
|
|
9591
|
-
const canWrite = _nullishCoalesce(_optionalChain([self, 'access',
|
|
10151
|
+
const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _229 => _229.get, 'call', _230 => _230(), 'optionalAccess', _231 => _231.canWrite]), () => ( true));
|
|
9592
10152
|
const root = context.root;
|
|
9593
10153
|
disableHistory(() => {
|
|
9594
10154
|
for (const key in context.initialStorage) {
|
|
@@ -9793,7 +10353,7 @@ function createRoom(options, config) {
|
|
|
9793
10353
|
}
|
|
9794
10354
|
context.myPresence.patch(patch);
|
|
9795
10355
|
if (context.activeBatch) {
|
|
9796
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10356
|
+
if (_optionalChain([options2, 'optionalAccess', _232 => _232.addToHistory])) {
|
|
9797
10357
|
context.activeBatch.reverseOps.pushLeft({
|
|
9798
10358
|
type: "presence",
|
|
9799
10359
|
data: oldValues
|
|
@@ -9802,7 +10362,7 @@ function createRoom(options, config) {
|
|
|
9802
10362
|
context.activeBatch.updates.presence = true;
|
|
9803
10363
|
} else {
|
|
9804
10364
|
flushNowOrSoon();
|
|
9805
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10365
|
+
if (_optionalChain([options2, 'optionalAccess', _233 => _233.addToHistory])) {
|
|
9806
10366
|
addToUndoStack([{ type: "presence", data: oldValues }]);
|
|
9807
10367
|
}
|
|
9808
10368
|
notify({ presence: true });
|
|
@@ -9842,7 +10402,9 @@ function createRoom(options, config) {
|
|
|
9842
10402
|
context.dynamicSessionInfoSig.set({
|
|
9843
10403
|
actor: message.actor,
|
|
9844
10404
|
nonce: message.nonce,
|
|
9845
|
-
|
|
10405
|
+
permissionMatrix: permissionMatrixFromScopes(
|
|
10406
|
+
normalizeRoomPermissions(message.scopes)
|
|
10407
|
+
),
|
|
9846
10408
|
meta: message.meta
|
|
9847
10409
|
});
|
|
9848
10410
|
context.idFactory = makeIdFactory(message.actor);
|
|
@@ -9863,7 +10425,7 @@ function createRoom(options, config) {
|
|
|
9863
10425
|
connectionId,
|
|
9864
10426
|
user.id,
|
|
9865
10427
|
user.info,
|
|
9866
|
-
user.scopes
|
|
10428
|
+
connectionAccessFromScopes(user.scopes)
|
|
9867
10429
|
);
|
|
9868
10430
|
}
|
|
9869
10431
|
return { type: "reset" };
|
|
@@ -9883,7 +10445,7 @@ function createRoom(options, config) {
|
|
|
9883
10445
|
message.actor,
|
|
9884
10446
|
message.id,
|
|
9885
10447
|
message.info,
|
|
9886
|
-
message.scopes
|
|
10448
|
+
connectionAccessFromScopes(message.scopes)
|
|
9887
10449
|
);
|
|
9888
10450
|
context.buffer.messages.push({
|
|
9889
10451
|
type: ClientMsgCode.UPDATE_PRESENCE,
|
|
@@ -9911,12 +10473,11 @@ function createRoom(options, config) {
|
|
|
9911
10473
|
}
|
|
9912
10474
|
}
|
|
9913
10475
|
function applyAndSendOfflineOps(unackedOps) {
|
|
9914
|
-
if (unackedOps.
|
|
10476
|
+
if (unackedOps.length === 0) {
|
|
9915
10477
|
return;
|
|
9916
10478
|
}
|
|
9917
10479
|
const messages = [];
|
|
9918
|
-
const
|
|
9919
|
-
const result = applyLocalOps(inOps);
|
|
10480
|
+
const result = applyLocalOps(unackedOps);
|
|
9920
10481
|
messages.push({
|
|
9921
10482
|
type: ClientMsgCode.UPDATE_STORAGE,
|
|
9922
10483
|
ops: result.opsToEmit
|
|
@@ -9980,11 +10541,11 @@ function createRoom(options, config) {
|
|
|
9980
10541
|
break;
|
|
9981
10542
|
}
|
|
9982
10543
|
case ServerMsgCode.STORAGE_CHUNK:
|
|
9983
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
10544
|
+
_optionalChain([stopwatch, 'optionalAccess', _234 => _234.lap, 'call', _235 => _235()]);
|
|
9984
10545
|
nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
|
|
9985
10546
|
break;
|
|
9986
10547
|
case ServerMsgCode.STORAGE_STREAM_END: {
|
|
9987
|
-
const timing = _optionalChain([stopwatch, 'optionalAccess',
|
|
10548
|
+
const timing = _optionalChain([stopwatch, 'optionalAccess', _236 => _236.stop, 'call', _237 => _237()]);
|
|
9988
10549
|
if (timing) {
|
|
9989
10550
|
const ms = (v) => `${v.toFixed(1)}ms`;
|
|
9990
10551
|
const rest = timing.laps.slice(1);
|
|
@@ -10119,11 +10680,11 @@ function createRoom(options, config) {
|
|
|
10119
10680
|
} else if (pendingFeedsRequests.has(requestId)) {
|
|
10120
10681
|
const pending = pendingFeedsRequests.get(requestId);
|
|
10121
10682
|
pendingFeedsRequests.delete(requestId);
|
|
10122
|
-
_optionalChain([pending, 'optionalAccess',
|
|
10683
|
+
_optionalChain([pending, 'optionalAccess', _238 => _238.reject, 'call', _239 => _239(err)]);
|
|
10123
10684
|
} else if (pendingFeedMessagesRequests.has(requestId)) {
|
|
10124
10685
|
const pending = pendingFeedMessagesRequests.get(requestId);
|
|
10125
10686
|
pendingFeedMessagesRequests.delete(requestId);
|
|
10126
|
-
_optionalChain([pending, 'optionalAccess',
|
|
10687
|
+
_optionalChain([pending, 'optionalAccess', _240 => _240.reject, 'call', _241 => _241(err)]);
|
|
10127
10688
|
}
|
|
10128
10689
|
eventHub.feeds.notify(message);
|
|
10129
10690
|
break;
|
|
@@ -10140,7 +10701,7 @@ function createRoom(options, config) {
|
|
|
10140
10701
|
const storageOps = context.buffer.storageOperations;
|
|
10141
10702
|
if (storageOps.length > 0) {
|
|
10142
10703
|
for (const op of storageOps) {
|
|
10143
|
-
context.unacknowledgedOps.
|
|
10704
|
+
context.unacknowledgedOps.add(op);
|
|
10144
10705
|
}
|
|
10145
10706
|
notifyStorageStatus();
|
|
10146
10707
|
}
|
|
@@ -10277,10 +10838,10 @@ function createRoom(options, config) {
|
|
|
10277
10838
|
timeoutId,
|
|
10278
10839
|
kind,
|
|
10279
10840
|
feedId,
|
|
10280
|
-
messageId: _optionalChain([options2, 'optionalAccess',
|
|
10281
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
10841
|
+
messageId: _optionalChain([options2, 'optionalAccess', _242 => _242.messageId]),
|
|
10842
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _243 => _243.expectedClientMessageId])
|
|
10282
10843
|
});
|
|
10283
|
-
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess',
|
|
10844
|
+
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _244 => _244.expectedClientMessageId]) === void 0) {
|
|
10284
10845
|
const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
|
|
10285
10846
|
q.push(requestId);
|
|
10286
10847
|
pendingAddMessageFifoByFeed.set(feedId, q);
|
|
@@ -10331,10 +10892,10 @@ function createRoom(options, config) {
|
|
|
10331
10892
|
}
|
|
10332
10893
|
if (!matched) {
|
|
10333
10894
|
const q = pendingAddMessageFifoByFeed.get(message.feedId);
|
|
10334
|
-
const headId = _optionalChain([q, 'optionalAccess',
|
|
10895
|
+
const headId = _optionalChain([q, 'optionalAccess', _245 => _245[0]]);
|
|
10335
10896
|
if (headId !== void 0) {
|
|
10336
10897
|
const pending = pendingFeedMutations.get(headId);
|
|
10337
|
-
if (_optionalChain([pending, 'optionalAccess',
|
|
10898
|
+
if (_optionalChain([pending, 'optionalAccess', _246 => _246.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
|
|
10338
10899
|
settleFeedMutation(headId, "ok");
|
|
10339
10900
|
}
|
|
10340
10901
|
}
|
|
@@ -10367,36 +10928,25 @@ function createRoom(options, config) {
|
|
|
10367
10928
|
}
|
|
10368
10929
|
}
|
|
10369
10930
|
function processInitialStorage(nodes) {
|
|
10370
|
-
const
|
|
10931
|
+
const unacknowledgedOps2 = [...context.unacknowledgedOps.values()];
|
|
10371
10932
|
createOrUpdateRootFromMessage(nodes);
|
|
10372
|
-
applyAndSendOfflineOps(
|
|
10373
|
-
_optionalChain([_resolveStoragePromise, 'optionalCall',
|
|
10933
|
+
applyAndSendOfflineOps(unacknowledgedOps2);
|
|
10934
|
+
_optionalChain([_resolveStoragePromise, 'optionalCall', _247 => _247()]);
|
|
10374
10935
|
notifyStorageStatus();
|
|
10375
10936
|
eventHub.storageDidLoad.notify();
|
|
10376
10937
|
}
|
|
10377
|
-
|
|
10378
|
-
if (!managedSocket.authValue) return;
|
|
10379
|
-
const nodes = new Map(
|
|
10380
|
-
await httpClient.streamStorage({ roomId })
|
|
10381
|
-
);
|
|
10382
|
-
processInitialStorage(nodes);
|
|
10383
|
-
}
|
|
10384
|
-
function refreshStorage(options2) {
|
|
10938
|
+
function refreshStorage() {
|
|
10385
10939
|
const messages = context.buffer.messages;
|
|
10386
|
-
if (
|
|
10387
|
-
void streamStorage();
|
|
10388
|
-
} else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
|
|
10940
|
+
if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
|
|
10389
10941
|
messages.push({ type: ClientMsgCode.FETCH_STORAGE });
|
|
10390
10942
|
nodeMapBuffer.take();
|
|
10391
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
10392
|
-
}
|
|
10393
|
-
if (options2.flush) {
|
|
10394
|
-
flushNowOrSoon();
|
|
10943
|
+
_optionalChain([stopwatch, 'optionalAccess', _248 => _248.start, 'call', _249 => _249()]);
|
|
10395
10944
|
}
|
|
10396
10945
|
}
|
|
10397
10946
|
function startLoadingStorage() {
|
|
10398
10947
|
if (_getStorage$ === null) {
|
|
10399
|
-
refreshStorage(
|
|
10948
|
+
refreshStorage();
|
|
10949
|
+
flushNowOrSoon();
|
|
10400
10950
|
_getStorage$ = new Promise((resolve) => {
|
|
10401
10951
|
_resolveStoragePromise = resolve;
|
|
10402
10952
|
});
|
|
@@ -10404,7 +10954,7 @@ function createRoom(options, config) {
|
|
|
10404
10954
|
}
|
|
10405
10955
|
return _getStorage$;
|
|
10406
10956
|
}
|
|
10407
|
-
function
|
|
10957
|
+
function getStorageOrNull() {
|
|
10408
10958
|
const root = context.root;
|
|
10409
10959
|
if (root !== void 0) {
|
|
10410
10960
|
return root;
|
|
@@ -10444,10 +10994,10 @@ function createRoom(options, config) {
|
|
|
10444
10994
|
const message = {
|
|
10445
10995
|
type: ClientMsgCode.FETCH_FEEDS,
|
|
10446
10996
|
requestId,
|
|
10447
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
10448
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
10449
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
10450
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
10997
|
+
cursor: _optionalChain([options2, 'optionalAccess', _250 => _250.cursor]),
|
|
10998
|
+
since: _optionalChain([options2, 'optionalAccess', _251 => _251.since]),
|
|
10999
|
+
limit: _optionalChain([options2, 'optionalAccess', _252 => _252.limit]),
|
|
11000
|
+
metadata: _optionalChain([options2, 'optionalAccess', _253 => _253.metadata])
|
|
10451
11001
|
};
|
|
10452
11002
|
context.buffer.messages.push(message);
|
|
10453
11003
|
flushNowOrSoon();
|
|
@@ -10467,9 +11017,9 @@ function createRoom(options, config) {
|
|
|
10467
11017
|
type: ClientMsgCode.FETCH_FEED_MESSAGES,
|
|
10468
11018
|
requestId,
|
|
10469
11019
|
feedId,
|
|
10470
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
10471
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
10472
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
11020
|
+
cursor: _optionalChain([options2, 'optionalAccess', _254 => _254.cursor]),
|
|
11021
|
+
since: _optionalChain([options2, 'optionalAccess', _255 => _255.since]),
|
|
11022
|
+
limit: _optionalChain([options2, 'optionalAccess', _256 => _256.limit])
|
|
10473
11023
|
};
|
|
10474
11024
|
context.buffer.messages.push(message);
|
|
10475
11025
|
flushNowOrSoon();
|
|
@@ -10488,8 +11038,8 @@ function createRoom(options, config) {
|
|
|
10488
11038
|
type: ClientMsgCode.ADD_FEED,
|
|
10489
11039
|
requestId,
|
|
10490
11040
|
feedId,
|
|
10491
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
10492
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11041
|
+
metadata: _optionalChain([options2, 'optionalAccess', _257 => _257.metadata]),
|
|
11042
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _258 => _258.createdAt])
|
|
10493
11043
|
};
|
|
10494
11044
|
context.buffer.messages.push(message);
|
|
10495
11045
|
flushNowOrSoon();
|
|
@@ -10523,15 +11073,15 @@ function createRoom(options, config) {
|
|
|
10523
11073
|
function addFeedMessage(feedId, data, options2) {
|
|
10524
11074
|
const requestId = nanoid();
|
|
10525
11075
|
const promise = registerFeedMutation(requestId, "add-message", feedId, {
|
|
10526
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
11076
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _259 => _259.id])
|
|
10527
11077
|
});
|
|
10528
11078
|
const message = {
|
|
10529
11079
|
type: ClientMsgCode.ADD_FEED_MESSAGE,
|
|
10530
11080
|
requestId,
|
|
10531
11081
|
feedId,
|
|
10532
11082
|
data,
|
|
10533
|
-
id: _optionalChain([options2, 'optionalAccess',
|
|
10534
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11083
|
+
id: _optionalChain([options2, 'optionalAccess', _260 => _260.id]),
|
|
11084
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _261 => _261.createdAt])
|
|
10535
11085
|
};
|
|
10536
11086
|
context.buffer.messages.push(message);
|
|
10537
11087
|
flushNowOrSoon();
|
|
@@ -10548,7 +11098,7 @@ function createRoom(options, config) {
|
|
|
10548
11098
|
feedId,
|
|
10549
11099
|
messageId,
|
|
10550
11100
|
data,
|
|
10551
|
-
updatedAt: _optionalChain([options2, 'optionalAccess',
|
|
11101
|
+
updatedAt: _optionalChain([options2, 'optionalAccess', _262 => _262.updatedAt])
|
|
10552
11102
|
};
|
|
10553
11103
|
context.buffer.messages.push(message);
|
|
10554
11104
|
flushNowOrSoon();
|
|
@@ -10718,7 +11268,7 @@ function createRoom(options, config) {
|
|
|
10718
11268
|
}
|
|
10719
11269
|
}
|
|
10720
11270
|
function isStorageReady() {
|
|
10721
|
-
return
|
|
11271
|
+
return getStorageOrNull() !== null;
|
|
10722
11272
|
}
|
|
10723
11273
|
async function waitUntilStorageReady() {
|
|
10724
11274
|
while (!isStorageReady()) {
|
|
@@ -10755,8 +11305,8 @@ function createRoom(options, config) {
|
|
|
10755
11305
|
async function getThreads(options2) {
|
|
10756
11306
|
return httpClient.getThreads({
|
|
10757
11307
|
roomId,
|
|
10758
|
-
query: _optionalChain([options2, 'optionalAccess',
|
|
10759
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
11308
|
+
query: _optionalChain([options2, 'optionalAccess', _263 => _263.query]),
|
|
11309
|
+
cursor: _optionalChain([options2, 'optionalAccess', _264 => _264.cursor])
|
|
10760
11310
|
});
|
|
10761
11311
|
}
|
|
10762
11312
|
async function getThread(threadId) {
|
|
@@ -10878,7 +11428,7 @@ function createRoom(options, config) {
|
|
|
10878
11428
|
function getSubscriptionSettings(options2) {
|
|
10879
11429
|
return httpClient.getSubscriptionSettings({
|
|
10880
11430
|
roomId,
|
|
10881
|
-
signal: _optionalChain([options2, 'optionalAccess',
|
|
11431
|
+
signal: _optionalChain([options2, 'optionalAccess', _265 => _265.signal])
|
|
10882
11432
|
});
|
|
10883
11433
|
}
|
|
10884
11434
|
function updateSubscriptionSettings(settings) {
|
|
@@ -10900,7 +11450,7 @@ function createRoom(options, config) {
|
|
|
10900
11450
|
{
|
|
10901
11451
|
[kInternal]: {
|
|
10902
11452
|
get presenceBuffer() {
|
|
10903
|
-
return deepClone(_nullishCoalesce(_optionalChain([context, 'access',
|
|
11453
|
+
return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _266 => _266.buffer, 'access', _267 => _267.presenceUpdates, 'optionalAccess', _268 => _268.data]), () => ( null)));
|
|
10904
11454
|
},
|
|
10905
11455
|
// prettier-ignore
|
|
10906
11456
|
get undoStack() {
|
|
@@ -10915,9 +11465,9 @@ function createRoom(options, config) {
|
|
|
10915
11465
|
return context.yjsProvider;
|
|
10916
11466
|
},
|
|
10917
11467
|
setYjsProvider(newProvider) {
|
|
10918
|
-
_optionalChain([context, 'access',
|
|
11468
|
+
_optionalChain([context, 'access', _269 => _269.yjsProvider, 'optionalAccess', _270 => _270.off, 'call', _271 => _271("status", yjsStatusDidChange)]);
|
|
10919
11469
|
context.yjsProvider = newProvider;
|
|
10920
|
-
_optionalChain([newProvider, 'optionalAccess',
|
|
11470
|
+
_optionalChain([newProvider, 'optionalAccess', _272 => _272.on, 'call', _273 => _273("status", yjsStatusDidChange)]);
|
|
10921
11471
|
context.yjsProviderDidChange.notify();
|
|
10922
11472
|
},
|
|
10923
11473
|
yjsProviderDidChange: context.yjsProviderDidChange.observable,
|
|
@@ -10958,6 +11508,13 @@ function createRoom(options, config) {
|
|
|
10958
11508
|
connect: () => managedSocket.connect(),
|
|
10959
11509
|
reconnect: () => managedSocket.reconnect(),
|
|
10960
11510
|
disconnect: () => managedSocket.disconnect(),
|
|
11511
|
+
_dump: () => {
|
|
11512
|
+
const n = context.pool.nodes.size;
|
|
11513
|
+
return `Room "${roomId}" (${n} node${n === 1 ? "" : "s"}):
|
|
11514
|
+
${dumpPool(
|
|
11515
|
+
context.pool
|
|
11516
|
+
)}`;
|
|
11517
|
+
},
|
|
10961
11518
|
destroy: () => {
|
|
10962
11519
|
pendingFeedsRequests.forEach(
|
|
10963
11520
|
(request) => request.reject(new Error("Room destroyed"))
|
|
@@ -10970,7 +11527,7 @@ function createRoom(options, config) {
|
|
|
10970
11527
|
source.dispose();
|
|
10971
11528
|
}
|
|
10972
11529
|
eventHub.roomWillDestroy.notify();
|
|
10973
|
-
_optionalChain([context, 'access',
|
|
11530
|
+
_optionalChain([context, 'access', _274 => _274.yjsProvider, 'optionalAccess', _275 => _275.off, 'call', _276 => _276("status", yjsStatusDidChange)]);
|
|
10974
11531
|
syncSourceForStorage.destroy();
|
|
10975
11532
|
syncSourceForYjs.destroy();
|
|
10976
11533
|
uninstallBgTabSpy();
|
|
@@ -11003,7 +11560,9 @@ function createRoom(options, config) {
|
|
|
11003
11560
|
updateFeedMessage,
|
|
11004
11561
|
deleteFeedMessage,
|
|
11005
11562
|
getStorage,
|
|
11006
|
-
|
|
11563
|
+
getStorageOrNull,
|
|
11564
|
+
getStorageSnapshot: getStorageOrNull,
|
|
11565
|
+
// Deprecated alias, will be removed in the future
|
|
11007
11566
|
getStorageStatus,
|
|
11008
11567
|
isPresenceReady,
|
|
11009
11568
|
isStorageReady,
|
|
@@ -11130,7 +11689,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
|
|
|
11130
11689
|
}
|
|
11131
11690
|
if (isLiveNode(first)) {
|
|
11132
11691
|
const node = first;
|
|
11133
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
11692
|
+
if (_optionalChain([options, 'optionalAccess', _277 => _277.isDeep])) {
|
|
11134
11693
|
const storageCallback = second;
|
|
11135
11694
|
return subscribeToLiveStructureDeeply(node, storageCallback);
|
|
11136
11695
|
} else {
|
|
@@ -11149,7 +11708,11 @@ function isRoomEventName(value) {
|
|
|
11149
11708
|
}
|
|
11150
11709
|
function makeAuthDelegateForRoom(roomId, authManager) {
|
|
11151
11710
|
return async () => {
|
|
11152
|
-
return authManager.getAuthValue({
|
|
11711
|
+
return authManager.getAuthValue({
|
|
11712
|
+
roomId,
|
|
11713
|
+
resource: "room",
|
|
11714
|
+
access: "read"
|
|
11715
|
+
});
|
|
11153
11716
|
};
|
|
11154
11717
|
}
|
|
11155
11718
|
function makeCreateSocketDelegateForRoom(roomId, baseUrl, WebSocketPolyfill) {
|
|
@@ -11198,7 +11761,7 @@ function getBaseUrl(baseUrl) {
|
|
|
11198
11761
|
function isLocalhost(url2) {
|
|
11199
11762
|
try {
|
|
11200
11763
|
return new URL(url2).hostname === "localhost";
|
|
11201
|
-
} catch (
|
|
11764
|
+
} catch (e11) {
|
|
11202
11765
|
return false;
|
|
11203
11766
|
}
|
|
11204
11767
|
}
|
|
@@ -11216,12 +11779,11 @@ function createClient(options) {
|
|
|
11216
11779
|
const authManager = createAuthManager(options, (token) => {
|
|
11217
11780
|
currentUserId.set(() => token.uid);
|
|
11218
11781
|
});
|
|
11219
|
-
const fetchPolyfill = _optionalChain([clientOptions, 'access',
|
|
11220
|
-
_optionalChain([globalThis, 'access',
|
|
11782
|
+
const fetchPolyfill = _optionalChain([clientOptions, 'access', _278 => _278.polyfills, 'optionalAccess', _279 => _279.fetch]) || /* istanbul ignore next */
|
|
11783
|
+
_optionalChain([globalThis, 'access', _280 => _280.fetch, 'optionalAccess', _281 => _281.bind, 'call', _282 => _282(globalThis)]);
|
|
11221
11784
|
const httpClient = createApiClient({
|
|
11222
11785
|
baseUrl,
|
|
11223
11786
|
fetchPolyfill,
|
|
11224
|
-
currentUserId,
|
|
11225
11787
|
authManager
|
|
11226
11788
|
});
|
|
11227
11789
|
const roomsById = /* @__PURE__ */ new Map();
|
|
@@ -11235,11 +11797,12 @@ function createClient(options) {
|
|
|
11235
11797
|
delegates: {
|
|
11236
11798
|
createSocket: makeCreateSocketDelegateForAi(
|
|
11237
11799
|
baseUrl,
|
|
11238
|
-
_optionalChain([clientOptions, 'access',
|
|
11800
|
+
_optionalChain([clientOptions, 'access', _283 => _283.polyfills, 'optionalAccess', _284 => _284.WebSocket])
|
|
11239
11801
|
),
|
|
11240
11802
|
authenticate: async () => {
|
|
11241
11803
|
const resp = await authManager.getAuthValue({
|
|
11242
|
-
|
|
11804
|
+
resource: "personal",
|
|
11805
|
+
access: "write"
|
|
11243
11806
|
});
|
|
11244
11807
|
if (resp.type === "public") {
|
|
11245
11808
|
throw new StopRetrying(
|
|
@@ -11305,14 +11868,13 @@ function createClient(options) {
|
|
|
11305
11868
|
createSocket: makeCreateSocketDelegateForRoom(
|
|
11306
11869
|
roomId,
|
|
11307
11870
|
baseUrl,
|
|
11308
|
-
_optionalChain([clientOptions, 'access',
|
|
11871
|
+
_optionalChain([clientOptions, 'access', _285 => _285.polyfills, 'optionalAccess', _286 => _286.WebSocket])
|
|
11309
11872
|
),
|
|
11310
11873
|
authenticate: makeAuthDelegateForRoom(roomId, authManager)
|
|
11311
11874
|
})),
|
|
11312
11875
|
enableDebugLogging: clientOptions.enableDebugLogging,
|
|
11313
11876
|
baseUrl,
|
|
11314
11877
|
errorEventSource: liveblocksErrorSource,
|
|
11315
|
-
unstable_streamData: !!clientOptions.unstable_streamData,
|
|
11316
11878
|
roomHttpClient: httpClient,
|
|
11317
11879
|
createSyncSource,
|
|
11318
11880
|
badgeLocation: _nullishCoalesce(clientOptions.badgeLocation, () => ( "bottom-right"))
|
|
@@ -11328,7 +11890,7 @@ function createClient(options) {
|
|
|
11328
11890
|
const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
|
|
11329
11891
|
if (shouldConnect) {
|
|
11330
11892
|
if (typeof atob === "undefined") {
|
|
11331
|
-
if (_optionalChain([clientOptions, 'access',
|
|
11893
|
+
if (_optionalChain([clientOptions, 'access', _287 => _287.polyfills, 'optionalAccess', _288 => _288.atob]) === void 0) {
|
|
11332
11894
|
throw new Error(
|
|
11333
11895
|
"You need to polyfill atob to use the client in your environment. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/atob-polyfill"
|
|
11334
11896
|
);
|
|
@@ -11340,7 +11902,7 @@ function createClient(options) {
|
|
|
11340
11902
|
return leaseRoom(newRoomDetails);
|
|
11341
11903
|
}
|
|
11342
11904
|
function getRoom(roomId) {
|
|
11343
|
-
const room = _optionalChain([roomsById, 'access',
|
|
11905
|
+
const room = _optionalChain([roomsById, 'access', _289 => _289.get, 'call', _290 => _290(roomId), 'optionalAccess', _291 => _291.room]);
|
|
11344
11906
|
return room ? room : null;
|
|
11345
11907
|
}
|
|
11346
11908
|
function logout() {
|
|
@@ -11356,7 +11918,7 @@ function createClient(options) {
|
|
|
11356
11918
|
const batchedResolveUsers = new Batch(
|
|
11357
11919
|
async (batchedUserIds) => {
|
|
11358
11920
|
const userIds = batchedUserIds.flat();
|
|
11359
|
-
const users = await _optionalChain([resolveUsers, 'optionalCall',
|
|
11921
|
+
const users = await _optionalChain([resolveUsers, 'optionalCall', _292 => _292({ userIds })]);
|
|
11360
11922
|
warnOnceIf(
|
|
11361
11923
|
!resolveUsers,
|
|
11362
11924
|
"Set the resolveUsers option in createClient to specify user info."
|
|
@@ -11373,7 +11935,7 @@ function createClient(options) {
|
|
|
11373
11935
|
const batchedResolveRoomsInfo = new Batch(
|
|
11374
11936
|
async (batchedRoomIds) => {
|
|
11375
11937
|
const roomIds = batchedRoomIds.flat();
|
|
11376
|
-
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall',
|
|
11938
|
+
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _293 => _293({ roomIds })]);
|
|
11377
11939
|
warnOnceIf(
|
|
11378
11940
|
!resolveRoomsInfo,
|
|
11379
11941
|
"Set the resolveRoomsInfo option in createClient to specify room info."
|
|
@@ -11390,7 +11952,7 @@ function createClient(options) {
|
|
|
11390
11952
|
const batchedResolveGroupsInfo = new Batch(
|
|
11391
11953
|
async (batchedGroupIds) => {
|
|
11392
11954
|
const groupIds = batchedGroupIds.flat();
|
|
11393
|
-
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall',
|
|
11955
|
+
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _294 => _294({ groupIds })]);
|
|
11394
11956
|
warnOnceIf(
|
|
11395
11957
|
!resolveGroupsInfo,
|
|
11396
11958
|
"Set the resolveGroupsInfo option in createClient to specify group info."
|
|
@@ -11449,7 +12011,7 @@ function createClient(options) {
|
|
|
11449
12011
|
}
|
|
11450
12012
|
};
|
|
11451
12013
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
11452
|
-
_optionalChain([win, 'optionalAccess',
|
|
12014
|
+
_optionalChain([win, 'optionalAccess', _295 => _295.addEventListener, 'call', _296 => _296("beforeunload", maybePreventClose)]);
|
|
11453
12015
|
}
|
|
11454
12016
|
async function getNotificationSettings(options2) {
|
|
11455
12017
|
const plainSettings = await httpClient.getNotificationSettings(options2);
|
|
@@ -11465,6 +12027,7 @@ function createClient(options) {
|
|
|
11465
12027
|
{
|
|
11466
12028
|
enterRoom,
|
|
11467
12029
|
getRoom,
|
|
12030
|
+
_dump: () => Array.from(roomsById.values(), ({ room }) => room._dump()).join("\n\n"),
|
|
11468
12031
|
logout,
|
|
11469
12032
|
// Public inbox notifications API
|
|
11470
12033
|
getInboxNotifications: httpClient.getInboxNotifications,
|
|
@@ -11576,7 +12139,7 @@ var commentBodyElementsTypes = {
|
|
|
11576
12139
|
mention: "inline"
|
|
11577
12140
|
};
|
|
11578
12141
|
function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
11579
|
-
if (!body || !_optionalChain([body, 'optionalAccess',
|
|
12142
|
+
if (!body || !_optionalChain([body, 'optionalAccess', _297 => _297.content])) {
|
|
11580
12143
|
return;
|
|
11581
12144
|
}
|
|
11582
12145
|
const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
|
|
@@ -11586,13 +12149,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
|
11586
12149
|
for (const block of body.content) {
|
|
11587
12150
|
if (type === "all" || type === "block") {
|
|
11588
12151
|
if (guard(block)) {
|
|
11589
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12152
|
+
_optionalChain([visitor, 'optionalCall', _298 => _298(block)]);
|
|
11590
12153
|
}
|
|
11591
12154
|
}
|
|
11592
12155
|
if (type === "all" || type === "inline") {
|
|
11593
12156
|
for (const inline of block.children) {
|
|
11594
12157
|
if (guard(inline)) {
|
|
11595
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12158
|
+
_optionalChain([visitor, 'optionalCall', _299 => _299(inline)]);
|
|
11596
12159
|
}
|
|
11597
12160
|
}
|
|
11598
12161
|
}
|
|
@@ -11762,7 +12325,7 @@ var stringifyCommentBodyPlainElements = {
|
|
|
11762
12325
|
text: ({ element }) => element.text,
|
|
11763
12326
|
link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
|
|
11764
12327
|
mention: ({ element, user, group }) => {
|
|
11765
|
-
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12328
|
+
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _300 => _300.name]), () => ( _optionalChain([group, 'optionalAccess', _301 => _301.name]))), () => ( element.id))}`;
|
|
11766
12329
|
}
|
|
11767
12330
|
};
|
|
11768
12331
|
var stringifyCommentBodyHtmlElements = {
|
|
@@ -11792,7 +12355,7 @@ var stringifyCommentBodyHtmlElements = {
|
|
|
11792
12355
|
return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
|
|
11793
12356
|
},
|
|
11794
12357
|
mention: ({ element, user, group }) => {
|
|
11795
|
-
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess',
|
|
12358
|
+
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _302 => _302.name]) ? html`${_optionalChain([user, 'optionalAccess', _303 => _303.name])}` : _optionalChain([group, 'optionalAccess', _304 => _304.name]) ? html`${_optionalChain([group, 'optionalAccess', _305 => _305.name])}` : element.id}</span>`;
|
|
11796
12359
|
}
|
|
11797
12360
|
};
|
|
11798
12361
|
var stringifyCommentBodyMarkdownElements = {
|
|
@@ -11822,20 +12385,20 @@ var stringifyCommentBodyMarkdownElements = {
|
|
|
11822
12385
|
return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
|
|
11823
12386
|
},
|
|
11824
12387
|
mention: ({ element, user, group }) => {
|
|
11825
|
-
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12388
|
+
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _306 => _306.name]), () => ( _optionalChain([group, 'optionalAccess', _307 => _307.name]))), () => ( element.id))}`;
|
|
11826
12389
|
}
|
|
11827
12390
|
};
|
|
11828
12391
|
async function stringifyCommentBody(body, options) {
|
|
11829
|
-
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
11830
|
-
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
12392
|
+
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _308 => _308.format]), () => ( "plain"));
|
|
12393
|
+
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _309 => _309.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
|
|
11831
12394
|
const elements = {
|
|
11832
12395
|
...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
|
|
11833
|
-
..._optionalChain([options, 'optionalAccess',
|
|
12396
|
+
..._optionalChain([options, 'optionalAccess', _310 => _310.elements])
|
|
11834
12397
|
};
|
|
11835
12398
|
const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
|
|
11836
12399
|
body,
|
|
11837
|
-
_optionalChain([options, 'optionalAccess',
|
|
11838
|
-
_optionalChain([options, 'optionalAccess',
|
|
12400
|
+
_optionalChain([options, 'optionalAccess', _311 => _311.resolveUsers]),
|
|
12401
|
+
_optionalChain([options, 'optionalAccess', _312 => _312.resolveGroupsInfo])
|
|
11839
12402
|
);
|
|
11840
12403
|
const blocks = body.content.flatMap((block, blockIndex) => {
|
|
11841
12404
|
switch (block.type) {
|
|
@@ -11970,9 +12533,9 @@ function makePoller(callback, intervalMs, options) {
|
|
|
11970
12533
|
const startTime = performance.now();
|
|
11971
12534
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
11972
12535
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
11973
|
-
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
12536
|
+
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _313 => _313.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
|
|
11974
12537
|
const context = {
|
|
11975
|
-
inForeground: _optionalChain([doc, 'optionalAccess',
|
|
12538
|
+
inForeground: _optionalChain([doc, 'optionalAccess', _314 => _314.visibilityState]) !== "hidden",
|
|
11976
12539
|
lastSuccessfulPollAt: startTime,
|
|
11977
12540
|
count: 0,
|
|
11978
12541
|
backoff: 0
|
|
@@ -12053,11 +12616,11 @@ function makePoller(callback, intervalMs, options) {
|
|
|
12053
12616
|
pollNowIfStale();
|
|
12054
12617
|
}
|
|
12055
12618
|
function onVisibilityChange() {
|
|
12056
|
-
setInForeground(_optionalChain([doc, 'optionalAccess',
|
|
12619
|
+
setInForeground(_optionalChain([doc, 'optionalAccess', _315 => _315.visibilityState]) !== "hidden");
|
|
12057
12620
|
}
|
|
12058
|
-
_optionalChain([doc, 'optionalAccess',
|
|
12059
|
-
_optionalChain([win, 'optionalAccess',
|
|
12060
|
-
_optionalChain([win, 'optionalAccess',
|
|
12621
|
+
_optionalChain([doc, 'optionalAccess', _316 => _316.addEventListener, 'call', _317 => _317("visibilitychange", onVisibilityChange)]);
|
|
12622
|
+
_optionalChain([win, 'optionalAccess', _318 => _318.addEventListener, 'call', _319 => _319("online", onVisibilityChange)]);
|
|
12623
|
+
_optionalChain([win, 'optionalAccess', _320 => _320.addEventListener, 'call', _321 => _321("focus", pollNowIfStale)]);
|
|
12061
12624
|
fsm.start();
|
|
12062
12625
|
return {
|
|
12063
12626
|
inc,
|
|
@@ -12194,5 +12757,13 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
|
12194
12757
|
|
|
12195
12758
|
|
|
12196
12759
|
|
|
12197
|
-
|
|
12760
|
+
|
|
12761
|
+
|
|
12762
|
+
|
|
12763
|
+
|
|
12764
|
+
|
|
12765
|
+
|
|
12766
|
+
|
|
12767
|
+
|
|
12768
|
+
exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.deepLiveify = deepLiveify; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.hasPermissionAccess = hasPermissionAccess; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.mergeRoomPermissionScopes = mergeRoomPermissionScopes; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.normalizeRoomAccesses = normalizeRoomAccesses; exports.normalizeRoomPermissions = normalizeRoomPermissions; exports.normalizeUpdateRoomAccesses = normalizeUpdateRoomAccesses; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.permissionMatrixFromScopes = permissionMatrixFromScopes; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.validatePermissionsSet = validatePermissionsSet; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
|
|
12198
12769
|
//# sourceMappingURL=index.cjs.map
|