{"_id":"@animastor/web-navigator","name":"@animastor/web-navigator","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@animastor/web-navigator","version":"0.1.0","description":"Preact/Web UI module: Animastor Web Navigator — book structure navigation tree (chapters/scenes/units) for the web frontend. NOT a platform-independent or domain module — it renders through Preact and consumes host capabilities only via the injected Navig","keywords":["animastor","navigator","preact","web-ui","frontend","ui-component","signals","book-structure","ports-and-adapters"],"type":"module","main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"sideEffects":false,"scripts":{"build":"tsup","typecheck":"tsc --noEmit","test":"vitest run","prepublishOnly":"npm run typecheck && npm run test && npm run build"},"peerDependencies":{"@preact/signals":">=1.0.0","preact":">=10.5.0"},"devDependencies":{"@preact/signals":"^1.3.0","@preact/preset-vite":"^2.9.0","@testing-library/dom":"^10.4.1","@testing-library/preact":"^3.2.4","happy-dom":"^20.14.0","preact":"^10.24.0","tsup":"^8.3.5","typescript":"^5.6.0","vitest":"^4.1.10"},"license":"MIT","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Animastor/animastor.git","directory":"packages/animastor-web-navigator"},"homepage":"https://github.com/Animastor/animastor/tree/main/packages/animastor-web-navigator#readme","bugs":{"url":"https://github.com/Animastor/animastor/issues"},"_id":"@animastor/web-navigator@0.1.0","gitHead":"88cd791e1c441b90a9a514e98e6ab4170fe8ddc8","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-apYJdCtXTpXR2JoxRAVvcsCTIztsWLGRAwAjGsOI1Xno5NT3Is67hmDdl63++TAlVwmwXHaZLgYLkruSrwcwuA==","shasum":"8b58b05aa47dec47eea00bef176653a47f847f99","tarball":"https://registry.npmjs.org/@animastor/web-navigator/-/web-navigator-0.1.0.tgz","fileCount":6,"unpackedSize":64912,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC5J38736fskjcWjI4rjhrxshMMbBRl+buUzFFEicNSqQIhAJznV5pVe72RNjJBEvfLMNvriUxggshnn59Yj0jxzxPW"}]},"_npmUser":{"name":"animastor","email":"admin@animastor.in"},"directories":{},"maintainers":[{"name":"animastor","email":"admin@animastor.in"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/web-navigator_0.1.0_1789140148690_0.9299930428326215"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-11T15:22:28.533Z","0.1.0":"2026-09-11T15:22:28.838Z","modified":"2026-09-11T15:22:29.070Z"},"maintainers":[{"name":"animastor","email":"admin@animastor.in"}],"description":"Preact/Web UI module: Animastor Web Navigator — book structure navigation tree (chapters/scenes/units) for the web frontend. NOT a platform-independent or domain module — it renders through Preact and consumes host capabilities only via the injected Navig","homepage":"https://github.com/Animastor/animastor/tree/main/packages/animastor-web-navigator#readme","keywords":["animastor","navigator","preact","web-ui","frontend","ui-component","signals","book-structure","ports-and-adapters"],"repository":{"type":"git","url":"git+https://github.com/Animastor/animastor.git","directory":"packages/animastor-web-navigator"},"bugs":{"url":"https://github.com/Animastor/animastor/issues"},"license":"MIT","readme":"# @animastor/web-navigator\n\nBook-structure navigation tree (chapters → scenes → units) for Animastor, packaged as a standalone Preact module.\n\n> **Scope — Preact/Web UI module.** This package is a **specialized Web/Frontend UI module** built on **Preact** (+ `@preact/signals`), for embedding into browser-based Animastor hosts (`frontends/app`). It is **not** a platform-independent or domain module: it renders DOM through Preact JSX, and its rendering semantics (desktop/mobile fork, thumbnails, `scrollIntoView`, `matchMedia`-driven shell mode) are web-specific. It is **not intended for Android/native UI** — the Android Navigator (`NavigateFragment` / `fragment_navigate.xml`) remains a separate native implementation; this package does not target it directly. Domain logic (book model, seek, reload, invalidations) stays host-owned behind the ports — extracting a cross-platform `navigator-core` is a possible future task, not part of this package.\n\nThe Navigator owns no runtime infrastructure. Every host dependency — playback seek, book source, shared position, invalidation bus, reload pipeline, desktop/mobile shell mode, navigation, HTTP, i18n, icons — arrives through the [`NavigatorPorts`](#navigatorports) contract injected as a prop. The package never imports host stores, the API client, router, i18n or icon kit, so it can be mounted by any **Preact** host that implements the ports.\n\n## Install\n\n```sh\nnpm install @animastor/web-navigator\n```\n\nPeer dependencies (must be provided by the host):\n\n- `preact` >= 10.5\n- `@preact/signals` >= 1\n\n## Usage\n\n```tsx\nimport { render } from 'preact';\nimport { NavigatePage, type NavigatorPorts } from '@animastor/web-navigator';\n\nconst ports: NavigatorPorts = {\n  seek: { seekToPosition: (ch, sc, idx, unitId) => myPlayer.seek(ch, sc, idx, unitId) },\n  bookSource: { bookId, buildId, onPlaybackPrepared },\n  position: { position: positionSignal, navigateTo },\n  invalidations: { onResourceInvalidated, bookResource: (id) => `book:${id}` },\n  reload: { resilientReload, sharedRecovery },\n  shellMode: { isDesktop: () => window.matchMedia('(min-width: 1180px)').matches },\n  navigation: { navigateToPlay: () => router.go('/play') },\n  http: { getJson, mediaUrl },\n  i18n: { t },\n  icons: { Play: IconPlay, ImageOff: IconImageOff },\n};\n\nrender(<NavigatePage ports={ports} />, document.getElementById('app'));\n```\n\n## Public API\n\n| Export | Kind | Purpose |\n|---|---|---|\n| `NavigatePage` | component | The Navigator surface; takes `{ path?: string; ports: NavigatorPorts }` |\n| `buildStructure` | function | Pure chapters→scenes→units tree builder (Android-parity labels) |\n| `chapterLabel`, `sceneLabel`, `unitLabel` | functions | Label grammar helpers |\n| `NavigatorPorts` | type | The full host contract (10 ports, see below) |\n| `NavItem` | type | Tree item union rendered by the list |\n| `BookData`, `BookChapter`, `BookScene`, `BookUnit` | types | Structural book models the Navigator reads |\n| Port payload types | types | `ActivePosition`, `PlaybackPreparedEvent`, `ResourceInvalidationEvent`, `NetworkRecoverySignal`, `ReloadResult`, `NavigatorT`, `NavigatorI18nKey`, `NavigatorIconProps` |\n| Individual port types | types | `SeekPort`, `BookSourcePort`, `PositionPort`, `InvalidationPort`, `ReloadPort`, `ShellModePort`, `NavigationPort`, `HttpPort`, `I18nPort`, `IconsPort` |\n\n### NavigatorPorts\n\n| Port | Role |\n|---|---|\n| `seek` (`SeekPort`) | External seek — 1:1 with the host player's `seekToPosition` (same async/error semantics) |\n| `bookSource` (`BookSourcePort`) | Session identity: `bookId`/`buildId` signals + generation-completion subscription |\n| `position` (`PositionPort`) | Shared navigation position signal + `navigateTo` |\n| `invalidations` (`InvalidationPort`) | External freshness events (`EXTERNAL`/`LOCAL`) for the open book |\n| `reload` (`ReloadPort`) | Bounded backoff reload + connectivity recovery signal |\n| `shellMode` (`ShellModePort`) | Desktop/mobile behavioral fork (`isDesktop()`) |\n| `navigation` (`NavigationPort`) | `navigateToPlay()` — router knowledge stays host-owned |\n| `http` (`HttpPort`) | `getJson` + `mediaUrl` (preview URL grammar stays host-owned) |\n| `i18n` (`I18nPort`) | `t` for the Navigator's i18n keys |\n| `icons` (`IconsPort`) | `Play` / `ImageOff` icon components |\n\n## Behavior contract\n\n- Desktop: unit tap selects only (position + seek, no route change); double-click or the active-row play button seeks and navigates to the player.\n- Mobile: unit tap selects, seeks and navigates to the player (`switchToPlayTab` parity).\n- The current position's scene auto-expands on mount and follows position changes.\n- The tree reloads on: `bookId` change, generation completion for the same book, `EXTERNAL` invalidation of the open book.\n- Unit thumbnails use `http.mediaUrl` with the `/preview/{book}/{ch}/{sc}/{iu}?build_id=` grammar; failures fall back to the `ImageOff` icon.\n\n## Package boundary\n\n- The package imports only `preact`, `preact/hooks`, `preact/jsx-runtime` and `@preact/signals`.\n- Host stores, `api/client`, router, i18n, icons, `AppShell` and adapter modules are **forbidden** inside the package (enforced by boundary tests in the repository).\n- `@animastor/web-navigator → host` = forbidden; `host → @animastor/web-navigator` = allowed through the public entry point only.\n- **Technology boundary**: `@animastor/web-navigator` is a **Preact/Web UI module** — not a cross-platform or domain package. No `navigator-core` split exists yet; the Android/native Navigator is out of scope for this package.\n\n## Development\n\n```sh\nnpm install\nnpm run typecheck   # tsc --noEmit\nnpm run test        # vitest (27 characterization + boundary tests)\nnpm run build       # tsup → dist/ (ESM + d.ts + sourcemaps)\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-6ccefae2681cdd95468fcb13cd579f03"}