@openrails/contentkit-ui 0.104.0-rc.3 → 0.105.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.
@@ -1 +1 @@
1
- {"version":3,"file":"zh.js","names":[],"sources":["../../../src/locales/content/zh.ts"],"sourcesContent":["import type { content as en } from \"./en.js\";\n\nexport const content: typeof en = {\n paywall: {\n locked: \"此内容已锁定。\",\n unknown: \"暂时无法确认你的访问权限,请稍后再试。\",\n requiresFirst: \"请先加入,然后即可购买。\",\n previewPages_one: \"第一页可以免费阅读。\",\n previewPages_other: \"前 {count} 页可以免费阅读。\",\n previewSegments_one: \"第一章免费。\",\n previewSegments_other: \"前 {count} 章免费。\",\n freeFrom: \"{date} 起对所有人免费。\",\n joinFirst: \"加入\",\n unlockFor: \"以 {price} 解锁\",\n unlockVersionFor: \"以 {price} 解锁此版本\",\n joinFor: \"以 {price} 加入\",\n subscribe: \"开通 {tier}\",\n haveIt: \"已经拥有?\",\n signIn: \"登录\",\n days_one: \"{count} 天\",\n days_other: \"{count} 天\",\n hours_one: \"{count} 小时\",\n hours_other: \"{count} 小时\",\n renews: \"{price} / {period}\",\n rents: \"{price},可用 {period}\",\n },\n versions: {\n language: \"语言\",\n version: \"版本\",\n locked: \"已锁定\",\n lockedOption: \"{name}(已锁定)\",\n },\n contentEditor: {\n saved: \"已保存。\",\n details: \"详情\",\n listing: \"列表显示\",\n listing_listed: \"显示\",\n listing_members: \"仅对可打开者显示\",\n listing_unlisted: \"不公开列出(仅限链接)\",\n comments: \"评论\",\n comments_open: \"开放\",\n comments_closed: \"关闭(保留已有评论)\",\n comments_hidden: \"隐藏\",\n accessTitle: \"访问权限与价格\",\n access: \"谁可以打开\",\n level_public: \"所有人\",\n level_tier: \"会员等级\",\n level_ppv: \"购买者\",\n level_group: \"分组成员\",\n level_group_ppv: \"购买的分组成员\",\n tiers: \"等级\",\n group: \"分组\",\n previewPages: \"免费页数\",\n previewSegments: \"免费章节数\",\n freeAfter: \"对所有人免费的时间\",\n onSale: \"在售\",\n syncing: \"正在与计费同步…\",\n withdraw: \"停止销售\",\n notForSale: \"未出售。\",\n price: \"价格\",\n currency: \"货币\",\n priceMode: \"销售方式\",\n mode_once: \"一次购买,永久\",\n mode_rent: \"限时访问\",\n mode_renew: \"自动续订\",\n days: \"天数\",\n sell: \"上架销售\",\n reprice: \"修改价格\",\n versions: \"版本\",\n live: \"已上线\",\n edit: \"编辑\",\n close: \"关闭\",\n pageCount: \"{count} 页\",\n addVersion: \"添加版本\",\n chooseLanguage: \"语言\",\n versionLanguage: \"版本语言\",\n versionLanguages: \"版本语言\",\n traits: \"特性\",\n versionLabel: \"标签(可选)\",\n versionPublishAt: \"上线时间(可选)\",\n versionDraft: \"草稿\",\n ownAccess: \"单独的访问规则\",\n deleteVersion: \"删除版本\",\n media: \"媒体\",\n segments: \"章节\",\n noSegments: \"没有章节。\",\n segmentTitle: \"第 {n} 章标题\",\n segmentTitlePlaceholder: \"标题\",\n segmentStart: \"第 {n} 章开始\",\n segmentEnd: \"第 {n} 章结束\",\n segmentRelease: \"第 {n} 章发布时间\",\n addSegment: \"添加章节\",\n saveSegments: \"保存章节\",\n },\n myStats: {\n accessFor: \"{tier}使用时长\",\n accessDescription: \"拥有访问权限的累计时间;一个月按30天计算。\",\n lessThanDay: \"不足1天\",\n unavailable: \"部分统计数据暂时不可用。\",\n completed: \"已看完的{kind}\",\n comments: \"评论\",\n likes: \"收到的赞\",\n dislikes: \"收到的踩\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAqB;CAChC,SAAS;EACP,QAAQ;EACR,SAAS;EACT,eAAe;EACf,kBAAkB;EAClB,oBAAoB;EACpB,qBAAqB;EACrB,uBAAuB;EACvB,UAAU;EACV,WAAW;EACX,WAAW;EACX,kBAAkB;EAClB,SAAS;EACT,WAAW;EACX,QAAQ;EACR,QAAQ;EACR,UAAU;EACV,YAAY;EACZ,WAAW;EACX,aAAa;EACb,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,UAAU;EACV,SAAS;EACT,QAAQ;EACR,cAAc;CAChB;CACA,eAAe;EACb,OAAO;EACP,SAAS;EACT,SAAS;EACT,gBAAgB;EAChB,iBAAiB;EACjB,kBAAkB;EAClB,UAAU;EACV,eAAe;EACf,iBAAiB;EACjB,iBAAiB;EACjB,aAAa;EACb,QAAQ;EACR,cAAc;EACd,YAAY;EACZ,WAAW;EACX,aAAa;EACb,iBAAiB;EACjB,OAAO;EACP,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,WAAW;EACX,QAAQ;EACR,SAAS;EACT,UAAU;EACV,YAAY;EACZ,OAAO;EACP,UAAU;EACV,WAAW;EACX,WAAW;EACX,WAAW;EACX,YAAY;EACZ,MAAM;EACN,MAAM;EACN,SAAS;EACT,UAAU;EACV,MAAM;EACN,MAAM;EACN,OAAO;EACP,WAAW;EACX,YAAY;EACZ,gBAAgB;EAChB,iBAAiB;EACjB,kBAAkB;EAClB,QAAQ;EACR,cAAc;EACd,kBAAkB;EAClB,cAAc;EACd,WAAW;EACX,eAAe;EACf,OAAO;EACP,UAAU;EACV,YAAY;EACZ,cAAc;EACd,yBAAyB;EACzB,cAAc;EACd,YAAY;EACZ,gBAAgB;EAChB,YAAY;EACZ,cAAc;CAChB;CACA,SAAS;EACP,WAAW;EACX,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,WAAW;EACX,UAAU;EACV,OAAO;EACP,UAAU;CACZ;AACF"}
1
+ {"version":3,"file":"zh.js","names":[],"sources":["../../../src/locales/content/zh.ts"],"sourcesContent":["import type { content as en } from \"./en.js\";\n\nexport const content: typeof en = {\n paywall: {\n locked: \"此内容已锁定。\",\n unknown: \"暂时无法确认你的访问权限,请稍后再试。\",\n requiresFirst: \"请先加入,然后即可购买。\",\n previewPages_one: \"第一页可以免费阅读。\",\n previewPages_other: \"前 {count} 页可以免费阅读。\",\n previewSegments_one: \"第一章免费。\",\n previewSegments_other: \"前 {count} 章免费。\",\n freeFrom: \"{date} 起对所有人免费。\",\n joinFirst: \"加入\",\n unlockFor: \"以 {price} 解锁\",\n unlockVersionFor: \"以 {price} 解锁此版本\",\n joinFor: \"以 {price} 加入\",\n subscribe: \"开通 {tier}\",\n haveIt: \"已经拥有?\",\n signIn: \"登录\",\n days_one: \"{count} 天\",\n days_other: \"{count} 天\",\n hours_one: \"{count} 小时\",\n hours_other: \"{count} 小时\",\n renews: \"{price} / {period}\",\n rents: \"{price},可用 {period}\",\n },\n versions: {\n language: \"语言\",\n version: \"版本\",\n locked: \"已锁定\",\n lockedOption: \"{name}(已锁定)\",\n },\n contentEditor: {\n saved: \"已保存。\",\n details: \"详情\",\n listing: \"列表显示\",\n listing_listed: \"显示\",\n listing_members: \"仅对可打开者显示\",\n listing_unlisted: \"不公开列出(仅限链接)\",\n comments: \"评论\",\n comments_open: \"开放\",\n comments_closed: \"关闭(保留已有评论)\",\n comments_hidden: \"隐藏\",\n accessTitle: \"访问权限与价格\",\n accessOnlyTitle: \"访问权限\",\n access: \"谁可以打开\",\n level_public: \"所有人\",\n level_tier: \"会员等级\",\n level_ppv: \"购买者\",\n level_group: \"分组成员\",\n level_group_ppv: \"购买的分组成员\",\n tiers: \"等级\",\n group: \"分组\",\n previewPages: \"免费页数\",\n previewSegments: \"免费章节数\",\n freeAfter: \"对所有人免费的时间\",\n onSale: \"在售\",\n syncing: \"正在与计费同步…\",\n withdraw: \"停止销售\",\n notForSale: \"未出售。\",\n price: \"价格\",\n currency: \"货币\",\n priceMode: \"销售方式\",\n mode_once: \"一次购买,永久\",\n mode_rent: \"限时访问\",\n mode_renew: \"自动续订\",\n days: \"天数\",\n sell: \"上架销售\",\n reprice: \"修改价格\",\n versions: \"版本\",\n live: \"已上线\",\n edit: \"编辑\",\n close: \"关闭\",\n pageCount: \"{count} 页\",\n addVersion: \"添加版本\",\n chooseLanguage: \"语言\",\n versionLanguage: \"版本语言\",\n versionLanguages: \"版本语言\",\n traits: \"特性\",\n versionLabel: \"标签(可选)\",\n versionPublishAt: \"上线时间(可选)\",\n versionDraft: \"草稿\",\n ownAccess: \"单独的访问规则\",\n deleteVersion: \"删除版本\",\n media: \"媒体\",\n segments: \"章节\",\n noSegments: \"没有章节。\",\n segmentTitle: \"第 {n} 章标题\",\n segmentTitlePlaceholder: \"标题\",\n segmentStart: \"第 {n} 章开始\",\n segmentEnd: \"第 {n} 章结束\",\n segmentRelease: \"第 {n} 章发布时间\",\n addSegment: \"添加章节\",\n saveSegments: \"保存章节\",\n },\n myStats: {\n accessFor: \"{tier}使用时长\",\n accessDescription: \"拥有访问权限的累计时间;一个月按30天计算。\",\n lessThanDay: \"不足1天\",\n unavailable: \"部分统计数据暂时不可用。\",\n completed: \"已看完的{kind}\",\n comments: \"评论\",\n likes: \"收到的赞\",\n dislikes: \"收到的踩\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAqB;CAChC,SAAS;EACP,QAAQ;EACR,SAAS;EACT,eAAe;EACf,kBAAkB;EAClB,oBAAoB;EACpB,qBAAqB;EACrB,uBAAuB;EACvB,UAAU;EACV,WAAW;EACX,WAAW;EACX,kBAAkB;EAClB,SAAS;EACT,WAAW;EACX,QAAQ;EACR,QAAQ;EACR,UAAU;EACV,YAAY;EACZ,WAAW;EACX,aAAa;EACb,QAAQ;EACR,OAAO;CACT;CACA,UAAU;EACR,UAAU;EACV,SAAS;EACT,QAAQ;EACR,cAAc;CAChB;CACA,eAAe;EACb,OAAO;EACP,SAAS;EACT,SAAS;EACT,gBAAgB;EAChB,iBAAiB;EACjB,kBAAkB;EAClB,UAAU;EACV,eAAe;EACf,iBAAiB;EACjB,iBAAiB;EACjB,aAAa;EACb,iBAAiB;EACjB,QAAQ;EACR,cAAc;EACd,YAAY;EACZ,WAAW;EACX,aAAa;EACb,iBAAiB;EACjB,OAAO;EACP,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,WAAW;EACX,QAAQ;EACR,SAAS;EACT,UAAU;EACV,YAAY;EACZ,OAAO;EACP,UAAU;EACV,WAAW;EACX,WAAW;EACX,WAAW;EACX,YAAY;EACZ,MAAM;EACN,MAAM;EACN,SAAS;EACT,UAAU;EACV,MAAM;EACN,MAAM;EACN,OAAO;EACP,WAAW;EACX,YAAY;EACZ,gBAAgB;EAChB,iBAAiB;EACjB,kBAAkB;EAClB,QAAQ;EACR,cAAc;EACd,kBAAkB;EAClB,cAAc;EACd,WAAW;EACX,eAAe;EACf,OAAO;EACP,UAAU;EACV,YAAY;EACZ,cAAc;EACd,yBAAyB;EACzB,cAAc;EACd,YAAY;EACZ,gBAAgB;EAChB,YAAY;EACZ,cAAc;CAChB;CACA,SAAS;EACP,WAAW;EACX,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,WAAW;EACX,UAAU;EACV,OAAO;EACP,UAAU;CACZ;AACF"}
@@ -329,6 +329,7 @@ export declare const en: {
329
329
  comments_closed: string;
330
330
  comments_hidden: string;
331
331
  accessTitle: string;
332
+ accessOnlyTitle: string;
332
333
  access: string;
333
334
  level_public: string;
334
335
  level_tier: string;
@@ -68,7 +68,9 @@ export declare function startDownload(d: FileDownload): void;
68
68
  export declare function downloadMessage(m: Translator, err: ContentKitError | undefined, now?: number): string | undefined;
69
69
  /**
70
70
  * A version's download, charged to the viewer's download quota: the
71
- * original or rendition its kind serves, or its pages as a zip.
71
+ * original or rendition its kind serves, or its pages as a zip. Polls while
72
+ * it is prepared (a zip is built after its pages publish, behind the worker
73
+ * queue); render_timeout after ten minutes.
72
74
  */
73
75
  export declare function useVersionDownload(content: string, version: string, o?: {
74
76
  poll?: number;
@@ -1,25 +1,25 @@
1
- import { throwIfAborted as e, toContentKitError as t } from "../client/errors.js";
2
- import { sleep as n } from "../client/media/client.js";
3
- import { useMessages as r } from "../i18n/context.js";
4
- import { keyOf as i, useContentScope as a, useResource as o } from "./use-resource.js";
5
- import { useMediaRead as s } from "./read.js";
6
- import { isPending as c } from "../client/versions.js";
7
- import { useCallback as l, useEffect as u, useMemo as d, useState as f } from "react";
1
+ import { ContentKitError as e, throwIfAborted as t, toContentKitError as n } from "../client/errors.js";
2
+ import { sleep as r } from "../client/media/client.js";
3
+ import { useMessages as i } from "../i18n/context.js";
4
+ import { keyOf as a, useContentScope as o, useResource as s } from "./use-resource.js";
5
+ import { useMediaRead as c } from "./read.js";
6
+ import { isPending as l } from "../client/versions.js";
7
+ import { useCallback as u, useEffect as d, useMemo as f, useState as p } from "react";
8
8
  //#region src/react/versions.ts
9
- var p = 2 ** 31 - 1;
10
- function m(e, t = Date.now()) {
9
+ var m = 2 ** 31 - 1;
10
+ function h(e, t = Date.now()) {
11
11
  let n = (e?.segments ?? []).flatMap((e) => !e.released && e.release_at ? [Date.parse(e.release_at)] : []).filter((e) => e > t);
12
12
  return n.length ? Math.min(...n) : null;
13
13
  }
14
- function h(e, t, n = {}) {
15
- let { client: r, store: s, scope: l } = a(n.client), d = e && t ? i("reader-plan", l, e, t) : null, f = o(s, d, {
14
+ function g(e, t, n = {}) {
15
+ let { client: r, store: i, scope: c } = o(n.client), u = e && t ? a("reader-plan", c, e, t) : null, f = s(i, u, {
16
16
  type: "reader-plan",
17
17
  id: t ?? void 0
18
- }, (n) => r.versions.reader(e, t, n)), h = c(f.data), g = f.data && !h ? f.data : null, { data: _, reload: v } = f;
19
- return u(() => {
20
- let e = c(_) ? Date.now() + (n.poll ?? 5e3) : m(_ || null);
18
+ }, (n) => r.versions.reader(e, t, n)), p = l(f.data), g = f.data && !p ? f.data : null, { data: _, reload: v } = f;
19
+ return d(() => {
20
+ let e = l(_) ? Date.now() + (n.poll ?? 5e3) : h(_ || null);
21
21
  if (e === null) return;
22
- let t = setTimeout(v, Math.min(p, Math.max(0, e - Date.now()) + 500));
22
+ let t = setTimeout(v, Math.min(m, Math.max(0, e - Date.now()) + 500));
23
23
  return () => clearTimeout(t);
24
24
  }, [
25
25
  _,
@@ -27,14 +27,14 @@ function h(e, t, n = {}) {
27
27
  n.poll
28
28
  ]), {
29
29
  plan: g,
30
- pending: h,
31
- loading: !!d && (f.loading || !f.loaded),
30
+ pending: p,
31
+ loading: !!u && (f.loading || !f.loaded),
32
32
  error: f.error,
33
33
  reload: v
34
34
  };
35
35
  }
36
- function g(e, t, n = {}) {
37
- let r = e?.item ?? null, i = s(r ?? {
36
+ function _(e, t, n = {}) {
37
+ let r = e?.item ?? null, i = c(r ?? {
38
38
  kind: "",
39
39
  id: ""
40
40
  }, {
@@ -43,7 +43,7 @@ function g(e, t, n = {}) {
43
43
  client: n.client
44
44
  });
45
45
  return {
46
- pages: d(() => {
46
+ pages: f(() => {
47
47
  let n = new Map((i.read?.files ?? []).flatMap((e) => e.url ? [[e.path, e.url]] : []));
48
48
  return (e?.pages ?? []).map((e) => {
49
49
  let r = e.files[t];
@@ -63,11 +63,11 @@ function g(e, t, n = {}) {
63
63
  error: i.error
64
64
  };
65
65
  }
66
- function _(e) {
66
+ function v(e) {
67
67
  let t = document.createElement("a");
68
68
  t.href = e.url, t.download = e.name, t.rel = "noopener", t.style.display = "none", document.body.appendChild(t), t.click(), t.remove();
69
69
  }
70
- function v(e, t, n = Date.now()) {
70
+ function y(e, t, n = Date.now()) {
71
71
  switch (t?.code) {
72
72
  case void 0: return;
73
73
  case "rate_limited": return e.t("versionDownload.limited", { minutes: Math.max(1, Math.ceil((t.retryAfter ?? 60) / 60)) });
@@ -80,64 +80,66 @@ function v(e, t, n = Date.now()) {
80
80
  default: return e.t("versionDownload.failed");
81
81
  }
82
82
  }
83
- function y(i, o, s = {}) {
84
- let { client: p, scope: m } = a(s.client), h = r(), g = d(() => ({
85
- client: p,
86
- scope: m,
87
- content: i,
88
- version: o,
83
+ function b(a, s, c = {}) {
84
+ let { client: m, scope: h } = o(c.client), g = i(), _ = f(() => ({
85
+ client: m,
86
+ scope: h,
87
+ content: a,
88
+ version: s,
89
89
  active: void 0
90
90
  }), [
91
- p,
92
91
  m,
93
- i,
94
- o
95
- ]), [y, b] = f();
96
- u(() => () => g.active?.abort(), [g]);
97
- let x = y?.owner === g ? y : void 0, S = s.start ?? _;
92
+ h,
93
+ a,
94
+ s
95
+ ]), [b, x] = p();
96
+ d(() => () => _.active?.abort(), [_]);
97
+ let S = b?.owner === _ ? b : void 0, C = c.start ?? v;
98
98
  return {
99
- download: l(async () => {
100
- g.active?.abort();
101
- let r = g.active = new AbortController(), { signal: a } = r;
102
- b({
103
- owner: g,
99
+ download: u(async () => {
100
+ _.active?.abort();
101
+ let i = _.active = new AbortController(), { signal: o } = i;
102
+ x({
103
+ owner: _,
104
104
  preparing: !0
105
105
  });
106
+ let u = Date.now() + 6e5;
106
107
  try {
107
108
  for (;;) {
108
- let t = await p.versions.download(i, o, a);
109
- if (e(a), !c(t)) return S(t), t;
110
- await n(s.poll ?? 3e3, a);
109
+ let n = await m.versions.download(a, s, o);
110
+ if (t(o), !l(n)) return C(n), n;
111
+ if (Date.now() >= u) throw new e("render_timeout", "the download is still being prepared");
112
+ await r(c.poll ?? 3e3, o);
111
113
  }
112
114
  } catch (e) {
113
- let n = t(e);
114
- throw !a.aborted && g.active === r && b({
115
- owner: g,
115
+ let t = n(e);
116
+ throw !o.aborted && _.active === i && x({
117
+ owner: _,
116
118
  preparing: !1,
117
- error: n,
118
- retryAt: n.code === "rate_limited" ? Date.now() + (n.retryAfter ?? 60) * 1e3 : void 0
119
- }), n;
119
+ error: t,
120
+ retryAt: t.code === "rate_limited" ? Date.now() + (t.retryAfter ?? 60) * 1e3 : void 0
121
+ }), t;
120
122
  } finally {
121
- !a.aborted && g.active === r && b((e) => e?.owner === g ? {
123
+ !o.aborted && _.active === i && x((e) => e?.owner === _ ? {
122
124
  ...e,
123
125
  preparing: !1
124
126
  } : e);
125
127
  }
126
128
  }, [
127
- p,
128
- i,
129
- o,
130
- s.poll,
131
- S,
132
- g
129
+ m,
130
+ a,
131
+ s,
132
+ c.poll,
133
+ C,
134
+ _
133
135
  ]),
134
- preparing: x?.preparing ?? !1,
135
- error: x?.error,
136
- retryAt: x?.retryAt,
137
- message: v(h, x?.error)
136
+ preparing: S?.preparing ?? !1,
137
+ error: S?.error,
138
+ retryAt: S?.retryAt,
139
+ message: y(g, S?.error)
138
140
  };
139
141
  }
140
142
  //#endregion
141
- export { v as downloadMessage, m as nextRelease, _ as startDownload, h as useReaderPlan, g as useSegmentPages, y as useVersionDownload };
143
+ export { y as downloadMessage, h as nextRelease, v as startDownload, g as useReaderPlan, _ as useSegmentPages, b as useVersionDownload };
142
144
 
143
145
  //# sourceMappingURL=versions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","names":[],"sources":["../../src/react/versions.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport { throwIfAborted, toContentKitError, type ContentKitError } from \"../client/errors.js\";\nimport type { FileDownload, Pending, PlanSegment, ReaderPlan } from \"../client/generated/wire.js\";\nimport { isPending } from \"../client/versions.js\";\nimport { sleep } from \"../client/media/client.js\";\nimport { useMessages } from \"../i18n/context.js\";\nimport type { Translator } from \"../i18n/messages.js\";\nimport { useMediaRead, type ReadWindow } from \"./read.js\";\nimport { keyOf, useContentScope, useResource } from \"./use-resource.js\";\n\nexport interface UseReaderPlan {\n /** null while loading, pending or failed. */\n plan: ReaderPlan | null;\n /** The version has no current publication yet; the hook asks again. */\n pending: boolean;\n loading: boolean;\n error?: ContentKitError;\n reload: () => void;\n}\n\n// setTimeout's longest delay.\nconst MAX_DELAY = 2 ** 31 - 1;\n\n/** When the plan changes by itself: its next scheduled segment's release. */\nexport function nextRelease(plan: ReaderPlan | null, now = Date.now()): number | null {\n const at = (plan?.segments ?? []).flatMap((s) => (!s.released && s.release_at ? [Date.parse(s.release_at)] : [])).filter((t) => t > now);\n return at.length ? Math.min(...at) : null;\n}\n\n/**\n * A version's reader plan for this viewer: its segments (released or not,\n * open or locked), previews, playback item and reader metadata. It asks again\n * while the version is being published and when its next segment is released.\n */\nexport function useReaderPlan(content: string | null | undefined, version: string | null | undefined, o: { poll?: number; client?: ContentKitClient } = {}): UseReaderPlan {\n const { client, store, scope } = useContentScope(o.client);\n const key = content && version ? keyOf(\"reader-plan\", scope, content, version) : null;\n const r = useResource<ReaderPlan | Pending>(store, key, { type: \"reader-plan\", id: version ?? undefined }, (s) => client.versions.reader(content!, version!, s));\n const pending = isPending(r.data);\n const plan = r.data && !pending ? (r.data as ReaderPlan) : null;\n const { data, reload } = r;\n // Every answer schedules the next look: a pending one polls, a plan waits for its next release.\n useEffect(() => {\n const at = isPending(data) ? Date.now() + (o.poll ?? 5000) : nextRelease(data ? (data as ReaderPlan) : null);\n if (at === null) return;\n const t = setTimeout(reload, Math.min(MAX_DELAY, Math.max(0, at - Date.now()) + 500));\n return () => clearTimeout(t);\n }, [data, reload, o.poll]);\n return { plan, pending, loading: !!key && (r.loading || !r.loaded), error: r.error, reload };\n}\n\n/** A segment's page with the URL of one rendition, once its item's read signed it. */\nexport interface ReaderPage {\n name: string;\n w: number;\n h: number;\n /** undefined until read, or when the page lacks the rendition. */\n url?: string;\n}\n\nexport interface UseSegmentPages {\n pages: ReaderPage[];\n loading: boolean;\n error?: ContentKitError;\n}\n\n/**\n * An open segment's pages with URLs of one rendition, read through its\n * published item (windowed for long segments, refreshed before the URLs expire).\n */\nexport function useSegmentPages(segment: PlanSegment | null | undefined, rendition: string, o: { window?: ReadWindow; client?: ContentKitClient } = {}): UseSegmentPages {\n const item = segment?.item ?? null;\n const read = useMediaRead(item ?? { kind: \"\", id: \"\" }, { window: o.window, read: item ? undefined : null, client: o.client });\n const pages = useMemo(() => {\n const urls = new Map((read.read?.files ?? []).flatMap((f) => (f.url ? [[f.path, f.url] as const] : [])));\n return (segment?.pages ?? []).map((p) => {\n const path = p.files[rendition];\n return { name: p.name, w: p.w, h: p.h, url: path ? urls.get(path) : undefined };\n });\n }, [segment, rendition, read.read]);\n return { pages, loading: !!item && read.loading, error: read.error };\n}\n\nexport interface UseVersionDownload {\n /**\n * Grants the download (asking again while it is prepared), starts it in the\n * browser and resolves with the grant.\n */\n download: () => Promise<FileDownload>;\n /** Being prepared by the server, or granted and starting. */\n preparing: boolean;\n error?: ContentKitError;\n /** While a quota refused: when the viewer may download again (ms). */\n retryAt?: number;\n /**\n * What to tell the viewer about the last refusal: when a quota frees, when\n * a download the site holds back opens (\"available to download in N\n * days\"), a locked version, nothing to download, or a failure.\n */\n message?: string;\n}\n\n/** Starts a granted download: the browser fetches its URL, an attachment. */\nexport function startDownload(d: FileDownload): void {\n const a = document.createElement(\"a\");\n a.href = d.url;\n a.download = d.name;\n a.rel = \"noopener\";\n a.style.display = \"none\";\n document.body.appendChild(a);\n a.click();\n a.remove();\n}\n\n/** The viewer's line for a download refusal at now. */\nexport function downloadMessage(m: Translator, err: ContentKitError | undefined, now = Date.now()): string | undefined {\n switch (err?.code) {\n case undefined:\n return undefined;\n case \"rate_limited\":\n return m.t(\"versionDownload.limited\", { minutes: Math.max(1, Math.ceil((err.retryAfter ?? 60) / 60)) });\n case \"download_unavailable\": {\n const ms = err.availableAt ? Date.parse(err.availableAt) - now : NaN;\n return ms > 0 ? m.plural(\"versionDownload.availableIn\", Math.max(1, Math.ceil(ms / 86_400_000))) : m.t(\"versionDownload.unavailable\");\n }\n case \"forbidden\":\n return m.t(\"versionDownload.locked\");\n case \"no_download\":\n return m.error(err);\n default:\n return m.t(\"versionDownload.failed\");\n }\n}\n\n/**\n * A version's download, charged to the viewer's download quota: the\n * original or rendition its kind serves, or its pages as a zip.\n */\nexport function useVersionDownload(\n content: string,\n version: string,\n o: { poll?: number; client?: ContentKitClient; start?: (d: FileDownload) => void } = {},\n): UseVersionDownload {\n const { client, scope } = useContentScope(o.client);\n const m = useMessages();\n const owner = useMemo(() => ({ client, scope, content, version, active: undefined as AbortController | undefined }), [client, scope, content, version]);\n const [state, setState] = useState<{ owner: typeof owner; preparing: boolean; error?: ContentKitError; retryAt?: number }>();\n useEffect(() => () => owner.active?.abort(), [owner]);\n const current = state?.owner === owner ? state : undefined;\n const start = o.start ?? startDownload;\n const download = useCallback(async () => {\n owner.active?.abort();\n const controller = owner.active = new AbortController();\n const { signal } = controller;\n setState({ owner, preparing: true });\n try {\n for (;;) {\n const out = await client.versions.download(content, version, signal);\n // Also reject a late result from a transport that ignored cancellation.\n throwIfAborted(signal);\n if (!isPending(out)) {\n start(out);\n return out;\n }\n await sleep(o.poll ?? 3000, signal);\n }\n } catch (e) {\n const error = toContentKitError(e);\n if (!signal.aborted && owner.active === controller) {\n setState({ owner, preparing: false, error, retryAt: error.code === \"rate_limited\" ? Date.now() + (error.retryAfter ?? 60) * 1000 : undefined });\n }\n throw error;\n } finally {\n if (!signal.aborted && owner.active === controller) setState((state) => state?.owner === owner ? { ...state, preparing: false } : state);\n }\n }, [client, content, version, o.poll, start, owner]);\n return { download, preparing: current?.preparing ?? false, error: current?.error, retryAt: current?.retryAt, message: downloadMessage(m, current?.error) };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"versions.js","names":[],"sources":["../../src/react/versions.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport { ContentKitError, throwIfAborted, toContentKitError } from \"../client/errors.js\";\nimport type { FileDownload, Pending, PlanSegment, ReaderPlan } from \"../client/generated/wire.js\";\nimport { isPending } from \"../client/versions.js\";\nimport { sleep } from \"../client/media/client.js\";\nimport { useMessages } from \"../i18n/context.js\";\nimport type { Translator } from \"../i18n/messages.js\";\nimport { useMediaRead, type ReadWindow } from \"./read.js\";\nimport { keyOf, useContentScope, useResource } from \"./use-resource.js\";\n\nexport interface UseReaderPlan {\n /** null while loading, pending or failed. */\n plan: ReaderPlan | null;\n /** The version has no current publication yet; the hook asks again. */\n pending: boolean;\n loading: boolean;\n error?: ContentKitError;\n reload: () => void;\n}\n\n// setTimeout's longest delay.\nconst MAX_DELAY = 2 ** 31 - 1;\n\n/** When the plan changes by itself: its next scheduled segment's release. */\nexport function nextRelease(plan: ReaderPlan | null, now = Date.now()): number | null {\n const at = (plan?.segments ?? []).flatMap((s) => (!s.released && s.release_at ? [Date.parse(s.release_at)] : [])).filter((t) => t > now);\n return at.length ? Math.min(...at) : null;\n}\n\n/**\n * A version's reader plan for this viewer: its segments (released or not,\n * open or locked), previews, playback item and reader metadata. It asks again\n * while the version is being published and when its next segment is released.\n */\nexport function useReaderPlan(content: string | null | undefined, version: string | null | undefined, o: { poll?: number; client?: ContentKitClient } = {}): UseReaderPlan {\n const { client, store, scope } = useContentScope(o.client);\n const key = content && version ? keyOf(\"reader-plan\", scope, content, version) : null;\n const r = useResource<ReaderPlan | Pending>(store, key, { type: \"reader-plan\", id: version ?? undefined }, (s) => client.versions.reader(content!, version!, s));\n const pending = isPending(r.data);\n const plan = r.data && !pending ? (r.data as ReaderPlan) : null;\n const { data, reload } = r;\n // Every answer schedules the next look: a pending one polls, a plan waits for its next release.\n useEffect(() => {\n const at = isPending(data) ? Date.now() + (o.poll ?? 5000) : nextRelease(data ? (data as ReaderPlan) : null);\n if (at === null) return;\n const t = setTimeout(reload, Math.min(MAX_DELAY, Math.max(0, at - Date.now()) + 500));\n return () => clearTimeout(t);\n }, [data, reload, o.poll]);\n return { plan, pending, loading: !!key && (r.loading || !r.loaded), error: r.error, reload };\n}\n\n/** A segment's page with the URL of one rendition, once its item's read signed it. */\nexport interface ReaderPage {\n name: string;\n w: number;\n h: number;\n /** undefined until read, or when the page lacks the rendition. */\n url?: string;\n}\n\nexport interface UseSegmentPages {\n pages: ReaderPage[];\n loading: boolean;\n error?: ContentKitError;\n}\n\n/**\n * An open segment's pages with URLs of one rendition, read through its\n * published item (windowed for long segments, refreshed before the URLs expire).\n */\nexport function useSegmentPages(segment: PlanSegment | null | undefined, rendition: string, o: { window?: ReadWindow; client?: ContentKitClient } = {}): UseSegmentPages {\n const item = segment?.item ?? null;\n const read = useMediaRead(item ?? { kind: \"\", id: \"\" }, { window: o.window, read: item ? undefined : null, client: o.client });\n const pages = useMemo(() => {\n const urls = new Map((read.read?.files ?? []).flatMap((f) => (f.url ? [[f.path, f.url] as const] : [])));\n return (segment?.pages ?? []).map((p) => {\n const path = p.files[rendition];\n return { name: p.name, w: p.w, h: p.h, url: path ? urls.get(path) : undefined };\n });\n }, [segment, rendition, read.read]);\n return { pages, loading: !!item && read.loading, error: read.error };\n}\n\nexport interface UseVersionDownload {\n /**\n * Grants the download (asking again while it is prepared), starts it in the\n * browser and resolves with the grant.\n */\n download: () => Promise<FileDownload>;\n /** Being prepared by the server, or granted and starting. */\n preparing: boolean;\n error?: ContentKitError;\n /** While a quota refused: when the viewer may download again (ms). */\n retryAt?: number;\n /**\n * What to tell the viewer about the last refusal: when a quota frees, when\n * a download the site holds back opens (\"available to download in N\n * days\"), a locked version, nothing to download, or a failure.\n */\n message?: string;\n}\n\n/** Starts a granted download: the browser fetches its URL, an attachment. */\nexport function startDownload(d: FileDownload): void {\n const a = document.createElement(\"a\");\n a.href = d.url;\n a.download = d.name;\n a.rel = \"noopener\";\n a.style.display = \"none\";\n document.body.appendChild(a);\n a.click();\n a.remove();\n}\n\n/** The viewer's line for a download refusal at now. */\nexport function downloadMessage(m: Translator, err: ContentKitError | undefined, now = Date.now()): string | undefined {\n switch (err?.code) {\n case undefined:\n return undefined;\n case \"rate_limited\":\n return m.t(\"versionDownload.limited\", { minutes: Math.max(1, Math.ceil((err.retryAfter ?? 60) / 60)) });\n case \"download_unavailable\": {\n const ms = err.availableAt ? Date.parse(err.availableAt) - now : NaN;\n return ms > 0 ? m.plural(\"versionDownload.availableIn\", Math.max(1, Math.ceil(ms / 86_400_000))) : m.t(\"versionDownload.unavailable\");\n }\n case \"forbidden\":\n return m.t(\"versionDownload.locked\");\n case \"no_download\":\n return m.error(err);\n default:\n return m.t(\"versionDownload.failed\");\n }\n}\n\n/**\n * A version's download, charged to the viewer's download quota: the\n * original or rendition its kind serves, or its pages as a zip. Polls while\n * it is prepared (a zip is built after its pages publish, behind the worker\n * queue); render_timeout after ten minutes.\n */\nexport function useVersionDownload(\n content: string,\n version: string,\n o: { poll?: number; client?: ContentKitClient; start?: (d: FileDownload) => void } = {},\n): UseVersionDownload {\n const { client, scope } = useContentScope(o.client);\n const m = useMessages();\n const owner = useMemo(() => ({ client, scope, content, version, active: undefined as AbortController | undefined }), [client, scope, content, version]);\n const [state, setState] = useState<{ owner: typeof owner; preparing: boolean; error?: ContentKitError; retryAt?: number }>();\n useEffect(() => () => owner.active?.abort(), [owner]);\n const current = state?.owner === owner ? state : undefined;\n const start = o.start ?? startDownload;\n const download = useCallback(async () => {\n owner.active?.abort();\n const controller = owner.active = new AbortController();\n const { signal } = controller;\n setState({ owner, preparing: true });\n const until = Date.now() + 600_000;\n try {\n for (;;) {\n const out = await client.versions.download(content, version, signal);\n // Also reject a late result from a transport that ignored cancellation.\n throwIfAborted(signal);\n if (!isPending(out)) {\n start(out);\n return out;\n }\n if (Date.now() >= until) throw new ContentKitError(\"render_timeout\", \"the download is still being prepared\");\n await sleep(o.poll ?? 3000, signal);\n }\n } catch (e) {\n const error = toContentKitError(e);\n if (!signal.aborted && owner.active === controller) {\n setState({ owner, preparing: false, error, retryAt: error.code === \"rate_limited\" ? Date.now() + (error.retryAfter ?? 60) * 1000 : undefined });\n }\n throw error;\n } finally {\n if (!signal.aborted && owner.active === controller) setState((state) => state?.owner === owner ? { ...state, preparing: false } : state);\n }\n }, [client, content, version, o.poll, start, owner]);\n return { download, preparing: current?.preparing ?? false, error: current?.error, retryAt: current?.retryAt, message: downloadMessage(m, current?.error) };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openrails/contentkit-ui",
3
- "version": "0.104.0-rc.3",
3
+ "version": "0.105.0",
4
4
  "description": "ContentKit in the browser: client, React hooks and styled components for media, uploads and content URLs.",
5
5
  "type": "module",
6
6
  "license": "MIT",