@tldraw/commenting 0.0.0-bootstrap

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.
Files changed (242) hide show
  1. package/README.md +11 -0
  2. package/commenting.css +832 -0
  3. package/dist-cjs/canvas/cluster-input.js +40 -0
  4. package/dist-cjs/canvas/cluster-input.js.map +7 -0
  5. package/dist-cjs/canvas/comment-body.js +31 -0
  6. package/dist-cjs/canvas/comment-body.js.map +7 -0
  7. package/dist-cjs/canvas/comment-render.js +72 -0
  8. package/dist-cjs/canvas/comment-render.js.map +7 -0
  9. package/dist-cjs/canvas/comment-store.js +48 -0
  10. package/dist-cjs/canvas/comment-store.js.map +7 -0
  11. package/dist-cjs/canvas/comment-tool.js +160 -0
  12. package/dist-cjs/canvas/comment-tool.js.map +7 -0
  13. package/dist-cjs/canvas/comments-filter-menu.js +109 -0
  14. package/dist-cjs/canvas/comments-filter-menu.js.map +7 -0
  15. package/dist-cjs/canvas/comments-menu-item.js +42 -0
  16. package/dist-cjs/canvas/comments-menu-item.js.map +7 -0
  17. package/dist-cjs/canvas/comments-overflow-menu.js +64 -0
  18. package/dist-cjs/canvas/comments-overflow-menu.js.map +7 -0
  19. package/dist-cjs/canvas/comments-overlay.js +1081 -0
  20. package/dist-cjs/canvas/comments-overlay.js.map +7 -0
  21. package/dist-cjs/canvas/comments-sidebar.js +134 -0
  22. package/dist-cjs/canvas/comments-sidebar.js.map +7 -0
  23. package/dist-cjs/canvas/hooks.js +45 -0
  24. package/dist-cjs/canvas/hooks.js.map +7 -0
  25. package/dist-cjs/canvas/license.js +28 -0
  26. package/dist-cjs/canvas/license.js.map +7 -0
  27. package/dist-cjs/canvas/options.js +45 -0
  28. package/dist-cjs/canvas/options.js.map +7 -0
  29. package/dist-cjs/canvas/region-options.js +49 -0
  30. package/dist-cjs/canvas/region-options.js.map +7 -0
  31. package/dist-cjs/canvas/rich-text.js +28 -0
  32. package/dist-cjs/canvas/rich-text.js.map +7 -0
  33. package/dist-cjs/canvas/sidebar-filters.js +30 -0
  34. package/dist-cjs/canvas/sidebar-filters.js.map +7 -0
  35. package/dist-cjs/canvas/state.js +76 -0
  36. package/dist-cjs/canvas/state.js.map +7 -0
  37. package/dist-cjs/canvas/thread-state.js +81 -0
  38. package/dist-cjs/canvas/thread-state.js.map +7 -0
  39. package/dist-cjs/clustering/computeClusterTable.js +83 -0
  40. package/dist-cjs/clustering/computeClusterTable.js.map +7 -0
  41. package/dist-cjs/clustering/mst.js +117 -0
  42. package/dist-cjs/clustering/mst.js.map +7 -0
  43. package/dist-cjs/clustering/replay.js +275 -0
  44. package/dist-cjs/clustering/replay.js.map +7 -0
  45. package/dist-cjs/clustering/runtime.js +134 -0
  46. package/dist-cjs/clustering/runtime.js.map +7 -0
  47. package/dist-cjs/clustering/schedule.js +170 -0
  48. package/dist-cjs/clustering/schedule.js.map +7 -0
  49. package/dist-cjs/clustering/types.js +17 -0
  50. package/dist-cjs/clustering/types.js.map +7 -0
  51. package/dist-cjs/index.d.ts +868 -0
  52. package/dist-cjs/index.js +126 -0
  53. package/dist-cjs/index.js.map +7 -0
  54. package/dist-cjs/ui/avatar.js +43 -0
  55. package/dist-cjs/ui/avatar.js.map +7 -0
  56. package/dist-cjs/ui/byline.js +35 -0
  57. package/dist-cjs/ui/byline.js.map +7 -0
  58. package/dist-cjs/ui/comment-card.js +37 -0
  59. package/dist-cjs/ui/comment-card.js.map +7 -0
  60. package/dist-cjs/ui/comment-composer.js +136 -0
  61. package/dist-cjs/ui/comment-composer.js.map +7 -0
  62. package/dist-cjs/ui/comment-extensions.js +37 -0
  63. package/dist-cjs/ui/comment-extensions.js.map +7 -0
  64. package/dist-cjs/ui/comment-mention.js +42 -0
  65. package/dist-cjs/ui/comment-mention.js.map +7 -0
  66. package/dist-cjs/ui/comment-pin.js +29 -0
  67. package/dist-cjs/ui/comment-pin.js.map +7 -0
  68. package/dist-cjs/ui/comment-text.js +29 -0
  69. package/dist-cjs/ui/comment-text.js.map +7 -0
  70. package/dist-cjs/ui/comment-thread.js +45 -0
  71. package/dist-cjs/ui/comment-thread.js.map +7 -0
  72. package/dist-cjs/ui/comments-list.js +106 -0
  73. package/dist-cjs/ui/comments-list.js.map +7 -0
  74. package/dist-cjs/ui/count-badge.js +28 -0
  75. package/dist-cjs/ui/count-badge.js.map +7 -0
  76. package/dist-cjs/ui/empty-state.js +31 -0
  77. package/dist-cjs/ui/empty-state.js.map +7 -0
  78. package/dist-cjs/ui/format-time.js +46 -0
  79. package/dist-cjs/ui/format-time.js.map +7 -0
  80. package/dist-cjs/ui/mention-list.js +70 -0
  81. package/dist-cjs/ui/mention-list.js.map +7 -0
  82. package/dist-cjs/ui/mention-suggestion.js +206 -0
  83. package/dist-cjs/ui/mention-suggestion.js.map +7 -0
  84. package/dist-cjs/ui/mention.js +31 -0
  85. package/dist-cjs/ui/mention.js.map +7 -0
  86. package/dist-cjs/ui/reaction.js +31 -0
  87. package/dist-cjs/ui/reaction.js.map +7 -0
  88. package/dist-cjs/ui/reactions.js +34 -0
  89. package/dist-cjs/ui/reactions.js.map +7 -0
  90. package/dist-cjs/ui/render-markdown.js +63 -0
  91. package/dist-cjs/ui/render-markdown.js.map +7 -0
  92. package/dist-cjs/ui/send-button.js +28 -0
  93. package/dist-cjs/ui/send-button.js.map +7 -0
  94. package/dist-esm/canvas/cluster-input.mjs +20 -0
  95. package/dist-esm/canvas/cluster-input.mjs.map +7 -0
  96. package/dist-esm/canvas/comment-body.mjs +11 -0
  97. package/dist-esm/canvas/comment-body.mjs.map +7 -0
  98. package/dist-esm/canvas/comment-render.mjs +52 -0
  99. package/dist-esm/canvas/comment-render.mjs.map +7 -0
  100. package/dist-esm/canvas/comment-store.mjs +28 -0
  101. package/dist-esm/canvas/comment-store.mjs.map +7 -0
  102. package/dist-esm/canvas/comment-tool.mjs +142 -0
  103. package/dist-esm/canvas/comment-tool.mjs.map +7 -0
  104. package/dist-esm/canvas/comments-filter-menu.mjs +99 -0
  105. package/dist-esm/canvas/comments-filter-menu.mjs.map +7 -0
  106. package/dist-esm/canvas/comments-menu-item.mjs +22 -0
  107. package/dist-esm/canvas/comments-menu-item.mjs.map +7 -0
  108. package/dist-esm/canvas/comments-overflow-menu.mjs +53 -0
  109. package/dist-esm/canvas/comments-overflow-menu.mjs.map +7 -0
  110. package/dist-esm/canvas/comments-overlay.mjs +1094 -0
  111. package/dist-esm/canvas/comments-overlay.mjs.map +7 -0
  112. package/dist-esm/canvas/comments-sidebar.mjs +120 -0
  113. package/dist-esm/canvas/comments-sidebar.mjs.map +7 -0
  114. package/dist-esm/canvas/hooks.mjs +25 -0
  115. package/dist-esm/canvas/hooks.mjs.map +7 -0
  116. package/dist-esm/canvas/license.mjs +8 -0
  117. package/dist-esm/canvas/license.mjs.map +7 -0
  118. package/dist-esm/canvas/options.mjs +27 -0
  119. package/dist-esm/canvas/options.mjs.map +7 -0
  120. package/dist-esm/canvas/region-options.mjs +29 -0
  121. package/dist-esm/canvas/region-options.mjs.map +7 -0
  122. package/dist-esm/canvas/rich-text.mjs +8 -0
  123. package/dist-esm/canvas/rich-text.mjs.map +7 -0
  124. package/dist-esm/canvas/sidebar-filters.mjs +10 -0
  125. package/dist-esm/canvas/sidebar-filters.mjs.map +7 -0
  126. package/dist-esm/canvas/state.mjs +60 -0
  127. package/dist-esm/canvas/state.mjs.map +7 -0
  128. package/dist-esm/canvas/thread-state.mjs +61 -0
  129. package/dist-esm/canvas/thread-state.mjs.map +7 -0
  130. package/dist-esm/clustering/computeClusterTable.mjs +63 -0
  131. package/dist-esm/clustering/computeClusterTable.mjs.map +7 -0
  132. package/dist-esm/clustering/mst.mjs +97 -0
  133. package/dist-esm/clustering/mst.mjs.map +7 -0
  134. package/dist-esm/clustering/replay.mjs +255 -0
  135. package/dist-esm/clustering/replay.mjs.map +7 -0
  136. package/dist-esm/clustering/runtime.mjs +114 -0
  137. package/dist-esm/clustering/runtime.mjs.map +7 -0
  138. package/dist-esm/clustering/schedule.mjs +150 -0
  139. package/dist-esm/clustering/schedule.mjs.map +7 -0
  140. package/dist-esm/clustering/types.mjs +1 -0
  141. package/dist-esm/clustering/types.mjs.map +7 -0
  142. package/dist-esm/index.d.mts +868 -0
  143. package/dist-esm/index.mjs +139 -0
  144. package/dist-esm/index.mjs.map +7 -0
  145. package/dist-esm/ui/avatar.mjs +23 -0
  146. package/dist-esm/ui/avatar.mjs.map +7 -0
  147. package/dist-esm/ui/byline.mjs +15 -0
  148. package/dist-esm/ui/byline.mjs.map +7 -0
  149. package/dist-esm/ui/comment-card.mjs +17 -0
  150. package/dist-esm/ui/comment-card.mjs.map +7 -0
  151. package/dist-esm/ui/comment-composer.mjs +116 -0
  152. package/dist-esm/ui/comment-composer.mjs.map +7 -0
  153. package/dist-esm/ui/comment-extensions.mjs +17 -0
  154. package/dist-esm/ui/comment-extensions.mjs.map +7 -0
  155. package/dist-esm/ui/comment-mention.mjs +22 -0
  156. package/dist-esm/ui/comment-mention.mjs.map +7 -0
  157. package/dist-esm/ui/comment-pin.mjs +9 -0
  158. package/dist-esm/ui/comment-pin.mjs.map +7 -0
  159. package/dist-esm/ui/comment-text.mjs +9 -0
  160. package/dist-esm/ui/comment-text.mjs.map +7 -0
  161. package/dist-esm/ui/comment-thread.mjs +25 -0
  162. package/dist-esm/ui/comment-thread.mjs.map +7 -0
  163. package/dist-esm/ui/comments-list.mjs +86 -0
  164. package/dist-esm/ui/comments-list.mjs.map +7 -0
  165. package/dist-esm/ui/count-badge.mjs +8 -0
  166. package/dist-esm/ui/count-badge.mjs.map +7 -0
  167. package/dist-esm/ui/empty-state.mjs +11 -0
  168. package/dist-esm/ui/empty-state.mjs.map +7 -0
  169. package/dist-esm/ui/format-time.mjs +26 -0
  170. package/dist-esm/ui/format-time.mjs.map +7 -0
  171. package/dist-esm/ui/mention-list.mjs +50 -0
  172. package/dist-esm/ui/mention-list.mjs.map +7 -0
  173. package/dist-esm/ui/mention-suggestion.mjs +186 -0
  174. package/dist-esm/ui/mention-suggestion.mjs.map +7 -0
  175. package/dist-esm/ui/mention.mjs +11 -0
  176. package/dist-esm/ui/mention.mjs.map +7 -0
  177. package/dist-esm/ui/reaction.mjs +11 -0
  178. package/dist-esm/ui/reaction.mjs.map +7 -0
  179. package/dist-esm/ui/reactions.mjs +14 -0
  180. package/dist-esm/ui/reactions.mjs.map +7 -0
  181. package/dist-esm/ui/render-markdown.mjs +45 -0
  182. package/dist-esm/ui/render-markdown.mjs.map +7 -0
  183. package/dist-esm/ui/send-button.mjs +8 -0
  184. package/dist-esm/ui/send-button.mjs.map +7 -0
  185. package/package.json +71 -0
  186. package/src/canvas/canvas.css +148 -0
  187. package/src/canvas/cluster-input.test.ts +223 -0
  188. package/src/canvas/cluster-input.ts +29 -0
  189. package/src/canvas/comment-body.tsx +21 -0
  190. package/src/canvas/comment-render.test.ts +90 -0
  191. package/src/canvas/comment-render.ts +92 -0
  192. package/src/canvas/comment-store.ts +55 -0
  193. package/src/canvas/comment-tool.tsx +200 -0
  194. package/src/canvas/comments-filter-menu.tsx +104 -0
  195. package/src/canvas/comments-menu-item.tsx +24 -0
  196. package/src/canvas/comments-overflow-menu.tsx +62 -0
  197. package/src/canvas/comments-overlay.tsx +1460 -0
  198. package/src/canvas/comments-sidebar.tsx +184 -0
  199. package/src/canvas/hooks.ts +28 -0
  200. package/src/canvas/license.ts +15 -0
  201. package/src/canvas/options.test.ts +127 -0
  202. package/src/canvas/options.ts +111 -0
  203. package/src/canvas/region-options.ts +57 -0
  204. package/src/canvas/rich-text.ts +15 -0
  205. package/src/canvas/sidebar-filters.ts +25 -0
  206. package/src/canvas/state.ts +102 -0
  207. package/src/canvas/thread-state.ts +91 -0
  208. package/src/clustering/computeClusterTable.test.ts +299 -0
  209. package/src/clustering/computeClusterTable.ts +82 -0
  210. package/src/clustering/locality.test.ts +189 -0
  211. package/src/clustering/mst.test.ts +383 -0
  212. package/src/clustering/mst.ts +134 -0
  213. package/src/clustering/replay.test.ts +547 -0
  214. package/src/clustering/replay.ts +326 -0
  215. package/src/clustering/runtime.test.ts +596 -0
  216. package/src/clustering/runtime.ts +153 -0
  217. package/src/clustering/schedule.test.ts +514 -0
  218. package/src/clustering/schedule.ts +184 -0
  219. package/src/clustering/types.ts +102 -0
  220. package/src/index.ts +96 -0
  221. package/src/ui/avatar.tsx +31 -0
  222. package/src/ui/byline.tsx +23 -0
  223. package/src/ui/comment-card.tsx +32 -0
  224. package/src/ui/comment-composer.tsx +179 -0
  225. package/src/ui/comment-extensions.ts +25 -0
  226. package/src/ui/comment-mention.ts +47 -0
  227. package/src/ui/comment-pin.tsx +21 -0
  228. package/src/ui/comment-text.tsx +12 -0
  229. package/src/ui/comment-thread.tsx +56 -0
  230. package/src/ui/comments-list.tsx +139 -0
  231. package/src/ui/comments.css +678 -0
  232. package/src/ui/count-badge.tsx +9 -0
  233. package/src/ui/empty-state.tsx +16 -0
  234. package/src/ui/format-time.ts +29 -0
  235. package/src/ui/mention-list.tsx +106 -0
  236. package/src/ui/mention-suggestion.test.ts +18 -0
  237. package/src/ui/mention-suggestion.tsx +285 -0
  238. package/src/ui/mention.tsx +9 -0
  239. package/src/ui/reaction.tsx +16 -0
  240. package/src/ui/reactions.tsx +15 -0
  241. package/src/ui/render-markdown.tsx +72 -0
  242. package/src/ui/send-button.tsx +15 -0
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var rich_text_exports = {};
20
+ __export(rich_text_exports, {
21
+ richTextToPlaintext: () => richTextToPlaintext
22
+ });
23
+ module.exports = __toCommonJS(rich_text_exports);
24
+ var import_comment_render = require("./comment-render");
25
+ function richTextToPlaintext(body, resolveName) {
26
+ return (0, import_comment_render.renderCommentPlaintext)(body, resolveName);
27
+ }
28
+ //# sourceMappingURL=rich-text.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/canvas/rich-text.ts"],
4
+ "sourcesContent": ["import { TLRichText } from 'tldraw'\nimport { renderCommentPlaintext } from './comment-render'\n\n/**\n * Flatten a rich-text comment body to plaintext through the limited comment extension set,\n * separating paragraphs and list items with newlines. A convenience for consumers rendering bodies\n * as plain text (e.g. the sidebar preview); richer rendering can read the `TLRichText` directly.\n * @public\n */\nexport function richTextToPlaintext(\n\tbody: TLRichText,\n\tresolveName?: (id: string) => string | undefined\n): string {\n\treturn renderCommentPlaintext(body, resolveName)\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,4BAAuC;AAQhC,SAAS,oBACf,MACA,aACS;AACT,aAAO,8CAAuB,MAAM,WAAW;AAChD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var sidebar_filters_exports = {};
20
+ __export(sidebar_filters_exports, {
21
+ DEFAULT_SIDEBAR_FILTERS: () => DEFAULT_SIDEBAR_FILTERS
22
+ });
23
+ module.exports = __toCommonJS(sidebar_filters_exports);
24
+ const DEFAULT_SIDEBAR_FILTERS = {
25
+ showResolved: true,
26
+ onlyMine: false,
27
+ onlyUnread: false,
28
+ onlyCurrentPage: true
29
+ };
30
+ //# sourceMappingURL=sidebar-filters.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/canvas/sidebar-filters.ts"],
4
+ "sourcesContent": ["/**\n * Which threads the comments sidebar shows. Held as an editor-scoped signal (the `sidebarFilters`\n * `EditorAtom` in `./state`) rather than component state so it survives the sidebar\n * unmounting when the comment tool deactivates \u2014 a user's \"hide resolved\" choice shouldn't reset\n * every time they leave the tool.\n * @public\n */\nexport interface SidebarFilters {\n\t/** Include resolved threads. */\n\tshowResolved: boolean\n\t/** Only threads the current user started. Ignored when there's no current user. */\n\tonlyMine: boolean\n\t/** Only threads with unread comments. Ignored when the host provides no read status. */\n\tonlyUnread: boolean\n\t/** Only threads on the current page. Off = every page's threads, each labelled. */\n\tonlyCurrentPage: boolean\n}\n\n/** @public */\nexport const DEFAULT_SIDEBAR_FILTERS: SidebarFilters = {\n\tshowResolved: true,\n\tonlyMine: false,\n\tonlyUnread: false,\n\tonlyCurrentPage: true,\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBO,MAAM,0BAA0C;AAAA,EACtD,cAAc;AAAA,EACd,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,iBAAiB;AAClB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var state_exports = {};
20
+ __export(state_exports, {
21
+ commentsHidden: () => commentsHidden,
22
+ commitCommentMutation: () => commitCommentMutation,
23
+ openThreadId: () => openThreadId,
24
+ pendingComment: () => pendingComment,
25
+ regionDraft: () => regionDraft,
26
+ sidebarFilters: () => sidebarFilters,
27
+ toggleCommentsHidden: () => toggleCommentsHidden,
28
+ useCommentsHidden: () => useCommentsHidden,
29
+ useOpenThreadId: () => useOpenThreadId,
30
+ usePendingComment: () => usePendingComment,
31
+ useSidebarFilters: () => useSidebarFilters
32
+ });
33
+ module.exports = __toCommonJS(state_exports);
34
+ var import_tldraw = require("tldraw");
35
+ var import_options = require("./options");
36
+ var import_sidebar_filters = require("./sidebar-filters");
37
+ const openThreadId = new import_tldraw.EditorAtom("openThreadId", () => null);
38
+ const pendingComment = new import_tldraw.EditorAtom("pendingComment", () => null);
39
+ const regionDraft = new import_tldraw.EditorAtom("regionDraft", () => null);
40
+ const commentsHidden = new import_tldraw.EditorAtom("commentsHidden", () => false);
41
+ const sidebarFilters = new import_tldraw.EditorAtom(
42
+ "sidebarFilters",
43
+ () => import_sidebar_filters.DEFAULT_SIDEBAR_FILTERS
44
+ );
45
+ function toggleCommentsHidden(editor) {
46
+ commentsHidden.update(editor, (hidden) => !hidden);
47
+ }
48
+ function useOpenThreadId() {
49
+ const editor = (0, import_tldraw.useEditor)();
50
+ return (0, import_tldraw.useValue)("open thread id", () => openThreadId.get(editor), [editor]);
51
+ }
52
+ function usePendingComment() {
53
+ const editor = (0, import_tldraw.useEditor)();
54
+ return (0, import_tldraw.useValue)("pending comment", () => pendingComment.get(editor), [editor]);
55
+ }
56
+ function useCommentsHidden() {
57
+ const editor = (0, import_tldraw.useEditor)();
58
+ return (0, import_tldraw.useValue)("comments hidden", () => commentsHidden.get(editor), [editor]);
59
+ }
60
+ function useSidebarFilters() {
61
+ const editor = (0, import_tldraw.useEditor)();
62
+ return (0, import_tldraw.useValue)("sidebar filters", () => sidebarFilters.get(editor), [editor]);
63
+ }
64
+ function commitCommentMutation(editor, fn, kind = "mutation") {
65
+ const options = (0, import_options.getCommentingOptions)(editor);
66
+ const history = kind === "drag" ? options.dragHistory ?? options.history : options.history;
67
+ let result;
68
+ editor.run(
69
+ () => {
70
+ result = fn();
71
+ },
72
+ { history }
73
+ );
74
+ return result;
75
+ }
76
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/canvas/state.ts"],
4
+ "sourcesContent": ["import {\n\tEditorAtom,\n\ttype BoxModel,\n\ttype Editor,\n\ttype TLHistoryBatchOptions,\n\tuseEditor,\n\tuseValue,\n} from 'tldraw'\nimport type { PendingComment } from './comment-tool'\nimport { getCommentingOptions } from './options'\nimport { DEFAULT_SIDEBAR_FILTERS, type SidebarFilters } from './sidebar-filters'\n\n/**\n * Transient commenting UI state, scoped per editor via {@link EditorAtom}. Editor-scoping (rather\n * than module-global atoms) keeps two editors on one page \u2014 or an editor and a second instance \u2014\n * from sharing open-thread, visibility, and filter state. Reachable from both React (`useEditor()`)\n * and the comment tool (`this.editor`).\n */\n\n/** The id of the one open thread (only one popover is open at a time), or null when all closed.\n * @public */\nexport const openThreadId = new EditorAtom<string | null>('openThreadId', () => null)\n\n/** The comment currently being placed (composer open, not yet posted), or null.\n * @public */\nexport const pendingComment = new EditorAtom<PendingComment | null>('pendingComment', () => null)\n\n/** The region rectangle being dragged out right now (page coords), or null when not dragging. The\n * comment tool writes it on each move; the overlay reads it to draw the live dashed box. */\nexport const regionDraft = new EditorAtom<BoxModel | null>('regionDraft', () => null)\n\n/**\n * Whether comment pins are hidden on the canvas. Governs the on-canvas layer (pins + open popover)\n * only \u2014 the sidebar is unaffected.\n * @public\n */\nexport const commentsHidden = new EditorAtom<boolean>('commentsHidden', () => false)\n\n/** Which threads the comments sidebar shows.\n * @public */\nexport const sidebarFilters = new EditorAtom<SidebarFilters>(\n\t'sidebarFilters',\n\t() => DEFAULT_SIDEBAR_FILTERS\n)\n\n/** Toggle comment-pin visibility for an editor.\n * @public */\nexport function toggleCommentsHidden(editor: Editor): void {\n\tcommentsHidden.update(editor, (hidden) => !hidden)\n}\n\n/** React hook for the open thread id.\n * @public */\nexport function useOpenThreadId(): string | null {\n\tconst editor = useEditor()\n\treturn useValue('open thread id', () => openThreadId.get(editor), [editor])\n}\n\n/** React hook for the pending (being-placed) comment.\n * @public */\nexport function usePendingComment(): PendingComment | null {\n\tconst editor = useEditor()\n\treturn useValue('pending comment', () => pendingComment.get(editor), [editor])\n}\n\n/** React hook for whether comment pins are hidden.\n * @public */\nexport function useCommentsHidden(): boolean {\n\tconst editor = useEditor()\n\treturn useValue('comments hidden', () => commentsHidden.get(editor), [editor])\n}\n\n/** React hook for the current sidebar filters.\n * @public */\nexport function useSidebarFilters(): SidebarFilters {\n\tconst editor = useEditor()\n\treturn useValue('sidebar filters', () => sidebarFilters.get(editor), [editor])\n}\n\n/**\n * Commit a comment mutation with the configured undo/redo behavior. All comment writes go through\n * here so the {@link CommentingOptions.history} option (and {@link CommentingOptions.dragHistory}\n * for pin re-anchors) governs whether they land on the undo stack. Defaults to `'ignore'`.\n * @public\n */\nexport function commitCommentMutation<T>(\n\teditor: Editor,\n\tfn: () => T,\n\tkind: 'mutation' | 'drag' = 'mutation'\n): T {\n\tconst options = getCommentingOptions(editor)\n\tconst history: TLHistoryBatchOptions['history'] =\n\t\tkind === 'drag' ? (options.dragHistory ?? options.history) : options.history\n\tlet result: T\n\teditor.run(\n\t\t() => {\n\t\t\tresult = fn()\n\t\t},\n\t\t{ history }\n\t)\n\treturn result!\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAOO;AAEP,qBAAqC;AACrC,6BAA6D;AAWtD,MAAM,eAAe,IAAI,yBAA0B,gBAAgB,MAAM,IAAI;AAI7E,MAAM,iBAAiB,IAAI,yBAAkC,kBAAkB,MAAM,IAAI;AAIzF,MAAM,cAAc,IAAI,yBAA4B,eAAe,MAAM,IAAI;AAO7E,MAAM,iBAAiB,IAAI,yBAAoB,kBAAkB,MAAM,KAAK;AAI5E,MAAM,iBAAiB,IAAI;AAAA,EACjC;AAAA,EACA,MAAM;AACP;AAIO,SAAS,qBAAqB,QAAsB;AAC1D,iBAAe,OAAO,QAAQ,CAAC,WAAW,CAAC,MAAM;AAClD;AAIO,SAAS,kBAAiC;AAChD,QAAM,aAAS,yBAAU;AACzB,aAAO,wBAAS,kBAAkB,MAAM,aAAa,IAAI,MAAM,GAAG,CAAC,MAAM,CAAC;AAC3E;AAIO,SAAS,oBAA2C;AAC1D,QAAM,aAAS,yBAAU;AACzB,aAAO,wBAAS,mBAAmB,MAAM,eAAe,IAAI,MAAM,GAAG,CAAC,MAAM,CAAC;AAC9E;AAIO,SAAS,oBAA6B;AAC5C,QAAM,aAAS,yBAAU;AACzB,aAAO,wBAAS,mBAAmB,MAAM,eAAe,IAAI,MAAM,GAAG,CAAC,MAAM,CAAC;AAC9E;AAIO,SAAS,oBAAoC;AACnD,QAAM,aAAS,yBAAU;AACzB,aAAO,wBAAS,mBAAmB,MAAM,eAAe,IAAI,MAAM,GAAG,CAAC,MAAM,CAAC;AAC9E;AAQO,SAAS,sBACf,QACA,IACA,OAA4B,YACxB;AACJ,QAAM,cAAU,qCAAqB,MAAM;AAC3C,QAAM,UACL,SAAS,SAAU,QAAQ,eAAe,QAAQ,UAAW,QAAQ;AACtE,MAAI;AACJ,SAAO;AAAA,IACN,MAAM;AACL,eAAS,GAAG;AAAA,IACb;AAAA,IACA,EAAE,QAAQ;AAAA,EACX;AACA,SAAO;AACR;",
6
+ "names": []
7
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var thread_state_exports = {};
20
+ __export(thread_state_exports, {
21
+ DEFAULT_IMPRECISE_SHAPE_ANCHOR: () => DEFAULT_IMPRECISE_SHAPE_ANCHOR,
22
+ REGION_PIN_CORNER: () => REGION_PIN_CORNER,
23
+ anchorPagePoint: () => anchorPagePoint,
24
+ focusThread: () => focusThread,
25
+ regionPinPoint: () => regionPinPoint,
26
+ shapeAnchorAt: () => shapeAnchorAt
27
+ });
28
+ module.exports = __toCommonJS(thread_state_exports);
29
+ var import_region_options = require("./region-options");
30
+ var import_state = require("./state");
31
+ const DEFAULT_IMPRECISE_SHAPE_ANCHOR = { x: 1, y: 0 };
32
+ const REGION_PIN_CORNER = { x: 1, y: 1 };
33
+ function regionPinPoint(region, corner = REGION_PIN_CORNER) {
34
+ return {
35
+ x: region.x + corner.x * region.w,
36
+ y: region.y + corner.y * region.h
37
+ };
38
+ }
39
+ function anchorPagePoint(editor, anchor, impreciseShapeAnchor = DEFAULT_IMPRECISE_SHAPE_ANCHOR) {
40
+ switch (anchor.type) {
41
+ case "shape": {
42
+ const bounds = editor.getShapePageBounds(anchor.shapeId);
43
+ if (!bounds) return null;
44
+ const { x, y } = anchor.isPrecise ? anchor : impreciseShapeAnchor;
45
+ return { x: bounds.minX + x * bounds.w, y: bounds.minY + y * bounds.h };
46
+ }
47
+ case "text-range": {
48
+ const bounds = editor.getShapePageBounds(anchor.shapeId);
49
+ if (!bounds) return null;
50
+ return { x: bounds.maxX, y: bounds.minY };
51
+ }
52
+ case "point":
53
+ return { x: anchor.x, y: anchor.y };
54
+ case "region":
55
+ return regionPinPoint(anchor, (0, import_region_options.getRegionCommentOptions)(editor).pinCorner);
56
+ case "page":
57
+ return null;
58
+ }
59
+ }
60
+ function shapeAnchorAt(editor, shapeId, page, precise) {
61
+ const bounds = editor.getShapePageBounds(shapeId);
62
+ if (!bounds || bounds.w === 0 || bounds.h === 0) {
63
+ return { type: "shape", shapeId, x: 0.5, y: 0.5, isPrecise: precise };
64
+ }
65
+ return {
66
+ type: "shape",
67
+ shapeId,
68
+ x: (page.x - bounds.minX) / bounds.w,
69
+ y: (page.y - bounds.minY) / bounds.h,
70
+ isPrecise: precise
71
+ };
72
+ }
73
+ function focusThread(editor, thread, impreciseShapeAnchor) {
74
+ if (thread.pageId !== editor.getCurrentPageId()) {
75
+ editor.setCurrentPage(thread.pageId);
76
+ }
77
+ import_state.openThreadId.set(editor, thread.id);
78
+ const point = anchorPagePoint(editor, thread.anchor, impreciseShapeAnchor);
79
+ if (point) editor.centerOnPoint(point, { animation: { duration: 200 } });
80
+ }
81
+ //# sourceMappingURL=thread-state.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/canvas/thread-state.ts"],
4
+ "sourcesContent": ["import { BoxModel, Editor, TLCommentAnchor, TLCommentThread, TLShapeId, VecLike } from 'tldraw'\nimport { getRegionCommentOptions } from './region-options'\nimport { openThreadId } from './state'\n\n/** Where an imprecise shape comment sits by default: the shape's top-right corner. Overridable. @public */\nexport const DEFAULT_IMPRECISE_SHAPE_ANCHOR = { x: 1, y: 0 }\n\n/** The default corner a region's pin and composer sit on, as a normalized 0\u20131 offset (bottom-right).\n * Overridable per editor via region options; pin position, composer placement, region move, and\n * which corner has no resize handle all derive from the chosen corner. */\nexport const REGION_PIN_CORNER: VecLike = { x: 1, y: 1 }\n\n/** The page point of a region's pin corner. */\nexport function regionPinPoint(region: BoxModel, corner: VecLike = REGION_PIN_CORNER): VecLike {\n\treturn {\n\t\tx: region.x + corner.x * region.w,\n\t\ty: region.y + corner.y * region.h,\n\t}\n}\n\n/**\n * Where a thread's pin sits on the page, for each anchor kind. Null hides the pin. For imprecise\n * shape anchors the pin uses `impreciseShapeAnchor` (a normalized 0\u20131 spot, top-right by default)\n * rather than the stored `x`/`y`.\n * @public\n */\nexport function anchorPagePoint(\n\teditor: Editor,\n\tanchor: TLCommentAnchor,\n\timpreciseShapeAnchor: { x: number; y: number } = DEFAULT_IMPRECISE_SHAPE_ANCHOR\n): { x: number; y: number } | null {\n\tswitch (anchor.type) {\n\t\tcase 'shape': {\n\t\t\tconst bounds = editor.getShapePageBounds(anchor.shapeId as TLShapeId)\n\t\t\tif (!bounds) return null\n\t\t\t// Precise pins sit at their stored x/y; imprecise ones at the consumer's default spot.\n\t\t\tconst { x, y } = anchor.isPrecise ? anchor : impreciseShapeAnchor\n\t\t\treturn { x: bounds.minX + x * bounds.w, y: bounds.minY + y * bounds.h }\n\t\t}\n\t\tcase 'text-range': {\n\t\t\tconst bounds = editor.getShapePageBounds(anchor.shapeId as TLShapeId)\n\t\t\tif (!bounds) return null\n\t\t\treturn { x: bounds.maxX, y: bounds.minY }\n\t\t}\n\t\tcase 'point':\n\t\t\treturn { x: anchor.x, y: anchor.y }\n\t\tcase 'region':\n\t\t\treturn regionPinPoint(anchor, getRegionCommentOptions(editor).pinCorner)\n\t\tcase 'page':\n\t\t\treturn null\n\t}\n}\n\n/**\n * A shape anchor for a page point. `x`/`y` are the point's normalized (0\u20131) offset within the\n * shape's page bounds, remembered either way. When `precise` (Alt held) the pin sits at exactly\n * `x`/`y`; otherwise it sits at the consumer's imprecise default (top-right out of the box).\n * @public\n */\nexport function shapeAnchorAt(\n\teditor: Editor,\n\tshapeId: TLShapeId,\n\tpage: { x: number; y: number },\n\tprecise: boolean\n): TLCommentAnchor {\n\tconst bounds = editor.getShapePageBounds(shapeId)\n\tif (!bounds || bounds.w === 0 || bounds.h === 0) {\n\t\treturn { type: 'shape', shapeId, x: 0.5, y: 0.5, isPrecise: precise }\n\t}\n\treturn {\n\t\ttype: 'shape',\n\t\tshapeId,\n\t\tx: (page.x - bounds.minX) / bounds.w,\n\t\ty: (page.y - bounds.minY) / bounds.h,\n\t\tisPrecise: precise,\n\t}\n}\n\n/** Open a thread and bring it into view \u2014 switch to its page if needed, then center its pin. @public */\nexport function focusThread(\n\teditor: Editor,\n\tthread: TLCommentThread,\n\timpreciseShapeAnchor?: { x: number; y: number }\n): void {\n\tif (thread.pageId !== editor.getCurrentPageId()) {\n\t\teditor.setCurrentPage(thread.pageId as any)\n\t}\n\topenThreadId.set(editor, thread.id)\n\tconst point = anchorPagePoint(editor, thread.anchor, impreciseShapeAnchor)\n\tif (point) editor.centerOnPoint(point, { animation: { duration: 200 } })\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,4BAAwC;AACxC,mBAA6B;AAGtB,MAAM,iCAAiC,EAAE,GAAG,GAAG,GAAG,EAAE;AAKpD,MAAM,oBAA6B,EAAE,GAAG,GAAG,GAAG,EAAE;AAGhD,SAAS,eAAe,QAAkB,SAAkB,mBAA4B;AAC9F,SAAO;AAAA,IACN,GAAG,OAAO,IAAI,OAAO,IAAI,OAAO;AAAA,IAChC,GAAG,OAAO,IAAI,OAAO,IAAI,OAAO;AAAA,EACjC;AACD;AAQO,SAAS,gBACf,QACA,QACA,uBAAiD,gCACf;AAClC,UAAQ,OAAO,MAAM;AAAA,IACpB,KAAK,SAAS;AACb,YAAM,SAAS,OAAO,mBAAmB,OAAO,OAAoB;AACpE,UAAI,CAAC,OAAQ,QAAO;AAEpB,YAAM,EAAE,GAAG,EAAE,IAAI,OAAO,YAAY,SAAS;AAC7C,aAAO,EAAE,GAAG,OAAO,OAAO,IAAI,OAAO,GAAG,GAAG,OAAO,OAAO,IAAI,OAAO,EAAE;AAAA,IACvE;AAAA,IACA,KAAK,cAAc;AAClB,YAAM,SAAS,OAAO,mBAAmB,OAAO,OAAoB;AACpE,UAAI,CAAC,OAAQ,QAAO;AACpB,aAAO,EAAE,GAAG,OAAO,MAAM,GAAG,OAAO,KAAK;AAAA,IACzC;AAAA,IACA,KAAK;AACJ,aAAO,EAAE,GAAG,OAAO,GAAG,GAAG,OAAO,EAAE;AAAA,IACnC,KAAK;AACJ,aAAO,eAAe,YAAQ,+CAAwB,MAAM,EAAE,SAAS;AAAA,IACxE,KAAK;AACJ,aAAO;AAAA,EACT;AACD;AAQO,SAAS,cACf,QACA,SACA,MACA,SACkB;AAClB,QAAM,SAAS,OAAO,mBAAmB,OAAO;AAChD,MAAI,CAAC,UAAU,OAAO,MAAM,KAAK,OAAO,MAAM,GAAG;AAChD,WAAO,EAAE,MAAM,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK,WAAW,QAAQ;AAAA,EACrE;AACA,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO;AAAA,IACnC,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO;AAAA,IACnC,WAAW;AAAA,EACZ;AACD;AAGO,SAAS,YACf,QACA,QACA,sBACO;AACP,MAAI,OAAO,WAAW,OAAO,iBAAiB,GAAG;AAChD,WAAO,eAAe,OAAO,MAAa;AAAA,EAC3C;AACA,4BAAa,IAAI,QAAQ,OAAO,EAAE;AAClC,QAAM,QAAQ,gBAAgB,QAAQ,OAAO,QAAQ,oBAAoB;AACzE,MAAI,MAAO,QAAO,cAAc,OAAO,EAAE,WAAW,EAAE,UAAU,IAAI,EAAE,CAAC;AACxE;",
6
+ "names": []
7
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var computeClusterTable_exports = {};
20
+ __export(computeClusterTable_exports, {
21
+ computeClusterTable: () => computeClusterTable
22
+ });
23
+ module.exports = __toCommonJS(computeClusterTable_exports);
24
+ var import_mst = require("./mst");
25
+ var import_replay = require("./replay");
26
+ var import_schedule = require("./schedule");
27
+ function computeClusterTable(leaves, options) {
28
+ const opts = resolveOptions(options);
29
+ const leafNodes = leaves.map(leafToNode);
30
+ const edges = (0, import_mst.mstEdges)(leaves);
31
+ if (leaves.length < 2) {
32
+ return { events: [], leaves: leafNodes };
33
+ }
34
+ const raw = (0, import_replay.cappedReplay)(leaves, edges, { Tc: opts.Tc, Dmax: opts.Dmax });
35
+ const contracted = (0, import_schedule.contract)(raw, opts.eps);
36
+ const events = (0, import_schedule.finalize)(contracted, {
37
+ Tc: opts.Tc,
38
+ Tu: opts.Tu,
39
+ minZoom: opts.minZoom,
40
+ maxZoom: opts.maxZoom,
41
+ maxSplitZoom: opts.maxSplitZoom
42
+ });
43
+ return { events, leaves: leafNodes };
44
+ }
45
+ function resolveOptions(options) {
46
+ const Tc = options.Tc ?? 40;
47
+ const Tu = options.Tu ?? 1.5 * Tc;
48
+ const eps = options.eps ?? 0.12;
49
+ const Dmax = options.Dmax ?? 3 * Tc;
50
+ const maxSplitZoom = options.maxSplitZoom ?? 6;
51
+ const { minZoom, maxZoom } = options;
52
+ if (!Number.isFinite(Tc) || Tc <= 0) {
53
+ throw new Error("Tc must be finite and greater than 0");
54
+ }
55
+ if (!Number.isFinite(Tu) || Tu <= Tc) {
56
+ throw new Error("Tu must be finite and greater than Tc");
57
+ }
58
+ if (!Number.isFinite(eps) || eps < 0) {
59
+ throw new Error("eps must be finite and greater than or equal to 0");
60
+ }
61
+ if (!Number.isFinite(Dmax) || Dmax < Tc) {
62
+ throw new Error("Dmax must be finite and greater than or equal to Tc");
63
+ }
64
+ if (!Number.isFinite(minZoom) || minZoom <= 0) {
65
+ throw new Error("minZoom must be finite and greater than 0");
66
+ }
67
+ if (!Number.isFinite(maxZoom) || maxZoom <= minZoom) {
68
+ throw new Error("maxZoom must be finite and greater than minZoom");
69
+ }
70
+ if (!Number.isFinite(maxSplitZoom) || maxSplitZoom <= 0) {
71
+ throw new Error("maxSplitZoom must be finite and greater than 0");
72
+ }
73
+ return { Tc, Tu, eps, Dmax, minZoom, maxZoom, maxSplitZoom };
74
+ }
75
+ function leafToNode(leaf) {
76
+ return {
77
+ id: leaf.id,
78
+ centroid: { x: leaf.point.x, y: leaf.point.y },
79
+ count: 1,
80
+ members: [leaf.id]
81
+ };
82
+ }
83
+ //# sourceMappingURL=computeClusterTable.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/clustering/computeClusterTable.ts"],
4
+ "sourcesContent": ["import { mstEdges } from './mst'\nimport { cappedReplay } from './replay'\nimport { contract, finalize } from './schedule'\nimport type { ClusterNode, ClusterOptions, ClusterTable, LeafInput } from './types'\n\ninterface ResolvedClusterOptions {\n\tTc: number\n\tTu: number\n\teps: number\n\tDmax: number\n\tminZoom: number\n\tmaxZoom: number\n\tmaxSplitZoom: number\n}\n\n/** @public */\nexport function computeClusterTable(\n\tleaves: readonly LeafInput[],\n\toptions: ClusterOptions\n): ClusterTable {\n\tconst opts = resolveOptions(options)\n\tconst leafNodes = leaves.map(leafToNode)\n\tconst edges = mstEdges(leaves)\n\n\tif (leaves.length < 2) {\n\t\treturn { events: [], leaves: leafNodes }\n\t}\n\n\tconst raw = cappedReplay(leaves, edges, { Tc: opts.Tc, Dmax: opts.Dmax })\n\tconst contracted = contract(raw, opts.eps)\n\tconst events = finalize(contracted, {\n\t\tTc: opts.Tc,\n\t\tTu: opts.Tu,\n\t\tminZoom: opts.minZoom,\n\t\tmaxZoom: opts.maxZoom,\n\t\tmaxSplitZoom: opts.maxSplitZoom,\n\t})\n\n\treturn { events, leaves: leafNodes }\n}\n\nfunction resolveOptions(options: ClusterOptions): ResolvedClusterOptions {\n\tconst Tc = options.Tc ?? 40\n\tconst Tu = options.Tu ?? 1.5 * Tc\n\tconst eps = options.eps ?? 0.12\n\tconst Dmax = options.Dmax ?? 3 * Tc\n\tconst maxSplitZoom = options.maxSplitZoom ?? 6\n\tconst { minZoom, maxZoom } = options\n\n\tif (!Number.isFinite(Tc) || Tc <= 0) {\n\t\tthrow new Error('Tc must be finite and greater than 0')\n\t}\n\tif (!Number.isFinite(Tu) || Tu <= Tc) {\n\t\tthrow new Error('Tu must be finite and greater than Tc')\n\t}\n\tif (!Number.isFinite(eps) || eps < 0) {\n\t\tthrow new Error('eps must be finite and greater than or equal to 0')\n\t}\n\tif (!Number.isFinite(Dmax) || Dmax < Tc) {\n\t\tthrow new Error('Dmax must be finite and greater than or equal to Tc')\n\t}\n\tif (!Number.isFinite(minZoom) || minZoom <= 0) {\n\t\tthrow new Error('minZoom must be finite and greater than 0')\n\t}\n\tif (!Number.isFinite(maxZoom) || maxZoom <= minZoom) {\n\t\tthrow new Error('maxZoom must be finite and greater than minZoom')\n\t}\n\tif (!Number.isFinite(maxSplitZoom) || maxSplitZoom <= 0) {\n\t\tthrow new Error('maxSplitZoom must be finite and greater than 0')\n\t}\n\n\treturn { Tc, Tu, eps, Dmax, minZoom, maxZoom, maxSplitZoom }\n}\n\nfunction leafToNode(leaf: LeafInput): ClusterNode {\n\treturn {\n\t\tid: leaf.id,\n\t\tcentroid: { x: leaf.point.x, y: leaf.point.y },\n\t\tcount: 1,\n\t\tmembers: [leaf.id],\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAyB;AACzB,oBAA6B;AAC7B,sBAAmC;AAc5B,SAAS,oBACf,QACA,SACe;AACf,QAAM,OAAO,eAAe,OAAO;AACnC,QAAM,YAAY,OAAO,IAAI,UAAU;AACvC,QAAM,YAAQ,qBAAS,MAAM;AAE7B,MAAI,OAAO,SAAS,GAAG;AACtB,WAAO,EAAE,QAAQ,CAAC,GAAG,QAAQ,UAAU;AAAA,EACxC;AAEA,QAAM,UAAM,4BAAa,QAAQ,OAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,KAAK,CAAC;AACxE,QAAM,iBAAa,0BAAS,KAAK,KAAK,GAAG;AACzC,QAAM,aAAS,0BAAS,YAAY;AAAA,IACnC,IAAI,KAAK;AAAA,IACT,IAAI,KAAK;AAAA,IACT,SAAS,KAAK;AAAA,IACd,SAAS,KAAK;AAAA,IACd,cAAc,KAAK;AAAA,EACpB,CAAC;AAED,SAAO,EAAE,QAAQ,QAAQ,UAAU;AACpC;AAEA,SAAS,eAAe,SAAiD;AACxE,QAAM,KAAK,QAAQ,MAAM;AACzB,QAAM,KAAK,QAAQ,MAAM,MAAM;AAC/B,QAAM,MAAM,QAAQ,OAAO;AAC3B,QAAM,OAAO,QAAQ,QAAQ,IAAI;AACjC,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,EAAE,SAAS,QAAQ,IAAI;AAE7B,MAAI,CAAC,OAAO,SAAS,EAAE,KAAK,MAAM,GAAG;AACpC,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACvD;AACA,MAAI,CAAC,OAAO,SAAS,EAAE,KAAK,MAAM,IAAI;AACrC,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACxD;AACA,MAAI,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM,GAAG;AACrC,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACpE;AACA,MAAI,CAAC,OAAO,SAAS,IAAI,KAAK,OAAO,IAAI;AACxC,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACtE;AACA,MAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,GAAG;AAC9C,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC5D;AACA,MAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,SAAS;AACpD,UAAM,IAAI,MAAM,iDAAiD;AAAA,EAClE;AACA,MAAI,CAAC,OAAO,SAAS,YAAY,KAAK,gBAAgB,GAAG;AACxD,UAAM,IAAI,MAAM,gDAAgD;AAAA,EACjE;AAEA,SAAO,EAAE,IAAI,IAAI,KAAK,MAAM,SAAS,SAAS,aAAa;AAC5D;AAEA,SAAS,WAAW,MAA8B;AACjD,SAAO;AAAA,IACN,IAAI,KAAK;AAAA,IACT,UAAU,EAAE,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,EAAE;AAAA,IAC7C,OAAO;AAAA,IACP,SAAS,CAAC,KAAK,EAAE;AAAA,EAClB;AACD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var mst_exports = {};
20
+ __export(mst_exports, {
21
+ mstEdges: () => mstEdges
22
+ });
23
+ module.exports = __toCommonJS(mst_exports);
24
+ function mstEdges(leaves) {
25
+ const n = leaves.length;
26
+ const ids = new Array(n);
27
+ const xs = new Float64Array(n);
28
+ const ys = new Float64Array(n);
29
+ const seen = /* @__PURE__ */ new Set();
30
+ let root = 0;
31
+ for (let i = 0; i < n; i++) {
32
+ const leaf = leaves[i];
33
+ if (seen.has(leaf.id)) {
34
+ throw new Error(`Duplicate leaf id: ${leaf.id}`);
35
+ }
36
+ seen.add(leaf.id);
37
+ if (!Number.isFinite(leaf.point.x) || !Number.isFinite(leaf.point.y)) {
38
+ throw new Error(`Non-finite coordinate for leaf id: ${leaf.id}`);
39
+ }
40
+ ids[i] = leaf.id;
41
+ xs[i] = leaf.point.x;
42
+ ys[i] = leaf.point.y;
43
+ if (i > 0 && leaf.id < ids[root]) root = i;
44
+ }
45
+ if (n < 2) return [];
46
+ const inTree = new Uint8Array(n);
47
+ const bestD2 = new Float64Array(n);
48
+ const bestFrom = new Int32Array(n);
49
+ inTree[root] = 1;
50
+ bestD2.fill(Number.POSITIVE_INFINITY);
51
+ bestFrom.fill(-1);
52
+ for (let i = 0; i < n; i++) {
53
+ if (i === root) continue;
54
+ bestD2[i] = squaredDistance(xs, ys, root, i);
55
+ bestFrom[i] = root;
56
+ }
57
+ const edges = [];
58
+ for (let edgeCount = 0; edgeCount < n - 1; edgeCount++) {
59
+ let next = -1;
60
+ for (let i = 0; i < n; i++) {
61
+ if (inTree[i]) continue;
62
+ if (next === -1 || edgeKeyLess(bestD2[i], bestFrom[i], i, bestD2[next], bestFrom[next], next, ids)) {
63
+ next = i;
64
+ }
65
+ }
66
+ const from = bestFrom[next];
67
+ edges.push(createOutputEdge(xs, ys, ids, from, next));
68
+ inTree[next] = 1;
69
+ for (let i = 0; i < n; i++) {
70
+ if (inTree[i]) continue;
71
+ const d2 = squaredDistance(xs, ys, next, i);
72
+ if (edgeKeyLess(d2, next, i, bestD2[i], bestFrom[i], i, ids)) {
73
+ bestD2[i] = d2;
74
+ bestFrom[i] = next;
75
+ }
76
+ }
77
+ }
78
+ edges.sort((a, b) => outputEdgeCompare(a, b, leaves));
79
+ return edges;
80
+ }
81
+ function squaredDistance(xs, ys, a, b) {
82
+ const dx = xs[a] - xs[b];
83
+ const dy = ys[a] - ys[b];
84
+ return dx * dx + dy * dy;
85
+ }
86
+ function edgeKeyLess(d2A, a0, a1, d2B, b0, b1, ids) {
87
+ if (d2A !== d2B) return d2A < d2B;
88
+ const aLo = ids[a0] < ids[a1] ? ids[a0] : ids[a1];
89
+ const aHi = ids[a0] < ids[a1] ? ids[a1] : ids[a0];
90
+ const bLo = ids[b0] < ids[b1] ? ids[b0] : ids[b1];
91
+ const bHi = ids[b0] < ids[b1] ? ids[b1] : ids[b0];
92
+ if (aLo !== bLo) return aLo < bLo;
93
+ return aHi < bHi;
94
+ }
95
+ function createOutputEdge(xs, ys, ids, i, j) {
96
+ const a = ids[i] < ids[j] ? i : j;
97
+ const b = ids[i] < ids[j] ? j : i;
98
+ return {
99
+ a,
100
+ b,
101
+ d: Math.hypot(xs[a] - xs[b], ys[a] - ys[b])
102
+ };
103
+ }
104
+ function outputEdgeCompare(a, b, leaves) {
105
+ if (a.d < b.d) return -1;
106
+ if (a.d > b.d) return 1;
107
+ const aLo = leaves[a.a].id;
108
+ const aHi = leaves[a.b].id;
109
+ const bLo = leaves[b.a].id;
110
+ const bHi = leaves[b.b].id;
111
+ if (aLo < bLo) return -1;
112
+ if (aLo > bLo) return 1;
113
+ if (aHi < bHi) return -1;
114
+ if (aHi > bHi) return 1;
115
+ return 0;
116
+ }
117
+ //# sourceMappingURL=mst.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/clustering/mst.ts"],
4
+ "sourcesContent": ["import type { LeafInput, MstEdge } from './types'\n\n/**\n * Return the Euclidean MST over the leaves, ordered by the canonical edge key:\n * distance, then normalized endpoint ids.\n */\nexport function mstEdges(leaves: readonly LeafInput[]): MstEdge[] {\n\tconst n = leaves.length\n\tconst ids = new Array<string>(n)\n\tconst xs = new Float64Array(n)\n\tconst ys = new Float64Array(n)\n\tconst seen = new Set<string>()\n\n\tlet root = 0\n\tfor (let i = 0; i < n; i++) {\n\t\tconst leaf = leaves[i]\n\t\tif (seen.has(leaf.id)) {\n\t\t\tthrow new Error(`Duplicate leaf id: ${leaf.id}`)\n\t\t}\n\t\tseen.add(leaf.id)\n\t\tif (!Number.isFinite(leaf.point.x) || !Number.isFinite(leaf.point.y)) {\n\t\t\tthrow new Error(`Non-finite coordinate for leaf id: ${leaf.id}`)\n\t\t}\n\t\tids[i] = leaf.id\n\t\txs[i] = leaf.point.x\n\t\tys[i] = leaf.point.y\n\t\tif (i > 0 && leaf.id < ids[root]) root = i\n\t}\n\n\tif (n < 2) return []\n\n\tconst inTree = new Uint8Array(n)\n\tconst bestD2 = new Float64Array(n)\n\tconst bestFrom = new Int32Array(n)\n\n\tinTree[root] = 1\n\tbestD2.fill(Number.POSITIVE_INFINITY)\n\tbestFrom.fill(-1)\n\n\tfor (let i = 0; i < n; i++) {\n\t\tif (i === root) continue\n\t\tbestD2[i] = squaredDistance(xs, ys, root, i)\n\t\tbestFrom[i] = root\n\t}\n\n\tconst edges: MstEdge[] = []\n\n\tfor (let edgeCount = 0; edgeCount < n - 1; edgeCount++) {\n\t\tlet next = -1\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tif (inTree[i]) continue\n\t\t\tif (\n\t\t\t\tnext === -1 ||\n\t\t\t\tedgeKeyLess(bestD2[i], bestFrom[i], i, bestD2[next], bestFrom[next], next, ids)\n\t\t\t) {\n\t\t\t\tnext = i\n\t\t\t}\n\t\t}\n\n\t\tconst from = bestFrom[next]\n\t\tedges.push(createOutputEdge(xs, ys, ids, from, next))\n\t\tinTree[next] = 1\n\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tif (inTree[i]) continue\n\t\t\tconst d2 = squaredDistance(xs, ys, next, i)\n\t\t\tif (edgeKeyLess(d2, next, i, bestD2[i], bestFrom[i], i, ids)) {\n\t\t\t\tbestD2[i] = d2\n\t\t\t\tbestFrom[i] = next\n\t\t\t}\n\t\t}\n\t}\n\n\tedges.sort((a, b) => outputEdgeCompare(a, b, leaves))\n\treturn edges\n}\n\nfunction squaredDistance(xs: Float64Array, ys: Float64Array, a: number, b: number): number {\n\tconst dx = xs[a] - xs[b]\n\tconst dy = ys[a] - ys[b]\n\treturn dx * dx + dy * dy\n}\n\nfunction edgeKeyLess(\n\td2A: number,\n\ta0: number,\n\ta1: number,\n\td2B: number,\n\tb0: number,\n\tb1: number,\n\tids: readonly string[]\n): boolean {\n\tif (d2A !== d2B) return d2A < d2B\n\n\tconst aLo = ids[a0] < ids[a1] ? ids[a0] : ids[a1]\n\tconst aHi = ids[a0] < ids[a1] ? ids[a1] : ids[a0]\n\tconst bLo = ids[b0] < ids[b1] ? ids[b0] : ids[b1]\n\tconst bHi = ids[b0] < ids[b1] ? ids[b1] : ids[b0]\n\n\tif (aLo !== bLo) return aLo < bLo\n\treturn aHi < bHi\n}\n\nfunction createOutputEdge(\n\txs: Float64Array,\n\tys: Float64Array,\n\tids: readonly string[],\n\ti: number,\n\tj: number\n): MstEdge {\n\tconst a = ids[i] < ids[j] ? i : j\n\tconst b = ids[i] < ids[j] ? j : i\n\treturn {\n\t\ta,\n\t\tb,\n\t\td: Math.hypot(xs[a] - xs[b], ys[a] - ys[b]),\n\t}\n}\n\nfunction outputEdgeCompare(a: MstEdge, b: MstEdge, leaves: readonly LeafInput[]): number {\n\tif (a.d < b.d) return -1\n\tif (a.d > b.d) return 1\n\n\tconst aLo = leaves[a.a].id\n\tconst aHi = leaves[a.b].id\n\tconst bLo = leaves[b.a].id\n\tconst bHi = leaves[b.b].id\n\n\tif (aLo < bLo) return -1\n\tif (aLo > bLo) return 1\n\tif (aHi < bHi) return -1\n\tif (aHi > bHi) return 1\n\treturn 0\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }