zreader 0.0.0-stage → 0.2.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 (69) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/LICENSE +21 -0
  3. package/README.md +467 -2
  4. package/dist/agent/index.d.ts +90 -0
  5. package/dist/agent/index.js +293 -0
  6. package/dist/agent/index.js.map +1 -0
  7. package/dist/agent/react/index.d.ts +65 -0
  8. package/dist/agent/react/index.js +286 -0
  9. package/dist/agent/react/index.js.map +1 -0
  10. package/dist/blocks-DwR7l7pz.d.ts +20 -0
  11. package/dist/chunk-3WQBK6DE.js +47 -0
  12. package/dist/chunk-3WQBK6DE.js.map +1 -0
  13. package/dist/chunk-DYQNGV46.js +31 -0
  14. package/dist/chunk-DYQNGV46.js.map +1 -0
  15. package/dist/chunk-ISI35TCM.js +62 -0
  16. package/dist/chunk-ISI35TCM.js.map +1 -0
  17. package/dist/chunk-RNSAFDZ5.js +105 -0
  18. package/dist/chunk-RNSAFDZ5.js.map +1 -0
  19. package/dist/config/index.cjs +196 -0
  20. package/dist/config/index.cjs.map +1 -0
  21. package/dist/config/index.d.cts +159 -0
  22. package/dist/config/index.d.ts +159 -0
  23. package/dist/config/index.js +182 -0
  24. package/dist/config/index.js.map +1 -0
  25. package/dist/content/index.d.ts +143 -0
  26. package/dist/content/index.js +379 -0
  27. package/dist/content/index.js.map +1 -0
  28. package/dist/core/index.d.ts +262 -0
  29. package/dist/core/index.js +935 -0
  30. package/dist/core/index.js.map +1 -0
  31. package/dist/editor/index.d.ts +19 -0
  32. package/dist/editor/index.js +277 -0
  33. package/dist/editor/index.js.map +1 -0
  34. package/dist/index-Bp5oIiZd.d.ts +61 -0
  35. package/dist/next/client/index.d.ts +8 -0
  36. package/dist/next/client/index.js +13 -0
  37. package/dist/next/client/index.js.map +1 -0
  38. package/dist/next/index.cjs +275 -0
  39. package/dist/next/index.cjs.map +1 -0
  40. package/dist/next/index.d.cts +47 -0
  41. package/dist/next/index.d.ts +47 -0
  42. package/dist/next/index.js +265 -0
  43. package/dist/next/index.js.map +1 -0
  44. package/dist/next/server/index.d.ts +81 -0
  45. package/dist/next/server/index.js +51 -0
  46. package/dist/next/server/index.js.map +1 -0
  47. package/dist/react/index.d.ts +392 -0
  48. package/dist/react/index.js +2798 -0
  49. package/dist/react/index.js.map +1 -0
  50. package/dist/reader.css +116 -0
  51. package/dist/rehype/index.d.ts +27 -0
  52. package/dist/rehype/index.js +4 -0
  53. package/dist/rehype/index.js.map +1 -0
  54. package/dist/stubs/empty-config.d.ts +9 -0
  55. package/dist/stubs/empty-config.js +7 -0
  56. package/dist/stubs/empty-config.js.map +1 -0
  57. package/dist/stubs/server-only.d.ts +2 -0
  58. package/dist/stubs/server-only.js +6 -0
  59. package/dist/stubs/server-only.js.map +1 -0
  60. package/dist/styles.css +1 -0
  61. package/dist/tailwind.css +42 -0
  62. package/dist/types-xkdpkPxA.d.ts +147 -0
  63. package/dist/user-config/index.d.ts +17 -0
  64. package/dist/user-config/index.js +35 -0
  65. package/dist/user-config/index.js.map +1 -0
  66. package/dist/virtual-config/index.d.ts +6 -0
  67. package/dist/virtual-config/index.js +10 -0
  68. package/dist/virtual-config/index.js.map +1 -0
  69. package/package.json +237 -4
@@ -0,0 +1,262 @@
1
+ import { R as ReaderClientOptions, a as ReaderSettings, P as Pad, b as BookProgress, H as Highlight, c as Bookmark, d as PadScope, A as Anchor, T as TocEntry } from '../types-xkdpkPxA.js';
2
+ export { B as BookMeta, C as ChapterMeta, e as ChapterProgress, F as FONT_FAMILIES, f as FontFamily, g as HIGHLIGHT_COLORS, h as HighlightColor, I as ISODate, L as LEADINGS, i as Leading, M as MEASURES, j as Measure, k as PadScopeKind, l as TEXT_SIZES, m as THEMES, n as TextSize, o as ThemeName } from '../types-xkdpkPxA.js';
3
+ export { B as BLOCK_TAGS, a as BLOCK_TAG_NAMES, c as createBlockIdAllocator, b as createSlugger, h as hashString, n as normalizeBlockText } from '../blocks-DwR7l7pz.js';
4
+
5
+ /** Pluggable key/value storage. localStorage by default, memory for SSR/tests. */
6
+ interface StorageAdapter {
7
+ get(key: string): string | null;
8
+ set(key: string, value: string): void;
9
+ remove(key: string): void;
10
+ keys(prefix?: string): string[];
11
+ /** Notified when another tab/window changes `key` (or any key if `key` is null). */
12
+ subscribe(listener: (key: string | null) => void): () => void;
13
+ }
14
+ declare class StorageQuotaError extends Error {
15
+ readonly key: string;
16
+ constructor(key: string, cause?: unknown);
17
+ }
18
+ declare function createMemoryAdapter(initial?: Record<string, string>): StorageAdapter & {
19
+ dump(): Record<string, string>;
20
+ };
21
+ /** Returns `null` when localStorage is unavailable (SSR, privacy mode, sandboxed iframes). */
22
+ declare function getLocalStorage(): Storage | null;
23
+ declare function createLocalStorageAdapter(storage?: Storage | null): StorageAdapter;
24
+ /**
25
+ * Ask the browser not to evict our data (Safari ITP / storage pressure).
26
+ * Resolves to whether persistence is granted. Never throws.
27
+ */
28
+ declare function requestPersistentStorage(): Promise<boolean>;
29
+
30
+ interface Cell<T> {
31
+ /** Stable reference until the value changes (safe for useSyncExternalStore). */
32
+ get(): T;
33
+ set(next: T | ((prev: T) => T)): void;
34
+ subscribe(listener: () => void): () => void;
35
+ }
36
+ interface ReaderStoreOptions {
37
+ adapter?: StorageAdapter;
38
+ options?: Partial<ReaderClientOptions>;
39
+ /** Debounce for writes (ms). Writes are also flushed on `pagehide`. */
40
+ writeDelay?: number;
41
+ onError?: (error: unknown) => void;
42
+ now?: () => Date;
43
+ id?: () => string;
44
+ }
45
+ type ReaderStore = ReturnType<typeof createReaderStore>;
46
+ declare function padKeySuffix(scope: PadScope): string;
47
+ declare function defaultId(): string;
48
+ declare function createReaderStore(opts?: ReaderStoreOptions): {
49
+ options: ReaderClientOptions;
50
+ adapter: StorageAdapter;
51
+ server: {
52
+ settings: ReaderSettings;
53
+ list: never[];
54
+ pad: Pad;
55
+ progress(bookId: string): BookProgress;
56
+ };
57
+ prefix: string;
58
+ settings: () => Cell<ReaderSettings>;
59
+ highlights: (bookId: string) => Cell<Highlight[]>;
60
+ bookmarks: (bookId: string) => Cell<Bookmark[]>;
61
+ progress: (bookId: string) => Cell<BookProgress>;
62
+ pad: (scope: PadScope) => Cell<Pad>;
63
+ updateSettings(patch: Partial<Omit<ReaderSettings, "updatedAt">>): void;
64
+ resetSettings(): void;
65
+ addHighlight(input: {
66
+ bookId: string;
67
+ chapterId: string;
68
+ anchor: Anchor;
69
+ color?: string;
70
+ note?: string;
71
+ }): Highlight;
72
+ updateHighlight(bookId: string, id: string, patch: Partial<Pick<Highlight, "color" | "note" | "anchor">>): void;
73
+ removeHighlight(bookId: string, id: string): void;
74
+ addBookmark(input: Omit<Bookmark, "id" | "createdAt" | "updatedAt">): Bookmark;
75
+ removeBookmark(bookId: string, id: string): void;
76
+ findChapterBookmark(bookId: string, chapterId: string): Bookmark | undefined;
77
+ /** Toggle a whole-chapter bookmark. Returns whether the chapter is now bookmarked. */
78
+ toggleChapterBookmark(bookId: string, chapterId: string, label?: string): boolean;
79
+ recordProgress(bookId: string, chapterId: string, p: {
80
+ blockId?: string;
81
+ percent: number;
82
+ }): void;
83
+ markChapterComplete(bookId: string, chapterId: string, completed?: boolean): void;
84
+ savePad(scope: PadScope, markdown: string, json?: unknown): void;
85
+ /** Append markdown to a pad from outside the editor (drops the JSON cache so the editor re-parses). */
86
+ appendToPad(scope: PadScope, markdown: string): void;
87
+ clearPad(scope: PadScope): void;
88
+ /** All storage keys owned by this store's prefix. */
89
+ keys(): string[];
90
+ flush: () => void;
91
+ connect: () => () => void;
92
+ /** Drop cached cells so the next read comes from storage (used after imports). */
93
+ reloadAll(): void;
94
+ };
95
+ /** Markdown blockquote for a passage, optionally linking back to its source. */
96
+ declare function quoteToMarkdown(text: string, opts?: {
97
+ href?: string;
98
+ note?: string;
99
+ }): string;
100
+ /** Markdown snippet used when sending a highlight to the scratchpad. */
101
+ declare function highlightToMarkdown(h: Pick<Highlight, "anchor" | "note">, href?: string): string;
102
+
103
+ /**
104
+ * Every persisted value is wrapped in an envelope carrying its schema version so
105
+ * records written by older versions of the package can be migrated forward.
106
+ */
107
+ interface Envelope<T = unknown> {
108
+ v: number;
109
+ data: T;
110
+ }
111
+ type RecordType = "settings" | "highlights" | "bookmarks" | "progress" | "pad";
112
+ type Migration = (data: unknown) => unknown;
113
+ /**
114
+ * `MIGRATIONS[type][i]` upgrades data from version `i + 1` to `i + 2`.
115
+ * Add a function here (never edit an old one) whenever a record shape changes.
116
+ */
117
+ declare const MIGRATIONS: Record<RecordType, Migration[]>;
118
+ declare function currentVersion(type: RecordType, migrations?: Record<RecordType, Migration[]>): number;
119
+ declare function wrap<T>(type: RecordType, data: T, migrations?: Record<RecordType, Migration[]>): string;
120
+ /** Parse + migrate. Returns `undefined` for missing, corrupt, or future-version data. */
121
+ declare function unwrap(type: RecordType, raw: string | null, migrations?: Record<RecordType, Migration[]>): unknown;
122
+ declare function isAnchor(x: unknown): x is Anchor;
123
+ declare function isHighlight(x: unknown): x is Highlight;
124
+ declare function isBookmark(x: unknown): x is Bookmark;
125
+
126
+ declare const BACKUP_FORMAT = "zreader-backup";
127
+ /** Backups written before the rename to zreader; still accepted on import. */
128
+ declare const LEGACY_BACKUP_FORMATS: readonly string[];
129
+ declare const BACKUP_VERSION = 1;
130
+ interface Backup {
131
+ format: typeof BACKUP_FORMAT | "alr-backup";
132
+ schemaVersion: number;
133
+ exportedAt: string;
134
+ /** Keys are store-relative (prefix stripped), values are stored envelopes. */
135
+ records: Record<string, Envelope>;
136
+ }
137
+ declare function recordTypeForKey(key: string): RecordType | null;
138
+ declare function exportBackup(store: ReaderStore, opts?: {
139
+ bookId?: string;
140
+ }): Backup;
141
+ declare class BackupFormatError extends Error {
142
+ constructor(message: string);
143
+ }
144
+ declare function parseBackup(input: string | unknown): Backup;
145
+ interface ImportResult {
146
+ imported: number;
147
+ skipped: number;
148
+ }
149
+ /**
150
+ * Import a backup. `merge` (default) unions lists by id and keeps the most recently
151
+ * updated version of every record; `replace` wipes this store's keys first.
152
+ */
153
+ declare function importBackup(store: ReaderStore, input: string | Backup, opts?: {
154
+ mode?: "merge" | "replace";
155
+ }): ImportResult;
156
+ /** Human-readable export of a book's highlights and notes. */
157
+ declare function highlightsToMarkdown(title: string, highlights: Highlight[], chapterTitle?: (chapterId: string) => string): string;
158
+
159
+ declare const CONTEXT_LENGTH = 32;
160
+ interface TextSpan {
161
+ start: number;
162
+ end: number;
163
+ }
164
+ declare function quoteFor(text: string, start: number, end: number): {
165
+ exact: string;
166
+ prefix: string;
167
+ suffix: string;
168
+ };
169
+ type ResolveStrategy = "position" | "block" | "quote" | "fuzzy";
170
+ /**
171
+ * Re-anchor a stored anchor in (possibly edited) chapter text.
172
+ * `blockOffset` is the current text offset of the anchor's block, if it still exists.
173
+ */
174
+ declare function resolveInText(text: string, anchor: Anchor, blockOffset?: number): (TextSpan & {
175
+ strategy: ResolveStrategy;
176
+ }) | null;
177
+ /**
178
+ * Sentence containing `offset` within `blockText`. Offsets are block-relative.
179
+ */
180
+ declare function sentenceAt(blockText: string, offset: number, locale?: string): TextSpan;
181
+ /** Expand a block-relative span so it covers whole sentences. */
182
+ declare function expandToSentences(blockText: string, start: number, end: number, locale?: string): TextSpan;
183
+ /** Expand a span so it doesn't cut words in half, and trim surrounding whitespace. */
184
+ declare function snapToWords(text: string, start: number, end: number): TextSpan;
185
+
186
+ /**
187
+ * DOM side of anchoring: map between Ranges and chapter text offsets,
188
+ * resolve stored anchors, paint highlights (CSS Custom Highlight API) and
189
+ * hit-test taps. Never mutates the content DOM, so it is
190
+ * safe with React-rendered (MDX) and server-rendered (HTML) chapters alike.
191
+ */
192
+
193
+ declare const BLOCK_ATTR = "data-block-id";
194
+ declare const IGNORE_ATTR = "data-zr-ignore";
195
+ interface Entry {
196
+ node: Text;
197
+ start: number;
198
+ end: number;
199
+ }
200
+ interface TextIndex {
201
+ root: Element;
202
+ text: string;
203
+ entries: Entry[];
204
+ }
205
+ /**
206
+ * Give blocks and headings the ids the build-time plugin would have given them
207
+ * (`zreader/rehype`), for content rendered without it: MDX compiled
208
+ * by your bundler, JSX, third-party HTML. Same traversal order, same hash, so ids
209
+ * match either way. No-op when the content already carries block ids.
210
+ * Only adds attributes; never changes text or structure.
211
+ */
212
+ declare function ensureBlockIds(root: Element): {
213
+ assigned: number;
214
+ };
215
+ /** Table of contents from the headings in `root` (those with an `id`). */
216
+ declare function collectToc(root: Element, depth?: [min: number, max: number]): TocEntry[];
217
+ declare function buildTextIndex(root: Element): TextIndex;
218
+ /** Text offset of a DOM boundary point. */
219
+ declare function pointToOffset(index: TextIndex, container: Node, offset: number): number;
220
+ declare function offsetToPoint(index: TextIndex, offset: number, preferNext?: boolean): {
221
+ node: Text;
222
+ offset: number;
223
+ } | null;
224
+ declare function rangeToSpan(index: TextIndex, range: Range): TextSpan | null;
225
+ declare function spanToRange(index: TextIndex, span: TextSpan): Range | null;
226
+ declare function blockElementAt(index: TextIndex, offset: number): Element | null;
227
+ /** Text span covered by a block element. */
228
+ declare function blockSpan(index: TextIndex, el: Element): TextSpan | null;
229
+ declare function findBlock(root: Element, blockId: string): Element | null;
230
+ declare function describeSpan(index: TextIndex, span: TextSpan, contentHash?: string): Anchor | null;
231
+ declare function resolveAnchor(index: TextIndex, anchor: Anchor): TextSpan | null;
232
+ /** Selection → word-snapped span inside root, or null. */
233
+ declare function selectionSpan(index: TextIndex, selection: Selection | null): TextSpan | null;
234
+ /** Sentence (chapter-relative span) at a chapter text offset. */
235
+ declare function sentenceSpanAt(index: TextIndex, offset: number, locale?: string): TextSpan | null;
236
+ /** Expand a chapter-relative span to whole sentences (within the start and end blocks). */
237
+ declare function expandSpanToSentences(index: TextIndex, span: TextSpan, locale?: string): TextSpan;
238
+ /** Chapter text offset under a viewport point (tap / click). */
239
+ declare function offsetFromPoint(index: TextIndex, x: number, y: number): number | null;
240
+ interface ResolvedHighlight {
241
+ highlight: Highlight;
242
+ span: TextSpan;
243
+ range: Range;
244
+ }
245
+ declare function supportsHighlightApi(): boolean;
246
+ /** Registry names used for painting: `::highlight(zr-<color>)` and `::highlight(zr-active)`. */
247
+ declare function highlightName(color: string, namespace?: string): string;
248
+ /**
249
+ * Paint highlights with the CSS Custom Highlight API. The DOM is never mutated
250
+ * and no inline styles are written; colours come from `::highlight()` rules in
251
+ * the stylesheet. Returns a cleanup function (no-op where unsupported).
252
+ */
253
+ declare function paintHighlights(resolved: ResolvedHighlight[], opts?: {
254
+ activeId?: string | null;
255
+ namespace?: string;
256
+ }): () => void;
257
+ declare function highlightAtOffset(resolved: ResolvedHighlight[], offset: number): ResolvedHighlight | null;
258
+
259
+ declare const DEFAULT_CLIENT_OPTIONS: ReaderClientOptions;
260
+
261
+ export { Anchor, BACKUP_FORMAT, BACKUP_VERSION, BLOCK_ATTR, BackupFormatError, BookProgress, Bookmark, CONTEXT_LENGTH, DEFAULT_CLIENT_OPTIONS, Highlight, IGNORE_ATTR, LEGACY_BACKUP_FORMATS, MIGRATIONS, Pad, PadScope, ReaderClientOptions, ReaderSettings, StorageQuotaError, TocEntry, blockElementAt, blockSpan, buildTextIndex, collectToc, createLocalStorageAdapter, createMemoryAdapter, createReaderStore, currentVersion, defaultId, describeSpan, ensureBlockIds, expandSpanToSentences, expandToSentences, exportBackup, findBlock, getLocalStorage, highlightAtOffset, highlightName, highlightToMarkdown, highlightsToMarkdown, importBackup, isAnchor, isBookmark, isHighlight, offsetFromPoint, offsetToPoint, padKeySuffix, paintHighlights, parseBackup, pointToOffset, quoteFor, quoteToMarkdown, rangeToSpan, recordTypeForKey, requestPersistentStorage, resolveAnchor, resolveInText, selectionSpan, sentenceAt, sentenceSpanAt, snapToWords, spanToRange, supportsHighlightApi, unwrap, wrap };
262
+ export type { Backup, Cell, Envelope, ImportResult, ReaderStore, ReaderStoreOptions, RecordType, ResolveStrategy, ResolvedHighlight, StorageAdapter, TextIndex, TextSpan };