@hyebook/vue3-adapter 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.
- package/dist/core/src/editor/commands.d.ts +10 -0
- package/dist/core/src/editor/commands.d.ts.map +1 -0
- package/dist/core/src/editor/commands.js +94 -0
- package/dist/core/src/editor/engine.d.ts +17 -0
- package/dist/core/src/editor/engine.d.ts.map +1 -0
- package/dist/core/src/editor/engine.js +89 -0
- package/dist/core/src/index.d.ts +8 -0
- package/dist/core/src/index.d.ts.map +1 -0
- package/dist/core/src/index.js +7 -0
- package/dist/core/src/player/engine.d.ts +25 -0
- package/dist/core/src/player/engine.d.ts.map +1 -0
- package/dist/core/src/player/engine.js +104 -0
- package/dist/core/src/types/ebook.d.ts +179 -0
- package/dist/core/src/types/ebook.d.ts.map +1 -0
- package/dist/core/src/types/ebook.js +1 -0
- package/dist/core/src/types/player.d.ts +30 -0
- package/dist/core/src/types/player.d.ts.map +1 -0
- package/dist/core/src/types/player.js +1 -0
- package/dist/core/src/utils/validate.d.ts +4 -0
- package/dist/core/src/utils/validate.d.ts.map +1 -0
- package/dist/core/src/utils/validate.js +35 -0
- package/dist/core/src/workbench/editor-workbench.d.ts +59 -0
- package/dist/core/src/workbench/editor-workbench.d.ts.map +1 -0
- package/dist/core/src/workbench/editor-workbench.js +6200 -0
- package/dist/vue3-adapter/src/index.d.ts +16 -0
- package/dist/vue3-adapter/src/index.d.ts.map +1 -0
- package/dist/vue3-adapter/src/index.js +12 -0
- package/package.json +27 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { EbookBlock, EbookDoc, PageNode, TextAlign } from "../types/ebook";
|
|
2
|
+
export interface EditorCommand {
|
|
3
|
+
description: string;
|
|
4
|
+
apply: (doc: EbookDoc) => EbookDoc;
|
|
5
|
+
revert: (doc: EbookDoc) => EbookDoc;
|
|
6
|
+
}
|
|
7
|
+
export declare function addPageCommand(page: PageNode, index?: number): EditorCommand;
|
|
8
|
+
export declare function addBlockCommand(pageId: string, block: EbookBlock): EditorCommand;
|
|
9
|
+
export declare function updateParagraphAlignCommand(pageId: string, blockId: string, paragraphId: string, align: TextAlign): EditorCommand;
|
|
10
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../../core/src/editor/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhF,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,QAAQ,CAAC;IACnC,MAAM,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,QAAQ,CAAC;CACrC;AAMD,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CA0B5E;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,GAChB,aAAa,CAwBf;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,GACf,aAAa,CAgDf"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
function cloneDoc(doc) {
|
|
2
|
+
return JSON.parse(JSON.stringify(doc));
|
|
3
|
+
}
|
|
4
|
+
export function addPageCommand(page, index) {
|
|
5
|
+
return {
|
|
6
|
+
description: `Add page ${page.id}`,
|
|
7
|
+
apply: (doc) => {
|
|
8
|
+
const next = cloneDoc(doc);
|
|
9
|
+
const pages = next.pages;
|
|
10
|
+
const target = index === undefined
|
|
11
|
+
? pages.length
|
|
12
|
+
: Math.max(0, Math.min(index, pages.length));
|
|
13
|
+
pages.splice(target, 0, page);
|
|
14
|
+
pages.forEach((p, i) => {
|
|
15
|
+
p.index = i;
|
|
16
|
+
});
|
|
17
|
+
next.meta.updatedAt = new Date().toISOString();
|
|
18
|
+
return next;
|
|
19
|
+
},
|
|
20
|
+
revert: (doc) => {
|
|
21
|
+
const next = cloneDoc(doc);
|
|
22
|
+
next.pages = next.pages
|
|
23
|
+
.filter((p) => p.id !== page.id)
|
|
24
|
+
.map((p, i) => ({ ...p, index: i }));
|
|
25
|
+
next.meta.updatedAt = new Date().toISOString();
|
|
26
|
+
return next;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function addBlockCommand(pageId, block) {
|
|
31
|
+
return {
|
|
32
|
+
description: `Add block ${block.id}`,
|
|
33
|
+
apply: (doc) => {
|
|
34
|
+
const next = cloneDoc(doc);
|
|
35
|
+
const page = next.pages.find((p) => p.id === pageId);
|
|
36
|
+
if (!page) {
|
|
37
|
+
return next;
|
|
38
|
+
}
|
|
39
|
+
page.blocks.push(block);
|
|
40
|
+
next.meta.updatedAt = new Date().toISOString();
|
|
41
|
+
return next;
|
|
42
|
+
},
|
|
43
|
+
revert: (doc) => {
|
|
44
|
+
const next = cloneDoc(doc);
|
|
45
|
+
const page = next.pages.find((p) => p.id === pageId);
|
|
46
|
+
if (!page) {
|
|
47
|
+
return next;
|
|
48
|
+
}
|
|
49
|
+
page.blocks = page.blocks.filter((item) => item.id !== block.id);
|
|
50
|
+
next.meta.updatedAt = new Date().toISOString();
|
|
51
|
+
return next;
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function updateParagraphAlignCommand(pageId, blockId, paragraphId, align) {
|
|
56
|
+
let previousAlign;
|
|
57
|
+
return {
|
|
58
|
+
description: `Set paragraph ${paragraphId} align to ${align}`,
|
|
59
|
+
apply: (doc) => {
|
|
60
|
+
const next = cloneDoc(doc);
|
|
61
|
+
const page = next.pages.find((p) => p.id === pageId);
|
|
62
|
+
const block = page?.blocks.find((item) => item.id === blockId && item.type === "text");
|
|
63
|
+
if (!block || block.type !== "text") {
|
|
64
|
+
return next;
|
|
65
|
+
}
|
|
66
|
+
const paragraph = block.content.paragraphs.find((item) => item.id === paragraphId);
|
|
67
|
+
if (!paragraph) {
|
|
68
|
+
return next;
|
|
69
|
+
}
|
|
70
|
+
previousAlign = paragraph.align;
|
|
71
|
+
paragraph.align = align;
|
|
72
|
+
next.meta.updatedAt = new Date().toISOString();
|
|
73
|
+
return next;
|
|
74
|
+
},
|
|
75
|
+
revert: (doc) => {
|
|
76
|
+
if (!previousAlign) {
|
|
77
|
+
return doc;
|
|
78
|
+
}
|
|
79
|
+
const next = cloneDoc(doc);
|
|
80
|
+
const page = next.pages.find((p) => p.id === pageId);
|
|
81
|
+
const block = page?.blocks.find((item) => item.id === blockId && item.type === "text");
|
|
82
|
+
if (!block || block.type !== "text") {
|
|
83
|
+
return next;
|
|
84
|
+
}
|
|
85
|
+
const paragraph = block.content.paragraphs.find((item) => item.id === paragraphId);
|
|
86
|
+
if (!paragraph) {
|
|
87
|
+
return next;
|
|
88
|
+
}
|
|
89
|
+
paragraph.align = previousAlign;
|
|
90
|
+
next.meta.updatedAt = new Date().toISOString();
|
|
91
|
+
return next;
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EbookDoc, NewEbookOptions, PageNode } from "../types/ebook";
|
|
2
|
+
import type { EditorCommand } from "./commands";
|
|
3
|
+
export declare class EditorEngine {
|
|
4
|
+
private doc;
|
|
5
|
+
private undoStack;
|
|
6
|
+
private redoStack;
|
|
7
|
+
constructor(initialDoc: EbookDoc);
|
|
8
|
+
static createEmptyDocument(options: NewEbookOptions): EbookDoc;
|
|
9
|
+
static createPage(pageId: string, index: number): PageNode;
|
|
10
|
+
getDocument(): EbookDoc;
|
|
11
|
+
setDocument(nextDoc: EbookDoc): void;
|
|
12
|
+
execute(command: EditorCommand): EbookDoc;
|
|
13
|
+
undo(): EbookDoc | null;
|
|
14
|
+
redo(): EbookDoc | null;
|
|
15
|
+
exportJSON(space?: number): string;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../../core/src/editor/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,SAAS,CAAuB;gBAE5B,UAAU,EAAE,QAAQ;IAKhC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ;IAsC9D,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;IAQ1D,WAAW,IAAI,QAAQ;IAIvB,WAAW,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI;IAOpC,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,QAAQ;IAOzC,IAAI,IAAI,QAAQ,GAAG,IAAI;IAUvB,IAAI,IAAI,QAAQ,GAAG,IAAI;IAUvB,UAAU,CAAC,KAAK,SAAI,GAAG,MAAM;CAG9B"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { assertEbookDoc } from "../utils/validate";
|
|
2
|
+
export class EditorEngine {
|
|
3
|
+
constructor(initialDoc) {
|
|
4
|
+
this.undoStack = [];
|
|
5
|
+
this.redoStack = [];
|
|
6
|
+
assertEbookDoc(initialDoc);
|
|
7
|
+
this.doc = initialDoc;
|
|
8
|
+
}
|
|
9
|
+
static createEmptyDocument(options) {
|
|
10
|
+
const now = new Date().toISOString();
|
|
11
|
+
return {
|
|
12
|
+
id: options.id,
|
|
13
|
+
version: "1.0.0",
|
|
14
|
+
meta: {
|
|
15
|
+
title: options.title,
|
|
16
|
+
...(options.author ? { author: options.author } : {}),
|
|
17
|
+
createdAt: now,
|
|
18
|
+
updatedAt: now,
|
|
19
|
+
},
|
|
20
|
+
settings: {
|
|
21
|
+
page: {
|
|
22
|
+
width: 794,
|
|
23
|
+
height: 1123,
|
|
24
|
+
marginTop: 48,
|
|
25
|
+
marginRight: 48,
|
|
26
|
+
marginBottom: 48,
|
|
27
|
+
marginLeft: 48,
|
|
28
|
+
background: "#FFFFFF",
|
|
29
|
+
},
|
|
30
|
+
defaultTextStyle: {
|
|
31
|
+
fontFamily: "Noto Sans SC",
|
|
32
|
+
fontSize: 16,
|
|
33
|
+
color: "#1F2937",
|
|
34
|
+
lineHeight: 1.6,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
pages: [
|
|
38
|
+
{
|
|
39
|
+
id: "page-1",
|
|
40
|
+
index: 0,
|
|
41
|
+
blocks: [],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
static createPage(pageId, index) {
|
|
47
|
+
return {
|
|
48
|
+
id: pageId,
|
|
49
|
+
index,
|
|
50
|
+
blocks: [],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
getDocument() {
|
|
54
|
+
return JSON.parse(JSON.stringify(this.doc));
|
|
55
|
+
}
|
|
56
|
+
setDocument(nextDoc) {
|
|
57
|
+
assertEbookDoc(nextDoc);
|
|
58
|
+
this.doc = JSON.parse(JSON.stringify(nextDoc));
|
|
59
|
+
this.undoStack = [];
|
|
60
|
+
this.redoStack = [];
|
|
61
|
+
}
|
|
62
|
+
execute(command) {
|
|
63
|
+
this.doc = command.apply(this.doc);
|
|
64
|
+
this.undoStack.push(command);
|
|
65
|
+
this.redoStack = [];
|
|
66
|
+
return this.getDocument();
|
|
67
|
+
}
|
|
68
|
+
undo() {
|
|
69
|
+
const command = this.undoStack.pop();
|
|
70
|
+
if (!command) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
this.doc = command.revert(this.doc);
|
|
74
|
+
this.redoStack.push(command);
|
|
75
|
+
return this.getDocument();
|
|
76
|
+
}
|
|
77
|
+
redo() {
|
|
78
|
+
const command = this.redoStack.pop();
|
|
79
|
+
if (!command) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
this.doc = command.apply(this.doc);
|
|
83
|
+
this.undoStack.push(command);
|
|
84
|
+
return this.getDocument();
|
|
85
|
+
}
|
|
86
|
+
exportJSON(space = 2) {
|
|
87
|
+
return JSON.stringify(this.doc, null, space);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./types/ebook";
|
|
2
|
+
export * from "./types/player";
|
|
3
|
+
export * from "./editor/commands";
|
|
4
|
+
export * from "./editor/engine";
|
|
5
|
+
export * from "./workbench/editor-workbench";
|
|
6
|
+
export * from "./player/engine";
|
|
7
|
+
export * from "./utils/validate";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../core/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { EbookDoc } from "../types/ebook";
|
|
2
|
+
import type { PlayerDataProvider, ReaderNote, ReaderProgress } from "../types/player";
|
|
3
|
+
export interface PlayerState {
|
|
4
|
+
currentPage: number;
|
|
5
|
+
zoom: number;
|
|
6
|
+
notes: ReaderNote[];
|
|
7
|
+
progress: ReaderProgress | null;
|
|
8
|
+
}
|
|
9
|
+
export declare class PlayerEngine {
|
|
10
|
+
private provider;
|
|
11
|
+
private doc;
|
|
12
|
+
private state;
|
|
13
|
+
constructor(provider: PlayerDataProvider);
|
|
14
|
+
load(): Promise<EbookDoc>;
|
|
15
|
+
getDocument(): EbookDoc;
|
|
16
|
+
getState(): PlayerState;
|
|
17
|
+
goToPage(index: number): number;
|
|
18
|
+
nextPage(): number;
|
|
19
|
+
prevPage(): number;
|
|
20
|
+
setZoom(zoom: number): number;
|
|
21
|
+
saveProgress(): Promise<void>;
|
|
22
|
+
addNote(note: Omit<ReaderNote, "id" | "createdAt" | "updatedAt" | "bookId">): Promise<ReaderNote>;
|
|
23
|
+
private restoreUserState;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../../core/src/player/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EACV,kBAAkB,EAClB,UAAU,EACV,cAAc,EACf,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;CACjC;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,GAAG,CAAyB;IACpC,OAAO,CAAC,KAAK,CAKX;gBAEU,QAAQ,EAAE,kBAAkB;IAIlC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC;IAa/B,WAAW,IAAI,QAAQ;IAOvB,QAAQ,IAAI,WAAW;IAIvB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAO/B,QAAQ,IAAI,MAAM;IAIlB,QAAQ,IAAI,MAAM;IAIlB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAMvB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAc7B,OAAO,CACX,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,CAAC,GAClE,OAAO,CAAC,UAAU,CAAC;YAiBR,gBAAgB;CAmB/B"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { assertEbookDoc } from "../utils/validate";
|
|
2
|
+
export class PlayerEngine {
|
|
3
|
+
constructor(provider) {
|
|
4
|
+
this.doc = null;
|
|
5
|
+
this.state = {
|
|
6
|
+
currentPage: 0,
|
|
7
|
+
zoom: 1,
|
|
8
|
+
notes: [],
|
|
9
|
+
progress: null,
|
|
10
|
+
};
|
|
11
|
+
this.provider = provider;
|
|
12
|
+
}
|
|
13
|
+
async load() {
|
|
14
|
+
try {
|
|
15
|
+
const data = await this.provider.getData();
|
|
16
|
+
assertEbookDoc(data);
|
|
17
|
+
this.doc = data;
|
|
18
|
+
await this.restoreUserState();
|
|
19
|
+
return this.doc;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
this.provider.onError?.(toError(error));
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
getDocument() {
|
|
27
|
+
if (!this.doc) {
|
|
28
|
+
throw new Error("Document is not loaded. Call load() first.");
|
|
29
|
+
}
|
|
30
|
+
return JSON.parse(JSON.stringify(this.doc));
|
|
31
|
+
}
|
|
32
|
+
getState() {
|
|
33
|
+
return JSON.parse(JSON.stringify(this.state));
|
|
34
|
+
}
|
|
35
|
+
goToPage(index) {
|
|
36
|
+
const doc = this.getDocument();
|
|
37
|
+
const safeIndex = Math.max(0, Math.min(index, doc.pages.length - 1));
|
|
38
|
+
this.state.currentPage = safeIndex;
|
|
39
|
+
return safeIndex;
|
|
40
|
+
}
|
|
41
|
+
nextPage() {
|
|
42
|
+
return this.goToPage(this.state.currentPage + 1);
|
|
43
|
+
}
|
|
44
|
+
prevPage() {
|
|
45
|
+
return this.goToPage(this.state.currentPage - 1);
|
|
46
|
+
}
|
|
47
|
+
setZoom(zoom) {
|
|
48
|
+
const safeZoom = Math.max(0.5, Math.min(zoom, 3));
|
|
49
|
+
this.state.zoom = safeZoom;
|
|
50
|
+
return safeZoom;
|
|
51
|
+
}
|
|
52
|
+
async saveProgress() {
|
|
53
|
+
if (!this.doc || !this.provider.saveProgress) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const progress = {
|
|
57
|
+
bookId: this.doc.id,
|
|
58
|
+
lastPage: this.state.currentPage,
|
|
59
|
+
zoom: this.state.zoom,
|
|
60
|
+
updatedAt: new Date().toISOString(),
|
|
61
|
+
};
|
|
62
|
+
this.state.progress = progress;
|
|
63
|
+
await this.provider.saveProgress(progress);
|
|
64
|
+
}
|
|
65
|
+
async addNote(note) {
|
|
66
|
+
const doc = this.getDocument();
|
|
67
|
+
const now = new Date().toISOString();
|
|
68
|
+
const nextNote = {
|
|
69
|
+
...note,
|
|
70
|
+
id: `note-${Date.now()}`,
|
|
71
|
+
bookId: doc.id,
|
|
72
|
+
createdAt: now,
|
|
73
|
+
updatedAt: now,
|
|
74
|
+
};
|
|
75
|
+
this.state.notes.push(nextNote);
|
|
76
|
+
if (this.provider.saveNotes) {
|
|
77
|
+
await this.provider.saveNotes(doc.id, this.state.notes);
|
|
78
|
+
}
|
|
79
|
+
return nextNote;
|
|
80
|
+
}
|
|
81
|
+
async restoreUserState() {
|
|
82
|
+
if (!this.doc) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (this.provider.loadProgress) {
|
|
86
|
+
const progress = await this.provider.loadProgress(this.doc.id);
|
|
87
|
+
if (progress) {
|
|
88
|
+
this.state.progress = progress;
|
|
89
|
+
this.state.currentPage = progress.lastPage;
|
|
90
|
+
this.state.zoom = progress.zoom;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (this.provider.loadNotes) {
|
|
94
|
+
const notes = await this.provider.loadNotes(this.doc.id);
|
|
95
|
+
this.state.notes = notes;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function toError(error) {
|
|
100
|
+
if (error instanceof Error) {
|
|
101
|
+
return error;
|
|
102
|
+
}
|
|
103
|
+
return new Error(String(error));
|
|
104
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
export type TextAlign = "left" | "center" | "right" | "justify";
|
|
2
|
+
export type ParagraphType = "p" | "h1" | "h2" | "h3" | "h4" | "quote" | "list";
|
|
3
|
+
export type BlockType = "text" | "image" | "video" | "table";
|
|
4
|
+
export type ImageFitMode = "contain" | "cover" | "fill";
|
|
5
|
+
export interface EbookDoc {
|
|
6
|
+
id: string;
|
|
7
|
+
version: string;
|
|
8
|
+
meta: EbookMeta;
|
|
9
|
+
settings: EbookSettings;
|
|
10
|
+
pages: PageNode[];
|
|
11
|
+
}
|
|
12
|
+
export interface EbookMeta {
|
|
13
|
+
title: string;
|
|
14
|
+
author?: string;
|
|
15
|
+
subject?: string;
|
|
16
|
+
cover?: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
previewAnnotations?: PreviewAnnotations;
|
|
20
|
+
}
|
|
21
|
+
export interface PreviewHighlightAnnotation {
|
|
22
|
+
id: string;
|
|
23
|
+
pageId: string;
|
|
24
|
+
blockId: string;
|
|
25
|
+
start: number;
|
|
26
|
+
end: number;
|
|
27
|
+
color?: string;
|
|
28
|
+
selectedText?: string;
|
|
29
|
+
createdAt?: string;
|
|
30
|
+
updatedAt?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface PreviewNoteAnnotation {
|
|
33
|
+
id: string;
|
|
34
|
+
pageId: string;
|
|
35
|
+
start: number;
|
|
36
|
+
end: number;
|
|
37
|
+
text: string;
|
|
38
|
+
selectedText?: string;
|
|
39
|
+
color?: string;
|
|
40
|
+
createdAt?: string;
|
|
41
|
+
updatedAt?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface PreviewAnnotations {
|
|
44
|
+
highlights: PreviewHighlightAnnotation[];
|
|
45
|
+
notes: PreviewNoteAnnotation[];
|
|
46
|
+
}
|
|
47
|
+
export interface EbookSettings {
|
|
48
|
+
page: PageSettings;
|
|
49
|
+
defaultTextStyle: TextStyle;
|
|
50
|
+
editMode?: "absolute" | "flow";
|
|
51
|
+
}
|
|
52
|
+
export interface PageSettings {
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
marginTop: number;
|
|
56
|
+
marginRight: number;
|
|
57
|
+
marginBottom: number;
|
|
58
|
+
marginLeft: number;
|
|
59
|
+
background?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface TextStyle {
|
|
62
|
+
fontFamily: string;
|
|
63
|
+
fontSize: number;
|
|
64
|
+
color: string;
|
|
65
|
+
lineHeight: number;
|
|
66
|
+
}
|
|
67
|
+
export interface PageNode {
|
|
68
|
+
id: string;
|
|
69
|
+
index: number;
|
|
70
|
+
blocks: EbookBlock[];
|
|
71
|
+
background?: string;
|
|
72
|
+
}
|
|
73
|
+
export interface Rect {
|
|
74
|
+
x: number;
|
|
75
|
+
y: number;
|
|
76
|
+
width: number;
|
|
77
|
+
height: number;
|
|
78
|
+
}
|
|
79
|
+
export interface BlockBase {
|
|
80
|
+
id: string;
|
|
81
|
+
type: BlockType;
|
|
82
|
+
rect: Rect;
|
|
83
|
+
zIndex: number;
|
|
84
|
+
locked?: boolean;
|
|
85
|
+
rotation?: number;
|
|
86
|
+
opacity?: number;
|
|
87
|
+
}
|
|
88
|
+
export interface TextBlock extends BlockBase {
|
|
89
|
+
type: "text";
|
|
90
|
+
content: TextContent;
|
|
91
|
+
style?: Partial<TextStyle>;
|
|
92
|
+
}
|
|
93
|
+
export interface ImageBlock extends BlockBase {
|
|
94
|
+
type: "image";
|
|
95
|
+
src: string;
|
|
96
|
+
alt?: string;
|
|
97
|
+
fit: ImageFitMode;
|
|
98
|
+
caption?: string;
|
|
99
|
+
}
|
|
100
|
+
export interface VideoBlock extends BlockBase {
|
|
101
|
+
type: "video";
|
|
102
|
+
src: string;
|
|
103
|
+
poster?: string;
|
|
104
|
+
controls: boolean;
|
|
105
|
+
autoplay?: boolean;
|
|
106
|
+
muted?: boolean;
|
|
107
|
+
loop?: boolean;
|
|
108
|
+
}
|
|
109
|
+
export interface TableCell {
|
|
110
|
+
id: string;
|
|
111
|
+
text: string;
|
|
112
|
+
html?: string;
|
|
113
|
+
isHeader?: boolean;
|
|
114
|
+
rowSpan?: number;
|
|
115
|
+
colSpan?: number;
|
|
116
|
+
style?: string;
|
|
117
|
+
textStyle?: {
|
|
118
|
+
color?: string;
|
|
119
|
+
fontFamily?: string;
|
|
120
|
+
fontSize?: number;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export interface TableRow {
|
|
124
|
+
id: string;
|
|
125
|
+
cells: TableCell[];
|
|
126
|
+
}
|
|
127
|
+
export interface TableBlock extends BlockBase {
|
|
128
|
+
type: "table";
|
|
129
|
+
rows: TableRow[];
|
|
130
|
+
style?: string;
|
|
131
|
+
}
|
|
132
|
+
export type EbookBlock = TextBlock | ImageBlock | VideoBlock | TableBlock;
|
|
133
|
+
export interface TextContent {
|
|
134
|
+
paragraphs: Paragraph[];
|
|
135
|
+
}
|
|
136
|
+
export interface Paragraph {
|
|
137
|
+
id: string;
|
|
138
|
+
type: ParagraphType;
|
|
139
|
+
align: TextAlign;
|
|
140
|
+
indent?: number;
|
|
141
|
+
lineHeight?: number;
|
|
142
|
+
spacingBefore?: number;
|
|
143
|
+
spacingAfter?: number;
|
|
144
|
+
inlineElements?: InlineElement[];
|
|
145
|
+
runs: TextRun[];
|
|
146
|
+
}
|
|
147
|
+
export interface TextRun {
|
|
148
|
+
text: string;
|
|
149
|
+
marks?: TextMarks;
|
|
150
|
+
inlineRef?: string;
|
|
151
|
+
}
|
|
152
|
+
export interface InlineElement {
|
|
153
|
+
id: string;
|
|
154
|
+
type: "image" | "video";
|
|
155
|
+
src: string;
|
|
156
|
+
alt?: string;
|
|
157
|
+
poster?: string;
|
|
158
|
+
width?: number;
|
|
159
|
+
height?: number;
|
|
160
|
+
align?: "left" | "center" | "right";
|
|
161
|
+
}
|
|
162
|
+
export interface TextMarks {
|
|
163
|
+
bold?: boolean;
|
|
164
|
+
italic?: boolean;
|
|
165
|
+
underline?: boolean;
|
|
166
|
+
strike?: boolean;
|
|
167
|
+
sup?: boolean;
|
|
168
|
+
sub?: boolean;
|
|
169
|
+
fontFamily?: string;
|
|
170
|
+
fontSize?: number;
|
|
171
|
+
color?: string;
|
|
172
|
+
backgroundColor?: string;
|
|
173
|
+
}
|
|
174
|
+
export interface NewEbookOptions {
|
|
175
|
+
id: string;
|
|
176
|
+
title: string;
|
|
177
|
+
author?: string;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=ebook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ebook.d.ts","sourceRoot":"","sources":["../../../../../core/src/types/ebook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EbookDoc } from "./ebook";
|
|
2
|
+
export interface ReaderProgress {
|
|
3
|
+
bookId: string;
|
|
4
|
+
lastPage: number;
|
|
5
|
+
zoom: number;
|
|
6
|
+
updatedAt: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ReaderNote {
|
|
9
|
+
id: string;
|
|
10
|
+
bookId: string;
|
|
11
|
+
pageId: string;
|
|
12
|
+
blockId: string;
|
|
13
|
+
range?: {
|
|
14
|
+
start: number;
|
|
15
|
+
end: number;
|
|
16
|
+
};
|
|
17
|
+
content: string;
|
|
18
|
+
color?: string;
|
|
19
|
+
createdAt: string;
|
|
20
|
+
updatedAt: string;
|
|
21
|
+
}
|
|
22
|
+
export interface PlayerDataProvider {
|
|
23
|
+
getData: () => Promise<EbookDoc>;
|
|
24
|
+
loadProgress?: (bookId: string) => Promise<ReaderProgress | null>;
|
|
25
|
+
saveProgress?: (progress: ReaderProgress) => Promise<void>;
|
|
26
|
+
loadNotes?: (bookId: string) => Promise<ReaderNote[]>;
|
|
27
|
+
saveNotes?: (bookId: string, notes: ReaderNote[]) => Promise<void>;
|
|
28
|
+
onError?: (error: Error) => void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=player.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../../../../../core/src/types/player.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAClE,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../../core/src/utils/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAmClE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,QAAQ,CAIxE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function validateEbookDoc(value) {
|
|
2
|
+
if (!isObject(value)) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
if (typeof value.id !== "string" || typeof value.version !== "string") {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if (!isObject(value.meta) ||
|
|
9
|
+
!isObject(value.settings) ||
|
|
10
|
+
!Array.isArray(value.pages)) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
if (typeof value.meta.title !== "string") {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
for (const page of value.pages) {
|
|
17
|
+
if (!isObject(page)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
if (typeof page.id !== "string" ||
|
|
21
|
+
typeof page.index !== "number" ||
|
|
22
|
+
!Array.isArray(page.blocks)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
export function assertEbookDoc(value) {
|
|
29
|
+
if (!validateEbookDoc(value)) {
|
|
30
|
+
throw new Error("Invalid EbookDoc payload.");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function isObject(value) {
|
|
34
|
+
return typeof value === "object" && value !== null;
|
|
35
|
+
}
|