bookish-press 0.7.4 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -9
- package/dist/components/Auth.svelte +29 -39
- package/dist/components/Auth.svelte.d.ts +5 -17
- package/dist/components/BookPreview.svelte +14 -20
- package/dist/components/BookPreview.svelte.d.ts +6 -18
- package/dist/components/Link.svelte +19 -30
- package/dist/components/Link.svelte.d.ts +7 -20
- package/dist/components/app/BookList.svelte +2 -3
- package/dist/components/app/BookList.svelte.d.ts +6 -18
- package/dist/components/app/Button.svelte +12 -8
- package/dist/components/app/Button.svelte.d.ts +10 -23
- package/dist/components/app/Feedback.svelte +4 -4
- package/dist/components/app/Feedback.svelte.d.ts +6 -19
- package/dist/components/app/Head.svelte +2 -2
- package/dist/components/app/Head.svelte.d.ts +6 -19
- package/dist/components/app/Large.svelte +4 -1
- package/dist/components/app/Large.svelte.d.ts +5 -28
- package/dist/components/app/Lead.svelte +4 -1
- package/dist/components/app/Lead.svelte.d.ts +5 -28
- package/dist/components/app/Link.svelte +12 -9
- package/dist/components/app/Link.svelte.d.ts +9 -22
- package/dist/components/app/Options.svelte +8 -6
- package/dist/components/app/Options.svelte.d.ts +8 -20
- package/dist/components/app/Paragraph.svelte +2 -2
- package/dist/components/app/Paragraph.svelte.d.ts +6 -19
- package/dist/components/app/Section.svelte +4 -1
- package/dist/components/app/Section.svelte.d.ts +5 -28
- package/dist/components/app/Table.svelte +4 -1
- package/dist/components/app/Table.svelte.d.ts +5 -28
- package/dist/components/app/TextInput.svelte +10 -8
- package/dist/components/app/TextInput.svelte.d.ts +12 -23
- package/dist/components/chapter/Atom.svelte +4 -7
- package/dist/components/chapter/Atom.svelte.d.ts +6 -19
- package/dist/components/chapter/Block.svelte +21 -23
- package/dist/components/chapter/Block.svelte.d.ts +5 -17
- package/dist/components/chapter/Callout.svelte +3 -5
- package/dist/components/chapter/Callout.svelte.d.ts +5 -17
- package/dist/components/chapter/CaptionedCode.svelte +12 -14
- package/dist/components/chapter/CaptionedCode.svelte.d.ts +5 -17
- package/dist/components/chapter/ChapterBody.svelte +14 -17
- package/dist/components/chapter/ChapterBody.svelte.d.ts +7 -19
- package/dist/components/chapter/ChapterBody.test.d.ts +1 -0
- package/dist/components/chapter/ChapterBody.test.js +85 -0
- package/dist/components/chapter/Citations.svelte +39 -45
- package/dist/components/chapter/Citations.svelte.d.ts +5 -17
- package/dist/components/chapter/Code.svelte +158 -155
- package/dist/components/chapter/Code.svelte.d.ts +10 -23
- package/dist/components/chapter/Comment.svelte +30 -23
- package/dist/components/chapter/Comment.svelte.d.ts +5 -17
- package/dist/components/chapter/Definition.svelte +36 -34
- package/dist/components/chapter/Definition.svelte.d.ts +5 -17
- package/dist/components/chapter/Embed.svelte +78 -72
- package/dist/components/chapter/Embed.svelte.d.ts +8 -20
- package/dist/components/chapter/ErrorMessage.svelte +2 -4
- package/dist/components/chapter/ErrorMessage.svelte.d.ts +5 -17
- package/dist/components/chapter/Figure.svelte +22 -29
- package/dist/components/chapter/Figure.svelte.d.ts +9 -22
- package/dist/components/chapter/Footnote.svelte +40 -32
- package/dist/components/chapter/Footnote.svelte.d.ts +5 -17
- package/dist/components/chapter/Format.svelte +26 -41
- package/dist/components/chapter/Format.svelte.d.ts +7 -18
- package/dist/components/chapter/InlineCode.svelte +7 -8
- package/dist/components/chapter/InlineCode.svelte.d.ts +5 -17
- package/dist/components/chapter/Label.svelte +5 -11
- package/dist/components/chapter/Label.svelte.d.ts +5 -17
- package/dist/components/chapter/LineBreak.svelte +1 -3
- package/dist/components/chapter/LineBreak.svelte.d.ts +5 -17
- package/dist/components/chapter/Link.svelte +17 -23
- package/dist/components/chapter/Link.svelte.d.ts +5 -17
- package/dist/components/chapter/List.svelte +9 -9
- package/dist/components/chapter/List.svelte.d.ts +6 -17
- package/dist/components/chapter/Marginal.svelte +59 -60
- package/dist/components/chapter/Marginal.svelte.d.ts +10 -22
- package/dist/components/chapter/Paragraph.svelte +8 -23
- package/dist/components/chapter/Paragraph.svelte.d.ts +6 -18
- package/dist/components/chapter/Positioned.svelte +2 -4
- package/dist/components/chapter/Positioned.svelte.d.ts +6 -19
- package/dist/components/chapter/Problem.svelte +3 -2
- package/dist/components/chapter/Problem.svelte.d.ts +5 -28
- package/dist/components/chapter/Python.svelte +45 -58
- package/dist/components/chapter/Python.svelte.d.ts +6 -18
- package/dist/components/chapter/Quote.svelte +5 -7
- package/dist/components/chapter/Quote.svelte.d.ts +5 -17
- package/dist/components/chapter/Rule.svelte +1 -3
- package/dist/components/chapter/Rule.svelte.d.ts +5 -17
- package/dist/components/chapter/Table.svelte +6 -8
- package/dist/components/chapter/Table.svelte.d.ts +5 -17
- package/dist/components/chapter/Text.svelte +54 -69
- package/dist/components/chapter/Text.svelte.d.ts +6 -18
- package/dist/components/controls/DarkToggle.svelte +7 -8
- package/dist/components/controls/DarkToggle.svelte.d.ts +6 -18
- package/dist/components/editor/BookishEditor.svelte +583 -761
- package/dist/components/editor/BookishEditor.svelte.d.ts +14 -26
- package/dist/components/editor/CalloutEditor.svelte +3 -3
- package/dist/components/editor/CalloutEditor.svelte.d.ts +5 -17
- package/dist/components/editor/CaptionedCodeEditor.svelte +5 -5
- package/dist/components/editor/CaptionedCodeEditor.svelte.d.ts +5 -17
- package/dist/components/editor/CaretView.svelte +23 -25
- package/dist/components/editor/CaretView.svelte.d.ts +15 -27
- package/dist/components/editor/CitationsEditor.svelte +25 -28
- package/dist/components/editor/CitationsEditor.svelte.d.ts +5 -17
- package/dist/components/editor/ConfirmButton.svelte +9 -6
- package/dist/components/editor/ConfirmButton.svelte.d.ts +8 -21
- package/dist/components/editor/DefinitionEditor.svelte +11 -15
- package/dist/components/editor/DefinitionEditor.svelte.d.ts +5 -17
- package/dist/components/editor/EmbedEditor.svelte +44 -45
- package/dist/components/editor/EmbedEditor.svelte.d.ts +5 -17
- package/dist/components/editor/Icon.svelte +1 -1
- package/dist/components/editor/Icon.svelte.d.ts +5 -17
- package/dist/components/editor/ImageChooser.svelte +15 -18
- package/dist/components/editor/ImageChooser.svelte.d.ts +6 -18
- package/dist/components/editor/ImageThumbnail.svelte +29 -24
- package/dist/components/editor/ImageThumbnail.svelte.d.ts +7 -19
- package/dist/components/editor/InlineCodeEditor.svelte +3 -3
- package/dist/components/editor/InlineCodeEditor.svelte.d.ts +5 -17
- package/dist/components/editor/LabelEditor.svelte +5 -6
- package/dist/components/editor/LabelEditor.svelte.d.ts +5 -17
- package/dist/components/editor/LanguageEditor.svelte +4 -5
- package/dist/components/editor/LanguageEditor.svelte.d.ts +6 -18
- package/dist/components/editor/LinkEditor.svelte +52 -68
- package/dist/components/editor/LinkEditor.svelte.d.ts +5 -17
- package/dist/components/editor/Note.svelte +4 -1
- package/dist/components/editor/Note.svelte.d.ts +5 -28
- package/dist/components/editor/Permissions.svelte +36 -34
- package/dist/components/editor/Permissions.svelte.d.ts +9 -21
- package/dist/components/editor/PositionEditor.svelte +6 -7
- package/dist/components/editor/PositionEditor.svelte.d.ts +6 -18
- package/dist/components/editor/QuoteEditor.svelte +3 -3
- package/dist/components/editor/QuoteEditor.svelte.d.ts +5 -17
- package/dist/components/editor/Switch.svelte +16 -11
- package/dist/components/editor/Switch.svelte.d.ts +9 -21
- package/dist/components/editor/TableEditor.svelte +3 -3
- package/dist/components/editor/TableEditor.svelte.d.ts +5 -17
- package/dist/components/editor/TextEditor.svelte +74 -87
- package/dist/components/editor/TextEditor.svelte.d.ts +13 -25
- package/dist/components/editor/Toggle.svelte +18 -21
- package/dist/components/editor/Toggle.svelte.d.ts +7 -20
- package/dist/components/editor/Toolbar.svelte +140 -145
- package/dist/components/editor/Toolbar.svelte.d.ts +5 -17
- package/dist/components/editor/ToolbarGroup.svelte +4 -4
- package/dist/components/editor/ToolbarGroup.svelte.d.ts +6 -19
- package/dist/components/editor/ToolbarSpacer.svelte +1 -1
- package/dist/components/editor/ToolbarSpacer.svelte.d.ts +22 -21
- package/dist/components/editor/URLEditor.svelte +3 -5
- package/dist/components/editor/URLEditor.svelte.d.ts +7 -19
- package/dist/components/page/Acknowledgements.svelte +14 -8
- package/dist/components/page/Acknowledgements.svelte.d.ts +3 -16
- package/dist/components/page/Analytics.svelte +2 -3
- package/dist/components/page/Analytics.svelte.d.ts +6 -17
- package/dist/components/page/Authors.svelte +29 -29
- package/dist/components/page/Authors.svelte.d.ts +11 -23
- package/dist/components/page/BookLoader.svelte +47 -43
- package/dist/components/page/BookLoader.svelte.d.ts +5 -17
- package/dist/components/page/BulkReferenceEditor.svelte +43 -26
- package/dist/components/page/BulkReferenceEditor.svelte.d.ts +3 -16
- package/dist/components/page/Chapter.svelte +224 -249
- package/dist/components/page/Chapter.svelte.d.ts +6 -18
- package/dist/components/page/ChapterContext.d.ts +3 -1
- package/dist/components/page/ChapterNumber.svelte +4 -1
- package/dist/components/page/ChapterNumber.svelte.d.ts +5 -28
- package/dist/components/page/ChapterTitle.svelte +4 -4
- package/dist/components/page/ChapterTitle.svelte.d.ts +6 -19
- package/dist/components/page/Contexts.js +2 -2
- package/dist/components/page/DefinitionView.svelte +51 -44
- package/dist/components/page/DefinitionView.svelte.d.ts +6 -18
- package/dist/components/page/Description.svelte +10 -4
- package/dist/components/page/Description.svelte.d.ts +16 -14
- package/dist/components/page/DownloadEPUB.svelte +234 -0
- package/dist/components/page/DownloadEPUB.svelte.d.ts +3 -0
- package/dist/components/page/EditableHeader.svelte +4 -6
- package/dist/components/page/EditableHeader.svelte.d.ts +7 -18
- package/dist/components/page/Edition.svelte +57 -71
- package/dist/components/page/Edition.svelte.d.ts +7 -20
- package/dist/components/page/EditionLoader.svelte +119 -82
- package/dist/components/page/EditionLoader.svelte.d.ts +6 -19
- package/dist/components/page/Editions.svelte +26 -31
- package/dist/components/page/Editions.svelte.d.ts +5 -17
- package/dist/components/page/Glossary.svelte +31 -35
- package/dist/components/page/Glossary.svelte.d.ts +3 -16
- package/dist/components/page/Header.svelte +43 -49
- package/dist/components/page/Header.svelte.d.ts +19 -30
- package/dist/components/page/Index.svelte +46 -46
- package/dist/components/page/Index.svelte.d.ts +3 -16
- package/dist/components/page/Instructions.svelte +2 -2
- package/dist/components/page/Instructions.svelte.d.ts +6 -19
- package/dist/components/page/License.svelte +13 -7
- package/dist/components/page/License.svelte.d.ts +16 -14
- package/dist/components/page/Loading.svelte +9 -9
- package/dist/components/page/Loading.svelte.d.ts +22 -21
- package/dist/components/page/Media.svelte +36 -27
- package/dist/components/page/Media.svelte.d.ts +3 -16
- package/dist/components/page/MediaPreview.svelte +22 -19
- package/dist/components/page/MediaPreview.svelte.d.ts +8 -21
- package/dist/components/page/Muted.svelte +4 -1
- package/dist/components/page/Muted.svelte.d.ts +5 -28
- package/dist/components/page/Outline.svelte +75 -97
- package/dist/components/page/Outline.svelte.d.ts +8 -20
- package/dist/components/page/Page.svelte +23 -33
- package/dist/components/page/Page.svelte.d.ts +7 -20
- package/dist/components/page/PageHeader.svelte +2 -2
- package/dist/components/page/PageHeader.svelte.d.ts +6 -19
- package/dist/components/page/PageParagraph.svelte +4 -1
- package/dist/components/page/PageParagraph.svelte.d.ts +5 -28
- package/dist/components/page/PossibleChapter.svelte +7 -7
- package/dist/components/page/PossibleChapter.svelte.d.ts +3 -16
- package/dist/components/page/PossibleReference.svelte +4 -5
- package/dist/components/page/PossibleReference.svelte.d.ts +6 -18
- package/dist/components/page/Print.svelte +11 -12
- package/dist/components/page/Print.svelte.d.ts +3 -16
- package/dist/components/page/Publish.svelte +47 -47
- package/dist/components/page/Publish.svelte.d.ts +3 -16
- package/dist/components/page/Reference.svelte +24 -35
- package/dist/components/page/Reference.svelte.d.ts +6 -18
- package/dist/components/page/References.svelte +21 -22
- package/dist/components/page/References.svelte.d.ts +3 -16
- package/dist/components/page/Rows.svelte +5 -2
- package/dist/components/page/Rows.svelte.d.ts +5 -28
- package/dist/components/page/Search.svelte +59 -61
- package/dist/components/page/Search.svelte.d.ts +3 -16
- package/dist/components/page/Status.svelte +2 -2
- package/dist/components/page/Status.svelte.d.ts +16 -14
- package/dist/components/page/SubdomainEditor.svelte +11 -11
- package/dist/components/page/SubdomainEditor.svelte.d.ts +16 -14
- package/dist/components/page/TableOfContents.svelte +157 -124
- package/dist/components/page/TableOfContents.svelte.d.ts +3 -16
- package/dist/components/page/TableOfContentsImage.svelte +6 -7
- package/dist/components/page/TableOfContentsImage.svelte.d.ts +6 -18
- package/dist/components/page/TableOfContentsRow.svelte +32 -32
- package/dist/components/page/TableOfContentsRow.svelte.d.ts +10 -22
- package/dist/components/page/ThemeEditor.svelte +35 -28
- package/dist/components/page/ThemeEditor.svelte.d.ts +3 -16
- package/dist/components/page/ThemeEditorPreview.svelte +11 -13
- package/dist/components/page/ThemeEditorPreview.svelte.d.ts +5 -17
- package/dist/components/page/ThemeSetEditor.svelte +4 -6
- package/dist/components/page/ThemeSetEditor.svelte.d.ts +7 -19
- package/dist/components/page/ThemeVariableEditor.svelte +9 -11
- package/dist/components/page/ThemeVariableEditor.svelte.d.ts +7 -19
- package/dist/components/page/Title.svelte +4 -1
- package/dist/components/page/Title.svelte.d.ts +5 -28
- package/dist/components/page/Unknown.svelte +11 -8
- package/dist/components/page/Unknown.svelte.d.ts +5 -17
- package/dist/epub/build.d.ts +39 -0
- package/dist/epub/build.js +143 -0
- package/dist/epub/build.test.d.ts +1 -0
- package/dist/epub/build.test.js +411 -0
- package/dist/epub/images.d.ts +79 -0
- package/dist/epub/images.js +260 -0
- package/dist/epub/images.test.d.ts +1 -0
- package/dist/epub/images.test.js +129 -0
- package/dist/epub/package.d.ts +75 -0
- package/dist/epub/package.js +392 -0
- package/dist/epub/stylesheet.test.d.ts +1 -0
- package/dist/epub/stylesheet.test.js +243 -0
- package/dist/epub/xhtml.d.ts +69 -0
- package/dist/epub/xhtml.js +367 -0
- package/dist/epub/xhtml.test.d.ts +1 -0
- package/dist/epub/xhtml.test.js +283 -0
- package/dist/epub/zip.d.ts +35 -0
- package/dist/epub/zip.js +202 -0
- package/dist/epub/zip.test.d.ts +1 -0
- package/dist/epub/zip.test.js +171 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models/Firebase.js +18 -4
- package/dist/models/book/Book.js +2 -1
- package/dist/models/book/BookMedia.js +1 -2
- package/dist/models/book/Chapter.js +3 -2
- package/dist/models/book/ChapterID.d.ts +1 -1
- package/dist/models/book/Edition.d.ts +1 -1
- package/dist/models/book/Edition.js +6 -1
- package/dist/models/chapter/BlocksNode.js +3 -1
- package/dist/models/chapter/BlocksNode.test.js +5 -1
- package/dist/models/chapter/Node.test.js +2 -2
- package/dist/models/chapter/TextNode.js +8 -5
- package/dist/models/chapter/TextNode.test.js +8 -0
- package/package.json +36 -22
package/README.md
CHANGED
|
@@ -6,6 +6,50 @@ Bookish is a framework and platform for writing and publishing web-based books.
|
|
|
6
6
|
|
|
7
7
|
I'm working on a 1.0 of the platform at [bookish.press](https://bookish.press) and expect to maintain the platform for the foreseeable future. Let me know if you'd like to help!
|
|
8
8
|
|
|
9
|
+
## Hosting architecture
|
|
10
|
+
|
|
11
|
+
The app is a SvelteKit app. Server-side rendering runs on a [Cloud Run](https://cloud.google.com/run) service named `bookish-ssr` (region `us-central1`) in each Firebase project; Firebase Hosting serves the static client assets from `build/client` and rewrites everything else to that service (see `firebase.json`). The `stage` and `release` scripts handle both: they build the app locally with the environment-specific `.env` (which is inlined at build time), deploy the resulting `build/` to Cloud Run (see `Dockerfile` and `.gcloudignore`), and then run `firebase deploy` for hosting, rules, and functions.
|
|
12
|
+
|
|
13
|
+
One-time setup on a new machine: install the [gcloud CLI](https://cloud.google.com/sdk/docs/install) and run `gcloud auth login`. (This replaced the experimental Firebase Hosting "web frameworks" integration, which required `firebase experiments:enable webframeworks` and capped the Vite version; the old auto-generated `ssrbookishprod` Cloud Function can be deleted once the Cloud Run deploy is verified.)
|
|
14
|
+
|
|
15
|
+
## The demo book
|
|
16
|
+
|
|
17
|
+
`npm run demo` seeds a book that uses every feature Bookish has into a set of
|
|
18
|
+
dedicated emulators, then serves it at <http://localhost:5173/demo>. Nothing is
|
|
19
|
+
uploaded and no sign-in is needed to read it; sign in as `demo@example.com` at
|
|
20
|
+
`/login` to edit it at `/write/demo/1`.
|
|
21
|
+
|
|
22
|
+
It exists so a change to the reading experience can be checked against
|
|
23
|
+
something real without hunting for a book that happens to exercise it. The
|
|
24
|
+
chapters cover every Bookdown construct — formatting, links of each kind,
|
|
25
|
+
footnotes, citations, definitions, lists, tables, quotes, callouts, code,
|
|
26
|
+
symbols, labels, comments — and the images are chosen to stress a small screen:
|
|
27
|
+
a photograph with fine texture, a diagram of hairlines, a stepped grey wedge,
|
|
28
|
+
extreme aspect ratios, transparency, and an SVG. That makes it the fastest way
|
|
29
|
+
to see what an EPUB export actually looks like on an e-reader.
|
|
30
|
+
|
|
31
|
+
The content lives in `scripts/demo-book.js` and the images are drawn by
|
|
32
|
+
`scripts/demo-images.js` rather than committed. Chapters must not use the ids
|
|
33
|
+
the reader reserves for its built-in pages (`references`, `search`, `media`,
|
|
34
|
+
`index`, `glossary`, `unknown`, `cover`); the seed script refuses to run if one
|
|
35
|
+
does.
|
|
36
|
+
|
|
37
|
+
It uses the offset emulator ports from `firebase.test.json`, so it does not
|
|
38
|
+
collide with another project's emulators on the default ports, and it builds
|
|
39
|
+
the app rather than running `vite dev` — the reader route's server render pulls
|
|
40
|
+
the chapter model through a module cycle that Vite's dev SSR evaluator cannot
|
|
41
|
+
order, though the production build resolves it fine.
|
|
42
|
+
|
|
43
|
+
## The demo book
|
|
44
|
+
|
|
45
|
+
`npm run demo` seeds a book that uses every feature Bookish has into a set of dedicated emulators, then serves it at <http://localhost:5173/demo>. Nothing is uploaded and no sign-in is needed to read it; sign in as `demo@example.com` at `/login` to edit it at `/write/demo/1`.
|
|
46
|
+
|
|
47
|
+
It exists so a change to the reading experience can be checked against something real without hunting for a book that happens to exercise it. The chapters cover every Bookdown construct — formatting, links of each kind, footnotes, citations, definitions, lists, tables, quotes, callouts, code, symbols, labels, comments — and the images are chosen to stress a small screen: a photograph with fine texture, a diagram of hairlines, a stepped grey wedge, extreme aspect ratios, transparency, and an SVG. That makes it the fastest way to see what an EPUB export actually looks like on an e-reader.
|
|
48
|
+
|
|
49
|
+
The content lives in `scripts/demo-book.js` and the images are drawn by `scripts/demo-images.js` rather than committed. Chapters must not use the ids the reader reserves for its built-in pages (`references`, `search`, `media`, `index`, `glossary`, `unknown`, `cover`); the seed script refuses to run if one does.
|
|
50
|
+
|
|
51
|
+
It uses the offset emulator ports from `firebase.test.json`, so it doesn't collide with another project's emulators on the default ports, and it builds the app rather than running `vite dev` — the reader route's server render pulls the chapter model through a module cycle that Vite's dev SSR evaluator can't order, though the production build resolves it fine.
|
|
52
|
+
|
|
9
53
|
## Deployment notes
|
|
10
54
|
|
|
11
55
|
There are two major components to Bookish: the authoring platform and the reading front end. Changes to the authoring platform that do not affect reading can be verified and deployed to Firebase without any other coordination. However, changes to the reading experience have downstream dependencies that need to be managed. Here's the general deployment workflow, which I'm currently using as reminders for myself:
|
|
@@ -13,14 +57,17 @@ There are two major components to Bookish: the authoring platform and the readin
|
|
|
13
57
|
0. Ensure you're working in the `dev` branch
|
|
14
58
|
1. Fix bugs, add features
|
|
15
59
|
2. Ensure there are no type errors (`npm run check`) or failed tests (`npm run test`).
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
60
|
+
3. Test with emulator (`npm run emu`), if possible. (Some features aren't possible to perfectly emulate, such as authentication, hosting configurations, permissions.)
|
|
61
|
+
4. Test on the [staging server](https://bookish-dev-21ac3.web.app/`) (`npm run stage`).
|
|
62
|
+
5. Bump the version in `package.json`
|
|
63
|
+
6. Describe the changes in `CHANGELOG.md`, linking to any issues closed
|
|
64
|
+
7. Commit changes to `dev`, referring to any issues addressed
|
|
65
|
+
8. Release to production (`npm run release`)
|
|
66
|
+
9. Verify the change in production on [bookish.press](https://bookish.press)
|
|
67
|
+
10. Merge dev to main (`npm run merge`)
|
|
68
|
+
|
|
69
|
+
> **Svelte 5 note**: as of 0.8.0, `bookish-press` requires Svelte 5 (declared as a peer dependency), which is a breaking change for consumers. Until `bookish-reader` has been migrated to Svelte 5, publish with `npm publish --tag next` so `latest` keeps pointing at the last Svelte 4 compatible release; flip the tag once the reader has migrated. The `0.7.x` branch exists for emergency maintenance releases of the Svelte 4 line.
|
|
70
|
+
|
|
24
71
|
10. If any of the changes affected the reading experience (essentially if any `.svelte` file or its dependencies in `/src/lib/components` changed), then we need to update the reader package for authors who pre-build their books manually:
|
|
25
72
|
1. Update the bookish package with the Sveltekit package tooling (`npm run package`)
|
|
26
73
|
2. Publish the package to npm (`npm publish`)
|
|
@@ -33,4 +80,4 @@ There are two major components to Bookish: the authoring platform and the readin
|
|
|
33
80
|
1. Cloning the reader repo: `git clone https://github.com/amyjko/bookish-reader`
|
|
34
81
|
2. Entering the repo directory: `cd bookish-reader`
|
|
35
82
|
3. Binding the book: `bind.sh`
|
|
36
|
-
4. Deploying the bound book in the newly created `build` folder to wherever it's hosted.
|
|
83
|
+
4. Deploying the bound book in the newly created `build` folder to wherever it's hosted.
|
|
@@ -1,55 +1,45 @@
|
|
|
1
|
-
<script>import { sendSignInLinkToEmail } from
|
|
2
|
-
import { onDestroy, setContext } from
|
|
3
|
-
import { writable } from
|
|
4
|
-
import { auth } from
|
|
5
|
-
import { USER } from
|
|
6
|
-
|
|
7
|
-
let loading = true;
|
|
8
|
-
// The store that tracks the auth context.
|
|
1
|
+
<script lang="ts">import { sendSignInLinkToEmail } from "firebase/auth";
|
|
2
|
+
import { onDestroy, setContext } from "svelte";
|
|
3
|
+
import { writable } from "svelte/store";
|
|
4
|
+
import { auth } from "../models/Firebase";
|
|
5
|
+
import { USER } from "./page/Contexts";
|
|
6
|
+
let { children } = $props();
|
|
7
|
+
let loading = $state(true);
|
|
9
8
|
const authentication = writable({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
user: null,
|
|
10
|
+
loading: true,
|
|
11
|
+
login,
|
|
12
|
+
logout
|
|
14
13
|
});
|
|
15
|
-
// Login using Firebase's password-less email verification
|
|
16
14
|
async function login(email) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// Remember the email in local storage so we don't have to ask for it again
|
|
26
|
-
// after returning to the link above.
|
|
27
|
-
window.localStorage.setItem('email', email);
|
|
28
|
-
}
|
|
15
|
+
if (auth) {
|
|
16
|
+
const actionCodeSettings = {
|
|
17
|
+
url: location.origin + "/confirm",
|
|
18
|
+
handleCodeInApp: true
|
|
19
|
+
};
|
|
20
|
+
await sendSignInLinkToEmail(auth, email, actionCodeSettings);
|
|
21
|
+
window.localStorage.setItem("email", email);
|
|
22
|
+
}
|
|
29
23
|
}
|
|
30
24
|
function updateAuth(user) {
|
|
31
|
-
|
|
25
|
+
authentication.set({ user, loading, login, logout });
|
|
32
26
|
}
|
|
33
|
-
// Logout using Firebase's authentication framework.
|
|
34
27
|
function logout() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
if (auth) {
|
|
29
|
+
return auth.signOut().then(() => updateAuth(null));
|
|
30
|
+
}
|
|
38
31
|
}
|
|
39
|
-
// On mount, subscribe to authentication changes.
|
|
40
32
|
if (auth) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
onDestroy(unsubscribe);
|
|
33
|
+
const unsubscribe = auth.onAuthStateChanged((user) => {
|
|
34
|
+
loading = false;
|
|
35
|
+
updateAuth(user);
|
|
36
|
+
});
|
|
37
|
+
onDestroy(unsubscribe);
|
|
47
38
|
}
|
|
48
|
-
// Expose the state and the login/logout functionality.
|
|
49
39
|
setContext(USER, authentication);
|
|
50
40
|
</script>
|
|
51
41
|
|
|
52
42
|
<!-- Wrap whatever children are given in this context. -->
|
|
53
43
|
{#if loading === false}
|
|
54
|
-
|
|
44
|
+
{@render children?.()}
|
|
55
45
|
{/if}
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
props: Record<string, never>;
|
|
4
|
-
events: {
|
|
5
|
-
[evt: string]: CustomEvent<any>;
|
|
6
|
-
};
|
|
7
|
-
slots: {
|
|
8
|
-
default: {};
|
|
9
|
-
};
|
|
10
|
-
exports?: {} | undefined;
|
|
11
|
-
bindings?: string | undefined;
|
|
12
|
-
};
|
|
13
|
-
export type AuthProps = typeof __propDef.props;
|
|
14
|
-
export type AuthEvents = typeof __propDef.events;
|
|
15
|
-
export type AuthSlots = typeof __propDef.slots;
|
|
16
|
-
export default class Auth extends SvelteComponent<AuthProps, AuthEvents, AuthSlots> {
|
|
1
|
+
interface Props {
|
|
2
|
+
children?: import('svelte').Snippet;
|
|
17
3
|
}
|
|
18
|
-
|
|
4
|
+
declare const Auth: import("svelte").Component<Props, {}, "">;
|
|
5
|
+
type Auth = ReturnType<typeof Auth>;
|
|
6
|
+
export default Auth;
|
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
<script>import EmbedNode from
|
|
2
|
-
import Parser from
|
|
3
|
-
import ChapterBody from
|
|
4
|
-
import Embed from
|
|
5
|
-
import Link from
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
$: url =
|
|
16
|
-
subdomain === null || write
|
|
17
|
-
? refID === undefined
|
|
18
|
-
? ''
|
|
19
|
-
: (write ? '/write/' : '/') + refID
|
|
20
|
-
: `/${subdomain}`;
|
|
1
|
+
<script lang="ts">import EmbedNode from "../models/chapter/EmbedNode";
|
|
2
|
+
import Parser from "../models/chapter/Parser";
|
|
3
|
+
import ChapterBody from "./chapter/ChapterBody.svelte";
|
|
4
|
+
import Embed from "./chapter/Embed.svelte";
|
|
5
|
+
import Link from "./app/Link.svelte";
|
|
6
|
+
let { book, write = false } = $props();
|
|
7
|
+
let refID = $derived(book.getID());
|
|
8
|
+
let cover = $derived(book.getCover());
|
|
9
|
+
let authors = $derived(book.getAuthors());
|
|
10
|
+
let description = $derived(book.getDescription());
|
|
11
|
+
let subdomain = $derived(book.getSubdomain());
|
|
12
|
+
let title = $derived(book.getTitle());
|
|
13
|
+
let embed = $derived(cover === null ? null : Parser.parseEmbed(void 0, cover));
|
|
14
|
+
let url = $derived(subdomain === null || write ? refID === void 0 ? "" : (write ? "/write/" : "/") + refID : `/${subdomain}`);
|
|
21
15
|
</script>
|
|
22
16
|
|
|
23
17
|
<article class="book-preview">
|
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
import type Book from '../models/book/Book';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
write?: boolean;
|
|
7
|
-
};
|
|
8
|
-
events: {
|
|
9
|
-
[evt: string]: CustomEvent<any>;
|
|
10
|
-
};
|
|
11
|
-
slots: {};
|
|
12
|
-
exports?: {} | undefined;
|
|
13
|
-
bindings?: string | undefined;
|
|
14
|
-
};
|
|
15
|
-
export type BookPreviewProps = typeof __propDef.props;
|
|
16
|
-
export type BookPreviewEvents = typeof __propDef.events;
|
|
17
|
-
export type BookPreviewSlots = typeof __propDef.slots;
|
|
18
|
-
export default class BookPreview extends SvelteComponent<BookPreviewProps, BookPreviewEvents, BookPreviewSlots> {
|
|
2
|
+
interface Props {
|
|
3
|
+
book: Book;
|
|
4
|
+
write?: boolean;
|
|
19
5
|
}
|
|
20
|
-
|
|
6
|
+
declare const BookPreview: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type BookPreview = ReturnType<typeof BookPreview>;
|
|
8
|
+
export default BookPreview;
|
|
@@ -1,41 +1,30 @@
|
|
|
1
|
-
<script>import { page } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
let link;
|
|
1
|
+
<script lang="ts">import { page } from "$app/state";
|
|
2
|
+
let { to, linked = true, children } = $props();
|
|
3
|
+
let link = $state();
|
|
5
4
|
function scroll(event) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// No anchor? Bail.
|
|
19
|
-
if (anchor === null)
|
|
20
|
-
return;
|
|
21
|
-
// Scroll to the anchor.
|
|
22
|
-
window.scrollTo({
|
|
23
|
-
top: anchor.offsetTop,
|
|
24
|
-
behavior: 'smooth',
|
|
25
|
-
});
|
|
26
|
-
// Update the hash (without scrolling)
|
|
27
|
-
history.pushState({}, '', hash);
|
|
5
|
+
if (link === void 0) return;
|
|
6
|
+
const hash = new URL(link.href).hash;
|
|
7
|
+
if (hash === "") return;
|
|
8
|
+
event.preventDefault();
|
|
9
|
+
const anchorId = new URL(link.href).hash.replace("#", "");
|
|
10
|
+
const anchor = document.getElementById(anchorId);
|
|
11
|
+
if (anchor === null) return;
|
|
12
|
+
window.scrollTo({
|
|
13
|
+
top: anchor.offsetTop,
|
|
14
|
+
behavior: "smooth"
|
|
15
|
+
});
|
|
16
|
+
history.pushState({}, "", hash);
|
|
28
17
|
}
|
|
29
18
|
</script>
|
|
30
19
|
|
|
31
|
-
{#if !linked ||
|
|
32
|
-
|
|
20
|
+
{#if !linked || page.url.pathname === (to.charAt(to.length - 1) === '/' ? to.substring(0, to.length - 1) : to)}
|
|
21
|
+
{@render children?.()}
|
|
33
22
|
{:else}
|
|
34
23
|
<a
|
|
35
24
|
href={to}
|
|
36
25
|
bind:this={link}
|
|
37
|
-
|
|
38
|
-
target={to.startsWith('http') ? '_blank' : null}
|
|
26
|
+
onclick={(event) => scroll(event)}
|
|
27
|
+
target={to.startsWith('http') ? '_blank' : null}>{@render children?.()}</a
|
|
39
28
|
>
|
|
40
29
|
{/if}
|
|
41
30
|
|
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
linked?: boolean;
|
|
6
|
-
};
|
|
7
|
-
events: {
|
|
8
|
-
[evt: string]: CustomEvent<any>;
|
|
9
|
-
};
|
|
10
|
-
slots: {
|
|
11
|
-
default: {};
|
|
12
|
-
};
|
|
13
|
-
exports?: {} | undefined;
|
|
14
|
-
bindings?: string | undefined;
|
|
15
|
-
};
|
|
16
|
-
export type LinkProps = typeof __propDef.props;
|
|
17
|
-
export type LinkEvents = typeof __propDef.events;
|
|
18
|
-
export type LinkSlots = typeof __propDef.slots;
|
|
19
|
-
export default class Link extends SvelteComponent<LinkProps, LinkEvents, LinkSlots> {
|
|
1
|
+
interface Props {
|
|
2
|
+
to: string;
|
|
3
|
+
linked?: boolean;
|
|
4
|
+
children?: import('svelte').Snippet;
|
|
20
5
|
}
|
|
21
|
-
|
|
6
|
+
declare const Link: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type Link = ReturnType<typeof Link>;
|
|
8
|
+
export default Link;
|
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
import type Book from '../../models/book/Book';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
write: boolean;
|
|
7
|
-
};
|
|
8
|
-
events: {
|
|
9
|
-
[evt: string]: CustomEvent<any>;
|
|
10
|
-
};
|
|
11
|
-
slots: {};
|
|
12
|
-
exports?: {} | undefined;
|
|
13
|
-
bindings?: string | undefined;
|
|
14
|
-
};
|
|
15
|
-
export type BookListProps = typeof __propDef.props;
|
|
16
|
-
export type BookListEvents = typeof __propDef.events;
|
|
17
|
-
export type BookListSlots = typeof __propDef.slots;
|
|
18
|
-
export default class BookList extends SvelteComponent<BookListProps, BookListEvents, BookListSlots> {
|
|
2
|
+
interface Props {
|
|
3
|
+
books: Book[];
|
|
4
|
+
write: boolean;
|
|
19
5
|
}
|
|
20
|
-
|
|
6
|
+
declare const BookList: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type BookList = ReturnType<typeof BookList>;
|
|
8
|
+
export default BookList;
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<script lang="ts">let {
|
|
2
|
+
type = null,
|
|
3
|
+
tooltip,
|
|
4
|
+
disabled = false,
|
|
5
|
+
command,
|
|
6
|
+
class: classes,
|
|
7
|
+
children
|
|
8
|
+
} = $props();
|
|
5
9
|
</script>
|
|
6
10
|
|
|
7
11
|
<button
|
|
8
|
-
class={
|
|
12
|
+
class={classes}
|
|
9
13
|
title={tooltip}
|
|
10
14
|
aria-label={tooltip}
|
|
11
15
|
{type}
|
|
12
16
|
{disabled}
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
onmousedown={command}
|
|
18
|
+
onkeypress={(event) =>
|
|
15
19
|
event.key === ' ' || event.key === 'Enter' ? command() : undefined}
|
|
16
20
|
>
|
|
17
|
-
|
|
21
|
+
{@render children?.()}
|
|
18
22
|
</button>
|
|
19
23
|
|
|
20
24
|
<style>
|
|
@@ -1,24 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
command: () => void;
|
|
9
|
-
};
|
|
10
|
-
events: {
|
|
11
|
-
[evt: string]: CustomEvent<any>;
|
|
12
|
-
};
|
|
13
|
-
slots: {
|
|
14
|
-
default: {};
|
|
15
|
-
};
|
|
16
|
-
exports?: undefined;
|
|
17
|
-
bindings?: undefined;
|
|
18
|
-
};
|
|
19
|
-
export type ButtonProps = typeof __propDef.props;
|
|
20
|
-
export type ButtonEvents = typeof __propDef.events;
|
|
21
|
-
export type ButtonSlots = typeof __propDef.slots;
|
|
22
|
-
export default class Button extends SvelteComponent<ButtonProps, ButtonEvents, ButtonSlots> {
|
|
1
|
+
interface Props {
|
|
2
|
+
type?: 'submit' | 'button' | null;
|
|
3
|
+
tooltip: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
command: () => void;
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: import('svelte').Snippet;
|
|
23
8
|
}
|
|
24
|
-
|
|
9
|
+
declare const Button: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type Button = ReturnType<typeof Button>;
|
|
11
|
+
export default Button;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<script>import Large from
|
|
2
|
-
|
|
1
|
+
<script lang="ts">import Large from "./Large.svelte";
|
|
2
|
+
let { error = false, children } = $props();
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
{#if error}
|
|
6
|
-
<p role="alert"
|
|
6
|
+
<p role="alert">{@render children?.()}</p>
|
|
7
7
|
{:else}
|
|
8
|
-
<p role="status" aria-live="polite"><Large
|
|
8
|
+
<p role="status" aria-live="polite"><Large>{@render children?.()}</Large></p>
|
|
9
9
|
{/if}
|
|
10
10
|
|
|
11
11
|
<style>
|
|
@@ -1,20 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
error?: boolean;
|
|
5
|
-
};
|
|
6
|
-
events: {
|
|
7
|
-
[evt: string]: CustomEvent<any>;
|
|
8
|
-
};
|
|
9
|
-
slots: {
|
|
10
|
-
default: {};
|
|
11
|
-
};
|
|
12
|
-
exports?: {} | undefined;
|
|
13
|
-
bindings?: string | undefined;
|
|
14
|
-
};
|
|
15
|
-
export type FeedbackProps = typeof __propDef.props;
|
|
16
|
-
export type FeedbackEvents = typeof __propDef.events;
|
|
17
|
-
export type FeedbackSlots = typeof __propDef.slots;
|
|
18
|
-
export default class Feedback extends SvelteComponent<FeedbackProps, FeedbackEvents, FeedbackSlots> {
|
|
1
|
+
interface Props {
|
|
2
|
+
error?: boolean;
|
|
3
|
+
children?: import('svelte').Snippet;
|
|
19
4
|
}
|
|
20
|
-
|
|
5
|
+
declare const Feedback: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type Feedback = ReturnType<typeof Feedback>;
|
|
7
|
+
export default Feedback;
|
|
@@ -1,20 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
id?: string | null;
|
|
5
|
-
};
|
|
6
|
-
events: {
|
|
7
|
-
[evt: string]: CustomEvent<any>;
|
|
8
|
-
};
|
|
9
|
-
slots: {
|
|
10
|
-
default: {};
|
|
11
|
-
};
|
|
12
|
-
exports?: {} | undefined;
|
|
13
|
-
bindings?: string | undefined;
|
|
14
|
-
};
|
|
15
|
-
export type HeadProps = typeof __propDef.props;
|
|
16
|
-
export type HeadEvents = typeof __propDef.events;
|
|
17
|
-
export type HeadSlots = typeof __propDef.slots;
|
|
18
|
-
export default class Head extends SvelteComponent<HeadProps, HeadEvents, HeadSlots> {
|
|
1
|
+
interface Props {
|
|
2
|
+
id?: string | null;
|
|
3
|
+
children?: import('svelte').Snippet;
|
|
19
4
|
}
|
|
20
|
-
|
|
5
|
+
declare const Head: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type Head = ReturnType<typeof Head>;
|
|
7
|
+
export default Head;
|
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/** @typedef {typeof __propDef.slots} LargeSlots */
|
|
4
|
-
export default class Large extends SvelteComponent<{
|
|
5
|
-
[x: string]: never;
|
|
6
|
-
}, {
|
|
7
|
-
[evt: string]: CustomEvent<any>;
|
|
8
|
-
}, {
|
|
9
|
-
default: {};
|
|
10
|
-
}> {
|
|
1
|
+
interface Props {
|
|
2
|
+
children?: import('svelte').Snippet;
|
|
11
3
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
import { SvelteComponent } from "svelte";
|
|
16
|
-
declare const __propDef: {
|
|
17
|
-
props: {
|
|
18
|
-
[x: string]: never;
|
|
19
|
-
};
|
|
20
|
-
events: {
|
|
21
|
-
[evt: string]: CustomEvent<any>;
|
|
22
|
-
};
|
|
23
|
-
slots: {
|
|
24
|
-
default: {};
|
|
25
|
-
};
|
|
26
|
-
exports?: undefined;
|
|
27
|
-
bindings?: undefined;
|
|
28
|
-
};
|
|
29
|
-
export {};
|
|
4
|
+
declare const Large: import("svelte").Component<Props, {}, "">;
|
|
5
|
+
type Large = ReturnType<typeof Large>;
|
|
6
|
+
export default Large;
|
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/** @typedef {typeof __propDef.slots} LeadSlots */
|
|
4
|
-
export default class Lead extends SvelteComponent<{
|
|
5
|
-
[x: string]: never;
|
|
6
|
-
}, {
|
|
7
|
-
[evt: string]: CustomEvent<any>;
|
|
8
|
-
}, {
|
|
9
|
-
default: {};
|
|
10
|
-
}> {
|
|
1
|
+
interface Props {
|
|
2
|
+
children?: import('svelte').Snippet;
|
|
11
3
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
import { SvelteComponent } from "svelte";
|
|
16
|
-
declare const __propDef: {
|
|
17
|
-
props: {
|
|
18
|
-
[x: string]: never;
|
|
19
|
-
};
|
|
20
|
-
events: {
|
|
21
|
-
[evt: string]: CustomEvent<any>;
|
|
22
|
-
};
|
|
23
|
-
slots: {
|
|
24
|
-
default: {};
|
|
25
|
-
};
|
|
26
|
-
exports?: undefined;
|
|
27
|
-
bindings?: undefined;
|
|
28
|
-
};
|
|
29
|
-
export {};
|
|
4
|
+
declare const Lead: import("svelte").Component<Props, {}, "">;
|
|
5
|
+
type Lead = ReturnType<typeof Lead>;
|
|
6
|
+
export default Lead;
|