@liveblocks/core 1.8.1 → 1.9.0-example1

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.mjs 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 = "1.8.1";
9
+ var PKG_VERSION = "1.9.0-example1";
10
10
  var PKG_FORMAT = "esm";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -1744,6 +1744,359 @@ function errorIf(condition, message) {
1744
1744
  }
1745
1745
  }
1746
1746
 
1747
+ // src/comments/comment-body.ts
1748
+ function isCommentBodyParagraph(element) {
1749
+ return "type" in element && element.type === "mention";
1750
+ }
1751
+ function isCommentBodyText(element) {
1752
+ return "text" in element && typeof element.text === "string";
1753
+ }
1754
+ function isCommentBodyMention(element) {
1755
+ return "type" in element && element.type === "mention";
1756
+ }
1757
+ function isCommentBodyLink(element) {
1758
+ return "type" in element && element.type === "link";
1759
+ }
1760
+ var commentBodyElementsGuards = {
1761
+ paragraph: isCommentBodyParagraph,
1762
+ text: isCommentBodyText,
1763
+ link: isCommentBodyLink,
1764
+ mention: isCommentBodyMention
1765
+ };
1766
+ var commentBodyElementsTypes = {
1767
+ paragraph: "block",
1768
+ text: "inline",
1769
+ link: "inline",
1770
+ mention: "inline"
1771
+ };
1772
+ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
1773
+ if (!body || !body?.content) {
1774
+ return;
1775
+ }
1776
+ const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
1777
+ const type = element ? commentBodyElementsTypes[element] : "all";
1778
+ const guard = element ? commentBodyElementsGuards[element] : () => true;
1779
+ const visitor = typeof elementOrVisitor === "function" ? elementOrVisitor : possiblyVisitor;
1780
+ for (const block of body.content) {
1781
+ if (type === "all" || type === "block") {
1782
+ if (guard(block)) {
1783
+ visitor?.(block);
1784
+ }
1785
+ }
1786
+ if (type === "all" || type === "inline") {
1787
+ for (const inline of block.children) {
1788
+ if (guard(inline)) {
1789
+ visitor?.(inline);
1790
+ }
1791
+ }
1792
+ }
1793
+ }
1794
+ }
1795
+ function getMentionedIdsFromCommentBody(body) {
1796
+ const mentionedIds = /* @__PURE__ */ new Set();
1797
+ traverseCommentBody(
1798
+ body,
1799
+ "mention",
1800
+ (mention) => mentionedIds.add(mention.id)
1801
+ );
1802
+ return Array.from(mentionedIds);
1803
+ }
1804
+ async function resolveUsersInCommentBody(body, resolveUsers) {
1805
+ const resolvedUsers = /* @__PURE__ */ new Map();
1806
+ if (!resolveUsers) {
1807
+ return resolvedUsers;
1808
+ }
1809
+ const userIds = getMentionedIdsFromCommentBody(body);
1810
+ const users = await resolveUsers({
1811
+ userIds
1812
+ });
1813
+ for (const [index, userId] of userIds.entries()) {
1814
+ const user = users?.[index];
1815
+ if (user) {
1816
+ resolvedUsers.set(userId, user);
1817
+ }
1818
+ }
1819
+ return resolvedUsers;
1820
+ }
1821
+ var htmlEscapables = {
1822
+ "&": "&",
1823
+ "<": "&lt;",
1824
+ ">": "&gt;",
1825
+ '"': "&quot;",
1826
+ "'": "&#39;"
1827
+ };
1828
+ var htmlEscapablesRegex = new RegExp(
1829
+ Object.keys(htmlEscapables).map((entity) => `\\${entity}`).join("|"),
1830
+ "g"
1831
+ );
1832
+ function htmlSafe(value) {
1833
+ return new HtmlSafeString([String(value)], []);
1834
+ }
1835
+ function joinHtml(strings) {
1836
+ if (strings.length <= 0) {
1837
+ return new HtmlSafeString([""], []);
1838
+ }
1839
+ return new HtmlSafeString(
1840
+ ["", ...Array(strings.length - 1).fill(""), ""],
1841
+ strings
1842
+ );
1843
+ }
1844
+ function escapeHtml(value) {
1845
+ if (value instanceof HtmlSafeString) {
1846
+ return value.toString();
1847
+ }
1848
+ if (Array.isArray(value)) {
1849
+ return joinHtml(value).toString();
1850
+ }
1851
+ return String(value).replace(
1852
+ htmlEscapablesRegex,
1853
+ (character) => htmlEscapables[character]
1854
+ );
1855
+ }
1856
+ var HtmlSafeString = class {
1857
+ constructor(strings, values) {
1858
+ this._strings = strings;
1859
+ this._values = values;
1860
+ }
1861
+ toString() {
1862
+ return this._strings.reduce((result, str, i) => {
1863
+ return result + escapeHtml(nn(this._values[i - 1])) + str;
1864
+ });
1865
+ }
1866
+ };
1867
+ function html(strings, ...values) {
1868
+ return new HtmlSafeString(strings, values);
1869
+ }
1870
+ var markdownEscapables = {
1871
+ _: "\\_",
1872
+ "*": "\\*",
1873
+ "#": "\\#",
1874
+ "`": "\\`",
1875
+ "~": "\\~",
1876
+ "!": "\\!",
1877
+ "|": "\\|",
1878
+ "(": "\\(",
1879
+ ")": "\\)",
1880
+ "{": "\\{",
1881
+ "}": "\\}",
1882
+ "[": "\\[",
1883
+ "]": "\\]"
1884
+ };
1885
+ var markdownEscapablesRegex = new RegExp(
1886
+ Object.keys(markdownEscapables).map((entity) => `\\${entity}`).join("|"),
1887
+ "g"
1888
+ );
1889
+ function joinMarkdown(strings) {
1890
+ if (strings.length <= 0) {
1891
+ return new MarkdownSafeString([""], []);
1892
+ }
1893
+ return new MarkdownSafeString(
1894
+ ["", ...Array(strings.length - 1).fill(""), ""],
1895
+ strings
1896
+ );
1897
+ }
1898
+ function escapeMarkdown(value) {
1899
+ if (value instanceof MarkdownSafeString) {
1900
+ return value.toString();
1901
+ }
1902
+ if (Array.isArray(value)) {
1903
+ return joinMarkdown(value).toString();
1904
+ }
1905
+ return String(value).replace(
1906
+ markdownEscapablesRegex,
1907
+ (character) => markdownEscapables[character]
1908
+ );
1909
+ }
1910
+ var MarkdownSafeString = class {
1911
+ constructor(strings, values) {
1912
+ this._strings = strings;
1913
+ this._values = values;
1914
+ }
1915
+ toString() {
1916
+ return this._strings.reduce((result, str, i) => {
1917
+ return result + escapeMarkdown(nn(this._values[i - 1])) + str;
1918
+ });
1919
+ }
1920
+ };
1921
+ function markdown(strings, ...values) {
1922
+ return new MarkdownSafeString(strings, values);
1923
+ }
1924
+ function toAbsoluteUrl(url) {
1925
+ if (url.startsWith("http://") || url.startsWith("https://")) {
1926
+ return url;
1927
+ } else if (url.startsWith("www.")) {
1928
+ return "https://" + url;
1929
+ }
1930
+ return;
1931
+ }
1932
+ var stringifyCommentBodyPlainElements = {
1933
+ paragraph: ({ children }) => children,
1934
+ text: ({ element }) => element.text,
1935
+ link: ({ element }) => element.url,
1936
+ mention: ({ element, user }) => {
1937
+ return `@${user?.name ?? element.id}`;
1938
+ }
1939
+ };
1940
+ var stringifyCommentBodyHtmlElements = {
1941
+ paragraph: ({ children }) => {
1942
+ return children ? html`<p>${htmlSafe(children)}</p>` : children;
1943
+ },
1944
+ text: ({ element }) => {
1945
+ let children = element.text;
1946
+ if (!children) {
1947
+ return children;
1948
+ }
1949
+ if (element.bold) {
1950
+ children = html`<strong>${children}</strong>`;
1951
+ }
1952
+ if (element.italic) {
1953
+ children = html`<em>${children}</em>`;
1954
+ }
1955
+ if (element.strikethrough) {
1956
+ children = html`<s>${children}</s>`;
1957
+ }
1958
+ if (element.code) {
1959
+ children = html`<code>${children}</code>`;
1960
+ }
1961
+ return children;
1962
+ },
1963
+ link: ({ element, href }) => {
1964
+ return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.url}</a>`;
1965
+ },
1966
+ mention: ({ element, user }) => {
1967
+ return html`<span data-mention>@${user?.name ?? element.id}</span>`;
1968
+ }
1969
+ };
1970
+ var stringifyCommentBodyMarkdownElements = {
1971
+ paragraph: ({ children }) => {
1972
+ return children;
1973
+ },
1974
+ text: ({ element }) => {
1975
+ let children = element.text;
1976
+ if (!children) {
1977
+ return children;
1978
+ }
1979
+ if (element.bold) {
1980
+ children = markdown`**${children}**`;
1981
+ }
1982
+ if (element.italic) {
1983
+ children = markdown`_${children}_`;
1984
+ }
1985
+ if (element.strikethrough) {
1986
+ children = markdown`~~${children}~~`;
1987
+ }
1988
+ if (element.code) {
1989
+ children = markdown`\`${children}\``;
1990
+ }
1991
+ return children;
1992
+ },
1993
+ link: ({ element, href }) => {
1994
+ return markdown`[${element.url}](${href})`;
1995
+ },
1996
+ mention: ({ element, user }) => {
1997
+ return markdown`@${user?.name ?? element.id}`;
1998
+ }
1999
+ };
2000
+ async function stringifyCommentBody(body, options) {
2001
+ const format = options?.format ?? "plain";
2002
+ const separator = options?.separator ?? (format === "markdown" ? "\n\n" : "\n");
2003
+ const elements = {
2004
+ ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
2005
+ ...options?.elements
2006
+ };
2007
+ const resolvedUsers = await resolveUsersInCommentBody(
2008
+ body,
2009
+ options?.resolveUsers
2010
+ );
2011
+ const blocks = body.content.flatMap((block, blockIndex) => {
2012
+ switch (block.type) {
2013
+ case "paragraph": {
2014
+ const inlines = block.children.flatMap((inline, inlineIndex) => {
2015
+ if (isCommentBodyMention(inline)) {
2016
+ return inline.id ? [
2017
+ elements.mention(
2018
+ {
2019
+ element: inline,
2020
+ user: resolvedUsers.get(inline.id)
2021
+ },
2022
+ inlineIndex
2023
+ )
2024
+ ] : [];
2025
+ }
2026
+ if (isCommentBodyLink(inline)) {
2027
+ return [
2028
+ elements.link(
2029
+ {
2030
+ element: inline,
2031
+ href: toAbsoluteUrl(inline.url) ?? inline.url
2032
+ },
2033
+ inlineIndex
2034
+ )
2035
+ ];
2036
+ }
2037
+ if (isCommentBodyText(inline)) {
2038
+ return [elements.text({ element: inline }, inlineIndex)];
2039
+ }
2040
+ return [];
2041
+ });
2042
+ return [
2043
+ elements.paragraph(
2044
+ { element: block, children: inlines.join("") },
2045
+ blockIndex
2046
+ )
2047
+ ];
2048
+ }
2049
+ default:
2050
+ return [];
2051
+ }
2052
+ });
2053
+ return blocks.join(separator);
2054
+ }
2055
+ function convertToCommentData(data) {
2056
+ const editedAt = data.editedAt ? new Date(data.editedAt) : void 0;
2057
+ const createdAt = new Date(data.createdAt);
2058
+ const reactions = data.reactions.map((reaction) => ({
2059
+ ...reaction,
2060
+ createdAt: new Date(reaction.createdAt)
2061
+ }));
2062
+ if (data.body) {
2063
+ return {
2064
+ ...data,
2065
+ reactions,
2066
+ createdAt,
2067
+ editedAt
2068
+ };
2069
+ } else {
2070
+ const deletedAt = new Date(data.deletedAt);
2071
+ return {
2072
+ ...data,
2073
+ reactions,
2074
+ createdAt,
2075
+ editedAt,
2076
+ deletedAt
2077
+ };
2078
+ }
2079
+ }
2080
+ function convertToThreadData(data) {
2081
+ const updatedAt = data.updatedAt ? new Date(data.updatedAt) : void 0;
2082
+ const createdAt = new Date(data.createdAt);
2083
+ const comments = data.comments.map(
2084
+ (comment) => convertToCommentData(comment)
2085
+ );
2086
+ return {
2087
+ ...data,
2088
+ createdAt,
2089
+ updatedAt,
2090
+ comments
2091
+ };
2092
+ }
2093
+ function convertToCommentUserReaction(data) {
2094
+ return {
2095
+ ...data,
2096
+ createdAt: new Date(data.createdAt)
2097
+ };
2098
+ }
2099
+
1747
2100
  // src/comments/index.ts
1748
2101
  function getAuthBearerHeaderFromAuthValue(authValue) {
1749
2102
  if (authValue.type === "public") {
@@ -1805,39 +2158,43 @@ function createCommentsApi(roomId, getAuthValue, config) {
1805
2158
  const response = await fetchApi(roomId, "/threads");
1806
2159
  if (response.ok) {
1807
2160
  const json = await response.json();
1808
- return json.data;
2161
+ return json.data.map((thread) => convertToThreadData(thread));
1809
2162
  } else if (response.status === 404) {
1810
2163
  return [];
1811
2164
  } else {
1812
2165
  throw new Error("There was an error while getting threads.");
1813
2166
  }
1814
2167
  }
1815
- function createThread({
2168
+ async function createThread({
1816
2169
  metadata,
1817
2170
  body,
1818
2171
  commentId,
1819
2172
  threadId
1820
2173
  }) {
1821
- return fetchJson("/threads", {
1822
- method: "POST",
1823
- headers: {
1824
- "Content-Type": "application/json"
1825
- },
1826
- body: JSON.stringify({
1827
- id: threadId,
1828
- comment: {
1829
- id: commentId,
1830
- body
2174
+ const thread = await fetchJson(
2175
+ "/threads",
2176
+ {
2177
+ method: "POST",
2178
+ headers: {
2179
+ "Content-Type": "application/json"
1831
2180
  },
1832
- metadata
1833
- })
1834
- });
2181
+ body: JSON.stringify({
2182
+ id: threadId,
2183
+ comment: {
2184
+ id: commentId,
2185
+ body
2186
+ },
2187
+ metadata
2188
+ })
2189
+ }
2190
+ );
2191
+ return convertToThreadData(thread);
1835
2192
  }
1836
- function editThreadMetadata({
2193
+ async function editThreadMetadata({
1837
2194
  metadata,
1838
2195
  threadId
1839
2196
  }) {
1840
- return fetchJson(
2197
+ return await fetchJson(
1841
2198
  `/threads/${encodeURIComponent(threadId)}/metadata`,
1842
2199
  {
1843
2200
  method: "POST",
@@ -1848,12 +2205,12 @@ function createCommentsApi(roomId, getAuthValue, config) {
1848
2205
  }
1849
2206
  );
1850
2207
  }
1851
- function createComment({
2208
+ async function createComment({
1852
2209
  threadId,
1853
2210
  commentId,
1854
2211
  body
1855
2212
  }) {
1856
- return fetchJson(
2213
+ const comment = await fetchJson(
1857
2214
  `/threads/${encodeURIComponent(threadId)}/comments`,
1858
2215
  {
1859
2216
  method: "POST",
@@ -1866,13 +2223,14 @@ function createCommentsApi(roomId, getAuthValue, config) {
1866
2223
  })
1867
2224
  }
1868
2225
  );
2226
+ return convertToCommentData(comment);
1869
2227
  }
1870
- function editComment({
2228
+ async function editComment({
1871
2229
  threadId,
1872
2230
  commentId,
1873
2231
  body
1874
2232
  }) {
1875
- return fetchJson(
2233
+ const comment = await fetchJson(
1876
2234
  `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
1877
2235
  commentId
1878
2236
  )}`,
@@ -1886,6 +2244,7 @@ function createCommentsApi(roomId, getAuthValue, config) {
1886
2244
  })
1887
2245
  }
1888
2246
  );
2247
+ return convertToCommentData(comment);
1889
2248
  }
1890
2249
  async function deleteComment({
1891
2250
  threadId,
@@ -1900,12 +2259,12 @@ function createCommentsApi(roomId, getAuthValue, config) {
1900
2259
  }
1901
2260
  );
1902
2261
  }
1903
- function addReaction({
2262
+ async function addReaction({
1904
2263
  threadId,
1905
2264
  commentId,
1906
2265
  emoji
1907
2266
  }) {
1908
- return fetchJson(
2267
+ const reaction = await fetchJson(
1909
2268
  `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
1910
2269
  commentId
1911
2270
  )}/reactions`,
@@ -1917,13 +2276,14 @@ function createCommentsApi(roomId, getAuthValue, config) {
1917
2276
  body: JSON.stringify({ emoji })
1918
2277
  }
1919
2278
  );
2279
+ return convertToCommentUserReaction(reaction);
1920
2280
  }
1921
- function removeReaction({
2281
+ async function removeReaction({
1922
2282
  threadId,
1923
2283
  commentId,
1924
2284
  emoji
1925
2285
  }) {
1926
- return fetchJson(
2286
+ await fetchJson(
1927
2287
  `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
1928
2288
  commentId
1929
2289
  )}/reactions/${encodeURIComponent(emoji)}`,
@@ -3065,7 +3425,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
3065
3425
  this._pool?.assertStorageIsWritable();
3066
3426
  if (index < 0 || index >= this._items.length) {
3067
3427
  throw new Error(
3068
- `Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length - 1}`
3428
+ `Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length - 1}`
3069
3429
  );
3070
3430
  }
3071
3431
  const item = this._items[index];
@@ -4995,9 +5355,13 @@ function createRoom(options, config) {
4995
5355
  ydoc: makeEventSource(),
4996
5356
  comments: makeEventSource()
4997
5357
  };
4998
- async function httpSend(authTokenOrPublicApiKey, roomId, nonce, messages) {
5358
+ async function httpPostToRoom(endpoint, body) {
5359
+ if (!managedSocket.authValue) {
5360
+ throw new Error("Not authorized");
5361
+ }
5362
+ const authTokenOrPublicApiKey = managedSocket.authValue.type === "public" ? managedSocket.authValue.publicApiKey : managedSocket.authValue.token.raw;
4999
5363
  const url = new URL(
5000
- `/v2/c/rooms/${encodeURIComponent(roomId)}/send-message`,
5364
+ `/v2/c/rooms/${encodeURIComponent(config.roomId)}${endpoint}`,
5001
5365
  config.baseUrl
5002
5366
  ).toString();
5003
5367
  const fetcher = config.polyfills?.fetch || /* istanbul ignore next */
@@ -5008,25 +5372,22 @@ function createRoom(options, config) {
5008
5372
  "Content-Type": "application/json",
5009
5373
  Authorization: `Bearer ${authTokenOrPublicApiKey}`
5010
5374
  },
5011
- body: JSON.stringify({ nonce, messages })
5375
+ body: JSON.stringify(body)
5012
5376
  });
5013
5377
  }
5014
5378
  function sendMessages(messages) {
5015
5379
  const serializedPayload = JSON.stringify(messages);
5016
5380
  const nonce = context.dynamicSessionInfo.current?.nonce;
5017
- if (config.unstable_fallbackToHTTP && managedSocket.authValue && nonce) {
5381
+ if (config.unstable_fallbackToHTTP && nonce) {
5018
5382
  const size = new TextEncoder().encode(serializedPayload).length;
5019
5383
  if (size > MAX_SOCKET_MESSAGE_SIZE) {
5020
- void httpSend(
5021
- managedSocket.authValue.type === "public" ? managedSocket.authValue.publicApiKey : managedSocket.authValue.token.raw,
5022
- config.roomId,
5023
- nonce,
5024
- messages
5025
- ).then((resp) => {
5026
- if (!resp.ok && resp.status === 403) {
5027
- managedSocket.reconnect();
5384
+ void httpPostToRoom("/send-message", { nonce, messages }).then(
5385
+ (resp) => {
5386
+ if (!resp.ok && resp.status === 403) {
5387
+ managedSocket.reconnect();
5388
+ }
5028
5389
  }
5029
- });
5390
+ );
5030
5391
  warn(
5031
5392
  "Message was too large for websockets and sent over HTTP instead"
5032
5393
  );
@@ -5539,7 +5900,7 @@ ${Array.from(traces).join("\n\n")}`
5539
5900
  }
5540
5901
  const now = Date.now();
5541
5902
  const elapsedMillis = now - context.buffer.lastFlushedAt;
5542
- if (elapsedMillis > config.throttleDelay) {
5903
+ if (elapsedMillis >= config.throttleDelay) {
5543
5904
  const messagesToFlush = serializeBuffer();
5544
5905
  if (messagesToFlush.length === 0) {
5545
5906
  return;
@@ -6772,6 +7133,9 @@ export {
6772
7133
  b64decode,
6773
7134
  cloneLson,
6774
7135
  fancy_console_exports as console,
7136
+ convertToCommentData,
7137
+ convertToCommentUserReaction,
7138
+ convertToThreadData,
6775
7139
  createAsyncCache,
6776
7140
  createClient,
6777
7141
  createCommentsApi,
@@ -6780,6 +7144,7 @@ export {
6780
7144
  detectDupes,
6781
7145
  errorIf,
6782
7146
  freeze,
7147
+ getMentionedIdsFromCommentBody,
6783
7148
  isChildCrdt,
6784
7149
  isJsonArray,
6785
7150
  isJsonObject,
@@ -6797,6 +7162,7 @@ export {
6797
7162
  raise,
6798
7163
  shallow,
6799
7164
  stringify,
7165
+ stringifyCommentBody,
6800
7166
  throwUsageError,
6801
7167
  toPlainLson,
6802
7168
  tryParseJson,