Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b9bbc25
refactor(web): rename web/_scripts → web/src
ddfreiling Jun 3, 2026
d9b9a82
refactor(web): Phase A1 — move logger/peripherals/extensions/enums to…
ddfreiling Jun 3, 2026
0091b75
refactor(web): Phase A2 — split helpers.ts into sub-modules
ddfreiling Jun 3, 2026
45334da
refactor(web): Phase A3 — move preferences to preferences/ dir; fix typo
ddfreiling Jun 3, 2026
c09a18c
refactor(web): Phase B4 — FlutterEpubNavigator class + locatorEnrich …
ddfreiling Jun 3, 2026
a615689
refactor(web): Phase B5 — FlutterWebPubNavigator class
ddfreiling Jun 3, 2026
babeb6e
refactor(web): Phase B6 — FlutterAudioNavigator class
ddfreiling Jun 3, 2026
9084eaa
refactor(web): Phase B7 — FlutterTTSNavigator (rename WebTTSEngine)
ddfreiling Jun 3, 2026
8e5a918
refactor(web): Phase B8 — FlutterMediaOverlayNavigator
ddfreiling Jun 3, 2026
1c9ffe6
refactor(web): Phase C9 — bridge/ReadiumBridge.ts + window.d.ts
ddfreiling Jun 3, 2026
d9ab2ee
refactor(web): Phase C10 — publication/PublicationManager.ts
ddfreiling Jun 3, 2026
d850409
refactor(web): Phase C11 — decorations/DecorationController.ts
ddfreiling Jun 3, 2026
21b7759
refactor(web): Phase C12 — preferences/FlutterAudioPreferences.ts
ddfreiling Jun 3, 2026
a0e800a
refactor(web): Phase D13 — rewrite ReadiumReader as thin dispatcher
ddfreiling Jun 3, 2026
a2621a3
refactor(web): Phase D14 — add index.ts entry; update webpack entry
ddfreiling Jun 3, 2026
97f0d62
refactor(web): Phase D15 — delete shims, update all test imports
ddfreiling Jun 3, 2026
de4db35
refactor(web): rename test files to match canonical module names
ddfreiling Jun 3, 2026
e9f782a
refactor(web): move syncNarration + guidedNavigation to mediaoverlay/
ddfreiling Jun 3, 2026
661ec96
refactor(web): trivial code-quality fixes across TS modules
ddfreiling Jun 3, 2026
e529a02
refactor(web): extract shared navigator utilities to navigatorUtils.ts
ddfreiling Jun 3, 2026
b5d5725
refactor(web): simplify _emitState call sites in FlutterAudioNavigator
ddfreiling Jun 3, 2026
80b1b79
refactor(web): remove dead delegation wrappers + dead code cleanup
ddfreiling Jun 3, 2026
005727b
refactor(web): remove dead underlying field from FlutterAudioNavigator
ddfreiling Jun 3, 2026
f8ba7f7
refactor(web): minor ReadiumReader.ts housekeeping
ddfreiling Jun 3, 2026
0aa50ce
chore: apply dart format to all packages
ddfreiling Jun 3, 2026
3015227
chore(web): rebuild JS bundle after TS refactor
ddfreiling Jun 3, 2026
044d551
ci: fix Flutter version pinning in all workflows
ddfreiling Jun 3, 2026
4d016c3
chore: reformat all Dart packages for page_width 120
ddfreiling Jun 3, 2026
ccc9160
Merge origin/main into agents/docs-web-ts-refactor-todo
ddfreiling Jun 10, 2026
8459442
refactor(web): rename decorationOverrides.ts to decorationFrameUtils.ts
ddfreiling Jun 10, 2026
b45f035
Merge branch 'main' into agents/docs-web-ts-refactor-todo
ddfreiling Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 0 additions & 86 deletions .agents/skills/source-command-flutter-marionette/SKILL.md

This file was deleted.

10 changes: 0 additions & 10 deletions .codex/config.toml

This file was deleted.

24 changes: 24 additions & 0 deletions .github/instructions/ci.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,30 @@ Use `bin/prepare-release <version>` before tagging. It:

Do not automate this in the CI pipeline — the changelog rewrite should be in the tagged commit itself, not a commit pushed by the workflow after tagging.

## `dart format` and `pub get` ordering

`analysis_options.base.yaml` sets `formatter: page_width: 120`. `dart format` only reads this setting if it can resolve the `flutter_lints` include — which requires `pub get` to have been run first. Without `pub get`, the formatter silently falls back to 80-char page width and produces different (narrower) output.

**Always run `flutter pub get` before `dart format`**, both locally and in CI. `bin/format` does this automatically. In CI workflows, the existing `Install dependencies` step runs `flutter pub get` before the `Check formatting` step — preserve that ordering.

## Flutter version pinning

All workflows pin Flutter via `.flutter-version` (the fvm version file). **Do not use `flutter-version-file:` in `subosito/flutter-action`** — that input treats the version as a semver constraint and resolves to the latest matching stable, not an exact pin. Instead, read the file in a dedicated step and pass the result as `flutter-version:`:

```yaml
- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@<sha> # v2.x
with:
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true
```

Omit `channel:` when an exact version is passed — it's inferred and `channel: stable` in combination with `flutter-version-file:` was observed to override the pinned version with latest stable.

## Integration vs build workflows

`flutter test integration_test` performs its own build internally (targeting the emulator/simulator) and cannot consume a pre-built APK/app from the build workflows. Don't couple the integration-test workflow to the build workflows — they serve different purposes. Share only caching patterns.
2 changes: 1 addition & 1 deletion .github/instructions/typescript.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ applyTo: 'flutter_readium/web/**/*.ts'

## Built JS

Do **not** hand-edit the compiled JS in `example/web/`. Edit TS sources in `flutter_readium/web/_scripts/`, then run `bin/update_web_example` from the repo root to rebuild and copy the bundle.
Do **not** hand-edit the compiled JS in `example/web/`. Edit TS sources in `flutter_readium/web/src/`, then run `bin/update_web_example` from the repo root to rebuild and copy the bundle.

## Linting

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/build-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ jobs:
distribution: jetbrains
java-version: '21'

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/build-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/build-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/integration-test-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@ jobs:
distribution: jetbrains
java-version: '21'

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/integration-test-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true

- name: Cache CocoaPods
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/integration-test-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down
14 changes: 10 additions & 4 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down Expand Up @@ -60,10 +63,13 @@ jobs:
steps:
- uses: actions/checkout@v5

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ jobs:
with:
fetch-depth: 0

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Read Flutter version
id: flutter_version
run: echo "version=$(cat .flutter-version)" >> "$GITHUB_OUTPUT"

- uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable
flutter-version-file: .flutter-version
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true
pub-cache: true

Expand Down
3 changes: 1 addition & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,5 @@
"videoref"
],
"java.configuration.updateBuildConfiguration": "interactive",
"dart.mcpServer": true,
"dart.flutterSdkPath": ".fvm/versions/3.41.9"
"dart.mcpServer": true
}
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Key scripts:
- `bin/install` — bootstrap everything: `pub get` in both packages, `pod update && pod install` for the example, build helper scripts, build web JS, copy JS into example. Run after a fresh clone or when dependencies change.
- `bin/format` — check Dart formatting across all three packages (platform interface, plugin, example). Fails if any file needs reformatting.
- `bin/analyze` — run `dart analyze --fatal-infos --fatal-warnings` across all three packages.
- `bin/typecheck` — type-check the web TypeScript (sources + Jest tests) via `tsc --noEmit` against `web/_scripts/tsconfig.json`. Run after editing any TS in `flutter_readium/web/`. Exits non-zero on a type error.
- `bin/typecheck` — type-check the web TypeScript (sources + Jest tests) via `tsc --noEmit` against `web/src/tsconfig.json`. Run after editing any TS in `flutter_readium/web/`. Exits non-zero on a type error.
- `bin/build_js` — build the web bundle (currently `build_dev`; production build is commented out).
- `bin/update_web_example` — `build_js` + copy the bundle into `flutter_readium/example/web/`. Run after editing TS in `flutter_readium/web/`.
- `bin/update_readium_voice_data` — refresh `flutter_readium/assets/voice_data/voices.json` from the upstream `readium/speech` repo (requires `jq`).
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ The same suite runs in CI on every push/PR via [.github/workflows/integration-te

## Building the web bundle

After editing TypeScript files in `flutter_readium/web/_scripts/` or `flutter_readium/assets/_helper_scripts/src/`:
After editing TypeScript files in `flutter_readium/web/src/` or `flutter_readium/assets/_helper_scripts/src/`:

```bash
bin/update_web_example # build + copy into example/web/
Expand Down
8 changes: 8 additions & 0 deletions bin/format
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/_common.sh"

# Format all Dart code across all packages in the repo.
# pub get must run first so the formatter can resolve analysis_options.yaml
# (which includes flutter_lints/flutter.yaml for the page_width: 120 setting).
# Without it, the formatter falls back to 80-char page width and produces
# different output than CI (which always runs pub get before dart format).

echo "Formatting flutter_readium_platform_interface..."
flutter pub get --directory "$REPO_ROOT/flutter_readium_platform_interface" > /dev/null
dart format --set-exit-if-changed "$REPO_ROOT/flutter_readium_platform_interface"

echo "Formatting flutter_readium..."
flutter pub get --directory "$REPO_ROOT/flutter_readium" > /dev/null
dart format --set-exit-if-changed "$REPO_ROOT/flutter_readium"

echo "Formatting example app..."
flutter pub get --directory "$REPO_ROOT/flutter_readium/example" > /dev/null
dart format --set-exit-if-changed "$REPO_ROOT/flutter_readium/example"
4 changes: 2 additions & 2 deletions bin/install
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ if [ "$(uname)" = "Darwin" ]; then
( cd "$REPO_ROOT/flutter_readium/example/ios" && pod update && pod install --repo-update )
fi

# Make sure web dependencies are installed
cd "$REPO_ROOT/flutter_readium/web/_scripts" && npm install --ignore-scripts
# Make sure web dependencies are installed (package.json lives at the plugin root)
cd "$REPO_ROOT/flutter_readium" && npm install --ignore-scripts

"$REPO_ROOT/flutter_readium/bin/build_helper_scripts.sh"
"$REPO_ROOT/bin/build_js"
Expand Down
4 changes: 2 additions & 2 deletions bin/typecheck
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/_common.sh"

# Type-check the flutter_readium web TypeScript (sources + Jest tests) without
# emitting any output. Uses web/_scripts/tsconfig.test.json so test files are
# included too. Run after editing any TS under flutter_readium/web/_scripts.
# emitting any output. Uses web/src/tsconfig.test.json so test files are
# included too. Run after editing any TS under flutter_readium/web/src.
echo "Type-checking flutter_readium web TypeScript"
cd "$REPO_ROOT/flutter_readium"

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ All models in `flutter_readium_platform_interface` define hand-written `toJson`

## Web implementation

The web plugin is a TypeScript/webpack bundle (`flutter_readium/web/_scripts/`) compiled to `flutter_readium/lib/helpers/readiumReader.js`. It is loaded inside a webview and communicates with Dart via `postMessage` / JS interop.
The web plugin is a TypeScript/webpack bundle (`flutter_readium/web/src/`) compiled to `flutter_readium/lib/helpers/readiumReader.js`. It is loaded inside a webview and communicates with Dart via `postMessage` / JS interop.

After any TypeScript change run `bin/update_web_example` to rebuild and deploy to the example app.

Expand Down
4 changes: 2 additions & 2 deletions docs/parity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ These plans have been implemented on the `feat/web-feature-parity` branch and ar

## Considered and deferred

- **Web TTS audit** — The original audit produced a `web-tts.md` plan claiming web TTS was entirely unimplemented. That premise is incorrect: `WebTTSEngine` lives at [flutter_readium/web/_scripts/TTS/ttsNavigator.ts](../../flutter_readium/web/_scripts/TTS/ttsNavigator.ts) and the full `ttsEnable` / `play` / `pause` / `stop` / `next` / `previous` / voice-selection surface is wired through `ReadiumReader.ts`. A genuine TTS parity audit (word-level highlighting, decoration sync, missing-voice fallback) is still worthwhile but needs a fresh investigation against the current code.
- **Web TTS audit** — The original audit produced a `web-tts.md` plan claiming web TTS was entirely unimplemented. That premise is incorrect: `WebTTSEngine` lives at [flutter_readium/web/src/TTS/ttsNavigator.ts](../../flutter_readium/web/src/TTS/ttsNavigator.ts) and the full `ttsEnable` / `play` / `pause` / `stop` / `next` / `previous` / voice-selection surface is wired through `ReadiumReader.ts`. A genuine TTS parity audit (word-level highlighting, decoration sync, missing-voice fallback) is still worthwhile but needs a fresh investigation against the current code.

- **Media overlay on web audit** — Same staleness: the original `media-overlay-missing-on-web.md` plan was written against an outdated snapshot. Media Overlay (`application/vnd.readium.narration+json`) and Guided Navigation (`application/guided-navigation+json`) both play through `audioEnable` on web today via [Audio/mediaOverlayNavigator.ts](../../flutter_readium/web/_scripts/Audio/mediaOverlayNavigator.ts) and [Audio/guidedNavigation.ts](../../flutter_readium/web/_scripts/Audio/guidedNavigation.ts). Any follow-up parity work in this area should start from a fresh audit.
- **Media overlay on web audit** — Same staleness: the original `media-overlay-missing-on-web.md` plan was written against an outdated snapshot. Media Overlay (`application/vnd.readium.narration+json`) and Guided Navigation (`application/guided-navigation+json`) both play through `audioEnable` on web today via [Audio/mediaOverlayNavigator.ts](../../flutter_readium/web/src/Audio/mediaOverlayNavigator.ts) and [Audio/guidedNavigation.ts](../../flutter_readium/web/src/Audio/guidedNavigation.ts). Any follow-up parity work in this area should start from a fresh audit.

- **Positions list API** — Both upstream toolkits compute a `positionsByReadingOrder` list internally but do not expose it as a public API on their navigators. The Dart `PositionsList` model exists, but surfacing it would require either polling the publication-level service or adding a dedicated method-channel call. Consumer demand is low compared to the maintenance cost; deferred.

Expand Down
Loading
Loading