@ecsplico/editor 2.0.0 → 2.1.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.
Files changed (278) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +4 -3
  3. package/dist/adapters/anchors.d.ts +80 -0
  4. package/dist/adapters/anchors.js +270 -0
  5. package/dist/adapters/anchors.js.map +1 -0
  6. package/dist/adapters/comments/client.d.ts +64 -0
  7. package/dist/adapters/comments/client.js +536 -0
  8. package/dist/adapters/comments/client.js.map +1 -0
  9. package/dist/adapters/comments/drizzle.d.ts +430 -0
  10. package/dist/adapters/comments/drizzle.js +236 -0
  11. package/dist/adapters/comments/drizzle.js.map +1 -0
  12. package/dist/adapters/comments/errors.d.ts +9 -0
  13. package/dist/adapters/comments/errors.js +19 -0
  14. package/dist/adapters/comments/errors.js.map +1 -0
  15. package/dist/adapters/comments/json.d.ts +19 -0
  16. package/dist/adapters/comments/json.js +94 -0
  17. package/dist/adapters/comments/json.js.map +1 -0
  18. package/dist/adapters/comments/record.js +78 -0
  19. package/dist/adapters/comments/record.js.map +1 -0
  20. package/dist/adapters/comments/server.d.ts +23 -0
  21. package/dist/adapters/comments/server.js +102 -0
  22. package/dist/adapters/comments/server.js.map +1 -0
  23. package/dist/adapters/comments/types.d.ts +109 -0
  24. package/dist/adapters/documents.js +108 -0
  25. package/dist/adapters/documents.js.map +1 -0
  26. package/dist/adapters/drizzle.d.ts +293 -0
  27. package/dist/adapters/drizzle.js +157 -0
  28. package/dist/adapters/drizzle.js.map +1 -0
  29. package/dist/adapters/files.js +30 -0
  30. package/dist/adapters/files.js.map +1 -0
  31. package/dist/adapters/forge.d.ts +58 -0
  32. package/dist/adapters/forge.js +91 -0
  33. package/dist/adapters/forge.js.map +1 -0
  34. package/dist/adapters/index.d.ts +13 -0
  35. package/dist/adapters/index.js +0 -0
  36. package/dist/adapters/json.d.ts +24 -0
  37. package/dist/adapters/json.js +128 -0
  38. package/dist/adapters/json.js.map +1 -0
  39. package/dist/adapters/nitro.d.ts +61 -0
  40. package/dist/adapters/nitro.js +212 -0
  41. package/dist/adapters/nitro.js.map +1 -0
  42. package/dist/adapters/routes.js +16 -0
  43. package/dist/adapters/routes.js.map +1 -0
  44. package/dist/adapters/shared.d.ts +37 -0
  45. package/dist/adapters/shared.js +32 -0
  46. package/dist/adapters/shared.js.map +1 -0
  47. package/dist/adapters/vue.d.ts +67 -0
  48. package/dist/adapters/vue.js +187 -0
  49. package/dist/adapters/vue.js.map +1 -0
  50. package/dist/code/CodeSurface.vue.d.ts +3 -3
  51. package/dist/core/doc-anchors.d.ts +5 -0
  52. package/dist/core/doc-anchors.js +4 -3
  53. package/dist/core/doc-anchors.js.map +1 -1
  54. package/dist/core/editor-ui.js +57 -1
  55. package/dist/core/editor-ui.js.map +1 -1
  56. package/dist/core/surface-session.js +139 -0
  57. package/dist/core/surface-session.js.map +1 -0
  58. package/dist/document/DocumentSurface.d.ts +1 -1
  59. package/dist/document/DocumentSurface.vue.d.ts +3 -3
  60. package/dist/features/ai/agent-op-review.d.ts +2 -2
  61. package/dist/features/ai/agent-op-review.js.map +1 -1
  62. package/dist/features/ai/agent-ops.d.ts +1 -1
  63. package/dist/features/ai/agent-ops.js +9 -6
  64. package/dist/features/ai/agent-ops.js.map +1 -1
  65. package/dist/features/ai/ai-apply.d.ts +1 -1
  66. package/dist/features/ai/ai-review.js +10 -1
  67. package/dist/features/ai/ai-review.js.map +1 -1
  68. package/dist/features/ai/components/AiSelectionMenu.js +78 -252
  69. package/dist/features/ai/components/AiSelectionMenu.js.map +1 -1
  70. package/dist/features/ai/components/AiSelectionMenu.vue.d.ts +2 -1
  71. package/dist/features/ai/components/AiSidebar.js +2 -2
  72. package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
  73. package/dist/features/ai/components/DocumentChatOps.js +1 -0
  74. package/dist/features/ai/components/DocumentChatOps.js.map +1 -1
  75. package/dist/features/ai/components/ModelQuickSwitch.js +1 -1
  76. package/dist/features/ai/components/SettingsAiTab.js +1 -1
  77. package/dist/features/ai/components/SettingsModelProfiles.js +1 -1
  78. package/dist/features/ai/document-chat.d.ts +3 -2
  79. package/dist/features/ai/document-chat.js +16 -19
  80. package/dist/features/ai/document-chat.js.map +1 -1
  81. package/dist/features/ai/index.d.ts +5 -3
  82. package/dist/features/ai/index.js +4 -2
  83. package/dist/features/ai/protocol/agent-ops.d.ts +22 -17
  84. package/dist/features/ai/protocol/agent-ops.js +65 -39
  85. package/dist/features/ai/protocol/agent-ops.js.map +1 -1
  86. package/dist/features/ai/protocol/block-lines.d.ts +89 -0
  87. package/dist/features/ai/protocol/block-lines.js +177 -0
  88. package/dist/features/ai/protocol/block-lines.js.map +1 -0
  89. package/dist/features/ai/protocol/chat.js +10 -10
  90. package/dist/features/ai/protocol/chat.js.map +1 -1
  91. package/dist/features/ai/protocol/index.d.ts +3 -2
  92. package/dist/features/ai/protocol/index.js +3 -2
  93. package/dist/features/ai/react/AiSelectionMenu.d.ts +3 -2
  94. package/dist/features/ai/react/AiSelectionMenu.js +64 -255
  95. package/dist/features/ai/react/AiSelectionMenu.js.map +1 -1
  96. package/dist/features/ai/react/AiSidebar.js +2 -2
  97. package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
  98. package/dist/features/ai/react/DocumentChatOps.js +1 -0
  99. package/dist/features/ai/react/DocumentChatOps.js.map +1 -1
  100. package/dist/features/ai/react/ModelQuickSwitch.js +1 -1
  101. package/dist/features/ai/react/SettingsAiTab.js +1 -1
  102. package/dist/features/ai/react/SettingsModelProfiles.js +1 -1
  103. package/dist/features/ai/react/use-ai-selection-flow.js +34 -0
  104. package/dist/features/ai/react/use-ai-selection-flow.js.map +1 -0
  105. package/dist/features/ai/selection-flow.d.ts +133 -0
  106. package/dist/features/ai/selection-flow.js +283 -0
  107. package/dist/features/ai/selection-flow.js.map +1 -0
  108. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  109. package/dist/features/ai/use-document-chat.d.ts +1 -1
  110. package/dist/features/authors/components/AuthorColorsPanel.js +1 -1
  111. package/dist/features/authors/feature.js +1 -1
  112. package/dist/features/authors/index.js +1 -1
  113. package/dist/features/authors/react/AuthorColorsPanel.js +1 -1
  114. package/dist/features/comments/components/CommentBubble.js +1 -1
  115. package/dist/features/comments/components/CommentComposer.js +1 -1
  116. package/dist/features/comments/components/CommentThreadView.js +5 -2
  117. package/dist/features/comments/components/CommentThreadView.js.map +1 -1
  118. package/dist/features/comments/components/CommentsMargin.js +108 -230
  119. package/dist/features/comments/components/CommentsMargin.js.map +1 -1
  120. package/dist/features/comments/components/CommentsOverlay.js +1 -1
  121. package/dist/features/comments/feature.js +1 -1
  122. package/dist/features/comments/index.d.ts +4 -2
  123. package/dist/features/comments/index.js +4 -2
  124. package/dist/features/comments/margin-controller.d.ts +44 -0
  125. package/dist/features/comments/margin-controller.js +132 -0
  126. package/dist/features/comments/margin-controller.js.map +1 -0
  127. package/dist/features/comments/margin-layout.d.ts +55 -0
  128. package/dist/features/comments/margin-layout.js +79 -0
  129. package/dist/features/comments/margin-layout.js.map +1 -0
  130. package/dist/features/comments/model.d.ts +8 -0
  131. package/dist/features/comments/model.js +60 -34
  132. package/dist/features/comments/model.js.map +1 -1
  133. package/dist/features/comments/react/CommentBubble.js +1 -1
  134. package/dist/features/comments/react/CommentComposer.js +1 -1
  135. package/dist/features/comments/react/CommentThreadView.js +2 -2
  136. package/dist/features/comments/react/CommentThreadView.js.map +1 -1
  137. package/dist/features/comments/react/CommentsMargin.d.ts +0 -5
  138. package/dist/features/comments/react/CommentsMargin.js +85 -251
  139. package/dist/features/comments/react/CommentsMargin.js.map +1 -1
  140. package/dist/features/comments/react/CommentsOverlay.js +1 -1
  141. package/dist/features/comments/react/use-comments.js +1 -1
  142. package/dist/features/comments/react/use-margin-layout.js +45 -0
  143. package/dist/features/comments/react/use-margin-layout.js.map +1 -0
  144. package/dist/features/comments/react.d.ts +1 -1
  145. package/dist/features/comments/schema.d.ts +23 -0
  146. package/dist/features/comments/schema.js.map +1 -1
  147. package/dist/features/comments/snapshot-equality.js +40 -0
  148. package/dist/features/comments/snapshot-equality.js.map +1 -0
  149. package/dist/features/comments/thread-anchor.js +33 -0
  150. package/dist/features/comments/thread-anchor.js.map +1 -0
  151. package/dist/features/comments/use-comments.d.ts +3 -1
  152. package/dist/features/comments/use-comments.js +1 -0
  153. package/dist/features/comments/use-comments.js.map +1 -1
  154. package/dist/features/comments/use-margin-layout.js +29 -0
  155. package/dist/features/comments/use-margin-layout.js.map +1 -0
  156. package/dist/features/comments/vue.d.ts +1 -1
  157. package/dist/features/composites/accepted-children.d.ts +21 -0
  158. package/dist/features/composites/accepted-children.js +126 -0
  159. package/dist/features/composites/accepted-children.js.map +1 -0
  160. package/dist/features/composites/components/CompositeDetails.js +1 -1
  161. package/dist/features/composites/components/CompositeInspector.js +38 -164
  162. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  163. package/dist/features/composites/feature.d.ts +2 -1
  164. package/dist/features/composites/feature.js +8 -2
  165. package/dist/features/composites/feature.js.map +1 -1
  166. package/dist/features/composites/index.d.ts +5 -3
  167. package/dist/features/composites/index.js +8 -6
  168. package/dist/features/composites/inspector-model.d.ts +97 -0
  169. package/dist/features/composites/inspector-model.js +255 -0
  170. package/dist/features/composites/inspector-model.js.map +1 -0
  171. package/dist/features/composites/kinds.d.ts +11 -0
  172. package/dist/features/composites/kinds.js +17 -2
  173. package/dist/features/composites/kinds.js.map +1 -1
  174. package/dist/features/composites/outline.d.ts +18 -5
  175. package/dist/features/composites/outline.js +44 -12
  176. package/dist/features/composites/outline.js.map +1 -1
  177. package/dist/features/composites/react/CompositeDetails.js +1 -1
  178. package/dist/features/composites/react/CompositeInspector.d.ts +1 -1
  179. package/dist/features/composites/react/CompositeInspector.js +21 -180
  180. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  181. package/dist/features/composites/react/CompositeStatusMenu.d.ts +1 -1
  182. package/dist/features/composites/react/CompositeView.js +1 -1
  183. package/dist/features/composites/react/use-composite-inspector.js +29 -0
  184. package/dist/features/composites/react/use-composite-inspector.js.map +1 -0
  185. package/dist/features/composites/schema.d.ts +2 -2
  186. package/dist/features/composites/schema.js +2 -2
  187. package/dist/features/composites/schema.js.map +1 -1
  188. package/dist/features/composites/use-composite-anchors.d.ts +1 -1
  189. package/dist/features/composites/use-composite-inspector.js +41 -0
  190. package/dist/features/composites/use-composite-inspector.js.map +1 -0
  191. package/dist/features/composites/use-composite-rows.d.ts +1 -1
  192. package/dist/features/media/index.d.ts +1 -1
  193. package/dist/features/media/vue.d.ts +1 -1
  194. package/dist/features/mentions/index.d.ts +3 -3
  195. package/dist/features/mentions/index.js +3 -3
  196. package/dist/features/mentions/schema.d.ts +1 -1
  197. package/dist/features/mentions/schema.js +1 -1
  198. package/dist/features/themes/index.d.ts +1 -1
  199. package/dist/features/themes/index.js +1 -1
  200. package/dist/features/transcript/feature.js +1 -1
  201. package/dist/features/transcript/index.js +2 -2
  202. package/dist/i18n/de/ai.js +2 -0
  203. package/dist/i18n/de/ai.js.map +1 -1
  204. package/dist/i18n/de/composites.js +8 -1
  205. package/dist/i18n/de/composites.js.map +1 -1
  206. package/dist/i18n/de/tree.js +14 -1
  207. package/dist/i18n/de/tree.js.map +1 -1
  208. package/dist/i18n/de.d.ts +22 -0
  209. package/dist/i18n/en/ai.js +2 -0
  210. package/dist/i18n/en/ai.js.map +1 -1
  211. package/dist/i18n/en/composites.js +8 -1
  212. package/dist/i18n/en/composites.js.map +1 -1
  213. package/dist/i18n/en/tree.js +14 -1
  214. package/dist/i18n/en/tree.js.map +1 -1
  215. package/dist/integrations/composite-ai/composite-fill.js +2 -2
  216. package/dist/integrations/composite-ai/composite-summary.js +2 -2
  217. package/dist/integrations/composite-ai/index.js +2 -2
  218. package/dist/integrations/transcript-ai/transcript-cleanup.js +1 -1
  219. package/dist/markdown/MarkdownSurface.d.ts +1 -1
  220. package/dist/markdown/MarkdownSurface.js +2 -2
  221. package/dist/markdown/MarkdownSurface.vue.d.ts +7 -7
  222. package/dist/markdown/index.d.ts +2 -2
  223. package/dist/nuxt/runtime/server/routes/collab/[id].js +1 -1
  224. package/dist/react/EditorSurface.d.ts +1 -1
  225. package/dist/react/EditorSurface.js +43 -149
  226. package/dist/react/EditorSurface.js.map +1 -1
  227. package/dist/react/EditorToolbar.js +3 -40
  228. package/dist/react/EditorToolbar.js.map +1 -1
  229. package/dist/schema/advanced.js +2 -2
  230. package/dist/server/adapter.d.ts +2 -2
  231. package/dist/server/collab.js +1 -1
  232. package/dist/server/handlers/ai.d.ts +4 -2
  233. package/dist/server/handlers/ai.js +11 -9
  234. package/dist/server/handlers/ai.js.map +1 -1
  235. package/dist/server/handlers/context.d.ts +1 -1
  236. package/dist/server/handlers/editor.d.ts +1 -1
  237. package/dist/server/handlers/editor.js +2 -2
  238. package/dist/server/host.d.ts +1 -1
  239. package/dist/server/index.d.ts +2 -2
  240. package/dist/settings/index.d.ts +1 -1
  241. package/dist/styles/tokens.css +1 -1
  242. package/dist/tree/DocumentTree.js +159 -387
  243. package/dist/tree/DocumentTree.js.map +1 -1
  244. package/dist/tree/drop-rules.js +37 -0
  245. package/dist/tree/drop-rules.js.map +1 -0
  246. package/dist/tree/react/DocumentTree.d.ts +2 -2
  247. package/dist/tree/react/DocumentTree.js +135 -397
  248. package/dist/tree/react/DocumentTree.js.map +1 -1
  249. package/dist/tree/react/use-tree-model.js +129 -0
  250. package/dist/tree/react/use-tree-model.js.map +1 -0
  251. package/dist/tree/react.js +1 -1
  252. package/dist/tree/tree-host.js +100 -0
  253. package/dist/tree/tree-host.js.map +1 -0
  254. package/dist/tree/tree-items.js +22 -43
  255. package/dist/tree/tree-items.js.map +1 -1
  256. package/dist/tree/tree-model.js +580 -0
  257. package/dist/tree/tree-model.js.map +1 -0
  258. package/dist/tree/tree-rows.js +77 -0
  259. package/dist/tree/tree-rows.js.map +1 -0
  260. package/dist/tree/use-tree-model.js +94 -0
  261. package/dist/tree/use-tree-model.js.map +1 -0
  262. package/dist/tree/vue.js +1 -1
  263. package/dist/vue/AdvancedEditor.vue.d.ts +4 -4
  264. package/dist/vue/SimpleEditor.vue.d.ts +2 -2
  265. package/dist/vue/components/EditorSurface.js +27 -87
  266. package/dist/vue/components/EditorSurface.js.map +1 -1
  267. package/dist/vue/components/EditorSurface.vue.d.ts +4 -4
  268. package/dist/vue/components/EditorToolbar.js +7 -44
  269. package/dist/vue/components/EditorToolbar.js.map +1 -1
  270. package/dist/vue/context.d.ts +1 -1
  271. package/dist/vue/context.js +1 -1
  272. package/dist/vue/context.js.map +1 -1
  273. package/dist/vue/use-editor-ui.d.ts +1 -1
  274. package/dist/vue/use-notifier.d.ts +1 -1
  275. package/docs/integration.md +97 -4
  276. package/docs/llms.md +9 -1
  277. package/docs/usage.md +10 -5
  278. package/package.json +67 -5
@@ -0,0 +1,430 @@
1
+ import { PortableAnchor } from "../anchors.js";
2
+ import { EditorDb } from "../drizzle.js";
3
+ import { CommentStore } from "./types.js";
4
+ import { SQLiteColumn } from "drizzle-orm/sqlite-core";
5
+ //#region src/adapters/comments/drizzle.d.ts
6
+ declare const COMMENT_TABLES: {
7
+ annotations: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
8
+ name: "editor_comment_annotations";
9
+ schema: undefined;
10
+ columns: {
11
+ documentId: SQLiteColumn<{
12
+ name: "document_id";
13
+ tableName: "editor_comment_annotations";
14
+ dataType: "string";
15
+ columnType: "SQLiteText";
16
+ data: string;
17
+ driverParam: string;
18
+ notNull: true;
19
+ hasDefault: false;
20
+ isPrimaryKey: false;
21
+ isAutoincrement: false;
22
+ hasRuntimeDefault: false;
23
+ enumValues: [string, ...string[]];
24
+ baseColumn: never;
25
+ identity: undefined;
26
+ generated: undefined;
27
+ }, {}, {
28
+ length: number | undefined;
29
+ }>;
30
+ id: SQLiteColumn<{
31
+ name: "id";
32
+ tableName: "editor_comment_annotations";
33
+ dataType: "string";
34
+ columnType: "SQLiteText";
35
+ data: string;
36
+ driverParam: string;
37
+ notNull: true;
38
+ hasDefault: false;
39
+ isPrimaryKey: false;
40
+ isAutoincrement: false;
41
+ hasRuntimeDefault: false;
42
+ enumValues: [string, ...string[]];
43
+ baseColumn: never;
44
+ identity: undefined;
45
+ generated: undefined;
46
+ }, {}, {
47
+ length: number | undefined;
48
+ }>;
49
+ threadId: SQLiteColumn<{
50
+ name: "thread_id";
51
+ tableName: "editor_comment_annotations";
52
+ dataType: "string";
53
+ columnType: "SQLiteText";
54
+ data: string;
55
+ driverParam: string;
56
+ notNull: true;
57
+ hasDefault: false;
58
+ isPrimaryKey: false;
59
+ isAutoincrement: false;
60
+ hasRuntimeDefault: false;
61
+ enumValues: [string, ...string[]];
62
+ baseColumn: never;
63
+ identity: undefined;
64
+ generated: undefined;
65
+ }, {}, {
66
+ length: number | undefined;
67
+ }>;
68
+ seq: SQLiteColumn<{
69
+ name: "seq";
70
+ tableName: "editor_comment_annotations";
71
+ dataType: "number";
72
+ columnType: "SQLiteInteger";
73
+ data: number;
74
+ driverParam: number;
75
+ notNull: true;
76
+ hasDefault: false;
77
+ isPrimaryKey: false;
78
+ isAutoincrement: false;
79
+ hasRuntimeDefault: false;
80
+ enumValues: undefined;
81
+ baseColumn: never;
82
+ identity: undefined;
83
+ generated: undefined;
84
+ }, {}, {}>;
85
+ anchor: SQLiteColumn<{
86
+ name: "anchor";
87
+ tableName: "editor_comment_annotations";
88
+ dataType: "json";
89
+ columnType: "SQLiteTextJson";
90
+ data: PortableAnchor;
91
+ driverParam: string;
92
+ notNull: true;
93
+ hasDefault: false;
94
+ isPrimaryKey: false;
95
+ isAutoincrement: false;
96
+ hasRuntimeDefault: false;
97
+ enumValues: undefined;
98
+ baseColumn: never;
99
+ identity: undefined;
100
+ generated: undefined;
101
+ }, {}, {
102
+ $type: PortableAnchor;
103
+ }>;
104
+ };
105
+ dialect: "sqlite";
106
+ }>;
107
+ threads: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
108
+ name: "editor_comment_threads";
109
+ schema: undefined;
110
+ columns: {
111
+ documentId: SQLiteColumn<{
112
+ name: "document_id";
113
+ tableName: "editor_comment_threads";
114
+ dataType: "string";
115
+ columnType: "SQLiteText";
116
+ data: string;
117
+ driverParam: string;
118
+ notNull: true;
119
+ hasDefault: false;
120
+ isPrimaryKey: false;
121
+ isAutoincrement: false;
122
+ hasRuntimeDefault: false;
123
+ enumValues: [string, ...string[]];
124
+ baseColumn: never;
125
+ identity: undefined;
126
+ generated: undefined;
127
+ }, {}, {
128
+ length: number | undefined;
129
+ }>;
130
+ id: SQLiteColumn<{
131
+ name: "id";
132
+ tableName: "editor_comment_threads";
133
+ dataType: "string";
134
+ columnType: "SQLiteText";
135
+ data: string;
136
+ driverParam: string;
137
+ notNull: true;
138
+ hasDefault: false;
139
+ isPrimaryKey: false;
140
+ isAutoincrement: false;
141
+ hasRuntimeDefault: false;
142
+ enumValues: [string, ...string[]];
143
+ baseColumn: never;
144
+ identity: undefined;
145
+ generated: undefined;
146
+ }, {}, {
147
+ length: number | undefined;
148
+ }>;
149
+ annotationId: SQLiteColumn<{
150
+ name: "annotation_id";
151
+ tableName: "editor_comment_threads";
152
+ dataType: "string";
153
+ columnType: "SQLiteText";
154
+ data: string;
155
+ driverParam: string;
156
+ notNull: true;
157
+ hasDefault: false;
158
+ isPrimaryKey: false;
159
+ isAutoincrement: false;
160
+ hasRuntimeDefault: false;
161
+ enumValues: [string, ...string[]];
162
+ baseColumn: never;
163
+ identity: undefined;
164
+ generated: undefined;
165
+ }, {}, {
166
+ length: number | undefined;
167
+ }>;
168
+ status: SQLiteColumn<{
169
+ name: "status";
170
+ tableName: "editor_comment_threads";
171
+ dataType: "string";
172
+ columnType: "SQLiteText";
173
+ data: "open" | "resolved";
174
+ driverParam: string;
175
+ notNull: true;
176
+ hasDefault: false;
177
+ isPrimaryKey: false;
178
+ isAutoincrement: false;
179
+ hasRuntimeDefault: false;
180
+ enumValues: ["open", "resolved"];
181
+ baseColumn: never;
182
+ identity: undefined;
183
+ generated: undefined;
184
+ }, {}, {
185
+ length: number | undefined;
186
+ }>;
187
+ seq: SQLiteColumn<{
188
+ name: "seq";
189
+ tableName: "editor_comment_threads";
190
+ dataType: "number";
191
+ columnType: "SQLiteInteger";
192
+ data: number;
193
+ driverParam: number;
194
+ notNull: true;
195
+ hasDefault: false;
196
+ isPrimaryKey: false;
197
+ isAutoincrement: false;
198
+ hasRuntimeDefault: false;
199
+ enumValues: undefined;
200
+ baseColumn: never;
201
+ identity: undefined;
202
+ generated: undefined;
203
+ }, {}, {}>;
204
+ };
205
+ dialect: "sqlite";
206
+ }>;
207
+ comments: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
208
+ name: "editor_comments";
209
+ schema: undefined;
210
+ columns: {
211
+ documentId: SQLiteColumn<{
212
+ name: "document_id";
213
+ tableName: "editor_comments";
214
+ dataType: "string";
215
+ columnType: "SQLiteText";
216
+ data: string;
217
+ driverParam: string;
218
+ notNull: true;
219
+ hasDefault: false;
220
+ isPrimaryKey: false;
221
+ isAutoincrement: false;
222
+ hasRuntimeDefault: false;
223
+ enumValues: [string, ...string[]];
224
+ baseColumn: never;
225
+ identity: undefined;
226
+ generated: undefined;
227
+ }, {}, {
228
+ length: number | undefined;
229
+ }>;
230
+ threadId: SQLiteColumn<{
231
+ name: "thread_id";
232
+ tableName: "editor_comments";
233
+ dataType: "string";
234
+ columnType: "SQLiteText";
235
+ data: string;
236
+ driverParam: string;
237
+ notNull: true;
238
+ hasDefault: false;
239
+ isPrimaryKey: false;
240
+ isAutoincrement: false;
241
+ hasRuntimeDefault: false;
242
+ enumValues: [string, ...string[]];
243
+ baseColumn: never;
244
+ identity: undefined;
245
+ generated: undefined;
246
+ }, {}, {
247
+ length: number | undefined;
248
+ }>;
249
+ id: SQLiteColumn<{
250
+ name: "id";
251
+ tableName: "editor_comments";
252
+ dataType: "string";
253
+ columnType: "SQLiteText";
254
+ data: string;
255
+ driverParam: string;
256
+ notNull: true;
257
+ hasDefault: false;
258
+ isPrimaryKey: false;
259
+ isAutoincrement: false;
260
+ hasRuntimeDefault: false;
261
+ enumValues: [string, ...string[]];
262
+ baseColumn: never;
263
+ identity: undefined;
264
+ generated: undefined;
265
+ }, {}, {
266
+ length: number | undefined;
267
+ }>;
268
+ seq: SQLiteColumn<{
269
+ name: "seq";
270
+ tableName: "editor_comments";
271
+ dataType: "number";
272
+ columnType: "SQLiteInteger";
273
+ data: number;
274
+ driverParam: number;
275
+ notNull: true;
276
+ hasDefault: false;
277
+ isPrimaryKey: false;
278
+ isAutoincrement: false;
279
+ hasRuntimeDefault: false;
280
+ enumValues: undefined;
281
+ baseColumn: never;
282
+ identity: undefined;
283
+ generated: undefined;
284
+ }, {}, {}>;
285
+ body: SQLiteColumn<{
286
+ name: "body";
287
+ tableName: "editor_comments";
288
+ dataType: "string";
289
+ columnType: "SQLiteText";
290
+ data: string;
291
+ driverParam: string;
292
+ notNull: true;
293
+ hasDefault: false;
294
+ isPrimaryKey: false;
295
+ isAutoincrement: false;
296
+ hasRuntimeDefault: false;
297
+ enumValues: [string, ...string[]];
298
+ baseColumn: never;
299
+ identity: undefined;
300
+ generated: undefined;
301
+ }, {}, {
302
+ length: number | undefined;
303
+ }>;
304
+ authorId: SQLiteColumn<{
305
+ name: "author_id";
306
+ tableName: "editor_comments";
307
+ dataType: "string";
308
+ columnType: "SQLiteText";
309
+ data: string;
310
+ driverParam: string;
311
+ notNull: true;
312
+ hasDefault: false;
313
+ isPrimaryKey: false;
314
+ isAutoincrement: false;
315
+ hasRuntimeDefault: false;
316
+ enumValues: [string, ...string[]];
317
+ baseColumn: never;
318
+ identity: undefined;
319
+ generated: undefined;
320
+ }, {}, {
321
+ length: number | undefined;
322
+ }>;
323
+ authorName: SQLiteColumn<{
324
+ name: "author_name";
325
+ tableName: "editor_comments";
326
+ dataType: "string";
327
+ columnType: "SQLiteText";
328
+ data: string;
329
+ driverParam: string;
330
+ notNull: false;
331
+ hasDefault: false;
332
+ isPrimaryKey: false;
333
+ isAutoincrement: false;
334
+ hasRuntimeDefault: false;
335
+ enumValues: [string, ...string[]];
336
+ baseColumn: never;
337
+ identity: undefined;
338
+ generated: undefined;
339
+ }, {}, {
340
+ length: number | undefined;
341
+ }>;
342
+ authorColor: SQLiteColumn<{
343
+ name: "author_color";
344
+ tableName: "editor_comments";
345
+ dataType: "string";
346
+ columnType: "SQLiteText";
347
+ data: string;
348
+ driverParam: string;
349
+ notNull: false;
350
+ hasDefault: false;
351
+ isPrimaryKey: false;
352
+ isAutoincrement: false;
353
+ hasRuntimeDefault: false;
354
+ enumValues: [string, ...string[]];
355
+ baseColumn: never;
356
+ identity: undefined;
357
+ generated: undefined;
358
+ }, {}, {
359
+ length: number | undefined;
360
+ }>;
361
+ createdAt: SQLiteColumn<{
362
+ name: "created_at";
363
+ tableName: "editor_comments";
364
+ dataType: "string";
365
+ columnType: "SQLiteText";
366
+ data: string;
367
+ driverParam: string;
368
+ notNull: true;
369
+ hasDefault: false;
370
+ isPrimaryKey: false;
371
+ isAutoincrement: false;
372
+ hasRuntimeDefault: false;
373
+ enumValues: [string, ...string[]];
374
+ baseColumn: never;
375
+ identity: undefined;
376
+ generated: undefined;
377
+ }, {}, {
378
+ length: number | undefined;
379
+ }>;
380
+ editedAt: SQLiteColumn<{
381
+ name: "edited_at";
382
+ tableName: "editor_comments";
383
+ dataType: "string";
384
+ columnType: "SQLiteText";
385
+ data: string;
386
+ driverParam: string;
387
+ notNull: false;
388
+ hasDefault: false;
389
+ isPrimaryKey: false;
390
+ isAutoincrement: false;
391
+ hasRuntimeDefault: false;
392
+ enumValues: [string, ...string[]];
393
+ baseColumn: never;
394
+ identity: undefined;
395
+ generated: undefined;
396
+ }, {}, {
397
+ length: number | undefined;
398
+ }>;
399
+ };
400
+ dialect: "sqlite";
401
+ }>;
402
+ };
403
+ export type CommentTables = typeof COMMENT_TABLES;
404
+ /**
405
+ * The tables of the comment store in a SQLite database:
406
+ *
407
+ * editor_comment_annotations(document_id, id, thread_id, seq, anchor json; PK (document_id, id))
408
+ * editor_comment_threads(document_id, id, annotation_id, status, seq; PK (document_id, id))
409
+ * editor_comments(document_id, thread_id, id, seq, body, author_id, author_name?, author_color?, created_at, edited_at?; PK (document_id, thread_id, id))
410
+ *
411
+ * `seq` orders rows within their document (annotations, threads) or thread (comments). Call it from the host's drizzle
412
+ * schema (so `drizzle-kit` migrates the tables) or use `bootstrapCommentTables` in a host without migrations.
413
+ */
414
+ export declare const commentTables: () => CommentTables;
415
+ /** `CREATE TABLE IF NOT EXISTS` for the tables of `commentTables()`. */
416
+ export declare function bootstrapCommentTables(db: EditorDb): Promise<void>;
417
+ export interface DrizzleCommentStoreOptions {
418
+ db: EditorDb;
419
+ tables: CommentTables;
420
+ }
421
+ /**
422
+ * The comment store on drizzle tables. Operations are several single statements (no transaction, so it runs on sync and
423
+ * async drivers) applied one after another per database; a failed `createThread` removes what it had written. A
424
+ * unique key still protects against a second process writing the same ids. Unlike the JSON store it keeps only the
425
+ * fields of `Comment`, `Annotation` and `CommentThread`.
426
+ */
427
+ export declare function createDrizzleCommentStore({ db, tables }: DrizzleCommentStoreOptions): CommentStore;
428
+ //#endregion
429
+ export {};
430
+ //# sourceMappingURL=drizzle.d.ts.map
@@ -0,0 +1,236 @@
1
+ import { conflict, invalid, notFound } from "./errors.js";
2
+ import { assertNewThread } from "./record.js";
3
+ import { and, eq, sql } from "drizzle-orm";
4
+ import { integer, primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core";
5
+ //#region src/adapters/comments/drizzle.ts
6
+ const COMMENT_TABLES = {
7
+ annotations: sqliteTable("editor_comment_annotations", {
8
+ documentId: text("document_id").notNull(),
9
+ id: text("id").notNull(),
10
+ threadId: text("thread_id").notNull(),
11
+ seq: integer("seq").notNull(),
12
+ anchor: text("anchor", { mode: "json" }).$type().notNull()
13
+ }, (table) => [primaryKey({ columns: [table.documentId, table.id] })]),
14
+ threads: sqliteTable("editor_comment_threads", {
15
+ documentId: text("document_id").notNull(),
16
+ id: text("id").notNull(),
17
+ annotationId: text("annotation_id").notNull(),
18
+ status: text("status", { enum: ["open", "resolved"] }).notNull(),
19
+ seq: integer("seq").notNull()
20
+ }, (table) => [primaryKey({ columns: [table.documentId, table.id] })]),
21
+ comments: sqliteTable("editor_comments", {
22
+ documentId: text("document_id").notNull(),
23
+ threadId: text("thread_id").notNull(),
24
+ id: text("id").notNull(),
25
+ seq: integer("seq").notNull(),
26
+ body: text("body").notNull(),
27
+ authorId: text("author_id").notNull(),
28
+ authorName: text("author_name"),
29
+ authorColor: text("author_color"),
30
+ createdAt: text("created_at").notNull(),
31
+ editedAt: text("edited_at")
32
+ }, (table) => [primaryKey({ columns: [
33
+ table.documentId,
34
+ table.threadId,
35
+ table.id
36
+ ] })])
37
+ };
38
+ /**
39
+ * The tables of the comment store in a SQLite database:
40
+ *
41
+ * editor_comment_annotations(document_id, id, thread_id, seq, anchor json; PK (document_id, id))
42
+ * editor_comment_threads(document_id, id, annotation_id, status, seq; PK (document_id, id))
43
+ * editor_comments(document_id, thread_id, id, seq, body, author_id, author_name?, author_color?, created_at, edited_at?; PK (document_id, thread_id, id))
44
+ *
45
+ * `seq` orders rows within their document (annotations, threads) or thread (comments). Call it from the host's drizzle
46
+ * schema (so `drizzle-kit` migrates the tables) or use `bootstrapCommentTables` in a host without migrations.
47
+ */
48
+ const commentTables = () => COMMENT_TABLES;
49
+ /** `CREATE TABLE IF NOT EXISTS` for the tables of `commentTables()`. */
50
+ async function bootstrapCommentTables(db) {
51
+ await db.run(sql`CREATE TABLE IF NOT EXISTS editor_comment_annotations (document_id text NOT NULL, id text NOT NULL, thread_id text NOT NULL, seq integer NOT NULL, anchor text NOT NULL, PRIMARY KEY (document_id, id))`);
52
+ await db.run(sql`CREATE TABLE IF NOT EXISTS editor_comment_threads (document_id text NOT NULL, id text NOT NULL, annotation_id text NOT NULL, status text NOT NULL, seq integer NOT NULL, PRIMARY KEY (document_id, id))`);
53
+ await db.run(sql`CREATE TABLE IF NOT EXISTS editor_comments (document_id text NOT NULL, thread_id text NOT NULL, id text NOT NULL, seq integer NOT NULL, body text NOT NULL, author_id text NOT NULL, author_name text, author_color text, created_at text NOT NULL, edited_at text, PRIMARY KEY (document_id, thread_id, id))`);
54
+ }
55
+ /** Writers on one database of one process run one after another: SQLite has one writer, and each operation is several statements. */
56
+ const queues = /* @__PURE__ */ new WeakMap();
57
+ function serialized(db, action) {
58
+ const run = (queues.get(db) ?? Promise.resolve()).then(action);
59
+ const tail = run.catch(() => {});
60
+ queues.set(db, tail);
61
+ tail.then(() => {
62
+ if (queues.get(db) === tail) queues.delete(db);
63
+ });
64
+ return run;
65
+ }
66
+ /**
67
+ * The comment store on drizzle tables. Operations are several single statements (no transaction, so it runs on sync and
68
+ * async drivers) applied one after another per database; a failed `createThread` removes what it had written. A
69
+ * unique key still protects against a second process writing the same ids. Unlike the JSON store it keeps only the
70
+ * fields of `Comment`, `Annotation` and `CommentThread`.
71
+ */
72
+ function createDrizzleCommentStore({ db, tables }) {
73
+ const { annotations, threads, comments } = tables;
74
+ const commentOf = (row) => ({
75
+ id: row.id,
76
+ body: row.body,
77
+ authorId: row.authorId,
78
+ createdAt: row.createdAt,
79
+ ...row.authorName !== null && { authorName: row.authorName },
80
+ ...row.authorColor !== null && { authorColor: row.authorColor },
81
+ ...row.editedAt !== null && { editedAt: row.editedAt }
82
+ });
83
+ async function threadRow(documentId, id) {
84
+ return db.select().from(threads).where(and(eq(threads.documentId, documentId), eq(threads.id, id))).get();
85
+ }
86
+ async function threadOf(documentId, id) {
87
+ const row = await threadRow(documentId, id);
88
+ if (!row) return void 0;
89
+ const rows = await db.select().from(comments).where(and(eq(comments.documentId, documentId), eq(comments.threadId, id))).orderBy(comments.seq).all();
90
+ return {
91
+ id: row.id,
92
+ annotationId: row.annotationId,
93
+ status: row.status,
94
+ comments: rows.map(commentOf)
95
+ };
96
+ }
97
+ async function requireThread(documentId, id) {
98
+ const thread = await threadOf(documentId, id);
99
+ if (!thread) throw notFound("comment thread", id);
100
+ return thread;
101
+ }
102
+ async function discussion(documentId) {
103
+ const [annotationRows, threadRows, commentRows] = await Promise.all([
104
+ db.select().from(annotations).where(eq(annotations.documentId, documentId)).orderBy(annotations.seq).all(),
105
+ db.select().from(threads).where(eq(threads.documentId, documentId)).orderBy(threads.seq).all(),
106
+ db.select().from(comments).where(eq(comments.documentId, documentId)).orderBy(comments.seq).all()
107
+ ]);
108
+ return {
109
+ annotations: annotationRows.map((row) => ({
110
+ id: row.id,
111
+ threadId: row.threadId,
112
+ anchor: row.anchor
113
+ })),
114
+ threads: threadRows.map((row) => ({
115
+ id: row.id,
116
+ annotationId: row.annotationId,
117
+ status: row.status,
118
+ comments: commentRows.filter((comment) => comment.threadId === row.id).map(commentOf)
119
+ }))
120
+ };
121
+ }
122
+ const nextSeq = async (column, table, where) => {
123
+ return ((await db.select({ value: sql`coalesce(max(${column}), 0)` }).from(table).where(where).get())?.value ?? 0) + 1;
124
+ };
125
+ const insertComment = async (documentId, threadId, comment) => {
126
+ await db.insert(comments).values({
127
+ documentId,
128
+ threadId,
129
+ id: comment.id,
130
+ seq: await nextSeq(comments.seq, comments, and(eq(comments.documentId, documentId), eq(comments.threadId, threadId))),
131
+ body: comment.body,
132
+ authorId: comment.authorId,
133
+ authorName: comment.authorName ?? null,
134
+ authorColor: comment.authorColor ?? null,
135
+ createdAt: comment.createdAt,
136
+ editedAt: comment.editedAt ?? null
137
+ }).run();
138
+ };
139
+ const write = (action) => serialized(db, action);
140
+ return {
141
+ getDiscussion: discussion,
142
+ getThread: (documentId, threadId) => threadOf(documentId, threadId),
143
+ async listThreads(documentId) {
144
+ return (await discussion(documentId)).threads;
145
+ },
146
+ createThread: (documentId, input) => write(async () => {
147
+ assertNewThread(input);
148
+ const { annotation, thread } = input;
149
+ if (await db.select({ id: annotations.id }).from(annotations).where(and(eq(annotations.documentId, documentId), eq(annotations.id, annotation.id))).get()) throw conflict(`Annotation "${annotation.id}" already exists.`);
150
+ if (await threadRow(documentId, thread.id)) throw conflict(`Comment thread "${thread.id}" already exists.`);
151
+ try {
152
+ await db.insert(annotations).values({
153
+ documentId,
154
+ id: annotation.id,
155
+ threadId: annotation.threadId,
156
+ seq: await nextSeq(annotations.seq, annotations, eq(annotations.documentId, documentId)),
157
+ anchor: annotation.anchor
158
+ }).run();
159
+ await db.insert(threads).values({
160
+ documentId,
161
+ id: thread.id,
162
+ annotationId: thread.annotationId,
163
+ status: "open",
164
+ seq: await nextSeq(threads.seq, threads, eq(threads.documentId, documentId))
165
+ }).run();
166
+ await insertComment(documentId, thread.id, thread.initialComment);
167
+ } catch (error) {
168
+ await db.delete(comments).where(and(eq(comments.documentId, documentId), eq(comments.threadId, thread.id))).run();
169
+ await db.delete(threads).where(and(eq(threads.documentId, documentId), eq(threads.id, thread.id))).run();
170
+ await db.delete(annotations).where(and(eq(annotations.documentId, documentId), eq(annotations.id, annotation.id))).run();
171
+ throw error;
172
+ }
173
+ return {
174
+ annotation: structuredClone(annotation),
175
+ thread: await requireThread(documentId, thread.id)
176
+ };
177
+ }),
178
+ addComment: (documentId, threadId, comment) => write(async () => {
179
+ await requireThread(documentId, threadId);
180
+ if (await db.select({ id: comments.id }).from(comments).where(and(eq(comments.documentId, documentId), eq(comments.threadId, threadId), eq(comments.id, comment.id))).get()) throw conflict(`Comment "${comment.id}" already exists in thread "${threadId}".`);
181
+ await insertComment(documentId, threadId, comment);
182
+ return requireThread(documentId, threadId);
183
+ }),
184
+ editComment: (documentId, threadId, commentId, body, editedAt) => write(async () => {
185
+ if (!(await requireThread(documentId, threadId)).comments.some((comment) => comment.id === commentId)) throw notFound("comment", commentId);
186
+ await db.update(comments).set({
187
+ body,
188
+ editedAt
189
+ }).where(and(eq(comments.documentId, documentId), eq(comments.threadId, threadId), eq(comments.id, commentId))).run();
190
+ return requireThread(documentId, threadId);
191
+ }),
192
+ removeComment: (documentId, threadId, commentId) => write(async () => {
193
+ const index = (await requireThread(documentId, threadId)).comments.findIndex((comment) => comment.id === commentId);
194
+ if (index < 0) throw notFound("comment", commentId);
195
+ if (index === 0) throw invalid("The first comment of a thread cannot be removed on its own; remove the thread.");
196
+ await db.delete(comments).where(and(eq(comments.documentId, documentId), eq(comments.threadId, threadId), eq(comments.id, commentId))).run();
197
+ return requireThread(documentId, threadId);
198
+ }),
199
+ setThreadStatus: (documentId, threadId, status) => write(async () => {
200
+ await requireThread(documentId, threadId);
201
+ await db.update(threads).set({ status }).where(and(eq(threads.documentId, documentId), eq(threads.id, threadId))).run();
202
+ return requireThread(documentId, threadId);
203
+ }),
204
+ updateAnchor: (documentId, annotation) => write(async () => {
205
+ const row = await db.select().from(annotations).where(and(eq(annotations.documentId, documentId), eq(annotations.id, annotation.id))).get();
206
+ if (!row) throw notFound("annotation", annotation.id);
207
+ if (row.threadId !== annotation.threadId) throw invalid("An annotation cannot move to another thread.");
208
+ await db.update(annotations).set({ anchor: annotation.anchor }).where(and(eq(annotations.documentId, documentId), eq(annotations.id, annotation.id))).run();
209
+ return structuredClone(annotation);
210
+ }),
211
+ removeThread: (documentId, threadId) => write(async () => {
212
+ await db.delete(comments).where(and(eq(comments.documentId, documentId), eq(comments.threadId, threadId))).run();
213
+ await db.delete(threads).where(and(eq(threads.documentId, documentId), eq(threads.id, threadId))).run();
214
+ await db.delete(annotations).where(and(eq(annotations.documentId, documentId), eq(annotations.threadId, threadId))).run();
215
+ }),
216
+ removeDocuments: (prefix) => write(async () => {
217
+ const under = (column) => sql`substr(${sql.identifier(column.name)}, 1, ${prefix.length}) = ${prefix}`;
218
+ const documents = /* @__PURE__ */ new Set();
219
+ for (const [table, column] of [
220
+ [annotations, annotations.documentId],
221
+ [threads, threads.documentId],
222
+ [comments, comments.documentId]
223
+ ]) for (const row of await db.selectDistinct({ documentId: column }).from(table).where(under(column)).all()) documents.add(row.documentId);
224
+ for (const [table, column] of [
225
+ [comments, comments.documentId],
226
+ [threads, threads.documentId],
227
+ [annotations, annotations.documentId]
228
+ ]) await db.delete(table).where(under(column)).run();
229
+ return documents.size;
230
+ })
231
+ };
232
+ }
233
+ //#endregion
234
+ export { bootstrapCommentTables, commentTables, createDrizzleCommentStore };
235
+
236
+ //# sourceMappingURL=drizzle.js.map