Skip to content

Commit 0a244bd

Browse files
authored
v1.4.0
v1.4.0
2 parents 7db91b9 + 4c44bdf commit 0a244bd

88 files changed

Lines changed: 2059 additions & 1123 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,38 @@
1-
# Changelog (03/11/2025)
1+
# Changelog (15/06/2026)
22

33
Changelog was generated by [Generi](https://github.com/betterwrite/generi). Any questions, consult the documentation.
44

5+
### v1.4.0
6+
7+
* **🔧 fix(pdf):** cover with correct creator field size - [[d398c258](https://github.com/Novout/betterwrite/commit/d398c258)]
8+
* **🚧 chore:** update epub-gen3 - [[316d0ebe](https://github.com/Novout/betterwrite/commit/316d0ebe)]
9+
* **🗿 ci:** fix stubs in runner text - [[ead66f46](https://github.com/Novout/betterwrite/commit/ead66f46)]
10+
* **🎉 feat:** landing background - [[8d09f5d1](https://github.com/Novout/betterwrite/commit/8d09f5d1)]
11+
* **🎉 feat:** some features for editor and preferences - [[8f3b8091](https://github.com/Novout/betterwrite/commit/8f3b8091)]
12+
* **🔧 test:** use file in setup - [[249d0738](https://github.com/Novout/betterwrite/commit/249d0738)]
13+
* **🚧 chore:** epub in app package field - [[5fd1435b](https://github.com/Novout/betterwrite/commit/5fd1435b)]
14+
* **🚧 chore:** update vite to v8 - [[34f392d8](https://github.com/Novout/betterwrite/commit/34f392d8)]
15+
* **🚩 refactor:** choice microphone - [[003e717f](https://github.com/Novout/betterwrite/commit/003e717f)]
16+
* **🚩 refactor!:** voice typing implement - [[9db0712a](https://github.com/Novout/betterwrite/commit/9db0712a)]
17+
* **🚩 refactor:** unique bionic option - [[537c0d57](https://github.com/Novout/betterwrite/commit/537c0d57)]
18+
* **🔧 fix:** gap in header principal item - [[e3099f3b](https://github.com/Novout/betterwrite/commit/e3099f3b)]
19+
* **🚧 chore:** lint - [[43d38269](https://github.com/Novout/betterwrite/commit/43d38269)]
20+
* **🚩 refactor:** alert erros in def components - [[d117e8b1](https://github.com/Novout/betterwrite/commit/d117e8b1)]
21+
* **🎉 feat!:** encrypt option for .bw - [[d4a88e04](https://github.com/Novout/betterwrite/commit/d4a88e04)]
22+
* **🎉 feat:** bionic reading docx and pdf - [[3c5b472e](https://github.com/Novout/betterwrite/commit/3c5b472e)]
23+
* **🎉 feat(epub):** ignore fixed and image case - [[a06d38b2](https://github.com/Novout/betterwrite/commit/a06d38b2)]
24+
* **🚧 chore:** update epub-gen-rs - [[21f27acd](https://github.com/Novout/betterwrite/commit/21f27acd)]
25+
* **🚧 chore(epub):** toc title - [[bb3f4aa8](https://github.com/Novout/betterwrite/commit/bb3f4aa8)]
26+
* **🎉 feat:** initial .epub implementation - [[fb0b5db8](https://github.com/Novout/betterwrite/commit/fb0b5db8)]
27+
* **🔧 fix!:** clean save in before set entity raw - [[6be2b614](https://github.com/Novout/betterwrite/commit/6be2b614)]
28+
* **🚩 refactor:** remove head dynamic set - [[3d3ef9b2](https://github.com/Novout/betterwrite/commit/3d3ef9b2)]
29+
* **🚧 chore:** remove dropbox support - [[86628245](https://github.com/Novout/betterwrite/commit/86628245)]
30+
* **🚧 chore:** ignore deprecation typescript - [[6a512ff2](https://github.com/Novout/betterwrite/commit/6a512ff2)]
31+
* **🚧 chore:** update vite - [[739e444f](https://github.com/Novout/betterwrite/commit/739e444f)]
32+
* **🚧 chore:** added claude.md - [[e10104cd](https://github.com/Novout/betterwrite/commit/e10104cd)]
33+
* **🎉 feat:** top file - [[7db91b93](https://github.com/Novout/betterwrite/commit/7db91b93)]
34+
* **🚧 chore:** readme - [[c94ebf14](https://github.com/Novout/betterwrite/commit/c94ebf14)]
35+
536
### v1.3.27
637

738
* **🚧 chore:** update generi - [[9929a27e](https://github.com/Novout/betterwrite/commit/9929a27e)]

CLAUDE.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# betterwrite — CLAUDE.md
2+
3+
## Project Overview
4+
5+
**Better Write** is a 100% client-side creative word processor built as a Vue 3 + TypeScript monorepo. There is no backend — all data lives in the browser (IndexedDB). Exports (PDF, DOCX, HTML, TXT, EPUB) are generated entirely in the browser. The project is deployed as a PWA at betterwrite.io.
6+
7+
## Monorepo Structure
8+
9+
Managed with **pnpm workspaces** + **Lerna** + **Nx** (task caching).
10+
11+
```
12+
packages/
13+
app/ # Main Vue 3 SPA — the entry point for everything
14+
better-write-types/ # Shared TypeScript types — check here first before defining new types
15+
contenteditable-ast/ # Custom AST for the entity-model text editor
16+
client-storage/ # IndexedDB abstraction layer
17+
extension/ # .bw file format (ZIP + data.json)
18+
plugin-*/ # Feature plugins (characters, theme, shortcuts, voice, etc.)
19+
plugin-exporter-*/ # Export generators (pdf, docx, html, txt, epub)
20+
plugin-importer/ # File import handling
21+
google-fonts-api/ # Google Fonts integration
22+
color-converter/ # Color utility
23+
image-converter/ # Image processing
24+
languages/ # i18n translation files
25+
```
26+
27+
## Key Architecture Concepts
28+
29+
### Entity Model
30+
The document is not stored as raw HTML. Content is a tree of **entities** (paragraphs, headings, images, page breaks, etc.), each with a `type`, `raw` text, and optional visual overrides. See `packages/better-write-types` and `docs/ENTITY_MODEL.md`.
31+
32+
### Plugin System
33+
Plugins receive three injection points: `emitter` (mitt event bus), `stores` (Pinia), and `hooks` (lifecycle). All plugins initialize in `packages/app/src/App.vue`. When adding a feature, check whether it belongs in an existing plugin or as a new `plugin-*` package. See `docs/PLUGIN_SYSTEM.md`.
34+
35+
### State Management
36+
Pinia stores live in `packages/app/src/store/`. There are ~14 stores. Prefer composables in `packages/app/src/use/` over direct store access in components.
37+
38+
### Export Pipeline
39+
Each export format is a separate `plugin-exporter-*` package. Generators receive the entity tree and produce browser-downloadable output. See `docs/GENERATOR_FLOW.md`.
40+
41+
### .bw Extension Format
42+
Project files saved as `.bw` are a ZIP archive containing `data.json`. Handled by `packages/extension/`. See `docs/PROJECT_FLOW.md`.
43+
44+
## Development Setup
45+
46+
```bash
47+
# Install dependencies
48+
pnpm install
49+
50+
# Start dev server (port 3000)
51+
pnpm dev
52+
53+
# Build all packages
54+
pnpm build
55+
56+
# Run tests
57+
pnpm test
58+
59+
# Format code
60+
pnpm lint
61+
```
62+
63+
Requires a `.env.local` file in `packages/app/` — copy from `.env.example`.
64+
65+
Node 16+ and pnpm 8+ required.
66+
67+
## Coding Conventions
68+
69+
- **TypeScript strict mode** — no `any` without justification.
70+
- **No semicolons**, **single quotes**, **2-space indent** (Prettier enforced).
71+
- **Conventional Commits** required: `feat:`, `fix:`, `chore:`, `refactor:`, `docs:`, `ci:`.
72+
- **Vue 3 Composition API** — use `<script setup>` syntax exclusively, no Options API.
73+
- **Windi CSS** for styling — utility-first, custom `wb-*` shortcuts defined in `packages/app/windi.config.ts`. Do not add raw inline styles.
74+
- CSS custom properties drive theming; never hardcode colors directly.
75+
- i18n keys for all user-facing strings — translations live in `packages/languages/`.
76+
77+
## Versioning
78+
79+
Versioning uses `generi` via conventional commits:
80+
81+
```bash
82+
pnpm patch # patch bump
83+
pnpm minor # minor bump
84+
pnpm major # major bump
85+
```
86+
87+
Do not manually edit version fields in `package.json` or `lerna.json`.
88+
89+
## Testing
90+
91+
Tests use **Vitest** with `happy-dom`. Run with `pnpm test`. Tests live alongside source files or in `__tests__/` subdirectories within packages. Keep tests focused on pure logic (generators, AST transforms, utilities) — do not test Vue component internals directly.
92+
93+
## Important Constraints
94+
95+
- **No server-side code.** Everything must run in the browser. Avoid Node-only APIs.
96+
- **No new direct `localStorage` usage.** Use the `client-storage` package (IndexedDB-backed) to avoid the 10 MB limit.
97+
- **Nx caches build outputs** in `dist/**`. If builds seem stale, run `pnpm build` from root to let Nx decide what to rebuild.
98+
- **Shameful hoisting is enabled** in pnpm — shared deps may hoist unexpectedly; prefer explicit imports from the package that owns the type.
99+
- The app targets **ESNext** — no need for legacy polyfills except where explicitly noted in `vite.config.ts`.
100+
101+
## Where to Look First
102+
103+
| Question | Where to look |
104+
|---|---|
105+
| Shared types | `packages/better-write-types/src/` |
106+
| App routing | `packages/app/src/routes.ts` |
107+
| Global events | `packages/better-write-types/src/``Events` interface |
108+
| Pinia stores | `packages/app/src/store/` |
109+
| Composables | `packages/app/src/use/` |
110+
| Theme tokens | `packages/plugin-theme/` + `packages/app/windi.config.ts` |
111+
| Export logic | `packages/plugin-exporter-*/` |
112+
| i18n strings | `packages/languages/` |
113+
| Plugin init | `packages/app/src/App.vue` |

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ betterwrite.io
2929
# Features
3030

3131
- ✅ Entity-Model Editor
32-
- ✅ PDF, DOCX, HTML and TXT Generator
32+
- ✅ PDF, DOCX, EPUB, HTML and TXT Generator
3333
- ✅ Full Customization
3434
- ✅ Mobile & Desktop (PWA)
3535
- ✅ Offline First

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"npmClient": "pnpm",
33
"useWorkspaces": true,
4-
"version": "1.3.27"
4+
"version": "1.4.0"
55
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
"devDependencies": {
1616
"generi": "2.0.4",
1717
"happy-dom": "20.0.10",
18-
"prettier": "3.6.2",
1918
"lerna": "6.6.2",
20-
"vitest": "4.0.6"
19+
"prettier": "3.6.2",
20+
"vitest": "4.1.8"
2121
},
2222
"packageManager": "pnpm@8.5.1"
2323
}

packages/app/package.json

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "better-write-app",
3-
"version": "1.3.27",
3+
"version": "1.4.0",
44
"repository": "https://github.com/Novout/betterwrite",
55
"description": "A Creative Word Processor",
66
"author": {
@@ -44,35 +44,35 @@
4444
"@vueuse/shared": "9.13.0",
4545
"@vueuse/sound": "2.0.1",
4646
"@zip.js/zip.js": "2.8.8",
47-
"better-write-client-storage": "^1.3.27",
48-
"better-write-color-converter": "^1.3.27",
49-
"better-write-contenteditable-ast": "^1.3.27",
50-
"better-write-extension": "^1.3.27",
51-
"better-write-google-fonts-api": "^1.3.27",
52-
"better-write-image-converter": "^1.3.27",
53-
"better-write-languages": "^1.3.27",
54-
"better-write-plugin-characters": "^1.3.27",
55-
"better-write-plugin-core": "^1.3.27",
56-
"better-write-plugin-dropbox": "^1.3.27",
57-
"better-write-plugin-editor-window": "^1.3.27",
58-
"better-write-plugin-entity-history": "^1.3.27",
59-
"better-write-plugin-exporter-docx": "^1.3.27",
60-
"better-write-plugin-exporter-epub": "^1.3.27",
61-
"better-write-plugin-exporter-html": "^1.3.27",
62-
"better-write-plugin-exporter-pdf": "^1.3.27",
63-
"better-write-plugin-exporter-txt": "^1.3.27",
64-
"better-write-plugin-importer": "^1.3.27",
65-
"better-write-plugin-progress-bar": "^1.3.27",
66-
"better-write-plugin-schemas": "^1.3.27",
67-
"better-write-plugin-shortcuts": "^1.3.27",
68-
"better-write-plugin-theme": "^1.3.27",
69-
"better-write-plugin-voice-typing": "^1.3.27",
70-
"better-write-types": "^1.3.27",
47+
"better-write-client-storage": "^1.4.0",
48+
"better-write-color-converter": "^1.4.0",
49+
"better-write-contenteditable-ast": "^1.4.0",
50+
"better-write-extension": "^1.4.0",
51+
"better-write-google-fonts-api": "^1.4.0",
52+
"better-write-image-converter": "^1.4.0",
53+
"better-write-languages": "^1.4.0",
54+
"better-write-plugin-characters": "^1.4.0",
55+
"better-write-plugin-core": "^1.4.0",
56+
"better-write-plugin-editor-window": "^1.4.0",
57+
"better-write-plugin-entity-history": "^1.4.0",
58+
"better-write-plugin-exporter-docx": "^1.4.0",
59+
"better-write-plugin-exporter-epub": "^1.4.0",
60+
"better-write-plugin-exporter-html": "^1.4.0",
61+
"better-write-plugin-exporter-pdf": "^1.4.0",
62+
"better-write-plugin-exporter-txt": "^1.4.0",
63+
"better-write-plugin-importer": "^1.4.0",
64+
"better-write-plugin-progress-bar": "^1.4.0",
65+
"better-write-plugin-schemas": "^1.4.0",
66+
"better-write-plugin-shortcuts": "^1.4.0",
67+
"better-write-plugin-theme": "^1.4.0",
68+
"better-write-plugin-voice-typing": "^1.4.0",
69+
"better-write-types": "^1.4.0",
7170
"compressorjs": "1.2.1",
7271
"destr": "2.0.5",
7372
"docx": "7.5.0",
7473
"drauu": "0.4.3",
7574
"dropbox": "10.34.0",
75+
"epub-gen3": "0.4.0",
7676
"file-saver": "2.0.5",
7777
"floating-vue": "2.0.0-beta.20",
7878
"hast": "1.0.0",

packages/app/src/App.vue

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import { ImporterPlugin } from 'better-write-plugin-importer'
1010
import { PDFPlugin } from 'better-write-plugin-exporter-pdf'
1111
import { DocxPlugin } from 'better-write-plugin-exporter-docx'
12-
// import { EpubPlugin } from 'better-write-plugin-exporter-epub'
12+
import { EpubPlugin } from 'better-write-plugin-exporter-epub'
1313
import { TxtPlugin } from 'better-write-plugin-exporter-txt'
1414
import { HtmlPlugin } from 'better-write-plugin-exporter-html'
1515
import { SchemasPlugin } from 'better-write-plugin-schemas'
@@ -19,14 +19,13 @@
1919
import { CharactersPlugin } from 'better-write-plugin-characters'
2020
import { ProgressBarPlugin } from 'better-write-plugin-progress-bar'
2121
import { EditorWindowPlugin } from 'better-write-plugin-editor-window'
22-
import { DropboxPlugin } from 'better-write-plugin-dropbox'
2322
2423
useStart([
2524
ThemePlugin(),
2625
ImporterPlugin(),
2726
PDFPlugin(),
2827
DocxPlugin(),
29-
// EpubPlugin(),
28+
EpubPlugin(),
3029
TxtPlugin(),
3130
HtmlPlugin(),
3231
SchemasPlugin(),
@@ -36,6 +35,5 @@
3635
CharactersPlugin(),
3736
ProgressBarPlugin(),
3837
EditorWindowPlugin(),
39-
DropboxPlugin(),
4038
]).init()
4139
</script>

packages/app/src/components/page/about/AboutInfo.vue

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@
7070
</AboutInfoItem>
7171
</div>
7272
<div class="flex flex-col gap-10">
73-
<AboutInfoItem :content="t('about.initial.list.3')">
74-
<IconVoid class="w-11 h-11" />
75-
</AboutInfoItem>
7673
<AboutInfoItem :content="t('about.initial.list.4')">
7774
<IconProjectTypeDocument class="w-11 h-11" />
7875
</AboutInfoItem>

packages/app/src/components/page/editor/entity/default/blocks/item/EditorEntityDefaultText.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
fontFamily: EDITOR.styles.text?.fontFamily || 'Raleway',
88
fontWeight: EDITOR.styles.text?.fontWeight || 500,
99
fontSize: `${EDITOR.styles.text?.fontSize || 16}px`,
10+
lineHeight: EDITOR.styles.text?.lineHeight ?? 1.5,
11+
letterSpacing: `${EDITOR.styles.text?.letterSpacing ?? 0}px`,
1012
}"
1113
class="editable whitespace-pre-line text-justify text-theme-editor-entity-text hover:text-theme-editor-entity-text-hover active:text-theme-editor-entity-text-active"
12-
:spellcheck="true"
14+
:spellcheck="EDITOR.configuration.entity?.spellcheck ?? true"
1315
:contenteditable="true"
1416
:data-placeholder="focused ? t('editor.text.placeholder.base') : ''"
1517
@input="block.onInput"

packages/app/src/components/page/editor/generator/pdf/generate/PDFGenerate.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
plugin.emit('plugin-pdf-generate', {
107107
chapters: chapters.value,
108108
color: color.value,
109+
bionicReading: ABSOLUTE.bionicReading,
109110
})
110111
}, 100)
111112
}

0 commit comments

Comments
 (0)