postext-epub 0.1.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/LICENSE +21 -0
- package/README.md +194 -0
- package/dist/__tests__/sampleBook.d.ts +17 -0
- package/dist/__tests__/sampleBook.d.ts.map +1 -0
- package/dist/__tests__/sampleBook.js +103 -0
- package/dist/__tests__/sampleBook.js.map +1 -0
- package/dist/epubcheck.test.d.ts +2 -0
- package/dist/epubcheck.test.d.ts.map +1 -0
- package/dist/epubcheck.test.js +69 -0
- package/dist/epubcheck.test.js.map +1 -0
- package/dist/fixed/fixed.test.d.ts +2 -0
- package/dist/fixed/fixed.test.d.ts.map +1 -0
- package/dist/fixed/fixed.test.js +225 -0
- package/dist/fixed/fixed.test.js.map +1 -0
- package/dist/fixed/fontUse.d.ts +21 -0
- package/dist/fixed/fontUse.d.ts.map +1 -0
- package/dist/fixed/fontUse.js +82 -0
- package/dist/fixed/fontUse.js.map +1 -0
- package/dist/fixed/index.d.ts +3 -0
- package/dist/fixed/index.d.ts.map +1 -0
- package/dist/fixed/index.js +254 -0
- package/dist/fixed/index.js.map +1 -0
- package/dist/fixed/outline.d.ts +40 -0
- package/dist/fixed/outline.d.ts.map +1 -0
- package/dist/fixed/outline.js +88 -0
- package/dist/fixed/outline.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/package/pack.d.ts +25 -0
- package/dist/package/pack.d.ts.map +1 -0
- package/dist/package/pack.js +253 -0
- package/dist/package/pack.js.map +1 -0
- package/dist/package/pack.test.d.ts +2 -0
- package/dist/package/pack.test.d.ts.map +1 -0
- package/dist/package/pack.test.js +164 -0
- package/dist/package/pack.test.js.map +1 -0
- package/dist/package/read.d.ts +15 -0
- package/dist/package/read.d.ts.map +1 -0
- package/dist/package/read.js +198 -0
- package/dist/package/read.js.map +1 -0
- package/dist/package/strings.d.ts +17 -0
- package/dist/package/strings.d.ts.map +1 -0
- package/dist/package/strings.js +24 -0
- package/dist/package/strings.js.map +1 -0
- package/dist/reflowable/__tests__/vdt.d.ts +13 -0
- package/dist/reflowable/__tests__/vdt.d.ts.map +1 -0
- package/dist/reflowable/__tests__/vdt.js +55 -0
- package/dist/reflowable/__tests__/vdt.js.map +1 -0
- package/dist/reflowable/__tests__/xml.d.ts +8 -0
- package/dist/reflowable/__tests__/xml.d.ts.map +1 -0
- package/dist/reflowable/__tests__/xml.js +107 -0
- package/dist/reflowable/__tests__/xml.js.map +1 -0
- package/dist/reflowable/css.d.ts +45 -0
- package/dist/reflowable/css.d.ts.map +1 -0
- package/dist/reflowable/css.js +491 -0
- package/dist/reflowable/css.js.map +1 -0
- package/dist/reflowable/index.d.ts +4 -0
- package/dist/reflowable/index.d.ts.map +1 -0
- package/dist/reflowable/index.js +257 -0
- package/dist/reflowable/index.js.map +1 -0
- package/dist/reflowable/inline.d.ts +56 -0
- package/dist/reflowable/inline.d.ts.map +1 -0
- package/dist/reflowable/inline.js +334 -0
- package/dist/reflowable/inline.js.map +1 -0
- package/dist/reflowable/model.d.ts +261 -0
- package/dist/reflowable/model.d.ts.map +1 -0
- package/dist/reflowable/model.js +6 -0
- package/dist/reflowable/model.js.map +1 -0
- package/dist/reflowable/reflowable.test.d.ts +2 -0
- package/dist/reflowable/reflowable.test.d.ts.map +1 -0
- package/dist/reflowable/reflowable.test.js +469 -0
- package/dist/reflowable/reflowable.test.js.map +1 -0
- package/dist/reflowable/rtl.test.d.ts +2 -0
- package/dist/reflowable/rtl.test.d.ts.map +1 -0
- package/dist/reflowable/rtl.test.js +217 -0
- package/dist/reflowable/rtl.test.js.map +1 -0
- package/dist/reflowable/walk.d.ts +42 -0
- package/dist/reflowable/walk.d.ts.map +1 -0
- package/dist/reflowable/walk.js +1096 -0
- package/dist/reflowable/walk.js.map +1 -0
- package/dist/reflowable/xhtml.d.ts +33 -0
- package/dist/reflowable/xhtml.d.ts.map +1 -0
- package/dist/reflowable/xhtml.js +472 -0
- package/dist/reflowable/xhtml.js.map +1 -0
- package/dist/shared/accessibility.d.ts +20 -0
- package/dist/shared/accessibility.d.ts.map +1 -0
- package/dist/shared/accessibility.js +30 -0
- package/dist/shared/accessibility.js.map +1 -0
- package/dist/shared/assets.d.ts +46 -0
- package/dist/shared/assets.d.ts.map +1 -0
- package/dist/shared/assets.js +143 -0
- package/dist/shared/assets.js.map +1 -0
- package/dist/shared/assets.test.d.ts +2 -0
- package/dist/shared/assets.test.d.ts.map +1 -0
- package/dist/shared/assets.test.js +106 -0
- package/dist/shared/assets.test.js.map +1 -0
- package/dist/shared/media.d.ts +11 -0
- package/dist/shared/media.d.ts.map +1 -0
- package/dist/shared/media.js +52 -0
- package/dist/shared/media.js.map +1 -0
- package/dist/shared/uuid.d.ts +7 -0
- package/dist/shared/uuid.d.ts.map +1 -0
- package/dist/shared/uuid.js +63 -0
- package/dist/shared/uuid.js.map +1 -0
- package/dist/shared/xml.d.ts +54 -0
- package/dist/shared/xml.d.ts.map +1 -0
- package/dist/shared/xml.js +214 -0
- package/dist/shared/xml.js.map +1 -0
- package/dist/shared/xml.test.d.ts +2 -0
- package/dist/shared/xml.test.d.ts.map +1 -0
- package/dist/shared/xml.test.js +71 -0
- package/dist/shared/xml.test.js.map +1 -0
- package/dist/shared/xmlRead.d.ts +19 -0
- package/dist/shared/xmlRead.d.ts.map +1 -0
- package/dist/shared/xmlRead.js +85 -0
- package/dist/shared/xmlRead.js.map +1 -0
- package/dist/types.d.ts +205 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/dist/worker/client.d.ts +39 -0
- package/dist/worker/client.d.ts.map +1 -0
- package/dist/worker/client.js +184 -0
- package/dist/worker/client.js.map +1 -0
- package/dist/worker/epub.worker.d.ts +2 -0
- package/dist/worker/epub.worker.d.ts.map +1 -0
- package/dist/worker/epub.worker.js +7 -0
- package/dist/worker/epub.worker.js.map +1 -0
- package/dist/worker/protocol.d.ts +44 -0
- package/dist/worker/protocol.d.ts.map +1 -0
- package/dist/worker/protocol.js +6 -0
- package/dist/worker/protocol.js.map +1 -0
- package/dist/worker/serve.d.ts +11 -0
- package/dist/worker/serve.d.ts.map +1 -0
- package/dist/worker/serve.js +53 -0
- package/dist/worker/serve.js.map +1 -0
- package/dist/worker/worker.test.d.ts +2 -0
- package/dist/worker/worker.test.d.ts.map +1 -0
- package/dist/worker/worker.test.js +168 -0
- package/dist/worker/worker.test.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
+
import { MessageChannel } from 'node:worker_threads';
|
|
3
|
+
import { renderToEpub, readEpub } from '../index';
|
|
4
|
+
import { LORA, PNG, sampleBook } from '../__tests__/sampleBook';
|
|
5
|
+
import { createEpubWorker, gatherResourceBytes, transferablesOf, EpubWorkerError } from './client';
|
|
6
|
+
import { serveEpubRequests } from './serve';
|
|
7
|
+
const MODIFIED = new Date(Date.UTC(2026, 9, 4));
|
|
8
|
+
const metadata = { title: 'Sample book', creators: ['Ada Lovelace'], language: 'en-US', modified: MODIFIED };
|
|
9
|
+
/** A Worker stand-in: the client talks to one end of a channel, the
|
|
10
|
+
* worker code serves the other, as it would in a real worker. */
|
|
11
|
+
class ChannelWorker extends EventTarget {
|
|
12
|
+
terminated = false;
|
|
13
|
+
posted = [];
|
|
14
|
+
port;
|
|
15
|
+
constructor(serve = true) {
|
|
16
|
+
super();
|
|
17
|
+
const { port1, port2 } = new MessageChannel();
|
|
18
|
+
this.port = port1;
|
|
19
|
+
port1.on('message', (data) => this.dispatchEvent(new MessageEvent('message', { data })));
|
|
20
|
+
if (serve) {
|
|
21
|
+
const workerSide = {
|
|
22
|
+
postMessage: (msg, transfer) => port2.postMessage(msg, transfer),
|
|
23
|
+
addEventListener: (_type, listener) => port2.on('message', (data) => listener(new MessageEvent('message', { data }))),
|
|
24
|
+
close: () => port2.close(),
|
|
25
|
+
};
|
|
26
|
+
serveEpubRequests(workerSide);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
postMessage(msg, transfer) {
|
|
30
|
+
this.posted.push(msg);
|
|
31
|
+
this.port.postMessage(msg, (transfer ?? []));
|
|
32
|
+
}
|
|
33
|
+
terminate() {
|
|
34
|
+
this.terminated = true;
|
|
35
|
+
this.port.close();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const asWorker = (w) => w;
|
|
39
|
+
let docs = null;
|
|
40
|
+
const book = () => (docs ??= sampleBook());
|
|
41
|
+
const handles = [];
|
|
42
|
+
afterEach(() => {
|
|
43
|
+
for (const h of handles.splice(0))
|
|
44
|
+
h.dispose();
|
|
45
|
+
});
|
|
46
|
+
describe('gatherResourceBytes', () => {
|
|
47
|
+
it('asks the provider once for every picture the pages place', async () => {
|
|
48
|
+
const asked = [];
|
|
49
|
+
const found = await gatherResourceBytes(book(), (fileId) => {
|
|
50
|
+
asked.push(fileId);
|
|
51
|
+
return fileId === 'f1.png' ? { bytes: PNG, mediaType: 'image/png' } : undefined;
|
|
52
|
+
});
|
|
53
|
+
expect(asked).toEqual(['f1.png']);
|
|
54
|
+
expect(found).toEqual([['f1.png', { bytes: PNG, mediaType: 'image/png' }]]);
|
|
55
|
+
});
|
|
56
|
+
it('takes a map as it is', async () => {
|
|
57
|
+
const map = new Map([['a', { bytes: PNG, mediaType: 'image/png' }]]);
|
|
58
|
+
expect(await gatherResourceBytes(book(), map)).toEqual([['a', { bytes: PNG, mediaType: 'image/png' }]]);
|
|
59
|
+
expect(await gatherResourceBytes(book(), undefined)).toEqual([]);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('transferablesOf', () => {
|
|
63
|
+
it('lists each buffer of the fonts, pictures and cover once', () => {
|
|
64
|
+
const shared = new Uint8Array(8);
|
|
65
|
+
const font = { family: 'A', weight: 400, style: 'normal', format: 'ttf' };
|
|
66
|
+
const buffers = transferablesOf({
|
|
67
|
+
fonts: [{ ...font, bytes: shared.subarray(0, 4) }, { ...font, bytes: shared.subarray(4) }],
|
|
68
|
+
cover: { bytes: new Uint8Array(2), mediaType: 'image/png' },
|
|
69
|
+
}, [['x', { bytes: new Uint8Array(3), mediaType: 'image/png' }], ['y', { bytes: new Uint8Array(0), mediaType: 'image/png' }]]);
|
|
70
|
+
expect(buffers.map((b) => b.byteLength)).toEqual([8, 3, 2]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe('createEpubWorker', () => {
|
|
74
|
+
it('writes the same book as renderToEpub, with progress and warnings', async () => {
|
|
75
|
+
const options = {
|
|
76
|
+
layout: 'fixed',
|
|
77
|
+
metadata,
|
|
78
|
+
fonts: [{ family: 'Lora', weight: 400, style: 'normal', bytes: LORA, format: 'ttf' }],
|
|
79
|
+
};
|
|
80
|
+
const direct = await renderToEpub(book(), {
|
|
81
|
+
...options,
|
|
82
|
+
resourceBytes: (fileId) => (fileId === 'f1.png' ? { bytes: PNG, mediaType: 'image/png' } : undefined),
|
|
83
|
+
});
|
|
84
|
+
const handle = createEpubWorker({ worker: asWorker(new ChannelWorker()) });
|
|
85
|
+
handles.push(handle);
|
|
86
|
+
const progress = [];
|
|
87
|
+
const warnings = [];
|
|
88
|
+
const fontBytes = LORA.slice();
|
|
89
|
+
const bytes = await handle.render(book(), {
|
|
90
|
+
...options,
|
|
91
|
+
fonts: [{ ...options.fonts[0], bytes: fontBytes }],
|
|
92
|
+
resourceBytes: (fileId) => (fileId === 'f1.png' ? { bytes: PNG.slice(), mediaType: 'image/png' } : undefined),
|
|
93
|
+
onProgress: (p) => progress.push(p),
|
|
94
|
+
onWarning: (w) => warnings.push(w),
|
|
95
|
+
});
|
|
96
|
+
expect(bytes).toEqual(direct);
|
|
97
|
+
// The font went over by transfer.
|
|
98
|
+
expect(fontBytes.byteLength).toBe(0);
|
|
99
|
+
expect(progress.at(-1)).toEqual({ phase: 'package', done: 1, total: 1 });
|
|
100
|
+
expect(progress.some((p) => p.phase === 'documents')).toBe(true);
|
|
101
|
+
// The sample sets its footer in the default face, which is not embedded.
|
|
102
|
+
expect(warnings.some((w) => w.kind === 'missingFont')).toBe(true);
|
|
103
|
+
expect(readEpub(bytes).layout).toBe('fixed');
|
|
104
|
+
});
|
|
105
|
+
it('writes a reflowable book with a picture map and a cover', async () => {
|
|
106
|
+
const handle = createEpubWorker({ worker: asWorker(new ChannelWorker()) });
|
|
107
|
+
handles.push(handle);
|
|
108
|
+
const bytes = await handle.render(book(), {
|
|
109
|
+
layout: 'reflowable',
|
|
110
|
+
metadata,
|
|
111
|
+
resourceBytes: new Map([['f1.png', { bytes: PNG.slice(), mediaType: 'image/png' }]]),
|
|
112
|
+
cover: { bytes: PNG.slice(), mediaType: 'image/png' },
|
|
113
|
+
});
|
|
114
|
+
const epub = readEpub(bytes);
|
|
115
|
+
expect(epub.layout).toBe('reflowable');
|
|
116
|
+
expect(epub.coverPath).toBeDefined();
|
|
117
|
+
expect([...epub.files.keys()].some((p) => p.includes('images/f1'))).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
it('rejects at once on abort and ends a worker of its own', async () => {
|
|
120
|
+
const made = [];
|
|
121
|
+
const handle = createEpubWorker({ worker: () => { const w = new ChannelWorker(); made.push(w); return asWorker(w); } });
|
|
122
|
+
handles.push(handle);
|
|
123
|
+
const controller = new AbortController();
|
|
124
|
+
// Stopped as soon as the worker says it has started.
|
|
125
|
+
const pending = handle.render(book(), { layout: 'fixed', metadata, signal: controller.signal, onProgress: () => controller.abort() });
|
|
126
|
+
await expect(pending).rejects.toMatchObject({ name: 'AbortError' });
|
|
127
|
+
expect(made).toHaveLength(1);
|
|
128
|
+
expect(made[0].terminated).toBe(true);
|
|
129
|
+
expect(made[0].posted.some((m) => m.kind === 'cancel')).toBe(true);
|
|
130
|
+
// The next render starts a fresh worker.
|
|
131
|
+
const bytes = await handle.render(book(), { layout: 'reflowable', metadata });
|
|
132
|
+
expect(readEpub(bytes).layout).toBe('reflowable');
|
|
133
|
+
expect(made).toHaveLength(2);
|
|
134
|
+
});
|
|
135
|
+
it('only asks a given worker to stop', async () => {
|
|
136
|
+
const w = new ChannelWorker();
|
|
137
|
+
const handle = createEpubWorker({ worker: asWorker(w) });
|
|
138
|
+
handles.push(handle);
|
|
139
|
+
const controller = new AbortController();
|
|
140
|
+
// Stopped as soon as the worker says it has started.
|
|
141
|
+
const pending = handle.render(book(), { layout: 'fixed', metadata, signal: controller.signal, onProgress: () => controller.abort() });
|
|
142
|
+
await expect(pending).rejects.toMatchObject({ name: 'AbortError' });
|
|
143
|
+
expect(w.terminated).toBe(false);
|
|
144
|
+
const bytes = await handle.render(book(), { layout: 'fixed', metadata });
|
|
145
|
+
expect(readEpub(bytes).layout).toBe('fixed');
|
|
146
|
+
});
|
|
147
|
+
it('turns a worker failure into an EpubWorkerError', async () => {
|
|
148
|
+
const w = new ChannelWorker(false);
|
|
149
|
+
const handle = createEpubWorker({ worker: asWorker(w) });
|
|
150
|
+
handles.push(handle);
|
|
151
|
+
const pending = handle.render(book(), { layout: 'fixed', metadata });
|
|
152
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
153
|
+
const event = Object.assign(new Event('error', { cancelable: true }), { message: 'failed to load' });
|
|
154
|
+
w.dispatchEvent(event);
|
|
155
|
+
await expect(pending).rejects.toBeInstanceOf(EpubWorkerError);
|
|
156
|
+
});
|
|
157
|
+
it('reports a worker that cannot be made as an EpubWorkerError', async () => {
|
|
158
|
+
const handle = createEpubWorker({ worker: () => { throw new Error('Module scripts are not supported'); } });
|
|
159
|
+
handles.push(handle);
|
|
160
|
+
await expect(handle.render(book(), { layout: 'fixed', metadata })).rejects.toBeInstanceOf(EpubWorkerError);
|
|
161
|
+
});
|
|
162
|
+
it('refuses work once disposed', async () => {
|
|
163
|
+
const handle = createEpubWorker({ worker: asWorker(new ChannelWorker()) });
|
|
164
|
+
handle.dispose();
|
|
165
|
+
await expect(handle.render(book(), { layout: 'fixed', metadata })).rejects.toThrow(/disposed/);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
//# sourceMappingURL=worker.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.test.js","sourceRoot":"","sources":["../../src/worker/worker.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "postext-epub",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser-native EPUB 3 writer for Postext documents: fixed-layout (pre-paginated) books that reproduce every printed page with real text, and reflowable books in semantic XHTML styled from the same configuration.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://postext.dev/",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"postext",
|
|
10
|
+
"epub",
|
|
11
|
+
"epub3",
|
|
12
|
+
"ebook",
|
|
13
|
+
"fixed-layout",
|
|
14
|
+
"reflowable",
|
|
15
|
+
"typesetting",
|
|
16
|
+
"typography"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/drnachio/postext.git",
|
|
21
|
+
"directory": "packages/postext-epub"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"sideEffects": [
|
|
27
|
+
"./dist/worker/epub.worker.js"
|
|
28
|
+
],
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./worker": {
|
|
35
|
+
"types": "./dist/worker/client.d.ts",
|
|
36
|
+
"default": "./dist/worker/client.js"
|
|
37
|
+
},
|
|
38
|
+
"./worker/entry": {
|
|
39
|
+
"types": "./dist/worker/epub.worker.d.ts",
|
|
40
|
+
"default": "./dist/worker/epub.worker.js"
|
|
41
|
+
},
|
|
42
|
+
"./package.json": "./package.json"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"postext": "^1.15.0"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"fflate": "^0.8.3"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@postext/typescript-config": "0.0.0",
|
|
52
|
+
"@types/node": "^26.5.0",
|
|
53
|
+
"eslint": "^9.39.4",
|
|
54
|
+
"postext": "1.15.0",
|
|
55
|
+
"typescript": "^6.0.3",
|
|
56
|
+
"typescript-eslint": "^8.70.0",
|
|
57
|
+
"vitest": "^5.0.0"
|
|
58
|
+
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "rm -rf dist && tsc",
|
|
61
|
+
"dev": "tsc --watch",
|
|
62
|
+
"check-types": "tsc --noEmit",
|
|
63
|
+
"lint": "eslint .",
|
|
64
|
+
"test": "vitest run",
|
|
65
|
+
"epubcheck": "EPUBCHECK=1 vitest run src/epubcheck.test.ts",
|
|
66
|
+
"validate": "tsc && node scripts/validate.mjs"
|
|
67
|
+
}
|
|
68
|
+
}
|