@storyteller-platform/align 0.1.40 → 0.1.41

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.
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var readium_exports = {};
20
+ __export(readium_exports, {
21
+ generateGuidedNavigationDocuments: () => import_guidedNavigation.generateGuidedNavigationDocuments,
22
+ generateGuidedNavigationManifest: () => import_guidedNavigation.generateGuidedNavigationManifest,
23
+ generateReadiumManifest: () => import_manifest.generateReadiumManifest
24
+ });
25
+ module.exports = __toCommonJS(readium_exports);
26
+ var import_manifest = require("./manifest.cjs");
27
+ var import_guidedNavigation = require("./guidedNavigation.cjs");
28
+ // Annotate the CommonJS export names for ESM import in node:
29
+ 0 && (module.exports = {
30
+ generateGuidedNavigationDocuments,
31
+ generateGuidedNavigationManifest,
32
+ generateReadiumManifest
33
+ });
@@ -0,0 +1,5 @@
1
+ export { generateReadiumManifest } from './manifest.cjs';
2
+ export { ReadiumWebPublicationManifest } from './manifest.types.cjs';
3
+ export { generateGuidedNavigationDocuments, generateGuidedNavigationManifest } from './guidedNavigation.cjs';
4
+ import '@storyteller-platform/epub';
5
+ import '@readium/shared';
@@ -0,0 +1,5 @@
1
+ export { generateReadiumManifest } from './manifest.js';
2
+ export { ReadiumWebPublicationManifest } from './manifest.types.js';
3
+ export { generateGuidedNavigationDocuments, generateGuidedNavigationManifest } from './guidedNavigation.js';
4
+ import '@storyteller-platform/epub';
5
+ import '@readium/shared';
@@ -0,0 +1,11 @@
1
+ import "../chunk-BIEQXUOY.js";
2
+ import { generateReadiumManifest } from "./manifest.js";
3
+ import {
4
+ generateGuidedNavigationDocuments,
5
+ generateGuidedNavigationManifest
6
+ } from "./guidedNavigation.js";
7
+ export {
8
+ generateGuidedNavigationDocuments,
9
+ generateGuidedNavigationManifest,
10
+ generateReadiumManifest
11
+ };
@@ -28,12 +28,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var manifest_exports = {};
30
30
  __export(manifest_exports, {
31
- generateManifest: () => generateManifest
31
+ generateReadiumManifest: () => generateReadiumManifest
32
32
  });
33
33
  module.exports = __toCommonJS(manifest_exports);
34
34
  var import_shared = require("@readium/shared");
35
35
  var import_smil_clockvalue = __toESM(require("smil-clockvalue"), 1);
36
- async function generateManifest(epub) {
36
+ const BYTES_PER_PAGE = 1024;
37
+ async function generateReadiumManifest(epub, options = {}) {
37
38
  const primaryLocale = await epub.getLanguage() ?? new Intl.Locale("en-US");
38
39
  const creators = await epub.getCreators();
39
40
  const authors = creators.filter((contributor) => contributor.role === "aut").map((author) => createContributor(author, primaryLocale));
@@ -53,9 +54,13 @@ async function generateManifest(epub) {
53
54
  const dcSubjects = await epub.getSubjects();
54
55
  const subjects = dcSubjects.map((subject) => {
55
56
  if (typeof subject === "string") {
56
- return new import_shared.Subject({ name: new import_shared.LocalizedString(subject) });
57
+ return new import_shared.Subject({
58
+ // TODO: should this be in primary locale?
59
+ name: new import_shared.LocalizedString(subject)
60
+ });
57
61
  }
58
62
  return new import_shared.Subject({
63
+ // TODO: should this be in primary locale?
59
64
  name: new import_shared.LocalizedString(subject.value),
60
65
  scheme: subject.authority,
61
66
  code: subject.term
@@ -86,6 +91,7 @@ async function generateManifest(epub) {
86
91
  const duration = epubMetadata.find(
87
92
  ({ properties }) => properties["property"] === "media:duration"
88
93
  )?.value;
94
+ const durationMs = duration !== void 0 ? (0, import_smil_clockvalue.default)(duration) : void 0;
89
95
  const otherMetadata = epubMetadata.filter(
90
96
  (meta) => (meta.properties["property"]?.split(":")[0] ?? "") in vocab
91
97
  ).map((meta) => {
@@ -93,6 +99,9 @@ async function generateManifest(epub) {
93
99
  const scheme = vocab[prefix];
94
100
  return [`${scheme}#${property}`, meta.value];
95
101
  });
102
+ const spine = await epub.getSpineItems();
103
+ const epubManifest = await epub.getManifest();
104
+ const numberOfPages = options.inferPageCount ? await inferPageCount(epub, spine, options.signal) : void 0;
96
105
  const metadata = new import_shared.Metadata({
97
106
  title: new import_shared.LocalizedString(title ?? ""),
98
107
  conformsTo: [import_shared.Profile.EPUB],
@@ -122,11 +131,10 @@ async function generateManifest(epub) {
122
131
  readingProgression: dir === "ltr" ? import_shared.ReadingProgression.ltr : import_shared.ReadingProgression.rtl
123
132
  },
124
133
  // TODO: is this meant to be in milliseconds (as here) or seconds?
125
- ...duration !== void 0 && { duration: (0, import_smil_clockvalue.default)(duration) },
134
+ ...durationMs !== void 0 && { duration: durationMs },
135
+ ...numberOfPages !== void 0 && { numberOfPages },
126
136
  otherMetadata: Object.fromEntries(otherMetadata)
127
137
  });
128
- const spine = await epub.getSpineItems();
129
- const epubManifest = await epub.getManifest();
130
138
  const readingOrder = await Promise.all(
131
139
  spine.map(async (item) => {
132
140
  const link = new import_shared.Link({
@@ -158,9 +166,9 @@ async function generateManifest(epub) {
158
166
  rels.add("cover");
159
167
  }
160
168
  if (item.mediaType === "application/xhtml+xml") {
161
- rels.add("content");
169
+ rels.add("contents");
162
170
  }
163
- const otherMetadata2 = epubMetadata.filter((meta) => meta.properties["refines"] === `#${item.id}`).filter(
171
+ const otherResourceMetadata = epubMetadata.filter((meta) => meta.properties["refines"] === `#${item.id}`).filter(
164
172
  (meta) => (meta.properties["property"]?.split(":")[0] ?? "") in vocab
165
173
  ).map((meta) => {
166
174
  const prefix = meta.properties["property"].split(":")[0];
@@ -171,7 +179,7 @@ async function generateManifest(epub) {
171
179
  href: await epub.resolveHref(item.href, void 0, { toRoot: true }),
172
180
  ...item.mediaType && { type: item.mediaType },
173
181
  rels,
174
- properties: new import_shared.Properties(Object.fromEntries(otherMetadata2))
182
+ properties: new import_shared.Properties(Object.fromEntries(otherResourceMetadata))
175
183
  });
176
184
  if (!item.mediaOverlay) return link;
177
185
  const mediaOverlayItem = epubManifest[item.id];
@@ -180,12 +188,12 @@ async function generateManifest(epub) {
180
188
  ({ properties }) => properties["property"] === "media:duration" && properties["refines"] === `#${mediaOverlayItem.id}`
181
189
  );
182
190
  if (!refinedBy?.value) return link;
183
- const duration2 = (0, import_smil_clockvalue.default)(refinedBy.value);
191
+ const itemDuration = (0, import_smil_clockvalue.default)(refinedBy.value);
184
192
  return new import_shared.Link({
185
193
  href: link.href,
186
194
  type: link.mediaType.string,
187
195
  ...link.properties && { properties: link.properties },
188
- duration: duration2
196
+ duration: itemDuration
189
197
  });
190
198
  })
191
199
  );
@@ -210,7 +218,7 @@ async function generateManifest(epub) {
210
218
  })
211
219
  ]);
212
220
  }
213
- return new import_shared.Manifest({
221
+ const manifest = new import_shared.Manifest({
214
222
  context: ["https://readium.org/webpub-manifest/context.jsonld"],
215
223
  metadata,
216
224
  readingOrder: new import_shared.Links(readingOrder),
@@ -225,6 +233,25 @@ async function generateManifest(epub) {
225
233
  ...toc && { toc: new import_shared.Links(toc) },
226
234
  subcollections
227
235
  });
236
+ return manifest.serialize();
237
+ }
238
+ async function inferPageCount(epub, spine, signal) {
239
+ let total = 0;
240
+ for (const item of spine) {
241
+ if (signal?.aborted) {
242
+ throw new (signal.reason instanceof Error ? signal.reason.constructor : Error)(
243
+ signal.reason instanceof Error ? signal.reason.message : "Aborted while inferring page count"
244
+ );
245
+ }
246
+ if (item.mediaType !== "application/xhtml+xml") continue;
247
+ try {
248
+ const length = await epub.getItemArchiveLength(item.id);
249
+ total += Math.max(1, Math.ceil(length / BYTES_PER_PAGE));
250
+ } catch {
251
+ total += 1;
252
+ }
253
+ }
254
+ return total > 0 ? total : void 0;
228
255
  }
229
256
  function createContributor(dcCreator, primaryLocale) {
230
257
  return new import_shared.Contributor({
@@ -256,5 +283,5 @@ function createLinkTree(navList) {
256
283
  }
257
284
  // Annotate the CommonJS export names for ESM import in node:
258
285
  0 && (module.exports = {
259
- generateManifest
286
+ generateReadiumManifest
260
287
  });
@@ -1,6 +1,17 @@
1
- import { Manifest } from '@readium/shared';
2
- import { Epub } from '@storyteller-platform/epub';
1
+ import { EpubReader } from '@storyteller-platform/epub';
2
+ import { ReadiumWebPublicationManifest } from './manifest.types.cjs';
3
3
 
4
- declare function generateManifest(epub: Epub): Promise<Manifest>;
4
+ interface ReadiumManifestOptions {
5
+ /**
6
+ * if true, infer a `numberOfPages`
7
+ * uses the compressed size of the entries, see {@link https://github.com/readium/architecture/issues/123}
8
+ */
9
+ inferPageCount?: boolean;
10
+ signal?: AbortSignal;
11
+ }
12
+ /**
13
+ * build a Readium WebPub manifest for an EPUB
14
+ */
15
+ declare function generateReadiumManifest(epub: EpubReader, options?: ReadiumManifestOptions): Promise<ReadiumWebPublicationManifest>;
5
16
 
6
- export { generateManifest };
17
+ export { type ReadiumManifestOptions, generateReadiumManifest };
@@ -1,6 +1,17 @@
1
- import { Manifest } from '@readium/shared';
2
- import { Epub } from '@storyteller-platform/epub';
1
+ import { EpubReader } from '@storyteller-platform/epub';
2
+ import { ReadiumWebPublicationManifest } from './manifest.types.js';
3
3
 
4
- declare function generateManifest(epub: Epub): Promise<Manifest>;
4
+ interface ReadiumManifestOptions {
5
+ /**
6
+ * if true, infer a `numberOfPages`
7
+ * uses the compressed size of the entries, see {@link https://github.com/readium/architecture/issues/123}
8
+ */
9
+ inferPageCount?: boolean;
10
+ signal?: AbortSignal;
11
+ }
12
+ /**
13
+ * build a Readium WebPub manifest for an EPUB
14
+ */
15
+ declare function generateReadiumManifest(epub: EpubReader, options?: ReadiumManifestOptions): Promise<ReadiumWebPublicationManifest>;
5
16
 
6
- export { generateManifest };
17
+ export { type ReadiumManifestOptions, generateReadiumManifest };
@@ -16,7 +16,8 @@ import {
16
16
  Subjects
17
17
  } from "@readium/shared";
18
18
  import clockvalue from "smil-clockvalue";
19
- async function generateManifest(epub) {
19
+ const BYTES_PER_PAGE = 1024;
20
+ async function generateReadiumManifest(epub, options = {}) {
20
21
  const primaryLocale = await epub.getLanguage() ?? new Intl.Locale("en-US");
21
22
  const creators = await epub.getCreators();
22
23
  const authors = creators.filter((contributor) => contributor.role === "aut").map((author) => createContributor(author, primaryLocale));
@@ -36,9 +37,13 @@ async function generateManifest(epub) {
36
37
  const dcSubjects = await epub.getSubjects();
37
38
  const subjects = dcSubjects.map((subject) => {
38
39
  if (typeof subject === "string") {
39
- return new Subject({ name: new LocalizedString(subject) });
40
+ return new Subject({
41
+ // TODO: should this be in primary locale?
42
+ name: new LocalizedString(subject)
43
+ });
40
44
  }
41
45
  return new Subject({
46
+ // TODO: should this be in primary locale?
42
47
  name: new LocalizedString(subject.value),
43
48
  scheme: subject.authority,
44
49
  code: subject.term
@@ -69,6 +74,7 @@ async function generateManifest(epub) {
69
74
  const duration = epubMetadata.find(
70
75
  ({ properties }) => properties["property"] === "media:duration"
71
76
  )?.value;
77
+ const durationMs = duration !== void 0 ? clockvalue(duration) : void 0;
72
78
  const otherMetadata = epubMetadata.filter(
73
79
  (meta) => (meta.properties["property"]?.split(":")[0] ?? "") in vocab
74
80
  ).map((meta) => {
@@ -76,6 +82,9 @@ async function generateManifest(epub) {
76
82
  const scheme = vocab[prefix];
77
83
  return [`${scheme}#${property}`, meta.value];
78
84
  });
85
+ const spine = await epub.getSpineItems();
86
+ const epubManifest = await epub.getManifest();
87
+ const numberOfPages = options.inferPageCount ? await inferPageCount(epub, spine, options.signal) : void 0;
79
88
  const metadata = new Metadata({
80
89
  title: new LocalizedString(title ?? ""),
81
90
  conformsTo: [Profile.EPUB],
@@ -105,11 +114,10 @@ async function generateManifest(epub) {
105
114
  readingProgression: dir === "ltr" ? ReadingProgression.ltr : ReadingProgression.rtl
106
115
  },
107
116
  // TODO: is this meant to be in milliseconds (as here) or seconds?
108
- ...duration !== void 0 && { duration: clockvalue(duration) },
117
+ ...durationMs !== void 0 && { duration: durationMs },
118
+ ...numberOfPages !== void 0 && { numberOfPages },
109
119
  otherMetadata: Object.fromEntries(otherMetadata)
110
120
  });
111
- const spine = await epub.getSpineItems();
112
- const epubManifest = await epub.getManifest();
113
121
  const readingOrder = await Promise.all(
114
122
  spine.map(async (item) => {
115
123
  const link = new Link({
@@ -141,9 +149,9 @@ async function generateManifest(epub) {
141
149
  rels.add("cover");
142
150
  }
143
151
  if (item.mediaType === "application/xhtml+xml") {
144
- rels.add("content");
152
+ rels.add("contents");
145
153
  }
146
- const otherMetadata2 = epubMetadata.filter((meta) => meta.properties["refines"] === `#${item.id}`).filter(
154
+ const otherResourceMetadata = epubMetadata.filter((meta) => meta.properties["refines"] === `#${item.id}`).filter(
147
155
  (meta) => (meta.properties["property"]?.split(":")[0] ?? "") in vocab
148
156
  ).map((meta) => {
149
157
  const prefix = meta.properties["property"].split(":")[0];
@@ -154,7 +162,7 @@ async function generateManifest(epub) {
154
162
  href: await epub.resolveHref(item.href, void 0, { toRoot: true }),
155
163
  ...item.mediaType && { type: item.mediaType },
156
164
  rels,
157
- properties: new Properties(Object.fromEntries(otherMetadata2))
165
+ properties: new Properties(Object.fromEntries(otherResourceMetadata))
158
166
  });
159
167
  if (!item.mediaOverlay) return link;
160
168
  const mediaOverlayItem = epubManifest[item.id];
@@ -163,12 +171,12 @@ async function generateManifest(epub) {
163
171
  ({ properties }) => properties["property"] === "media:duration" && properties["refines"] === `#${mediaOverlayItem.id}`
164
172
  );
165
173
  if (!refinedBy?.value) return link;
166
- const duration2 = clockvalue(refinedBy.value);
174
+ const itemDuration = clockvalue(refinedBy.value);
167
175
  return new Link({
168
176
  href: link.href,
169
177
  type: link.mediaType.string,
170
178
  ...link.properties && { properties: link.properties },
171
- duration: duration2
179
+ duration: itemDuration
172
180
  });
173
181
  })
174
182
  );
@@ -193,7 +201,7 @@ async function generateManifest(epub) {
193
201
  })
194
202
  ]);
195
203
  }
196
- return new Manifest({
204
+ const manifest = new Manifest({
197
205
  context: ["https://readium.org/webpub-manifest/context.jsonld"],
198
206
  metadata,
199
207
  readingOrder: new Links(readingOrder),
@@ -208,6 +216,25 @@ async function generateManifest(epub) {
208
216
  ...toc && { toc: new Links(toc) },
209
217
  subcollections
210
218
  });
219
+ return manifest.serialize();
220
+ }
221
+ async function inferPageCount(epub, spine, signal) {
222
+ let total = 0;
223
+ for (const item of spine) {
224
+ if (signal?.aborted) {
225
+ throw new (signal.reason instanceof Error ? signal.reason.constructor : Error)(
226
+ signal.reason instanceof Error ? signal.reason.message : "Aborted while inferring page count"
227
+ );
228
+ }
229
+ if (item.mediaType !== "application/xhtml+xml") continue;
230
+ try {
231
+ const length = await epub.getItemArchiveLength(item.id);
232
+ total += Math.max(1, Math.ceil(length / BYTES_PER_PAGE));
233
+ } catch {
234
+ total += 1;
235
+ }
236
+ }
237
+ return total > 0 ? total : void 0;
211
238
  }
212
239
  function createContributor(dcCreator, primaryLocale) {
213
240
  return new Contributor({
@@ -238,5 +265,5 @@ function createLinkTree(navList) {
238
265
  );
239
266
  }
240
267
  export {
241
- generateManifest
268
+ generateReadiumManifest
242
269
  };
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var manifest_types_exports = {};
16
+ module.exports = __toCommonJS(manifest_types_exports);