flipbookengine 0.6.5 → 1.0.0

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 (89) hide show
  1. package/CHANGELOG.md +24 -3
  2. package/README.md +136 -8
  3. package/dist/components/App.d.ts +19 -0
  4. package/dist/components/HotspotLayer.d.ts +14 -0
  5. package/dist/components/NotesPanel.d.ts +14 -0
  6. package/dist/components/PluginPanels.d.ts +5 -0
  7. package/dist/components/SearchPanel.d.ts +11 -0
  8. package/dist/components/Toolbar.d.ts +6 -0
  9. package/dist/components/Viewer.d.ts +6 -0
  10. package/dist/core/LayoutManager.d.ts +1 -1
  11. package/dist/core/PdfRenderer.d.ts +11 -0
  12. package/dist/core-entry.d.ts +13 -0
  13. package/dist/core.d.ts +1 -0
  14. package/dist/embed.d.ts +80 -0
  15. package/dist/engine-Dt2Fn6O-.js +4060 -0
  16. package/dist/engine-Dt2Fn6O-.js.map +1 -0
  17. package/dist/engine.d.ts +101 -0
  18. package/dist/feature-Cicli9ie.js +17 -0
  19. package/dist/feature-Cicli9ie.js.map +1 -0
  20. package/dist/flipbook-engine.core.js +8 -0
  21. package/dist/flipbook-engine.core.js.map +1 -0
  22. package/dist/flipbook-engine.css +1 -1
  23. package/dist/flipbook-engine.iife.js +56 -47
  24. package/dist/flipbook-engine.iife.js.map +1 -1
  25. package/dist/flipbook-engine.js +10 -6
  26. package/dist/flipbook-engine.js.map +1 -1
  27. package/dist/flipbook-engine.plugins-annotations.js +14 -0
  28. package/dist/flipbook-engine.plugins-annotations.js.map +1 -0
  29. package/dist/flipbook-engine.plugins-bookmarks.js +16 -0
  30. package/dist/flipbook-engine.plugins-bookmarks.js.map +1 -0
  31. package/dist/flipbook-engine.plugins-deep-link.js +14 -0
  32. package/dist/flipbook-engine.plugins-deep-link.js.map +1 -0
  33. package/dist/flipbook-engine.plugins-hotspots.js +15 -0
  34. package/dist/flipbook-engine.plugins-hotspots.js.map +1 -0
  35. package/dist/flipbook-engine.plugins-notes.js +16 -0
  36. package/dist/flipbook-engine.plugins-notes.js.map +1 -0
  37. package/dist/flipbook-engine.plugins-search.js +15 -0
  38. package/dist/flipbook-engine.plugins-search.js.map +1 -0
  39. package/dist/flipbook-engine.plugins-share.js +13 -0
  40. package/dist/flipbook-engine.plugins-share.js.map +1 -0
  41. package/dist/flipbook-engine.plugins-toc.js +14 -0
  42. package/dist/flipbook-engine.plugins-toc.js.map +1 -0
  43. package/dist/flipbook-engine.plugins.js +5 -0
  44. package/dist/flipbook-engine.plugins.js.map +1 -0
  45. package/dist/flipbook-engine.react.js +1 -1
  46. package/dist/flipbook-engine.vue.js +1 -1
  47. package/dist/i18n/locales/en.d.ts +17 -0
  48. package/dist/i18n/locales/tr.d.ts +17 -0
  49. package/dist/i18n/service.d.ts +51 -0
  50. package/dist/index-BhTR2SK6.js +366 -0
  51. package/dist/index-BhTR2SK6.js.map +1 -0
  52. package/dist/index.d.ts +7 -0
  53. package/dist/model/annotations.d.ts +14 -0
  54. package/dist/model/hotspots.d.ts +40 -0
  55. package/dist/model/search.d.ts +25 -0
  56. package/dist/plugins/annotations.d.ts +4 -0
  57. package/dist/plugins/bookmarks.d.ts +4 -0
  58. package/dist/plugins/deep-link.d.ts +4 -0
  59. package/dist/plugins/feature.d.ts +5 -0
  60. package/dist/plugins/hotspots.d.ts +4 -0
  61. package/dist/plugins/index.d.ts +65 -0
  62. package/dist/plugins/notes.d.ts +4 -0
  63. package/dist/plugins/search.d.ts +4 -0
  64. package/dist/plugins/share.d.ts +4 -0
  65. package/dist/plugins/toc.d.ts +4 -0
  66. package/dist/plugins-annotations.d.ts +1 -0
  67. package/dist/plugins-bookmarks.d.ts +1 -0
  68. package/dist/plugins-deep-link.d.ts +1 -0
  69. package/dist/plugins-hotspots.d.ts +1 -0
  70. package/dist/plugins-notes.d.ts +1 -0
  71. package/dist/plugins-search.d.ts +1 -0
  72. package/dist/plugins-share.d.ts +1 -0
  73. package/dist/plugins-toc.d.ts +1 -0
  74. package/dist/plugins.d.ts +1 -0
  75. package/dist/state/store.d.ts +19 -5
  76. package/dist/vue/index.d.ts +1 -1
  77. package/docs/api-reference.md +206 -0
  78. package/docs/frameworks.md +73 -0
  79. package/docs/getting-started.md +128 -0
  80. package/docs/i18n.md +47 -0
  81. package/docs/migration-0.4.0.md +24 -0
  82. package/docs/migration-0.5.0.md +25 -0
  83. package/docs/migration-1.0.0.md +59 -0
  84. package/docs/plugin-architecture.md +103 -0
  85. package/docs/release-checklist.md +37 -0
  86. package/docs/theming.md +61 -0
  87. package/package.json +165 -114
  88. package/dist/engine-DhQ2zxpm.js +0 -3535
  89. package/dist/engine-DhQ2zxpm.js.map +0 -1
@@ -0,0 +1 @@
1
+ export * from './plugins/share'
@@ -0,0 +1 @@
1
+ export * from './plugins/toc'
@@ -0,0 +1 @@
1
+ export * from './plugins/index'
@@ -4,6 +4,9 @@ import { NormalizedFlipbookPage } from '../model/pages';
4
4
  import { FlipbookTocEntry } from '../model/toc';
5
5
  import { FlipbookEngineOptions } from '../engine';
6
6
  import { PartialFlipbookMessages } from '../i18n/service';
7
+ import { FlipbookSearchResult } from '../model/search';
8
+ import { FlipbookHotspot } from '../model/hotspots';
9
+ import { FlipbookAnnotation } from '../model/annotations';
7
10
 
8
11
  export type FlipState = 'read' | 'fold_corner' | 'flipping';
9
12
  export type Orientation = 'landscape' | 'portrait';
@@ -20,18 +23,29 @@ export interface FlipbookStore {
20
23
  isSingleMode: Signal<boolean>;
21
24
  showThumbs: Signal<boolean>;
22
25
  showToc: Signal<boolean>;
26
+ showNotes: Signal<boolean>;
27
+ showSearch: Signal<boolean>;
23
28
  showArrows: Signal<boolean>;
24
29
  orientation: Signal<Orientation>;
25
30
  flipState: Signal<FlipState>;
26
31
  themeMode: Signal<FlipbookThemeMode>;
27
32
  allowDownload: Signal<boolean>;
33
+ bookmarkedPages: Signal<ReadonlySet<number>>;
34
+ pageNotes: Signal<ReadonlyMap<number, string>>;
28
35
  hasDownloadUrl: Signal<boolean>;
36
+ isPdfMode: Signal<boolean>;
29
37
  primaryColor: Signal<string>;
30
38
  whiteLabel: Signal<boolean>;
31
39
  isZoomed: Signal<boolean>;
32
40
  isAutoPlaying: Signal<boolean>;
33
41
  autoPlayInterval: Signal<number>;
34
42
  soundEnabled: Signal<boolean>;
43
+ searchQuery: Signal<string>;
44
+ searchResults: Signal<FlipbookSearchResult[]>;
45
+ hotspots: Signal<FlipbookHotspot[]>;
46
+ activeHotspotId: Signal<string | null>;
47
+ annotations: Signal<FlipbookAnnotation[]>;
48
+ activeAnnotationId: Signal<string | null>;
35
49
  locale: Signal<string>;
36
50
  messages: Signal<Partial<Record<string, PartialFlipbookMessages>>>;
37
51
  zoomState: Signal<ZoomState>;
@@ -40,16 +54,16 @@ export interface FlipbookStore {
40
54
  isDoublePageLayout: ReadonlySignal<boolean>;
41
55
  isFrontCover: ReadonlySignal<boolean>;
42
56
  isBackCover: ReadonlySignal<boolean>;
43
- init(options: FlipbookEngineOptions, total: number, mappedPages: NormalizedFlipbookPage[], hasPdfUrl: boolean): void;
57
+ init(options: FlipbookEngineOptions, total: number, mappedPages: NormalizedFlipbookPage[], hasPdfUrl: boolean, isPdfMode?: boolean): void;
44
58
  reset(): void;
45
59
  }
46
60
  /** Creates an isolated reactive state container for one FlipbookEngine instance. */
47
61
  export declare function createFlipbookStore(): FlipbookStore;
48
62
  export declare const currentPage: Signal<number>, totalPages: Signal<number>, isSingleMode: Signal<boolean>;
49
- export declare const showThumbs: Signal<boolean>, showToc: Signal<boolean>, showArrows: Signal<boolean>, orientation: Signal<Orientation>;
50
- export declare const flipState: Signal<FlipState>, themeMode: Signal<FlipbookThemeMode>, allowDownload: Signal<boolean>;
51
- export declare const hasDownloadUrl: Signal<boolean>, primaryColor: Signal<string>, whiteLabel: Signal<boolean>;
63
+ export declare const showThumbs: Signal<boolean>, showToc: Signal<boolean>, showNotes: Signal<boolean>, showSearch: Signal<boolean>, showArrows: Signal<boolean>, orientation: Signal<Orientation>;
64
+ export declare const flipState: Signal<FlipState>, themeMode: Signal<FlipbookThemeMode>, allowDownload: Signal<boolean>, bookmarkedPages: Signal<ReadonlySet<number>>, pageNotes: Signal<ReadonlyMap<number, string>>;
65
+ export declare const hasDownloadUrl: Signal<boolean>, isPdfMode: Signal<boolean>, primaryColor: Signal<string>, whiteLabel: Signal<boolean>;
52
66
  export declare const isZoomed: Signal<boolean>, isAutoPlaying: Signal<boolean>, autoPlayInterval: Signal<number>;
53
- export declare const soundEnabled: Signal<boolean>, locale: Signal<string>, messages: Signal<Partial<Record<string, Partial<import('..').FlipbookMessages>>>>, zoomState: Signal<ZoomState>, pages: Signal<NormalizedFlipbookPage[]>, toc: Signal<FlipbookTocEntry[]>;
67
+ export declare const soundEnabled: Signal<boolean>, searchQuery: Signal<string>, searchResults: Signal<FlipbookSearchResult[]>, hotspots: Signal<FlipbookHotspot[]>, activeHotspotId: Signal<string | null>, annotations: Signal<FlipbookAnnotation[]>, activeAnnotationId: Signal<string | null>, locale: Signal<string>, messages: Signal<Partial<Record<string, Partial<import('..').FlipbookMessages>>>>, zoomState: Signal<ZoomState>, pages: Signal<NormalizedFlipbookPage[]>, toc: Signal<FlipbookTocEntry[]>;
54
68
  export declare const isDoublePageLayout: ReadonlySignal<boolean>, isFrontCover: ReadonlySignal<boolean>, isBackCover: ReadonlySignal<boolean>;
55
69
  export declare function initStore(options: FlipbookEngineOptions, total: number, mappedPages: NormalizedFlipbookPage[], hasPdfUrl: boolean): void;
@@ -41,8 +41,8 @@ export declare const Flipbook: import('vue').DefineComponent<import('vue').Extra
41
41
  onPageChange?: ((...args: any[]) => any) | undefined;
42
42
  }>, {
43
43
  pages: FlipbookPageAsset[];
44
- pdfUrl: string;
45
44
  options: Omit<FlipbookEngineOptions, "theme"> & {
46
45
  theme?: "auto" | "light" | "dark";
47
46
  };
47
+ pdfUrl: string;
48
48
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,206 @@
1
+ # API Reference
2
+
3
+ This document describes the options, methods, and events exposed by the `FlipbookEngine` class.
4
+
5
+ ## Constructor Options
6
+
7
+ When instantiating `new FlipbookEngine(selector, options)`, you can configure the following options:
8
+
9
+ | Property | Type | Default | Description |
10
+ |---|---|---|---|
11
+ | `allowDownload` | `boolean` | `true` | Exposes a download button in the toolbar. |
12
+ | `showThumbs` | `boolean` | `false` | Starts the viewer with the thumbnail navigation rail hidden. |
13
+ | `showToc` | `boolean` | `false` | Shows the supplied table of contents panel when it contains entries. |
14
+ | `toc` | `FlipbookTocEntry[]` | `[]` | Host-provided chapter/category entries using zero-based page indexes. |
15
+ | `showArrows` | `boolean` | `true` | Shows the previous/next navigation arrows. |
16
+ | `primaryColor` | `string` | `'#7367f0'` | Sets the primary theme accent color. |
17
+ | `theme` | `'auto' \| 'light' \| 'dark'` | `'auto'` | Force light/dark mode or let it respond automatically. |
18
+ | `locale` | `'en' \| 'tr' \| string` | `'en'` | Active language interface. |
19
+ | `soundEnabled` | `boolean` | `true` | Enables page turning sound effect. |
20
+ | `soundUrl` | `string` | `'https://flipbookengine.com/Content/page-flip.mp3'` | URL of the page turning audio file. |
21
+ | `autoPlayInterval` | `number` | `3000` | Duration (ms) before automatically turning to the next page in Autoplay mode. |
22
+ | `flippingTime` | `number` | `1000` | Duration (ms) of the page turning animation; automatically set to `0` when reduced motion is preferred. |
23
+ | `maxShadowOpacity` | `number` | `0.5` | Maximum opacity of the shadow during page turn (0 to 1). |
24
+ | `messages` | `Record<string, PartialFlipbookMessages>` | `null` | Custom localization overrides. |
25
+ | `cssVariables` | `Record<string, string>` | `null` | Per-instance custom CSS property overrides. |
26
+ | `whiteLabel` | `boolean` | `false` | If true, hides the "Powered by FlipbookEngine" watermark. |
27
+ | `watermarkUrl` | `string` | `null` | Custom image logo URL for watermark attribution. |
28
+ | `pdfRenderConcurrency` | `number` | `3` | Maximum number of PDF pages rendered concurrently when on-demand pages are requested. |
29
+ | `pdfRenderCacheSize` | `number` | `32` | Maximum number of rendered PDF page images retained per engine instance (LRU); `0` disables caching. |
30
+ | `pdfPageMode` | `'auto' \| 'single' \| 'split'` | `'auto'` | Automatically split A3 landscape pages, split every landscape page, or keep source pages intact. |
31
+ | `background` | `FlipbookBackgrounds \| null` | `null` | Optional per-theme viewer background styles. |
32
+ | `deepLink` | `boolean` | `false` | Synchronizes the active page with a `?page=` URL parameter and browser history. |
33
+ | `onShare` | `(url: string) => void` | `null` | Optional callback invoked after the localized toolbar Share control shares or copies the generated page URL. |
34
+ | `bookmarks` | `number[]` | `[]` | Initial zero-based page indexes marked as bookmarks; persistence remains with the host application. |
35
+ | `notes` | `Record<number, string>` | `{}` | Initial page notes keyed by zero-based page index; the localized toolbar editor is host-storage agnostic. |
36
+ | `hotspots` | `FlipbookHotspot[]` | `[]` | Normalized page overlays with accessible labels, media/gallery previews, plain-text content, and optional commerce links. |
37
+ | `annotations` | `FlipbookAnnotation[]` | `[]` | Host-managed page note markers with normalized coordinates and plain-text popup content. |
38
+
39
+ ---
40
+
41
+ ## Public Methods
42
+
43
+ ### `init(pdfUrl: string, imageList?: FlipbookPageAsset[])`
44
+ Initializes and mounts the viewer into the container element. Returns a `Promise<void>`.
45
+
46
+ ### `goToPage(pageIndex: number)`
47
+ Programmatically turns to the specified 0-based page index.
48
+
49
+ ### `getCurrentPage()`
50
+ Returns the 0-based index of the currently active page.
51
+
52
+ ### `getTotalPages()`
53
+ Returns the total count of normalized pages.
54
+
55
+ ### `getZoom()`
56
+ Returns the current zoom scale (usually `1` to `5`).
57
+
58
+ ### `setZoom(zoomLevel: number)`
59
+ Sets the zoom scale. Acceptable bounds are `0.5` to `5`.
60
+
61
+ ### `setSingleMode(isSingle: boolean)`
62
+ Enforces single page layout (typically for mobile viewports) or spread mode.
63
+
64
+ ### `toggleFullscreen()`
65
+ Toggles browser fullscreen.
66
+
67
+ ### `updateOptions(options: Partial<FlipbookEngineOptions>)`
68
+ Updates options dynamically at runtime.
69
+
70
+ ### `setLocale(locale: string, messages?: PartialFlipbookMessages | Record<string, PartialFlipbookMessages>)`
71
+ Changes the UI language programmatically.
72
+
73
+ ### `getPageUrl(pageIndex = getCurrentPage())`
74
+ Returns a shareable URL with a 1-based `?page=` parameter for the requested 0-based page index.
75
+
76
+ ### `sharePage(pageIndex = getCurrentPage())`
77
+ Uses the native share dialog when available, otherwise copies the page URL to the clipboard. The toolbar exposes this behavior through a localized Share button. Enable `deepLink: true` in the receiving viewer to resolve the `?page=` parameter.
78
+
79
+ ### Bookmark methods
80
+
81
+ `getBookmarkedPages()`, `isBookmarked()`, `setBookmark(pageIndex, bookmarked)`, and `toggleBookmark(pageIndex)` manage zero-based bookmark state. The `bookmarkChange` event payload is `{ pageIndex, pageNumber, bookmarked }`; hosts should persist this payload in their own storage.
82
+
83
+ `getNotes()`, `getNote(pageIndex)`, `setNote(pageIndex, note)`, and `clearNote(pageIndex)` manage host-owned notes. The toolbar's localized **Page note** button opens an inline editor; empty notes are removed; `noteChange` emits `{ pageIndex, pageNumber, note }` with `null` when a note is cleared. Hosts can persist that payload in a database or other storage.
84
+
85
+ ### `connectEmbed(options?: FlipbookEmbedOptions)`
86
+ Connects an origin-validated postMessage bridge for iframe integrations. Call this from the document loaded inside the iframe.
87
+
88
+ ### `destroy(keepContainer = false)`
89
+ Tears down the instance, unsubscribes all event handlers, and optionally clears the container element HTML.
90
+
91
+ ---
92
+
93
+ ## Iframe embedding
94
+
95
+ Embed integrations use a small, origin-validated `postMessage` bridge. The viewer page (inside the iframe) connects the bridge:
96
+
97
+ ```ts
98
+ const engine = new FlipbookEngine('#viewer', { showThumbs: false });
99
+ const embedBridge = engine.connectEmbed({
100
+ allowedOrigins: ['https://catalog.example.com']
101
+ });
102
+ await engine.init('/files/catalog.pdf');
103
+ ```
104
+
105
+ The parent page can control the iframe with the exported controller:
106
+
107
+ ```ts
108
+ import { createFlipbookEmbedController } from 'flipbookengine';
109
+
110
+ const iframe = document.querySelector('#catalog-frame') as HTMLIFrameElement;
111
+ const catalog = createFlipbookEmbedController(iframe, {
112
+ targetOrigin: 'https://viewer.example.com'
113
+ });
114
+
115
+ await catalog.goToPage(3);
116
+ await catalog.setZoom(1.5);
117
+ catalog.on('pageChange', (state) => console.log(state.pageNumber));
118
+ ```
119
+
120
+ Commands are restricted to navigation, zoom, single-mode, option updates, fullscreen, TOC read/update, search, and state queries. Configure an explicit `allowedOrigins` value in the iframe and `targetOrigin` value in the parent for cross-origin deployments. The bridge rejects messages from other windows or origins.
121
+
122
+ ## Event Subscriptions
123
+
124
+ Use `.on(eventName, handler)` to listen to runtime events:
125
+
126
+ ```javascript
127
+ const unsubscribe = engine.on('pageChange', ({ currentPage, pageNumber, totalPages, isSingle }) => {
128
+ console.log(`Now on page ${pageNumber} of ${totalPages}`);
129
+ });
130
+ ```
131
+
132
+ ### Supported Events
133
+
134
+ - **`pageChange`**: Emitted when page is changed.
135
+ - Payload: `{ currentPage: number; pageNumber: number; totalPages: number; isSingle: boolean }`
136
+ - **`zoomChange`**: Emitted when zoom factor changes.
137
+ - Payload: `{ zoom: number; isActive: boolean }`
138
+ - **`singlePageModeChange`**: Emitted when switching layout mode.
139
+ - Payload: `{ isSingle: boolean }`
140
+ - **`thumbsToggle`**: Emitted when thumbnail rail is toggled.
141
+ - **`tocToggle`**: Emitted when the table of contents panel is toggled.
142
+ - Payload: `{ showToc: boolean }`
143
+ - Payload: `{ showThumbs: boolean }`
144
+ - **`init`**: Emitted after the viewer is ready. Payload: `{ totalPages: number }`
145
+ - **`progress`**: Emitted during PDF loading/rendering. Payload: `{ phase: 'loading' | 'rendering'; completed: number; total: number }`
146
+ - **`orientationChange`**: Emitted when layout orientation changes. Payload: `{ orientation: 'landscape' | 'portrait' }`.
147
+ - **`deepLinkChange`**: Emitted when the active page updates the shareable URL. Payload: `{ pageIndex: number; pageNumber: number; url: string }`.
148
+ - **`bookmarkChange`**: Emitted when a page bookmark is added or removed. Payload: `{ pageIndex: number; pageNumber: number; bookmarked: boolean }`.
149
+ - **`noteChange`**: Emitted when a page note is added, updated, or cleared. Payload: `{ pageIndex: number; pageNumber: number; note: string | null }`.
150
+ - **`error`**: Emitted when PDF loading/rendering fails. Payload: `{ code: 'PDF_LOAD_FAILED' | 'PDF_RENDER_FAILED'; message: string; cause?: unknown }`
151
+ - **`destroy`**: Emitted when the engine is destroyed.
152
+
153
+
154
+ ## PDF rendering lifecycle
155
+
156
+ When `pdfUrl` is supplied without a `pages` list, the engine creates lightweight page placeholders immediately after the document metadata loads. The first page is rendered before `init()` resolves, and the next page is prefetched. Remaining pages render on demand as they become visible or are selected. Rendering requests are deduplicated per page and cancelled when initialization is superseded or the engine is destroyed.
157
+
158
+ Use `pdfRenderConcurrency` to bound concurrent PDF.js work and `pdfRenderCacheSize` to configure the per-instance LRU cache. Set the cache size to `0` when rendered page data should not be retained. `pdfPageMode: 'auto'` detects ISO A3 landscape pages and exposes their left/right halves as two logical pages; `'single'` disables splitting and `'split'` splits every landscape page.
159
+
160
+ ## PDF page formats
161
+
162
+ The viewer derives its page ratio from PDF.js metadata or the supplied image asset. Portrait A4 and landscape A4 are both supported. For a landscape A3 page that contains two A4 pages, use the default `pdfPageMode: 'auto'` or explicit `'split'`; each half becomes a navigable logical page.
163
+
164
+ ## Table of contents
165
+
166
+ TOC entries are supplied by the host application so the viewer stays backend-agnostic. `pageIndex` is zero-based and is clamped to the loaded page range. Nested `children` entries are supported.
167
+
168
+ Use `engine.getToc()` to read the normalized tree or `engine.setToc(entries, show?)` to replace it at runtime. The open-source viewer consumes this manifest; it does not extract PDF outline destinations or generate OCR metadata.
169
+
170
+ ```ts
171
+ const engine = new FlipbookEngine('#viewer', {
172
+ toc: [
173
+ { title: 'Introduction', pageIndex: 0 },
174
+ { title: 'Products', pageIndex: 4, children: [
175
+ { title: 'Category A', pageIndex: 5 }
176
+ ] }
177
+ ],
178
+ showToc: true
179
+ });
180
+ ```
181
+
182
+ ### Search
183
+
184
+ - **`search(query, options?)`**: Extracts and searches PDF text client-side. Returns `{ pageIndex, pageNumber, matches, snippet, sourcePageNumber, highlights? }[]`, stores results for the built-in search panel, and overlays matching text rectangles. `pageIndex` is zero-based; `pageNumber` is one-based. `highlights` coordinates are normalized to the logical page (0..1), including left/right mapping for split PDF pages.
185
+ - **`clearSearch()`** / **`getSearchResults()`**: Clears or reads the current search state.
186
+
187
+ ### Hotspots
188
+
189
+ - **`getHotspots(pageIndex = getCurrentPage())`**: Returns host-provided overlays for a logical page.
190
+ - **`activateHotspot(id)`** / **`closeHotspot()`**: Opens or closes a hotspot popup. Activation emits `hotspotActivate`. Hotspots may include `kind`, `media` (`image`, `video`, `audio`), `gallery` image items, and an optional `href` for commerce/product links; popup text is always rendered as plain text.
191
+
192
+
193
+ ### Page annotations
194
+
195
+ Host uygulamaları, kullanıcı notunu sayfa üzerindeki normalize koordinata bağlamak için `annotations` seçeneğini kullanabilir. Marker tıklaması popup açar ve `annotationActivate` olayı yayınlanır. Bu sözleşme şimdilik host-managed'dir; annotation kayıtlarının backend koordinatlarına taşınması tüketici uygulamanın sorumluluğundadır.
196
+
197
+ ```ts
198
+ const engine = new FlipbookEngine('#viewer', {
199
+ annotations: [{ id: 'note-1', pageIndex: 4, x: .42, y: .36, text: 'Review pricing' }]
200
+ });
201
+ ```
202
+
203
+ ## Plugins
204
+
205
+ See [Plugin architecture](./plugin-architecture.md) for the v1 plugin contract and lifecycle.
206
+
@@ -0,0 +1,73 @@
1
+ # Framework Integrations
2
+
3
+ FlipbookEngine ships with built-in, type-safe wrappers for both React and Vue 3.
4
+
5
+ ## React Wrapper
6
+
7
+ ### Usage
8
+
9
+ ```tsx
10
+ import React, { useRef } from 'react';
11
+ import { Flipbook, FlipbookRef } from 'flipbookengine/react';
12
+ import 'flipbookengine/dist/flipbook-engine.css';
13
+
14
+ function App() {
15
+ const flipbookRef = useRef<FlipbookRef>(null);
16
+
17
+ const handleNextPage = () => {
18
+ if (flipbookRef.current) {
19
+ const current = flipbookRef.current.getCurrentPage();
20
+ flipbookRef.current.goToPage(current + 1);
21
+ }
22
+ };
23
+
24
+ return (
25
+ <div>
26
+ <button onClick={handleNextPage}>Next Page</button>
27
+
28
+ <Flipbook
29
+ ref={flipbookRef}
30
+ pdfUrl="/catalog.pdf"
31
+ pages={[
32
+ { normal: '/1.png', low: '/1-low.png', thumb: '/1-thumb.png' },
33
+ { normal: '/2.png', low: '/2-low.png', thumb: '/2-thumb.png' }
34
+ ]}
35
+ showThumbs={false}
36
+ />
37
+ </div>
38
+ );
39
+ }
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Vue 3 Wrapper
45
+
46
+ ### Usage
47
+
48
+ ```vue
49
+ <template>
50
+ <div>
51
+ <Flipbook
52
+ pdfUrl="/catalog.pdf"
53
+ :pages="pages"
54
+ :allowDownload="true"
55
+ @page-change="onPageChange"
56
+ />
57
+ </div>
58
+ </template>
59
+
60
+ <script setup>
61
+ import { Flipbook } from 'flipbookengine/vue';
62
+ import 'flipbookengine/dist/flipbook-engine.css';
63
+
64
+ const pages = [
65
+ { normal: '/1.png', low: '/1-low.png', thumb: '/1-thumb.png' },
66
+ { normal: '/2.png', low: '/2-low.png', thumb: '/2-thumb.png' }
67
+ ];
68
+
69
+ function onPageChange(event) {
70
+ console.log('Page index changed to:', event.currentPage);
71
+ }
72
+ </script>
73
+ ```
@@ -0,0 +1,128 @@
1
+ # Getting Started
2
+
3
+ Welcome to **FlipbookEngine**! This guide will help you set up and embed FlipbookEngine into your web applications.
4
+
5
+ ## Quick Installation
6
+
7
+ You can install FlipbookEngine via npm:
8
+
9
+ ```bash
10
+ npm install flipbookengine
11
+ ```
12
+
13
+ Or reference it directly via CDN (such as unpkg) in your HTML:
14
+
15
+ ```html
16
+ <link rel="stylesheet" href="https://unpkg.com/flipbookengine/dist/flipbook-engine.css" />
17
+ <script src="https://unpkg.com/flipbookengine/dist/flipbook-engine.iife.js"></script>
18
+ ```
19
+
20
+ ## Setup Container
21
+
22
+ Create an element in your HTML that will contain the flipbook viewer. Ensure the container has explicit dimensions:
23
+
24
+ ```html
25
+ <div id="viewer" style="width: 100%; height: 600px;"></div>
26
+ ```
27
+
28
+ ## Initialize the Engine
29
+
30
+ Import `FlipbookEngine` (if using ESM) and instantiate it:
31
+
32
+ ```javascript
33
+ import { FlipbookEngine } from 'flipbookengine';
34
+ import 'flipbookengine/dist/flipbook-engine.css';
35
+
36
+ const engine = new FlipbookEngine('#viewer', {
37
+ allowDownload: true,
38
+ showThumbs: false,
39
+ primaryColor: '#7367f0'
40
+ });
41
+
42
+ // Load the PDF catalog file along with its rendered images
43
+ await engine.init('/files/catalog.pdf', [
44
+ { kind: 'cover', pageNumber: 1, normal: '/img/1.jpg', low: '/img/1-low.jpg', thumb: '/img/1-thumb.jpg' },
45
+ { kind: 'spread', pageNumbers: [2, 3], normal: '/img/2-3.jpg', low: '/img/2-3-low.jpg', thumb: '/img/2-3-thumb.jpg' }
46
+ ]);
47
+ ```
48
+
49
+ ## Mixed Page Spreads
50
+
51
+ FlipbookEngine supports loading single pages, spreads (double-pages), and covers mixed together. The engine will automatically normalize spreads (cutting them into left and right halves on portrait viewports) for responsive mobile viewing.
52
+
53
+
54
+ ## Iframe embedding
55
+
56
+ For a viewer hosted in an iframe, connect the bridge from the iframe document and allow only the parent origin:
57
+
58
+ ```javascript
59
+ const engine = new FlipbookEngine('#viewer', { showThumbs: false });
60
+ engine.connectEmbed({
61
+ allowedOrigins: ['https://catalog.example.com']
62
+ });
63
+ await engine.init('/files/catalog.pdf');
64
+ ```
65
+
66
+ From the parent page, use the controller exported by the package:
67
+
68
+ ```javascript
69
+ import { createFlipbookEmbedController } from 'flipbookengine';
70
+
71
+ const controller = createFlipbookEmbedController(
72
+ document.querySelector('#catalog-frame'),
73
+ { targetOrigin: 'https://viewer.example.com' }
74
+ );
75
+ await controller.goToPage(2);
76
+ ```
77
+
78
+ Always configure explicit origins for cross-origin embeds. The bridge supports page navigation, zoom, single mode, option updates, fullscreen, TOC read/update, search, state queries, and event forwarding.
79
+
80
+
81
+ ## Deep links and sharing
82
+
83
+ Enable opt-in URL synchronization with the `deepLink` option. The viewer reads an initial `?page=` value, updates it when the page changes, and responds to browser back/forward navigation. Page numbers in URLs are 1-based; engine API indexes remain 0-based.
84
+
85
+ ```ts
86
+ const engine = new FlipbookEngine('#viewer', { deepLink: true });
87
+ await engine.init('/files/catalog.pdf');
88
+
89
+ const pageUrl = engine.getPageUrl(4);
90
+ await engine.sharePage(4);
91
+ // The viewer toolbar also exposes a localized Share button.
92
+ // Bookmark state is host-managed and can be persisted from bookmarkChange.
93
+ engine.on('bookmarkChange', ({ pageNumber, bookmarked }) => {
94
+ console.log(`Page ${pageNumber} bookmarked: ${bookmarked}`);
95
+ });
96
+ engine.on('noteChange', ({ pageNumber, note }) => {
97
+ console.log(`Page ${pageNumber} note changed`, note);
98
+ });
99
+ engine.on('deepLinkChange', ({ pageNumber, url }) => {
100
+ console.log(`Sharing page ${pageNumber}: ${url}`);
101
+ });
102
+ ```
103
+
104
+
105
+ ## Client-side PDF search
106
+
107
+ When initialized with a PDF URL, `search(query)` extracts text through PDF.js without rendering every page. It returns page-level matches and snippets, updates the search toolbar panel, and overlays precise normalized rectangles over matching text when PDF.js exposes text geometry. Search results use a zero-based `pageIndex` for API navigation and a one-based `pageNumber` for display.
108
+
109
+ ```ts
110
+ const results = await engine.search('catalog', { caseSensitive: false, maxResults: 50 });
111
+ engine.goToPage(results[0]?.pageIndex ?? 0);
112
+ engine.clearSearch();
113
+ ```
114
+
115
+ Search is unavailable for image-only page lists because those assets do not contain extractable PDF text or text geometry. For image mode, applications that need search/highlights should generate page text and normalized coordinates on the server and pass the resulting page metadata as a host-side feature; the open-source viewer does not OCR raster images. The iframe controller exposes the same operation with `search`, `clearSearch`, and `getSearchResults`.
116
+
117
+ ## Interactive hotspots
118
+
119
+ Hosts can provide normalized (0..1) page coordinates for lightweight links and pop-ups:
120
+
121
+ ```ts
122
+ const engine = new FlipbookEngine('#viewer', {
123
+ hotspots: [{ id: 'product-42', pageIndex: 3, x: 0.60, y: 0.25, width: 0.25, height: 0.18, label: 'Product details', content: 'Open the product details page.', href: '/products/42' }]
124
+ });
125
+ engine.on('hotspotActivate', ({ hotspot }) => console.log(hotspot.id));
126
+ ```
127
+
128
+ Hotspots support `kind: 'info' | 'media' | 'gallery' | 'commerce'`. A hotspot can render a single image/video/audio preview through `media`, a selectable image gallery through `gallery`, and a safe external/product destination through `href`. Content remains plain text; applications should sanitize server-provided URLs before passing them to the viewer. Use `activateHotspot(id)` and `closeHotspot()` for programmatic control.
package/docs/i18n.md ADDED
@@ -0,0 +1,47 @@
1
+ # Internationalization (i18n)
2
+
3
+ FlipbookEngine features built-in support for multiple locales and customization of all user-facing copy.
4
+
5
+ ## Supported Locales
6
+
7
+ - **`en`** (English - default)
8
+ - **`tr`** (Turkish)
9
+
10
+ ## Set Active Locale
11
+
12
+ Change the language on initialization or dynamically at runtime:
13
+
14
+ ```javascript
15
+ // Initialization
16
+ const engine = new FlipbookEngine('#viewer', {
17
+ locale: 'tr'
18
+ });
19
+
20
+ // Runtime change
21
+ engine.setLocale('en');
22
+ ```
23
+
24
+ ## Overriding Messages
25
+
26
+ Provide translation strings to override specific labels or define messages for a new locale:
27
+
28
+ ```javascript
29
+ const engine = new FlipbookEngine('#viewer', {
30
+ locale: 'de',
31
+ messages: {
32
+ de: {
33
+ emptyStateTitle: 'Keine Seiten gefunden.',
34
+ thumbnails: 'Miniaturansichten',
35
+ singlePageMode: 'Einzelseiten-Modus',
36
+ pages: 'Seiten',
37
+ previous: 'Zurück',
38
+ next: 'Weiter',
39
+ zoomOut: 'Herauszoomen',
40
+ zoomIn: 'Herinzoomen',
41
+ fullscreen: 'Vollbild',
42
+ settings: 'Einstellungen',
43
+ downloadCatalog: 'PDF Herunterladen'
44
+ }
45
+ }
46
+ });
47
+ ```
@@ -0,0 +1,24 @@
1
+ # Migration Guide for 0.4.0
2
+
3
+ ## Scope
4
+
5
+ FlipbookEngine 0.4.0 is the stabilization release described by the audit plan. It keeps the core public navigation methods while making lifecycle, state, wrapper, event, and viewer behavior deterministic across multiple instances.
6
+
7
+ ## Required consumer checks
8
+
9
+ - Keep `pdfjs-dist` installed as the production dependency and provide `pdfWorkerSrc` from the host bundler or CDN. PDF.js is intentionally external to the FlipbookEngine bundle.
10
+ - If host CSS or automation selected fixed viewer IDs, migrate to the instance-scoped classes such as `.bk-book-wrapper`, `.bk-book-sizer`, `.bk-book`, and `.bk-single-view` within the engine container.
11
+ - Treat `pages` as optional when `pdfUrl` is provided. Framework wrappers may update `pdfUrl` and `pages` independently without triggering duplicate initialization.
12
+ - Image-only viewers do not render a download button because no PDF URL is available.
13
+
14
+ ## Runtime behavior changes
15
+
16
+ - Each `FlipbookEngine` instance owns its reactive state; internal singleton store imports must not be used by integrations.
17
+ - A newer `init()` or `destroy()` cancels stale PDF loading, rendering, timers, and listeners.
18
+ - `progress` and `error` events are available for PDF loading/rendering telemetry and failure handling.
19
+ - High-quality page assets are promoted when pages become visible. PDF rendering uses bounded concurrency controlled by `pdfRenderConcurrency` (default `3`).
20
+ - Toolbar and thumbnail controls expose accessible names, state, and keyboard interaction.
21
+
22
+ ## Verification
23
+
24
+ Before shipping an integration, run `npm run typecheck`, `npm test`, and `npm run build` against the locked 0.4.0 dependency tree.
@@ -0,0 +1,25 @@
1
+ # Migration Guide for 0.5.0
2
+
3
+ ## Scope
4
+
5
+ FlipbookEngine 0.5.0 makes PDF-backed viewers responsive for large documents. Page markup is created from PDF metadata, while rendered page images are requested only for the current/nearby pages or when a page becomes visible.
6
+
7
+ ## Runtime behavior changes
8
+
9
+ - `init()` resolves after the first PDF page has rendered. The next page is prefetched in the background.
10
+ - PDF render requests are deduplicated and cancelled when a newer initialization starts or the engine is destroyed.
11
+ - `pdfRenderConcurrency` continues to bound PDF.js work (default `3`).
12
+ - `pdfRenderCacheSize` controls a per-instance least-recently-used cache (default `32`). Set it to `0` to disable retention of rendered page images.
13
+ - `progress` reports loading and rendering phases; `error` reports `PDF_LOAD_FAILED` and `PDF_RENDER_FAILED` failures.
14
+ - Browser, React, and Vue wrappers share the same lifecycle-safe on-demand behavior.
15
+ - Keyboard controls and visible focus states remain available, and `prefers-reduced-motion: reduce` disables page-turn animation and shortens CSS transitions.
16
+
17
+ ## Consumer checks
18
+
19
+ - Keep `pdfjs-dist` installed as the production dependency and provide `pdfWorkerSrc` from the host bundler or CDN.
20
+ - If an application assumed that every PDF page image existed immediately after `init()`, listen for `progress` events or select the page before reading its image element.
21
+ - Choose a cache size based on available memory and page dimensions. A value of `0` is appropriate for strictly bounded memory usage.
22
+
23
+ ## Verification
24
+
25
+ Run `npm run typecheck`, `npm test`, `npm run build`, and `npm run test:e2e` (after installing Playwright browsers) before shipping an integration.
@@ -0,0 +1,59 @@
1
+ # 1.0.0 migration guide
2
+
3
+ FlipbookEngine 1.0.0 is the first stable open-source release. The 0.x line was
4
+ alpha/beta and does not provide a compatibility guarantee. Test the viewer and
5
+ wrapper integrations against the new package before deploying.
6
+
7
+ ## Plugin entry points
8
+
9
+ The all-in-one import remains available:
10
+
11
+ ```ts
12
+ import { FlipbookEngine } from 'flipbookengine';
13
+ ```
14
+
15
+ Optional feature adapters can be loaded independently:
16
+
17
+ ```ts
18
+ import { FlipbookEngine } from 'flipbookengine/core';
19
+ import { notesPlugin } from 'flipbookengine/plugins/notes';
20
+
21
+ const engine = new FlipbookEngine('#viewer', { plugins: [notesPlugin] });
22
+ ```
23
+
24
+ Available adapters are documented in [plugin architecture](./plugin-architecture.md).
25
+ The official OSS package does not include analytics, OCR, PDF outline extraction,
26
+ protected downloads, or backend rendering.
27
+
28
+ ## TOC and iframe API
29
+
30
+ TOC is supplied as a host-provided `FlipbookTocEntry[]` manifest. Use
31
+ `engine.getToc()` and `engine.setToc(entries, show?)` for runtime updates. Iframe
32
+ controllers additionally expose `getToc()` and `setToc()` through the validated
33
+ postMessage bridge.
34
+
35
+ ## Wrapper validation
36
+
37
+ React and Vue wrappers continue to accept the engine options object, including
38
+ `plugins`. Validate wrapper lifecycle, CSS import, PDF worker configuration, and
39
+ host-managed note/bookmark persistence during migration.
40
+
41
+ ## 0.8.0 to 1.0.0 differences
42
+
43
+ The 1.0.0 release is the first compatibility boundary. The 0.x line was alpha/beta, so applications must validate the complete integration instead of assuming semver compatibility.
44
+
45
+ | Area | 0.8.0 | 1.0.0 | Migration impact |
46
+ | --- | --- | --- | --- |
47
+ | Package surface | All-in-one public entry | All-in-one plus core, plugins, and feature subpaths | Imports from documented public paths are supported; imports from internal src/dist files are breaking and must be replaced. |
48
+ | Optional features | Built-in reader surface only | Plugin contract with install/uninstall, typed events, toolbar/panel/API contributions | If an application wants an adapter API, register the adapter explicitly; omitted adapters are inactive. |
49
+ | TOC | Host-provided TOC panel | Nested TOC plus getToc/setToc and iframe commands | Existing TOC data remains host-provided; update integrations that need runtime or embed control. |
50
+ | Hotspots | Basic text/link overlays | info/media/gallery/commerce, image/video/audio previews, galleries, product links | Existing overlays remain valid; new media/gallery fields are additive. |
51
+ | Image mode search | Disabled for raster page lists | Still disabled; PDF mode only | No change; raster search requires host/server text metadata. |
52
+ | Commercial capabilities | Not part of OSS | Still not part of OSS | Backend rendering, OCR/indexing, protected downloads, persistence, identity, and analytics remain commercial/backend work. |
53
+
54
+ ### Breaking-change requirements
55
+
56
+ - Do not depend on undocumented internal modules, generated chunk filenames, or 0.x implementation details.
57
+ - Re-run wrapper and iframe smoke tests after upgrading; React and Vue wrappers must be rebuilt against the 1.0.0 declarations.
58
+ - Treat plugin registration as explicit state. Calling uninstallPlugin removes APIs, UI contributions, event listeners, and cleanup callbacks; it does not merely hide a button.
59
+ - Existing all-in-one initialization with documented options is retained, but the 0.x line has no compatibility guarantee and must not be used as a rollback contract.