bookish-press 0.4.46 → 0.4.47

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 (533) hide show
  1. package/.env.example +8 -0
  2. package/.firebaserc +8 -0
  3. package/.prettierignore +8 -0
  4. package/.prettierrc.json +5 -0
  5. package/_update-notifier-last-checked +0 -0
  6. package/firebase.json +46 -0
  7. package/firestore.indexes.json +4 -0
  8. package/firestore.rules +59 -0
  9. package/functions/.eslintrc.js +28 -0
  10. package/functions/package-lock.json +12595 -0
  11. package/functions/package.json +43 -0
  12. package/functions/src/index.ts +345 -0
  13. package/functions/tsconfig.dev.json +3 -0
  14. package/functions/tsconfig.json +15 -0
  15. package/package.json +53 -270
  16. package/scripts/claims.cjs +99 -0
  17. package/src/app.d.ts +9 -0
  18. package/src/app.html +24 -0
  19. package/src/lib/components/Auth.svelte +65 -0
  20. package/{components/Authentication.d.ts → src/lib/components/Authentication.ts} +2 -0
  21. package/{components → src/lib/components}/BookPreview.svelte +27 -22
  22. package/{components → src/lib/components}/External.svelte +2 -1
  23. package/src/lib/components/Link.svelte +58 -0
  24. package/{components → src/lib/components}/app/BookList.svelte +6 -3
  25. package/{components → src/lib/components}/app/Button.svelte +5 -4
  26. package/{components → src/lib/components}/app/Feedback.svelte +11 -7
  27. package/{components → src/lib/components}/app/Head.svelte +2 -1
  28. package/{components → src/lib/components}/app/Large.svelte +0 -0
  29. package/{components → src/lib/components}/app/Lead.svelte +0 -0
  30. package/{components → src/lib/components}/app/Link.svelte +4 -3
  31. package/{components → src/lib/components}/app/Options.svelte +5 -4
  32. package/{components → src/lib/components}/app/Paragraph.svelte +2 -1
  33. package/{components → src/lib/components}/app/Section.svelte +0 -0
  34. package/{components → src/lib/components}/app/Table.svelte +0 -0
  35. package/{components → src/lib/components}/app/TextInput.svelte +12 -9
  36. package/{components → src/lib/components}/chapter/Atom.svelte +18 -12
  37. package/src/lib/components/chapter/Block.svelte +42 -0
  38. package/{components → src/lib/components}/chapter/Callout.svelte +6 -3
  39. package/{components → src/lib/components}/chapter/CaptionedCode.svelte +21 -13
  40. package/{components → src/lib/components}/chapter/ChapterBody.svelte +13 -9
  41. package/{components → src/lib/components}/chapter/Citations.svelte +34 -33
  42. package/{components → src/lib/components}/chapter/Code.svelte +63 -59
  43. package/{components → src/lib/components}/chapter/Comment.svelte +30 -18
  44. package/{components → src/lib/components}/chapter/Definition.svelte +23 -17
  45. package/{components → src/lib/components}/chapter/Embed.svelte +97 -77
  46. package/src/lib/components/chapter/ErrorMessage.svelte +12 -0
  47. package/{components → src/lib/components}/chapter/ExtendedPrism.js +0 -0
  48. package/{components → src/lib/components}/chapter/Figure.svelte +34 -26
  49. package/{components → src/lib/components}/chapter/Footnote.svelte +32 -20
  50. package/{components → src/lib/components}/chapter/Format.svelte +39 -34
  51. package/{components → src/lib/components}/chapter/InlineCode.svelte +9 -5
  52. package/{components → src/lib/components}/chapter/Label.svelte +23 -14
  53. package/{components → src/lib/components}/chapter/Link.svelte +27 -21
  54. package/{components → src/lib/components}/chapter/List.svelte +5 -3
  55. package/{components → src/lib/components}/chapter/Marginal.svelte +54 -41
  56. package/{components → src/lib/components}/chapter/Paragraph.svelte +25 -20
  57. package/{components → src/lib/components}/chapter/Positioned.svelte +4 -1
  58. package/{components → src/lib/components}/chapter/Problem.svelte +0 -0
  59. package/src/lib/components/chapter/Python.svelte +144 -0
  60. package/{components → src/lib/components}/chapter/Quote.svelte +9 -5
  61. package/{components → src/lib/components}/chapter/Rule.svelte +4 -1
  62. package/{components → src/lib/components}/chapter/Table.svelte +11 -7
  63. package/src/lib/components/chapter/Text.svelte +109 -0
  64. package/src/lib/components/editor/BookishEditor.svelte +1101 -0
  65. package/src/lib/components/editor/CalloutEditor.svelte +14 -0
  66. package/{components → src/lib/components}/editor/CaptionedCodeEditor.svelte +10 -6
  67. package/src/lib/components/editor/CaretContext.ts +55 -0
  68. package/{components/editor/CaretState.d.ts → src/lib/components/editor/CaretState.ts} +6 -7
  69. package/{components/editor/CaretUtilities.d.ts → src/lib/components/editor/CaretUtilities.ts} +1 -0
  70. package/{components → src/lib/components}/editor/CaretView.svelte +25 -20
  71. package/src/lib/components/editor/CitationsEditor.svelte +64 -0
  72. package/{components/editor/Clipboard.d.ts → src/lib/components/editor/Clipboard.ts} +2 -1
  73. package/{components/editor/Command.d.ts → src/lib/components/editor/Command.ts} +8 -2
  74. package/{components/editor/Commands.js → src/lib/components/editor/Commands.ts} +730 -315
  75. package/src/lib/components/editor/ConfirmButton.svelte +51 -0
  76. package/src/lib/components/editor/DefinitionEditor.svelte +44 -0
  77. package/src/lib/components/editor/EmbedEditor.svelte +152 -0
  78. package/{components → src/lib/components}/editor/Icon.svelte +2 -1
  79. package/{components → src/lib/components}/editor/ImageChooser.svelte +24 -19
  80. package/src/lib/components/editor/InlineCodeEditor.svelte +16 -0
  81. package/{components → src/lib/components}/editor/LabelEditor.svelte +14 -9
  82. package/{components → src/lib/components}/editor/LanguageEditor.svelte +8 -5
  83. package/src/lib/components/editor/LinkEditor.svelte +110 -0
  84. package/{components → src/lib/components}/editor/Note.svelte +0 -0
  85. package/{components → src/lib/components}/editor/Permissions.svelte +43 -36
  86. package/src/lib/components/editor/PositionEditor.svelte +21 -0
  87. package/src/lib/components/editor/QuoteEditor.svelte +14 -0
  88. package/{components → src/lib/components}/editor/Switch.svelte +14 -11
  89. package/src/lib/components/editor/TableEditor.svelte +14 -0
  90. package/{components → src/lib/components}/editor/TextEditor.svelte +101 -89
  91. package/src/lib/components/editor/Toggle.svelte +47 -0
  92. package/src/lib/components/editor/Toolbar.svelte +297 -0
  93. package/{components → src/lib/components}/editor/ToolbarGroup.svelte +5 -3
  94. package/{components → src/lib/components}/editor/ToolbarSpacer.svelte +0 -0
  95. package/src/lib/components/editor/URLEditor.svelte +15 -0
  96. package/{components/editor/UndoState.d.ts → src/lib/components/editor/UndoState.ts} +3 -2
  97. package/{components → src/lib/components}/editor/icons/annotate.svg +0 -0
  98. package/{components → src/lib/components}/editor/icons/block.svg +0 -0
  99. package/{components → src/lib/components}/editor/icons/bold.svg +0 -0
  100. package/{components → src/lib/components}/editor/icons/bullets.svg +0 -0
  101. package/{components → src/lib/components}/editor/icons/callout.svg +0 -0
  102. package/{components → src/lib/components}/editor/icons/citation.svg +0 -0
  103. package/{components → src/lib/components}/editor/icons/clear.svg +0 -0
  104. package/{components → src/lib/components}/editor/icons/clipboard.svg +0 -0
  105. package/{components → src/lib/components}/editor/icons/code.svg +0 -0
  106. package/{components → src/lib/components}/editor/icons/columnafter.svg +0 -0
  107. package/{components → src/lib/components}/editor/icons/columnbefore.svg +0 -0
  108. package/{components → src/lib/components}/editor/icons/comment.svg +0 -0
  109. package/{components → src/lib/components}/editor/icons/copy.svg +0 -0
  110. package/{components → src/lib/components}/editor/icons/cut.svg +0 -0
  111. package/{components → src/lib/components}/editor/icons/define.svg +0 -0
  112. package/{components → src/lib/components}/editor/icons/deletecolumn.svg +0 -0
  113. package/{components → src/lib/components}/editor/icons/deleterow.svg +0 -0
  114. package/{components → src/lib/components}/editor/icons/footnote.svg +0 -0
  115. package/{components → src/lib/components}/editor/icons/header1.svg +0 -0
  116. package/{components → src/lib/components}/editor/icons/header2.svg +0 -0
  117. package/{components → src/lib/components}/editor/icons/header3.svg +0 -0
  118. package/{components → src/lib/components}/editor/icons/home.svg +0 -0
  119. package/{components → src/lib/components}/editor/icons/indent.svg +0 -0
  120. package/{components → src/lib/components}/editor/icons/italic.svg +0 -0
  121. package/{components → src/lib/components}/editor/icons/label.svg +0 -0
  122. package/{components → src/lib/components}/editor/icons/left.svg +0 -0
  123. package/{components → src/lib/components}/editor/icons/level.svg +0 -0
  124. package/{components → src/lib/components}/editor/icons/link.svg +0 -0
  125. package/{components → src/lib/components}/editor/icons/list.svg +0 -0
  126. package/{components → src/lib/components}/editor/icons/media.svg +0 -0
  127. package/{components → src/lib/components}/editor/icons/middle.svg +0 -0
  128. package/{components → src/lib/components}/editor/icons/numbers.svg +0 -0
  129. package/{components → src/lib/components}/editor/icons/paragraph.svg +0 -0
  130. package/{components → src/lib/components}/editor/icons/paste.svg +0 -0
  131. package/{components → src/lib/components}/editor/icons/quote.svg +0 -0
  132. package/{components → src/lib/components}/editor/icons/redo.svg +0 -0
  133. package/{components → src/lib/components}/editor/icons/right.svg +0 -0
  134. package/{components → src/lib/components}/editor/icons/rowabove.svg +0 -0
  135. package/{components → src/lib/components}/editor/icons/rowbelow.svg +0 -0
  136. package/{components → src/lib/components}/editor/icons/rule.svg +0 -0
  137. package/{components → src/lib/components}/editor/icons/sub.svg +0 -0
  138. package/{components → src/lib/components}/editor/icons/super.svg +0 -0
  139. package/{components → src/lib/components}/editor/icons/table.svg +0 -0
  140. package/{components → src/lib/components}/editor/icons/text.svg +0 -0
  141. package/{components → src/lib/components}/editor/icons/time.svg +0 -0
  142. package/{components → src/lib/components}/editor/icons/undo.svg +0 -0
  143. package/{components → src/lib/components}/editor/icons/unindent.svg +0 -0
  144. package/{components → src/lib/components}/editor/icons/unlink.svg +0 -0
  145. package/{components → src/lib/components}/page/Acknowledgements.svelte +19 -10
  146. package/src/lib/components/page/Authors.svelte +92 -0
  147. package/src/lib/components/page/BookLoader.svelte +77 -0
  148. package/src/lib/components/page/BulkReferenceEditor.svelte +86 -0
  149. package/src/lib/components/page/Chapter.svelte +449 -0
  150. package/src/lib/components/page/ChapterContext.ts +13 -0
  151. package/{components → src/lib/components}/page/ChapterNumber.svelte +0 -0
  152. package/{components → src/lib/components}/page/ChapterTitle.svelte +4 -2
  153. package/src/lib/components/page/Contexts.ts +176 -0
  154. package/{components → src/lib/components}/page/DefinitionView.svelte +52 -37
  155. package/{components → src/lib/components}/page/Description.svelte +15 -7
  156. package/src/lib/components/page/Edition.svelte +189 -0
  157. package/src/lib/components/page/EditionLoader.svelte +123 -0
  158. package/{components → src/lib/components}/page/Editions.svelte +22 -18
  159. package/{components → src/lib/components}/page/Glossary.svelte +33 -28
  160. package/{components → src/lib/components}/page/Header.svelte +59 -52
  161. package/{components → src/lib/components}/page/Index.svelte +48 -41
  162. package/{components → src/lib/components}/page/Instructions.svelte +2 -1
  163. package/{components → src/lib/components}/page/License.svelte +17 -9
  164. package/{components → src/lib/components}/page/Loading.svelte +0 -0
  165. package/{components → src/lib/components}/page/Media.svelte +44 -27
  166. package/{components → src/lib/components}/page/MediaPreview.svelte +3 -2
  167. package/{components → src/lib/components}/page/Muted.svelte +0 -0
  168. package/{components → src/lib/components}/page/Outline.svelte +140 -110
  169. package/src/lib/components/page/Page.svelte +94 -0
  170. package/{components → src/lib/components}/page/PageHeader.svelte +2 -1
  171. package/{components → src/lib/components}/page/PageParagraph.svelte +0 -0
  172. package/src/lib/components/page/PossibleChapter.svelte +16 -0
  173. package/src/lib/components/page/PossibleReference.svelte +14 -0
  174. package/{components → src/lib/components}/page/Print.svelte +5 -3
  175. package/{components → src/lib/components}/page/Publish.svelte +59 -52
  176. package/{components → src/lib/components}/page/Reference.svelte +39 -30
  177. package/{components → src/lib/components}/page/References.svelte +18 -14
  178. package/{components → src/lib/components}/page/Rows.svelte +0 -0
  179. package/src/lib/components/page/Search.svelte +153 -0
  180. package/{components → src/lib/components}/page/Status.svelte +5 -3
  181. package/{components → src/lib/components}/page/SubdomainEditor.svelte +16 -13
  182. package/{components → src/lib/components}/page/TableOfContents.svelte +79 -68
  183. package/src/lib/components/page/TableOfContentsImage.svelte +22 -0
  184. package/{components → src/lib/components}/page/TableOfContentsRow.svelte +34 -24
  185. package/{components → src/lib/components}/page/ThemeEditor.svelte +44 -33
  186. package/{components → src/lib/components}/page/ThemeEditorPreview.svelte +21 -12
  187. package/src/lib/components/page/ThemeSetEditor.svelte +21 -0
  188. package/{components → src/lib/components}/page/ThemeVariableEditor.svelte +18 -14
  189. package/{components → src/lib/components}/page/Title.svelte +0 -0
  190. package/{components → src/lib/components}/page/Unknown.svelte +10 -8
  191. package/{components/page/margins.js → src/lib/components/page/margins.ts} +79 -46
  192. package/{index.js → src/lib/index.js} +0 -0
  193. package/src/lib/models/CRUD.ts +469 -0
  194. package/{models/Firebase.js → src/lib/models/Firebase.ts} +26 -16
  195. package/src/lib/models/book/Book.ts +283 -0
  196. package/src/lib/models/book/BookMedia.ts +182 -0
  197. package/src/lib/models/book/BookSaveStatus.ts +8 -0
  198. package/src/lib/models/book/Chapter.ts +462 -0
  199. package/{models/book/ChapterID.js → src/lib/models/book/ChapterID.ts} +1 -0
  200. package/src/lib/models/book/Definition.ts +2 -0
  201. package/src/lib/models/book/Edition.ts +1216 -0
  202. package/src/lib/models/book/Reference.ts +171 -0
  203. package/{models/book/Schema.js → src/lib/models/book/Schema.ts} +1 -0
  204. package/{models/book/Theme.js → src/lib/models/book/Theme.ts} +110 -6
  205. package/{models/book/ThemeColors.d.ts → src/lib/models/book/ThemeColors.ts} +6 -0
  206. package/{models/book/Words.js → src/lib/models/book/Words.ts} +1 -0
  207. package/{models/chapter/AtomNode.js → src/lib/models/chapter/AtomNode.ts} +30 -10
  208. package/{models/chapter/BlockNode.js → src/lib/models/chapter/BlockNode.ts} +80 -47
  209. package/src/lib/models/chapter/BlocksNode.test.ts +867 -0
  210. package/{models/chapter/BlocksNode.js → src/lib/models/chapter/BlocksNode.ts} +571 -359
  211. package/{models/chapter/Bookkeeping.d.ts → src/lib/models/chapter/Bookkeeping.ts} +0 -0
  212. package/src/lib/models/chapter/CalloutNode.ts +79 -0
  213. package/{models/chapter/Caret.js → src/lib/models/chapter/Caret.ts} +50 -26
  214. package/src/lib/models/chapter/ChapterNode.ts +169 -0
  215. package/{models/chapter/CitationsNode.js → src/lib/models/chapter/CitationsNode.ts} +17 -10
  216. package/{models/chapter/CodeNode.js → src/lib/models/chapter/CodeNode.ts} +125 -62
  217. package/src/lib/models/chapter/CommentNode.ts +61 -0
  218. package/{models/chapter/DefinitionNode.js → src/lib/models/chapter/DefinitionNode.ts} +14 -8
  219. package/src/lib/models/chapter/Edit.ts +6 -0
  220. package/src/lib/models/chapter/EmbedNode.ts +257 -0
  221. package/{models/chapter/ErrorNode.js → src/lib/models/chapter/ErrorNode.ts} +15 -8
  222. package/src/lib/models/chapter/FootnoteNode.ts +59 -0
  223. package/src/lib/models/chapter/FormatNode.test.ts +137 -0
  224. package/{models/chapter/FormatNode.js → src/lib/models/chapter/FormatNode.ts} +443 -262
  225. package/{models/chapter/InlineCodeNode.js → src/lib/models/chapter/InlineCodeNode.ts} +17 -9
  226. package/{models/chapter/LabelNode.js → src/lib/models/chapter/LabelNode.ts} +26 -10
  227. package/{models/chapter/LinkNode.js → src/lib/models/chapter/LinkNode.ts} +12 -7
  228. package/{models/chapter/ListNode.test.js → src/lib/models/chapter/ListNode.test.ts} +57 -20
  229. package/{models/chapter/ListNode.js → src/lib/models/chapter/ListNode.ts} +277 -200
  230. package/src/lib/models/chapter/MetadataNode.ts +44 -0
  231. package/{models → src/lib/models}/chapter/Node.test.js +0 -0
  232. package/{models/chapter/Node.js → src/lib/models/chapter/Node.ts} +155 -71
  233. package/src/lib/models/chapter/ParagraphNode.test.ts +54 -0
  234. package/{models/chapter/ParagraphNode.js → src/lib/models/chapter/ParagraphNode.ts} +95 -58
  235. package/{models/chapter/Parser.test.js → src/lib/models/chapter/Parser.test.ts} +7 -0
  236. package/{models/chapter/Parser.js → src/lib/models/chapter/Parser.ts} +369 -184
  237. package/{models/chapter/Position.d.ts → src/lib/models/chapter/Position.ts} +0 -0
  238. package/src/lib/models/chapter/QuoteNode.ts +135 -0
  239. package/{models/chapter/RootNode.d.ts → src/lib/models/chapter/RootNode.ts} +2 -0
  240. package/{models/chapter/RuleNode.js → src/lib/models/chapter/RuleNode.ts} +9 -6
  241. package/{models/chapter/TableNode.test.js → src/lib/models/chapter/TableNode.test.ts} +27 -10
  242. package/{models/chapter/TableNode.js → src/lib/models/chapter/TableNode.ts} +141 -82
  243. package/{models/chapter/TextNode.test.js → src/lib/models/chapter/TextNode.test.ts} +2 -0
  244. package/{models/chapter/TextNode.js → src/lib/models/chapter/TextNode.ts} +117 -65
  245. package/{util/getSubdomain.js → src/lib/util/getSubdomain.ts} +14 -8
  246. package/{util/isMobile.js → src/lib/util/isMobile.ts} +1 -0
  247. package/{util/mineReference.js → src/lib/util/mineReference.ts} +45 -25
  248. package/{util/scrollToEyeLevel.js → src/lib/util/scrollToEyeLevel.ts} +4 -2
  249. package/src/params/edition.ts +3 -0
  250. package/src/routes/+error.svelte +12 -0
  251. package/src/routes/+layout.svelte +241 -0
  252. package/src/routes/+page.svelte +43 -0
  253. package/src/routes/Footer.svelte +0 -0
  254. package/src/routes/Header.svelte +112 -0
  255. package/src/routes/[bookid]/+layout.svelte +5 -0
  256. package/src/routes/[bookid]/[[editionid=edition]]/+error.svelte +14 -0
  257. package/src/routes/[bookid]/[[editionid=edition]]/+layout.svelte +7 -0
  258. package/src/routes/[bookid]/[[editionid=edition]]/+page.svelte +5 -0
  259. package/src/routes/[bookid]/[[editionid=edition]]/[chapterid]/+page.svelte +5 -0
  260. package/src/routes/[bookid]/[[editionid=edition]]/glossary/+page.svelte +5 -0
  261. package/src/routes/[bookid]/[[editionid=edition]]/index/[[letter]]/+page.svelte +5 -0
  262. package/src/routes/[bookid]/[[editionid=edition]]/media/+page.svelte +5 -0
  263. package/src/routes/[bookid]/[[editionid=edition]]/print/+page.svelte +5 -0
  264. package/src/routes/[bookid]/[[editionid=edition]]/references/+page.svelte +5 -0
  265. package/src/routes/[bookid]/[[editionid=edition]]/search/+page.svelte +5 -0
  266. package/src/routes/[bookid]/editions/+page.svelte +20 -0
  267. package/src/routes/about/+page.svelte +102 -0
  268. package/src/routes/confirm/+page.svelte +62 -0
  269. package/src/routes/email/+page.svelte +99 -0
  270. package/src/routes/login/+page.svelte +66 -0
  271. package/src/routes/read/+page.svelte +38 -0
  272. package/src/routes/write/+error.svelte +10 -0
  273. package/src/routes/write/+layout.svelte +11 -0
  274. package/src/routes/write/+page.svelte +114 -0
  275. package/src/routes/write/[bookid]/+layout.svelte +5 -0
  276. package/src/routes/write/[bookid]/[[editionid=edition]]/+layout.svelte +7 -0
  277. package/src/routes/write/[bookid]/[[editionid=edition]]/+page.svelte +5 -0
  278. package/src/routes/write/[bookid]/[[editionid=edition]]/[chapterid]/+page.svelte +5 -0
  279. package/src/routes/write/[bookid]/[[editionid=edition]]/glossary/+page.svelte +5 -0
  280. package/src/routes/write/[bookid]/[[editionid=edition]]/index/[[letter]]/+page.svelte +5 -0
  281. package/src/routes/write/[bookid]/[[editionid=edition]]/media/+page.svelte +5 -0
  282. package/src/routes/write/[bookid]/[[editionid=edition]]/print/+page.svelte +5 -0
  283. package/src/routes/write/[bookid]/[[editionid=edition]]/references/+page.svelte +5 -0
  284. package/src/routes/write/[bookid]/[[editionid=edition]]/search/+page.svelte +5 -0
  285. package/src/routes/write/[bookid]/[[editionid=edition]]/theme/+page.svelte +5 -0
  286. package/src/routes/write/[bookid]/[[editionid=edition]]/unknown/+page.svelte +5 -0
  287. package/src/routes/write/[bookid]/editions/+page.svelte +20 -0
  288. package/src/vite-env.d.ts +1 -0
  289. package/static/icons/favicon.png +0 -0
  290. package/static/icons/icon.png +0 -0
  291. package/static/icons/ios-icon.png +0 -0
  292. package/storage.rules +9 -0
  293. package/svelte.config.js +19 -0
  294. package/tsconfig.json +18 -0
  295. package/tsconfig.node.json +9 -0
  296. package/vite.config.ts +8 -0
  297. package/vite.reader.config.ts +32 -0
  298. package/components/Auth.svelte +0 -55
  299. package/components/Auth.svelte.d.ts +0 -16
  300. package/components/Authentication.js +0 -1
  301. package/components/BookPreview.svelte.d.ts +0 -18
  302. package/components/External.svelte.d.ts +0 -18
  303. package/components/Link.svelte +0 -51
  304. package/components/Link.svelte.d.ts +0 -18
  305. package/components/app/BookList.svelte.d.ts +0 -18
  306. package/components/app/Button.svelte.d.ts +0 -22
  307. package/components/app/Feedback.svelte.d.ts +0 -18
  308. package/components/app/Head.svelte.d.ts +0 -18
  309. package/components/app/Large.svelte.d.ts +0 -27
  310. package/components/app/Lead.svelte.d.ts +0 -27
  311. package/components/app/Link.svelte.d.ts +0 -20
  312. package/components/app/Options.svelte.d.ts +0 -19
  313. package/components/app/Paragraph.svelte.d.ts +0 -18
  314. package/components/app/Section.svelte.d.ts +0 -27
  315. package/components/app/Table.svelte.d.ts +0 -27
  316. package/components/app/TextInput.svelte.d.ts +0 -22
  317. package/components/chapter/Atom.svelte.d.ts +0 -19
  318. package/components/chapter/Block.svelte +0 -37
  319. package/components/chapter/Block.svelte.d.ts +0 -17
  320. package/components/chapter/Callout.svelte.d.ts +0 -17
  321. package/components/chapter/CaptionedCode.svelte.d.ts +0 -17
  322. package/components/chapter/ChapterBody.svelte.d.ts +0 -19
  323. package/components/chapter/Citations.svelte.d.ts +0 -17
  324. package/components/chapter/Code.svelte.d.ts +0 -22
  325. package/components/chapter/Comment.svelte.d.ts +0 -17
  326. package/components/chapter/Definition.svelte.d.ts +0 -17
  327. package/components/chapter/Embed.svelte.d.ts +0 -20
  328. package/components/chapter/ErrorMessage.svelte +0 -9
  329. package/components/chapter/ErrorMessage.svelte.d.ts +0 -17
  330. package/components/chapter/ExtendedPrism.d.ts +0 -2
  331. package/components/chapter/Figure.svelte.d.ts +0 -24
  332. package/components/chapter/Footnote.svelte.d.ts +0 -19
  333. package/components/chapter/Format.svelte.d.ts +0 -19
  334. package/components/chapter/InlineCode.svelte.d.ts +0 -17
  335. package/components/chapter/Label.svelte.d.ts +0 -17
  336. package/components/chapter/Link.svelte.d.ts +0 -17
  337. package/components/chapter/List.svelte.d.ts +0 -17
  338. package/components/chapter/Marginal.svelte.d.ts +0 -22
  339. package/components/chapter/Paragraph.svelte.d.ts +0 -18
  340. package/components/chapter/Positioned.svelte.d.ts +0 -19
  341. package/components/chapter/Problem.svelte.d.ts +0 -27
  342. package/components/chapter/Python.svelte +0 -128
  343. package/components/chapter/Python.svelte.d.ts +0 -18
  344. package/components/chapter/Quote.svelte.d.ts +0 -17
  345. package/components/chapter/Rule.svelte.d.ts +0 -17
  346. package/components/chapter/Table.svelte.d.ts +0 -17
  347. package/components/chapter/Text.svelte +0 -87
  348. package/components/chapter/Text.svelte.d.ts +0 -18
  349. package/components/editor/BookishEditor.svelte +0 -884
  350. package/components/editor/BookishEditor.svelte.d.ts +0 -25
  351. package/components/editor/CalloutEditor.svelte +0 -10
  352. package/components/editor/CalloutEditor.svelte.d.ts +0 -17
  353. package/components/editor/CaptionedCodeEditor.svelte.d.ts +0 -17
  354. package/components/editor/CaretContext.d.ts +0 -50
  355. package/components/editor/CaretContext.js +0 -1
  356. package/components/editor/CaretState.js +0 -1
  357. package/components/editor/CaretUtilities.js +0 -1
  358. package/components/editor/CaretView.svelte.d.ts +0 -25
  359. package/components/editor/CitationsEditor.svelte +0 -53
  360. package/components/editor/CitationsEditor.svelte.d.ts +0 -17
  361. package/components/editor/Clipboard.js +0 -1
  362. package/components/editor/Command.js +0 -1
  363. package/components/editor/Commands.d.ts +0 -3
  364. package/components/editor/ConfirmButton.svelte +0 -49
  365. package/components/editor/ConfirmButton.svelte.d.ts +0 -19
  366. package/components/editor/DefinitionEditor.svelte +0 -36
  367. package/components/editor/DefinitionEditor.svelte.d.ts +0 -17
  368. package/components/editor/EmbedEditor.svelte +0 -137
  369. package/components/editor/EmbedEditor.svelte.d.ts +0 -17
  370. package/components/editor/Icon.svelte.d.ts +0 -16
  371. package/components/editor/ImageChooser.svelte.d.ts +0 -18
  372. package/components/editor/InlineCodeEditor.svelte +0 -12
  373. package/components/editor/InlineCodeEditor.svelte.d.ts +0 -17
  374. package/components/editor/LabelEditor.svelte.d.ts +0 -17
  375. package/components/editor/LanguageEditor.svelte.d.ts +0 -17
  376. package/components/editor/LinkEditor.svelte +0 -100
  377. package/components/editor/LinkEditor.svelte.d.ts +0 -17
  378. package/components/editor/Note.svelte.d.ts +0 -27
  379. package/components/editor/Permissions.svelte.d.ts +0 -20
  380. package/components/editor/PositionEditor.svelte +0 -17
  381. package/components/editor/PositionEditor.svelte.d.ts +0 -18
  382. package/components/editor/QuoteEditor.svelte +0 -10
  383. package/components/editor/QuoteEditor.svelte.d.ts +0 -17
  384. package/components/editor/Switch.svelte.d.ts +0 -20
  385. package/components/editor/TableEditor.svelte +0 -10
  386. package/components/editor/TableEditor.svelte.d.ts +0 -17
  387. package/components/editor/TextEditor.svelte.d.ts +0 -24
  388. package/components/editor/Toggle.svelte +0 -41
  389. package/components/editor/Toggle.svelte.d.ts +0 -19
  390. package/components/editor/Toolbar.svelte +0 -249
  391. package/components/editor/Toolbar.svelte.d.ts +0 -17
  392. package/components/editor/ToolbarGroup.svelte.d.ts +0 -18
  393. package/components/editor/ToolbarSpacer.svelte.d.ts +0 -23
  394. package/components/editor/URLEditor.svelte +0 -13
  395. package/components/editor/URLEditor.svelte.d.ts +0 -18
  396. package/components/editor/UndoState.js +0 -1
  397. package/components/page/Acknowledgements.svelte.d.ts +0 -14
  398. package/components/page/Authors.svelte +0 -85
  399. package/components/page/Authors.svelte.d.ts +0 -21
  400. package/components/page/BookLoader.svelte +0 -59
  401. package/components/page/BookLoader.svelte.d.ts +0 -16
  402. package/components/page/BulkReferenceEditor.svelte +0 -63
  403. package/components/page/BulkReferenceEditor.svelte.d.ts +0 -14
  404. package/components/page/Chapter.svelte +0 -392
  405. package/components/page/Chapter.svelte.d.ts +0 -18
  406. package/components/page/ChapterContext.d.ts +0 -10
  407. package/components/page/ChapterContext.js +0 -1
  408. package/components/page/ChapterNumber.svelte.d.ts +0 -27
  409. package/components/page/ChapterTitle.svelte.d.ts +0 -18
  410. package/components/page/Contexts.d.ts +0 -47
  411. package/components/page/Contexts.js +0 -133
  412. package/components/page/DefinitionView.svelte.d.ts +0 -18
  413. package/components/page/Description.svelte.d.ts +0 -14
  414. package/components/page/Edition.svelte +0 -161
  415. package/components/page/Edition.svelte.d.ts +0 -20
  416. package/components/page/EditionLoader.svelte +0 -99
  417. package/components/page/EditionLoader.svelte.d.ts +0 -18
  418. package/components/page/Editions.svelte.d.ts +0 -14
  419. package/components/page/Glossary.svelte.d.ts +0 -14
  420. package/components/page/Header.svelte.d.ts +0 -29
  421. package/components/page/Index.svelte.d.ts +0 -14
  422. package/components/page/Instructions.svelte.d.ts +0 -18
  423. package/components/page/License.svelte.d.ts +0 -14
  424. package/components/page/Loading.svelte.d.ts +0 -23
  425. package/components/page/Media.svelte.d.ts +0 -14
  426. package/components/page/MediaPreview.svelte.d.ts +0 -19
  427. package/components/page/Muted.svelte.d.ts +0 -27
  428. package/components/page/Outline.svelte.d.ts +0 -19
  429. package/components/page/Page.svelte +0 -84
  430. package/components/page/Page.svelte.d.ts +0 -19
  431. package/components/page/PageHeader.svelte.d.ts +0 -18
  432. package/components/page/PageParagraph.svelte.d.ts +0 -27
  433. package/components/page/PossibleChapter.svelte +0 -14
  434. package/components/page/PossibleChapter.svelte.d.ts +0 -14
  435. package/components/page/PossibleReference.svelte +0 -11
  436. package/components/page/PossibleReference.svelte.d.ts +0 -18
  437. package/components/page/Print.svelte.d.ts +0 -14
  438. package/components/page/Publish.svelte.d.ts +0 -14
  439. package/components/page/Reference.svelte.d.ts +0 -17
  440. package/components/page/References.svelte.d.ts +0 -14
  441. package/components/page/Rows.svelte.d.ts +0 -27
  442. package/components/page/Search.svelte +0 -133
  443. package/components/page/Search.svelte.d.ts +0 -14
  444. package/components/page/Status.svelte.d.ts +0 -14
  445. package/components/page/SubdomainEditor.svelte.d.ts +0 -14
  446. package/components/page/TableOfContents.svelte.d.ts +0 -14
  447. package/components/page/TableOfContentsImage.svelte +0 -18
  448. package/components/page/TableOfContentsImage.svelte.d.ts +0 -16
  449. package/components/page/TableOfContentsRow.svelte.d.ts +0 -24
  450. package/components/page/ThemeEditor.svelte.d.ts +0 -14
  451. package/components/page/ThemeEditorPreview.svelte.d.ts +0 -17
  452. package/components/page/ThemeSetEditor.svelte +0 -19
  453. package/components/page/ThemeSetEditor.svelte.d.ts +0 -18
  454. package/components/page/ThemeVariableEditor.svelte.d.ts +0 -18
  455. package/components/page/Title.svelte.d.ts +0 -27
  456. package/components/page/Unknown.svelte.d.ts +0 -16
  457. package/components/page/margins.d.ts +0 -2
  458. package/index.d.ts +0 -15
  459. package/models/CRUD.d.ts +0 -27
  460. package/models/CRUD.js +0 -262
  461. package/models/Firebase.d.ts +0 -5
  462. package/models/book/Book.d.ts +0 -61
  463. package/models/book/Book.js +0 -135
  464. package/models/book/BookMedia.d.ts +0 -23
  465. package/models/book/BookMedia.js +0 -108
  466. package/models/book/BookSaveStatus.d.ts +0 -7
  467. package/models/book/BookSaveStatus.js +0 -8
  468. package/models/book/Chapter.d.ts +0 -81
  469. package/models/book/Chapter.js +0 -212
  470. package/models/book/ChapterID.d.ts +0 -10
  471. package/models/book/Definition.d.ts +0 -6
  472. package/models/book/Definition.js +0 -1
  473. package/models/book/Edition.d.ts +0 -139
  474. package/models/book/Edition.js +0 -620
  475. package/models/book/Reference.d.ts +0 -24
  476. package/models/book/Reference.js +0 -78
  477. package/models/book/Schema.d.ts +0 -174
  478. package/models/book/Theme.d.ts +0 -113
  479. package/models/book/ThemeColors.js +0 -1
  480. package/models/book/Words.d.ts +0 -2
  481. package/models/chapter/AtomNode.d.ts +0 -18
  482. package/models/chapter/BlockNode.d.ts +0 -20
  483. package/models/chapter/BlocksNode.d.ts +0 -50
  484. package/models/chapter/BlocksNode.test.d.ts +0 -1
  485. package/models/chapter/BlocksNode.test.js +0 -568
  486. package/models/chapter/Bookkeeping.js +0 -1
  487. package/models/chapter/CalloutNode.d.ts +0 -17
  488. package/models/chapter/CalloutNode.js +0 -58
  489. package/models/chapter/Caret.d.ts +0 -23
  490. package/models/chapter/ChapterNode.d.ts +0 -34
  491. package/models/chapter/ChapterNode.js +0 -117
  492. package/models/chapter/CitationsNode.d.ts +0 -16
  493. package/models/chapter/CodeNode.d.ts +0 -35
  494. package/models/chapter/CommentNode.d.ts +0 -18
  495. package/models/chapter/CommentNode.js +0 -48
  496. package/models/chapter/DefinitionNode.d.ts +0 -12
  497. package/models/chapter/Edit.d.ts +0 -7
  498. package/models/chapter/Edit.js +0 -1
  499. package/models/chapter/EmbedNode.d.ts +0 -45
  500. package/models/chapter/EmbedNode.js +0 -168
  501. package/models/chapter/ErrorNode.d.ts +0 -17
  502. package/models/chapter/FootnoteNode.d.ts +0 -18
  503. package/models/chapter/FootnoteNode.js +0 -47
  504. package/models/chapter/FormatNode.d.ts +0 -60
  505. package/models/chapter/FormatNode.test.d.ts +0 -1
  506. package/models/chapter/FormatNode.test.js +0 -96
  507. package/models/chapter/InlineCodeNode.d.ts +0 -12
  508. package/models/chapter/LabelNode.d.ts +0 -17
  509. package/models/chapter/LinkNode.d.ts +0 -12
  510. package/models/chapter/ListNode.d.ts +0 -51
  511. package/models/chapter/ListNode.test.d.ts +0 -1
  512. package/models/chapter/MetadataNode.d.ts +0 -17
  513. package/models/chapter/MetadataNode.js +0 -32
  514. package/models/chapter/Node.d.ts +0 -38
  515. package/models/chapter/Node.test.d.ts +0 -1
  516. package/models/chapter/ParagraphNode.d.ts +0 -33
  517. package/models/chapter/ParagraphNode.test.d.ts +0 -1
  518. package/models/chapter/ParagraphNode.test.js +0 -30
  519. package/models/chapter/Parser.d.ts +0 -75
  520. package/models/chapter/Parser.test.d.ts +0 -1
  521. package/models/chapter/Position.js +0 -1
  522. package/models/chapter/QuoteNode.d.ts +0 -25
  523. package/models/chapter/QuoteNode.js +0 -99
  524. package/models/chapter/RootNode.js +0 -1
  525. package/models/chapter/RuleNode.d.ts +0 -15
  526. package/models/chapter/TableNode.d.ts +0 -37
  527. package/models/chapter/TableNode.test.d.ts +0 -1
  528. package/models/chapter/TextNode.d.ts +0 -36
  529. package/models/chapter/TextNode.test.d.ts +0 -1
  530. package/util/getSubdomain.d.ts +0 -3
  531. package/util/isMobile.d.ts +0 -2
  532. package/util/mineReference.d.ts +0 -4
  533. package/util/scrollToEyeLevel.d.ts +0 -2
package/models/CRUD.js DELETED
@@ -1,262 +0,0 @@
1
- import { db, functions } from './Firebase';
2
- import { collection, getDocs, getDoc, setDoc, doc, addDoc, query, where, deleteDoc, DocumentReference, onSnapshot, QueryFieldFilterConstraint, } from 'firebase/firestore';
3
- import { httpsCallable } from 'firebase/functions';
4
- import Edition from './book/Edition';
5
- import Book, {} from './book/Book';
6
- function editionPath(bookID, editionID) {
7
- return `books/${bookID}/editions/${editionID}`;
8
- }
9
- const NO_DATABASE_CONNECTION = 'Not connected to database';
10
- ///////////////
11
- //// READ BOOKS
12
- ///////////////
13
- function listenToBooks(constraint, react) {
14
- if (!db)
15
- throw NO_DATABASE_CONNECTION;
16
- try {
17
- return onSnapshot(query(collection(db, 'books'), constraint), (snapshot) => react(snapshot.empty
18
- ? []
19
- : snapshot.docs.map((doc) => Book.fromJSON(doc.ref, doc.data()))));
20
- }
21
- catch (err) {
22
- throw 'Issue querying database';
23
- }
24
- }
25
- export function listenToPublishedBooks(react) {
26
- return listenToBooks(where('published', '==', true), react);
27
- }
28
- export function listenToEditableBooks(userID, react) {
29
- return listenToBooks(where('uids', 'array-contains', userID), react);
30
- }
31
- export function listenToPartiallyEditableBooks(userID, react) {
32
- return listenToBooks(where('readuids', 'array-contains', userID), react);
33
- }
34
- export function listenToBooksByName(name, react) {
35
- return listenToBooks(where('domain', '==', name), react);
36
- }
37
- export function listenToBookWithID(id, react) {
38
- if (!db)
39
- throw NO_DATABASE_CONNECTION;
40
- const ref = doc(db, 'books', id);
41
- return onSnapshot(doc(db, 'books', id), (doc) => {
42
- if (!doc.metadata.hasPendingWrites)
43
- react(doc.exists()
44
- ? Book.fromJSON(ref, doc.data())
45
- : null);
46
- });
47
- }
48
- export function listenToEdition(bookID, editionID, react) {
49
- if (!db)
50
- throw NO_DATABASE_CONNECTION;
51
- return onSnapshot(doc(db, 'books', bookID, 'editions', editionID), (doc) => {
52
- if (!doc.metadata.hasPendingWrites)
53
- react(doc.exists()
54
- ? Edition.fromJSON(doc.ref, doc.data())
55
- : null);
56
- });
57
- }
58
- export function listenToChapters(bookID, editionID, react) {
59
- if (!db)
60
- throw NO_DATABASE_CONNECTION;
61
- return onSnapshot(collection(db, 'books', bookID, 'editions', editionID, 'chapters'), (docs) => {
62
- const chapters = [];
63
- docs.forEach((doc) => {
64
- chapters.push([doc.ref, doc.data().text]);
65
- });
66
- react(chapters);
67
- });
68
- }
69
- /////////////////
70
- //// MANAGE USERS
71
- /////////////////
72
- /** Hit the authentication database to get user emails. */
73
- export async function getUserEmails(uids) {
74
- if (!functions)
75
- throw Error("Can't publish, no connection to Firebase functions.");
76
- const getUserEmails = httpsCallable(functions, 'getUserEmails');
77
- const result = await getUserEmails({
78
- uids,
79
- });
80
- return new Map(Object.entries(result.data));
81
- }
82
- export async function createUser(email) {
83
- if (!functions)
84
- throw Error("Can't publish, no connection to Firebase functions.");
85
- const createUserWithEmail = httpsCallable(functions, 'createUserWithEmail');
86
- const result = await createUserWithEmail({
87
- email,
88
- });
89
- return result.data;
90
- }
91
- export async function createBook(userID) {
92
- if (!db)
93
- throw Error("Can't create book, not connected to Firebase.");
94
- // Create a new book
95
- const newBookData = {
96
- title: 'Untitled',
97
- authors: [],
98
- description: '',
99
- cover: null,
100
- published: false,
101
- domain: null,
102
- editions: [],
103
- uids: [userID],
104
- readuids: [],
105
- };
106
- // Create the book
107
- const bookRef = await addDoc(collection(db, 'books'), newBookData);
108
- // Create a model to store it.
109
- let book = Book.fromJSON(bookRef, newBookData);
110
- // Make a new default edition with a single chapter with this user id.
111
- let newEdition = new Edition(bookRef, undefined, [], 'Untitled', [], 1, '', null, {}, '', [], 'All rights reserved.', '', [], {}, {}, {}, {}, null, null, {}).withNewChapter();
112
- // Add the edition to the editions collection in the database so we can get an edition ref.
113
- const editionRef = await addDoc(collection(db, 'books', bookRef.id, 'editions'), newEdition.toObject());
114
- // Remember the ref.
115
- newEdition = newEdition.withRef(editionRef);
116
- // Now replicate the edition info in the book. We dodge type checking here because we know with certainty
117
- // that the ref was just added the line before.
118
- const info = newEdition.getInfo();
119
- if (info)
120
- book = book.withEditions([info]);
121
- // Update the book with the edition info.
122
- await updateBook(book);
123
- // Update all of the changes to the edition in Firestore, persisting the refs and chapter text.
124
- await updateEdition(undefined, newEdition);
125
- // Return the book id
126
- return bookRef.id;
127
- }
128
- export async function createNewEdition(book) {
129
- if (!db)
130
- throw Error("Can't publish draft, no Firebase connection.");
131
- // Get the latest draft.
132
- const latestEditionID = book.getLatestEditionID();
133
- if (latestEditionID === undefined)
134
- throw 'No editions on this book';
135
- const latestDraftDoc = await getDoc(doc(db, 'books', book.ref.id, 'editions', latestEditionID));
136
- const latestDraft = latestDraftDoc.exists()
137
- ? latestDraftDoc.data()
138
- : undefined;
139
- if (latestDraft === undefined)
140
- return book;
141
- // Make a copy without chapter and edition refs, because we want to create new ones,
142
- // and with an incremented edition number.
143
- const newEdition = latestDraft.withoutRefs();
144
- // Create a copy of the existing draft as a new edition.
145
- const newEditionRef = await addDoc(collection(db, 'editions'), newEdition.toObject());
146
- // Create the edition, creating chapter text as necessary, using the edition sync function.
147
- updateEdition(undefined, newEdition.withRef(newEditionRef));
148
- // Put the new edition in the book.
149
- book = book.withEditions([
150
- newEdition.getInfo(),
151
- ...book.getEditions(),
152
- ]);
153
- // Update the book.
154
- updateBook(book);
155
- return book;
156
- }
157
- export async function updateLock(edition, uid, content, lock) {
158
- if (!db)
159
- throw NO_DATABASE_CONNECTION;
160
- if (edition.editionRef === undefined)
161
- return false;
162
- if (lock && edition.hasLease(uid, content))
163
- return true;
164
- if (!lock && !edition.hasLease(uid, content))
165
- return true;
166
- await setDoc(doc(db, editionPath(edition.bookRef.id, edition.editionRef.id)), edition.withLock(uid, content, lock).toObject());
167
- return lock;
168
- }
169
- /**
170
- * Persists the edition in the database, creating and deleting chapters as necessary.
171
- * returns a map of DocumentReferences for new chapters so they can be persisted client side.
172
- */
173
- export async function updateEdition(previousEdition, newEdition) {
174
- if (!db)
175
- throw Error("Can't update edition, not connected to Firebase.");
176
- // Get the reference to the edition, fail if we don't have one.
177
- const editionRef = newEdition.getEditionRef();
178
- if (!editionRef)
179
- throw Error('Book given has no ID');
180
- const newChapterRefs = new Map();
181
- // Create any new chapters that aren't in the current edition, and update text if it changed.
182
- for (const newChapter of newEdition.chapters) {
183
- if (newChapter.ref === undefined) {
184
- // Make the new chapter's text.
185
- const newChapterRef = await addDoc(collection(db, editionPath(newEdition.bookRef.id, editionRef.id), 'chapters'), { text: newChapter.text });
186
- // Add the ref of the new chapter to the revised chapter.
187
- newEdition = newEdition.withRevisedChapter(newChapter, newChapter.withRef(newChapterRef));
188
- // Map the chapter ref to it's id.
189
- newChapterRefs.set(newChapter.id, newChapterRef);
190
- }
191
- // If we have a previous version, did the text change? If so, update it.
192
- else {
193
- const previousChapter = previousEdition === undefined
194
- ? undefined
195
- : previousEdition.getChapterByRef(newChapter.ref);
196
- if (previousChapter === undefined ||
197
- newChapter.text !== previousChapter.text) {
198
- await setDoc(doc(db, editionPath(newEdition.bookRef.id, editionRef.id), 'chapters', newChapter.ref.id), { text: newChapter.text });
199
- }
200
- }
201
- }
202
- // Remove any chapters from Firebase that are removed.
203
- if (previousEdition) {
204
- for (const previousChapter of previousEdition.chapters) {
205
- if (previousChapter.ref &&
206
- newEdition.getChapterByRef(previousChapter.ref) === undefined) {
207
- await deleteDoc(previousChapter.ref);
208
- }
209
- }
210
- }
211
- // If the edition's summary info changed, update it.
212
- if (previousEdition !== undefined) {
213
- const previousInfo = previousEdition.getInfo();
214
- const newInfo = newEdition.getInfo();
215
- if (previousInfo && newInfo) {
216
- const previousKeys = Object.keys(previousInfo);
217
- const newKeys = Object.keys(newInfo);
218
- if (previousKeys.length !== newKeys.length ||
219
- !previousKeys.every((key) => previousInfo[key] === newInfo[key])) {
220
- const bookDoc = await getDoc(doc(db, 'books', newEdition.bookRef.id));
221
- if (!bookDoc.exists())
222
- throw Error('Book does not exist');
223
- const book = Book.fromJSON(newEdition.bookRef, bookDoc.data());
224
- updateBook(book.withRevisedEdition(previousEdition, newEdition));
225
- }
226
- }
227
- }
228
- // Finally, update the edition's document.
229
- await setDoc(doc(db, editionPath(newEdition.bookRef.id, editionRef.id)), newEdition.toObject());
230
- return newChapterRefs;
231
- }
232
- export async function updateBook(book) {
233
- if (!db)
234
- throw Error("Can't update book, not connected to Firebase.");
235
- await setDoc(doc(db, 'books', book.getRefID()), book.toJSON());
236
- }
237
- export async function isSubdomainAvailable(subdomain, book) {
238
- if (!db)
239
- throw Error('Not connected to Firebase.');
240
- const matches = await getDocs(query(collection(db, 'books'), where('domain', '==', subdomain)));
241
- return matches.empty || matches.docs[0].id === book.getRefID();
242
- }
243
- export async function publish(edition) {
244
- if (!db)
245
- throw Error('Cannot publish, no database connection');
246
- if (!functions)
247
- throw Error('Cannot publish, no cloud connection');
248
- const editionRef = edition.getEditionRef();
249
- const bookRef = edition.getBookRef();
250
- if (editionRef === undefined)
251
- return `Cannot publish, no edition ID`;
252
- // Get a reference to the publishing function
253
- const publishEdition = httpsCallable(functions, 'publishEdition');
254
- // Call the function, passing
255
- const result = await publishEdition({
256
- bookID: bookRef.id,
257
- editionID: editionRef.id,
258
- });
259
- return result.data;
260
- // Update the edition's published status in the book.
261
- // await updateBook(book.withEditionAsPublished(true, index));
262
- }
@@ -1,5 +0,0 @@
1
- export declare const app: import("@firebase/app").FirebaseApp | undefined;
2
- export declare const auth: import("@firebase/auth").Auth | undefined;
3
- export declare const db: import("@firebase/firestore").Firestore | undefined;
4
- export declare const storage: import("@firebase/storage").FirebaseStorage | undefined;
5
- export declare const functions: import("@firebase/functions").Functions | undefined;
@@ -1,61 +0,0 @@
1
- import type { DocumentReference } from 'firebase/firestore';
2
- import BookMedia from './BookMedia';
3
- import type Edition from './Edition';
4
- /** A replication of edition info */
5
- export type EditionInfo = {
6
- ref: DocumentReference;
7
- summary: string;
8
- number: number;
9
- published: number | null;
10
- editionuids: string[];
11
- chapteruids: string[];
12
- };
13
- export type BookSpecification = {
14
- title: string;
15
- authors: string[];
16
- description: string;
17
- cover: string | null;
18
- published: boolean;
19
- editions: EditionInfo[];
20
- domain: string | null;
21
- uids: string[];
22
- readuids: string[];
23
- };
24
- export default class Book {
25
- readonly ref: DocumentReference;
26
- readonly title: string;
27
- readonly authors: string[];
28
- readonly description: string;
29
- readonly cover: string | null;
30
- readonly published: boolean;
31
- readonly editions: EditionInfo[];
32
- readonly domain: string | null;
33
- readonly uids: string[];
34
- media: BookMedia;
35
- constructor(ref: DocumentReference, title: string, authors: string[], description: string, cover: string | null, editions: EditionInfo[], domain: string | null, uids: string[]);
36
- getMedia(): BookMedia;
37
- static fromJSON(ref: DocumentReference, book: BookSpecification): Book;
38
- toJSON(): BookSpecification;
39
- getSubdomain(): string | null;
40
- withSubdomain(domain: string): Book;
41
- getTitle(): string;
42
- withTitle(title: string): Book;
43
- getDescription(): string;
44
- withDescription(description: string): Book;
45
- getCover(): string | null;
46
- withCover(cover: string | null): Book;
47
- getAuthors(): string[];
48
- withAuthors(authors: string[]): Book;
49
- getRef(): DocumentReference<import("@firebase/firestore").DocumentData>;
50
- getRefID(): string;
51
- getEditionNumberID(number: number): string | undefined;
52
- getLatestPublishedEditionID(): string;
53
- getLatestEditionID(): string | undefined;
54
- getEditions(): EditionInfo[];
55
- getPublishedEditionCount(): number;
56
- isEditor(uid: string): boolean;
57
- withEditors(uids: string[]): Book;
58
- withEditions(revisions: EditionInfo[]): Book;
59
- withRevisedEdition(previous: Edition, revised: Edition): Book;
60
- hasPublishedEdition(): boolean;
61
- }
@@ -1,135 +0,0 @@
1
- import BookMedia from './BookMedia';
2
- export default class Book {
3
- ref;
4
- title;
5
- authors;
6
- description;
7
- cover;
8
- published;
9
- editions;
10
- domain;
11
- uids;
12
- media;
13
- constructor(ref, title, authors, description, cover, editions, domain, uids) {
14
- this.ref = ref;
15
- this.title = title;
16
- this.authors = authors;
17
- this.description = description;
18
- this.cover = cover;
19
- // The published state is always true if some edition's published flag isn't null.
20
- this.published = editions.some((edition) => edition.published !== null);
21
- // We always keep editions in reversed edition number for easy reference.
22
- this.editions = editions.sort((a, b) => a.number - b.number);
23
- this.domain = domain;
24
- this.uids = uids;
25
- this.media = new BookMedia(this);
26
- }
27
- getMedia() {
28
- return this.media;
29
- }
30
- static fromJSON(ref, book) {
31
- return new Book(ref, book.title, book.authors, book.description, book.cover, book.editions, book.domain, book.uids);
32
- }
33
- toJSON() {
34
- const json = {
35
- title: this.title,
36
- authors: this.authors,
37
- description: this.description,
38
- cover: this.cover,
39
- published: this.published,
40
- domain: this.domain,
41
- editions: this.editions,
42
- uids: this.uids,
43
- readuids: Array.from(new Set(this.editions
44
- .map((edition) => [
45
- ...edition.editionuids,
46
- ...edition.chapteruids,
47
- ])
48
- .flat())),
49
- };
50
- return json;
51
- }
52
- getSubdomain() {
53
- return this.domain;
54
- }
55
- withSubdomain(domain) {
56
- return new Book(this.ref, this.title, this.authors, this.description, this.cover, this.editions, domain.length === 0 ? null : domain, this.uids);
57
- }
58
- getTitle() {
59
- return this.title;
60
- }
61
- withTitle(title) {
62
- return new Book(this.ref, title, this.authors, this.description, this.cover, this.editions, this.domain, this.uids);
63
- }
64
- getDescription() {
65
- return this.description;
66
- }
67
- withDescription(description) {
68
- return new Book(this.ref, this.title, this.authors, description, this.cover, this.editions, this.domain, this.uids);
69
- }
70
- getCover() {
71
- return this.cover;
72
- }
73
- withCover(cover) {
74
- return new Book(this.ref, this.title, this.authors, this.description, cover, this.editions, this.domain, this.uids);
75
- }
76
- getAuthors() {
77
- return this.authors;
78
- }
79
- withAuthors(authors) {
80
- return new Book(this.ref, this.title, authors, this.description, this.cover, this.editions, this.domain, this.uids);
81
- }
82
- getRef() {
83
- return this.ref;
84
- }
85
- getRefID() {
86
- return this.ref.id;
87
- }
88
- getEditionNumberID(number) {
89
- // Get the ID corresponding to this number.
90
- const edition = this.editions.find((ed) => ed.number === number);
91
- return edition ? edition.ref.id : undefined;
92
- }
93
- getLatestPublishedEditionID() {
94
- return this.editions.filter((ed) => ed.published !== null)[0]?.ref.id;
95
- }
96
- getLatestEditionID() {
97
- return this.editions[0]?.ref.id;
98
- }
99
- getEditions() {
100
- return this.editions.slice();
101
- }
102
- getPublishedEditionCount() {
103
- return this.editions.filter((edition) => edition.published).length;
104
- }
105
- isEditor(uid) {
106
- return this.uids.includes(uid);
107
- }
108
- withEditors(uids) {
109
- return new Book(this.ref, this.title, this.authors, this.description, this.cover, this.editions, this.domain, uids);
110
- }
111
- withEditions(revisions) {
112
- return new Book(this.ref, this.title, this.authors, this.description, this.cover, revisions, this.domain, this.uids);
113
- }
114
- withRevisedEdition(previous, revised) {
115
- // Get the new info.
116
- const info = revised.getInfo();
117
- if (info === undefined)
118
- return this;
119
- // If no previous addition, just add it.
120
- if (previous === undefined)
121
- return this.withEditions([...this.editions, info]);
122
- // Find the corresponding edition.
123
- const index = this.editions.findIndex((edition) => edition.number === previous.number);
124
- return index < 0
125
- ? this
126
- : this.withEditions([
127
- ...this.editions.slice(0, index),
128
- info,
129
- ...this.editions.slice(index + 1),
130
- ]);
131
- }
132
- hasPublishedEdition() {
133
- return this.editions.some((revision) => revision.published !== null);
134
- }
135
- }
@@ -1,23 +0,0 @@
1
- import type { StorageReference } from 'firebase/storage';
2
- import type Book from './Book';
3
- export type Image = {
4
- url: string;
5
- ref: StorageReference;
6
- };
7
- export default class BookMedia {
8
- readonly book: Book;
9
- _images: Image[] | undefined;
10
- readonly observers: Set<(images: Image[]) => void>;
11
- constructor(book: Book);
12
- notify(observer: (images: Image[]) => void): void;
13
- stopNotifying(observer: (images: Image[]) => void): void;
14
- /** Get all non-thumbnail images. */
15
- getImages(): Promise<Image[]>;
16
- getImagePath(): string;
17
- /** Get a listing of all of the images for the book. */
18
- cacheImages(): Promise<Image[]>;
19
- retrieveImages(): Promise<(Image | undefined)[]>;
20
- getThumbnailURL(url: string, thumbnailRef: StorageReference, error: (message: string) => void, finished: (url: string, thumbnailURL: string) => void, attempt?: number): void;
21
- upload(file: File, progressHandler: (progress: number) => void, errorHandler: (message: string) => void, finishedHandler: (url: string, thumbnailURL: string) => void): void;
22
- remove(image: Image): Promise<Image[] | undefined>;
23
- }
@@ -1,108 +0,0 @@
1
- import { deleteObject, getDownloadURL, listAll, ref, uploadBytes, } from 'firebase/storage';
2
- import { v4 as uuidv4 } from 'uuid';
3
- import { storage } from '../Firebase';
4
- export default class BookMedia {
5
- book;
6
- _images;
7
- // A list of functions to call when the book media changes.
8
- observers = new Set();
9
- constructor(book) {
10
- this.book = book;
11
- }
12
- notify(observer) {
13
- this.observers.add(observer);
14
- // Notify it right away!
15
- this.getImages().then((images) => observer(images));
16
- }
17
- stopNotifying(observer) {
18
- this.observers.delete(observer);
19
- }
20
- /** Get all non-thumbnail images. */
21
- async getImages() {
22
- return this._images === undefined ? this.cacheImages() : this._images;
23
- }
24
- getImagePath() {
25
- return `images/${this.book.getRefID()}/`;
26
- }
27
- /** Get a listing of all of the images for the book. */
28
- async cacheImages() {
29
- if (storage === undefined)
30
- return [];
31
- // Find all the prefixes and items.
32
- this._images = (await this.retrieveImages()).filter((image) => image !== undefined);
33
- // Notify observers
34
- for (const observer of this.observers)
35
- observer(this._images.slice());
36
- return this._images;
37
- }
38
- async retrieveImages() {
39
- if (storage === undefined)
40
- return [];
41
- // Create a reference under which you want to list
42
- const listRef = ref(storage, this.getImagePath());
43
- // Find all the prefixes and items.
44
- return listAll(listRef).then((res) => Promise.all(res.items.map((itemRef) => getDownloadURL(itemRef).then((url) => {
45
- const image = {
46
- url: url,
47
- description: '',
48
- ref: itemRef,
49
- };
50
- if (this._images !== undefined) {
51
- this._images.push(image);
52
- }
53
- return image;
54
- }))));
55
- }
56
- getThumbnailURL(url, thumbnailRef, error, finished, attempt = 0) {
57
- getDownloadURL(thumbnailRef)
58
- .then((thumbnail) => finished(url, thumbnail))
59
- // Try again in a bit.
60
- .catch(() => attempt > 25
61
- ? error("Couldn't get the image URL. Connection issues?")
62
- : setTimeout(() => this.getThumbnailURL(url, thumbnailRef, error, finished, attempt + 1), 250));
63
- }
64
- upload(file, progressHandler, errorHandler, finishedHandler) {
65
- progressHandler;
66
- if (storage === undefined)
67
- return;
68
- // The canonical path format for Bookish images in the store is image/{bookid}/{imageid}
69
- // where {bookid} is the Firestore ID of the book being edited and {imageid} is just a random id.
70
- const imageName = `image-${uuidv4()}`;
71
- const imageRef = ref(storage, `${this.getImagePath()}/${imageName}`);
72
- const thumbnailRef = ref(storage, `${this.getImagePath()}/thumbnails/${imageName}`);
73
- uploadBytes(imageRef, file)
74
- .then((snapshot) => {
75
- getDownloadURL(snapshot.ref)
76
- .then((url) => {
77
- // Give some time for the cloud function to create a thumbnail, then try to get it's URL.
78
- setTimeout(() => this.getThumbnailURL(url, thumbnailRef, errorHandler, finishedHandler), 250);
79
- })
80
- .catch(() => errorHandler('Unable to get image URL.'));
81
- })
82
- .then(() => this.cacheImages());
83
- // This seems to be broken in Firebase right now. Switched above to a no-feedback approach.
84
- // const uploadTask = uploadBytesResumable(imageRef, file);
85
- // uploadTask.on("state_changed",
86
- // // During upload, notify of progress by sending an integer percent complete.
87
- // (snapshot) => progressHandler(Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100)),
88
- // // If there's an error, map it to a message.
89
- // // https://firebase.google.com/docs/storage/web/handle-errors
90
- // (error) => {
91
- // console.error(error);
92
- // errorHandler(
93
- // error.code === "storage/unauthorized" ? "Wrong permissions to upload" :
94
- // error.code === "storage/canceled" ? "Upload canceled" :
95
- // error.code === "storage/quota-exceeded" ? "Storage limit reached" :
96
- // error.code === "storage/unauthenticated" ? "Log in again to upload" :
97
- // "Unknown upload error"
98
- // )
99
- // },
100
- }
101
- async remove(image) {
102
- if (storage === undefined)
103
- return;
104
- const imageRef = ref(storage, image.ref.fullPath);
105
- await deleteObject(imageRef);
106
- return await this.cacheImages();
107
- }
108
- }
@@ -1,7 +0,0 @@
1
- declare enum BookSaveStatus {
2
- Changed = 0,
3
- Saving = 1,
4
- Saved = 2,
5
- Error = 3
6
- }
7
- export default BookSaveStatus;
@@ -1,8 +0,0 @@
1
- var BookSaveStatus;
2
- (function (BookSaveStatus) {
3
- BookSaveStatus[BookSaveStatus["Changed"] = 0] = "Changed";
4
- BookSaveStatus[BookSaveStatus["Saving"] = 1] = "Saving";
5
- BookSaveStatus[BookSaveStatus["Saved"] = 2] = "Saved";
6
- BookSaveStatus[BookSaveStatus["Error"] = 3] = "Error";
7
- })(BookSaveStatus || (BookSaveStatus = {}));
8
- export default BookSaveStatus;