@khorsheed/dsh-reader 0.3.0 → 0.3.2
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/CHANGELOG.md +29 -0
- package/README.en.md +26 -121
- package/README.i18n.yaml +3 -3
- package/README.md +26 -121
- package/cordis.patch.yml +7 -0
- package/lib/client.js +29105 -6692
- package/lib/index.js +3500 -321
- package/lib/typert.host.js +2145 -259
- package/lib/typert.remote-client.d.ts +97 -3
- package/lib/typert.remote-client.js +1590 -250
- package/lib/types/captions.d.ts +99 -0
- package/lib/types/captions.js +236 -0
- package/lib/types/client/MediaPlayer.d.ts +55 -0
- package/lib/types/client/MediaPlayer.js +106 -0
- package/lib/types/client/NotesView.d.ts +57 -0
- package/lib/types/client/NotesView.js +124 -0
- package/lib/types/client/ReaderPane.d.ts +20 -3
- package/lib/types/client/ReaderPane.js +860 -164
- package/lib/types/client/SpeakerLegend.d.ts +18 -0
- package/lib/types/client/SpeakerLegend.js +26 -0
- package/lib/types/client/canvas-sync.d.ts +84 -0
- package/lib/types/client/canvas-sync.js +59 -0
- package/lib/types/client/contract.d.ts +130 -3
- package/lib/types/client/extract-article.d.ts +38 -1
- package/lib/types/client/extract-article.js +561 -33
- package/lib/types/client/icons.d.ts +1 -1
- package/lib/types/client/icons.js +1 -1
- package/lib/types/client/index.js +81 -2
- package/lib/types/client/locales.d.ts +279 -11
- package/lib/types/client/locales.js +278 -10
- package/lib/types/client/notes.d.ts +142 -0
- package/lib/types/client/notes.js +334 -0
- package/lib/types/client/parse-rss.js +40 -0
- package/lib/types/client/preset-visibility.d.ts +93 -0
- package/lib/types/client/preset-visibility.js +115 -0
- package/lib/types/client/selectors.d.ts +5 -0
- package/lib/types/client/selectors.js +5 -0
- package/lib/types/client/session.d.ts +21 -1
- package/lib/types/client/session.js +12 -0
- package/lib/types/client/store.js +4 -1
- package/lib/types/client/translate.d.ts +26 -1
- package/lib/types/client/translate.js +29 -12
- package/lib/types/client/useLocalTranscript.d.ts +43 -0
- package/lib/types/client/useLocalTranscript.js +129 -0
- package/lib/types/client/useMedia.d.ts +68 -0
- package/lib/types/client/useMedia.js +299 -0
- package/lib/types/client/useMediaStates.d.ts +9 -0
- package/lib/types/client/useMediaStates.js +43 -0
- package/lib/types/client/useNotes.d.ts +110 -0
- package/lib/types/client/useNotes.js +423 -0
- package/lib/types/client/usePolish.d.ts +47 -0
- package/lib/types/client/usePolish.js +162 -0
- package/lib/types/document-fetch.d.ts +106 -0
- package/lib/types/document-fetch.js +100 -0
- package/lib/types/index.d.ts +15 -0
- package/lib/types/index.js +3 -0
- package/lib/types/local-transcribe.d.ts +171 -0
- package/lib/types/local-transcribe.js +473 -0
- package/lib/types/media-host.d.ts +91 -0
- package/lib/types/media-host.js +230 -0
- package/lib/types/media.d.ts +100 -0
- package/lib/types/media.js +207 -0
- package/lib/types/notes-types.d.ts +158 -0
- package/lib/types/notes-types.js +8 -0
- package/lib/types/notes.d.ts +213 -0
- package/lib/types/notes.js +718 -0
- package/lib/types/polish.d.ts +41 -0
- package/lib/types/polish.js +136 -0
- package/lib/types/remote.d.ts +118 -0
- package/lib/types/remote.js +151 -1
- package/lib/types/service.d.ts +81 -6
- package/lib/types/service.js +286 -65
- package/lib/types/skill.d.ts +20 -0
- package/lib/types/skill.js +78 -0
- package/lib/types/store.js +30 -8
- package/lib/types/tool.d.ts +23 -0
- package/lib/types/tool.js +40 -0
- package/lib/types/tools.d.ts +69 -0
- package/lib/types/tools.js +400 -0
- package/lib/types/types.d.ts +90 -2
- package/lib/types/types.js +66 -0
- package/lib/types/xiaoyuzhou.d.ts +43 -0
- package/lib/types/xiaoyuzhou.js +134 -0
- package/lib/types/ytdlp.d.ts +111 -0
- package/lib/types/ytdlp.js +269 -0
- package/package.json +33 -20
- package/lib/invariant.js +0 -38
- package/lib/types/invariant.d.ts +0 -29
- package/lib/types/invariant.js +0 -38
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ReaderPolishView } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* What a layer belongs to: the paragraphs' text without their time and
|
|
4
|
+
* speaker prefixes, hashed.
|
|
5
|
+
*/
|
|
6
|
+
export declare function sourceKey(paragraphs: readonly string[]): string;
|
|
7
|
+
/**
|
|
8
|
+
* Parse the model's write-back: lines `¶12:译文…` (a line without a ¶
|
|
9
|
+
* continues the paragraph before it).
|
|
10
|
+
*
|
|
11
|
+
* @param text - what the model sent.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parsePolish(text: string): Map<number, string>;
|
|
14
|
+
/** The per-article 润色 layers. */
|
|
15
|
+
export declare class ReaderPolishStore {
|
|
16
|
+
private readonly dir;
|
|
17
|
+
private readonly memory;
|
|
18
|
+
constructor(stateRoot: string);
|
|
19
|
+
private fileOf;
|
|
20
|
+
private load;
|
|
21
|
+
private save;
|
|
22
|
+
/**
|
|
23
|
+
* An article's layer, when it belongs to the text now captured.
|
|
24
|
+
*
|
|
25
|
+
* @param entryId - the article.
|
|
26
|
+
* @param key - the current text's {@link sourceKey}.
|
|
27
|
+
*/
|
|
28
|
+
view(entryId: string, key: string | undefined): ReaderPolishView | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Merge the model's translations into the layer (a different text starts a
|
|
31
|
+
* fresh one).
|
|
32
|
+
*
|
|
33
|
+
* @returns the layer after the write.
|
|
34
|
+
*/
|
|
35
|
+
write(entryId: string, key: string, total: number, updates: ReadonlyMap<number, string>): ReaderPolishView;
|
|
36
|
+
/** Turn one paragraph back to (or away from) the machine translation. */
|
|
37
|
+
setOff(entryId: string, key: string | undefined, paragraph: number, off: boolean): ReaderPolishView | undefined;
|
|
38
|
+
/** Forget an article's layer. */
|
|
39
|
+
drop(entryId: string): void;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=polish.d.ts.map
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 润色 layer: an agent's paragraph-by-paragraph translation of an
|
|
3
|
+
* article, written back through `reader_translate` and shown in place of the
|
|
4
|
+
* browser's sentence-by-sentence machine translation.
|
|
5
|
+
*
|
|
6
|
+
* Keyed to the article's text as the model read it (the snapshot): a
|
|
7
|
+
* re-transcription changes the text and so drops the layer; renaming a
|
|
8
|
+
* speaker only changes the "[mm:ss] 名字:" prefixes and keeps it.
|
|
9
|
+
*
|
|
10
|
+
* One JSON file per article under `<state>/polish/`, memory-only when the
|
|
11
|
+
* state root cannot be written.
|
|
12
|
+
*
|
|
13
|
+
* @module @khorsheed/dsh-reader/polish
|
|
14
|
+
*/
|
|
15
|
+
import { createHash } from 'node:crypto';
|
|
16
|
+
import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
/** The time / speaker prefix of a transcript paragraph in the snapshot. */
|
|
19
|
+
const PREFIX = /^\[\d+(?::\d+){1,2}\]\s*(?:[^:\n]{1,40}:)?/;
|
|
20
|
+
/**
|
|
21
|
+
* What a layer belongs to: the paragraphs' text without their time and
|
|
22
|
+
* speaker prefixes, hashed.
|
|
23
|
+
*/
|
|
24
|
+
export function sourceKey(paragraphs) {
|
|
25
|
+
const hash = createHash('sha1');
|
|
26
|
+
hash.update(String(paragraphs.length));
|
|
27
|
+
for (const paragraph of paragraphs)
|
|
28
|
+
hash.update(`\n${paragraph.replace(PREFIX, '')}`);
|
|
29
|
+
return hash.digest('hex').slice(0, 24);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse the model's write-back: lines `¶12:译文…` (a line without a ¶
|
|
33
|
+
* continues the paragraph before it).
|
|
34
|
+
*
|
|
35
|
+
* @param text - what the model sent.
|
|
36
|
+
*/
|
|
37
|
+
export function parsePolish(text) {
|
|
38
|
+
const out = new Map();
|
|
39
|
+
let current;
|
|
40
|
+
for (const line of text.split(/\r?\n/)) {
|
|
41
|
+
const head = /^\s*¶\s*(\d+)\s*[::]\s*(.*)$/.exec(line);
|
|
42
|
+
if (head !== null) {
|
|
43
|
+
current = Number(head[1]);
|
|
44
|
+
out.set(current, head[2].trim());
|
|
45
|
+
}
|
|
46
|
+
else if (current !== undefined && line.trim() !== '') {
|
|
47
|
+
out.set(current, `${out.get(current) ?? ''}${line.trim()}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const [key, value] of out)
|
|
51
|
+
if (value === '')
|
|
52
|
+
out.delete(key);
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
/** The per-article 润色 layers. */
|
|
56
|
+
export class ReaderPolishStore {
|
|
57
|
+
dir;
|
|
58
|
+
memory = new Map();
|
|
59
|
+
constructor(stateRoot) {
|
|
60
|
+
this.dir = join(stateRoot, 'polish');
|
|
61
|
+
}
|
|
62
|
+
fileOf(entryId) {
|
|
63
|
+
return join(this.dir, `${createHash('sha1').update(entryId).digest('hex').slice(0, 32)}.json`);
|
|
64
|
+
}
|
|
65
|
+
load(entryId) {
|
|
66
|
+
const cached = this.memory.get(entryId);
|
|
67
|
+
if (cached !== undefined)
|
|
68
|
+
return cached;
|
|
69
|
+
try {
|
|
70
|
+
const parsed = JSON.parse(readFileSync(this.fileOf(entryId), 'utf8'));
|
|
71
|
+
if (parsed.entryId !== entryId)
|
|
72
|
+
return undefined;
|
|
73
|
+
this.memory.set(entryId, parsed);
|
|
74
|
+
return parsed;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
save(file) {
|
|
81
|
+
this.memory.set(file.entryId, file);
|
|
82
|
+
try {
|
|
83
|
+
mkdirSync(this.dir, { recursive: true });
|
|
84
|
+
const target = this.fileOf(file.entryId);
|
|
85
|
+
writeFileSync(`${target}.tmp`, JSON.stringify(file));
|
|
86
|
+
renameSync(`${target}.tmp`, target);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Memory-only: the layer lasts this process.
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* An article's layer, when it belongs to the text now captured.
|
|
94
|
+
*
|
|
95
|
+
* @param entryId - the article.
|
|
96
|
+
* @param key - the current text's {@link sourceKey}.
|
|
97
|
+
*/
|
|
98
|
+
view(entryId, key) {
|
|
99
|
+
const file = this.load(entryId);
|
|
100
|
+
if (file === undefined || key === undefined || file.sourceKey !== key)
|
|
101
|
+
return undefined;
|
|
102
|
+
const done = Object.keys(file.paragraphs).length;
|
|
103
|
+
return { total: file.total, done, paragraphs: { ...file.paragraphs }, off: [...file.off], updatedAt: file.updatedAt, complete: done >= file.total };
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Merge the model's translations into the layer (a different text starts a
|
|
107
|
+
* fresh one).
|
|
108
|
+
*
|
|
109
|
+
* @returns the layer after the write.
|
|
110
|
+
*/
|
|
111
|
+
write(entryId, key, total, updates) {
|
|
112
|
+
const before = this.load(entryId);
|
|
113
|
+
const fresh = before === undefined || before.sourceKey !== key;
|
|
114
|
+
const paragraphs = fresh ? {} : { ...before.paragraphs };
|
|
115
|
+
for (const [index, value] of updates)
|
|
116
|
+
if (index >= 1 && index <= total)
|
|
117
|
+
paragraphs[String(index)] = value;
|
|
118
|
+
const file = { entryId, sourceKey: key, total, paragraphs, off: fresh ? [] : before.off, updatedAt: new Date().toISOString() };
|
|
119
|
+
this.save(file);
|
|
120
|
+
return this.view(entryId, key);
|
|
121
|
+
}
|
|
122
|
+
/** Turn one paragraph back to (or away from) the machine translation. */
|
|
123
|
+
setOff(entryId, key, paragraph, off) {
|
|
124
|
+
const file = this.load(entryId);
|
|
125
|
+
if (file === undefined || key === undefined || file.sourceKey !== key)
|
|
126
|
+
return undefined;
|
|
127
|
+
const rest = file.off.filter(item => item !== paragraph);
|
|
128
|
+
this.save({ ...file, off: off ? [...rest, paragraph] : rest });
|
|
129
|
+
return this.view(entryId, key);
|
|
130
|
+
}
|
|
131
|
+
/** Forget an article's layer. */
|
|
132
|
+
drop(entryId) {
|
|
133
|
+
this.memory.delete(entryId);
|
|
134
|
+
rmSync(this.fileOf(entryId), { force: true });
|
|
135
|
+
}
|
|
136
|
+
}
|
package/lib/types/remote.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { Context } from '@deepseek-ai/cordis';
|
|
13
13
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
14
|
+
import type { LocalTranscriptStatus, MediaCardStates, ReaderEntryIdentity, ReaderPolishView, ReaderEntryNotes, ReaderMedia, ReaderNote, ReaderNoteInput, ReaderNoteOutcome } from './types.ts';
|
|
14
15
|
import type { ReaderAddFailure, ReaderAddOutcome, ReaderAddRefusal, ReaderAnnotationOutcome, ReaderBackfillCandidate, ReaderEntryBodyView, ReaderImageResult, ReaderEntryFetchState, ReaderBody, ReaderCapabilities, ReaderEntryTranslationView, ReaderMutationOutcome, ReaderRecentEntry, ReaderRefreshResult, ReaderSentenceLearn, ReaderSourceSummary, ReaderStorageStats, ReaderTag } from './types.ts';
|
|
15
16
|
declare module '@deepseek-ai/cordis' {
|
|
16
17
|
interface Context {
|
|
@@ -26,6 +27,8 @@ export declare class ReaderRemoteService extends TypertRemoteService<ReaderRemot
|
|
|
26
27
|
constructor(ctx: Context, _config?: ReaderRemoteConfig);
|
|
27
28
|
/** The service core this face delegates to. */
|
|
28
29
|
private get core();
|
|
30
|
+
/** The notes store this face delegates to. */
|
|
31
|
+
private get notes();
|
|
29
32
|
/** Capability handshake: what the browser may rely on in this composition. */
|
|
30
33
|
capabilities(): Promise<ReaderCapabilities>;
|
|
31
34
|
/** The configured sources, without payloads. */
|
|
@@ -227,6 +230,121 @@ export declare class ReaderRemoteService extends TypertRemoteService<ReaderRemot
|
|
|
227
230
|
label: string;
|
|
228
231
|
text: string;
|
|
229
232
|
}): Promise<'ok' | 'unavailable'>;
|
|
233
|
+
/** One article's notes and the conversations that discussed it. */
|
|
234
|
+
entryNotes(request: {
|
|
235
|
+
entryId: string;
|
|
236
|
+
}): Promise<{
|
|
237
|
+
entry?: ReaderEntryNotes;
|
|
238
|
+
}>;
|
|
239
|
+
/** How many notes each article carries. */
|
|
240
|
+
noteCounts(): Promise<{
|
|
241
|
+
counts: Record<string, number>;
|
|
242
|
+
}>;
|
|
243
|
+
/** Keep one excerpt (and its comment). */
|
|
244
|
+
addNote(request: ReaderNoteInput): Promise<ReaderNote | 'empty' | 'full'>;
|
|
245
|
+
/** Change or clear one note's comment. */
|
|
246
|
+
updateNote(request: {
|
|
247
|
+
entryId: string;
|
|
248
|
+
noteId: string;
|
|
249
|
+
comment: string;
|
|
250
|
+
}): Promise<ReaderNoteOutcome>;
|
|
251
|
+
/** Delete one note. */
|
|
252
|
+
deleteNote(request: {
|
|
253
|
+
entryId: string;
|
|
254
|
+
noteId: string;
|
|
255
|
+
}): Promise<ReaderNoteOutcome>;
|
|
256
|
+
/** Remember that a conversation discussed this article. */
|
|
257
|
+
recordDiscussion(request: ReaderEntryIdentity & {
|
|
258
|
+
sessionId: string;
|
|
259
|
+
sessionTitle?: string;
|
|
260
|
+
}): Promise<'ok' | 'empty'>;
|
|
261
|
+
/** Add the reader's own line under a note. */
|
|
262
|
+
addReply(request: {
|
|
263
|
+
entryId: string;
|
|
264
|
+
noteId: string;
|
|
265
|
+
text: string;
|
|
266
|
+
}): Promise<ReaderNoteOutcome>;
|
|
267
|
+
/** Rewrite (or, with empty text, remove) one line under a note. */
|
|
268
|
+
editReply(request: {
|
|
269
|
+
entryId: string;
|
|
270
|
+
noteId: string;
|
|
271
|
+
index: number;
|
|
272
|
+
text: string;
|
|
273
|
+
}): Promise<ReaderNoteOutcome>;
|
|
274
|
+
/** Remember that a note or a discussion note became a canvas card. */
|
|
275
|
+
markSynced(request: {
|
|
276
|
+
entryId: string;
|
|
277
|
+
noteId?: string;
|
|
278
|
+
discussionId?: string;
|
|
279
|
+
canvasId: string;
|
|
280
|
+
cardId: string;
|
|
281
|
+
canvasTitle: string;
|
|
282
|
+
}): Promise<ReaderNoteOutcome>;
|
|
283
|
+
/** Delete one discussion note. */
|
|
284
|
+
deleteDiscussion(request: {
|
|
285
|
+
entryId: string;
|
|
286
|
+
discussionId: string;
|
|
287
|
+
}): Promise<ReaderNoteOutcome>;
|
|
288
|
+
/** A video entry's transcript from its platform captions (stored; `none` when it has none). */
|
|
289
|
+
mediaTranscript(request: {
|
|
290
|
+
entryId: string;
|
|
291
|
+
url: string;
|
|
292
|
+
}): Promise<{
|
|
293
|
+
entryId: string;
|
|
294
|
+
html?: string;
|
|
295
|
+
captions: 'platform' | 'none' | 'failed';
|
|
296
|
+
language?: string;
|
|
297
|
+
error?: string;
|
|
298
|
+
}>;
|
|
299
|
+
/**
|
|
300
|
+
* Start (or rejoin) local transcription of an entry without captions.
|
|
301
|
+
* Answers `unavailable` without the transcription plugin and `needs-models`
|
|
302
|
+
* until the first model download is confirmed.
|
|
303
|
+
*/
|
|
304
|
+
startLocalTranscript(request: {
|
|
305
|
+
entryId: string;
|
|
306
|
+
url: string;
|
|
307
|
+
media: ReaderMedia;
|
|
308
|
+
title?: string;
|
|
309
|
+
confirmModels?: boolean;
|
|
310
|
+
}): Promise<LocalTranscriptStatus>;
|
|
311
|
+
/** Where an entry's local transcription stands, with the transcript so far. */
|
|
312
|
+
localTranscript(request: {
|
|
313
|
+
entryId: string;
|
|
314
|
+
}): Promise<LocalTranscriptStatus>;
|
|
315
|
+
/** The reader's names for a transcript's speakers, by index. */
|
|
316
|
+
speakerNames(request: {
|
|
317
|
+
entryId: string;
|
|
318
|
+
}): Promise<Record<string, string>>;
|
|
319
|
+
/** Name one speaker of a transcript (empty: back to 说话人 A…); answers all the names. */
|
|
320
|
+
nameSpeaker(request: {
|
|
321
|
+
entryId: string;
|
|
322
|
+
speaker: number;
|
|
323
|
+
name: string;
|
|
324
|
+
}): Promise<Record<string, string>>;
|
|
325
|
+
/** The wall's video / audio cards: what each one's transcript is (captions, local, transcribing…). */
|
|
326
|
+
mediaStates(request: {
|
|
327
|
+
entryIds: string[];
|
|
328
|
+
}): Promise<MediaCardStates>;
|
|
329
|
+
/** Leave (withdraws a queued job) or, with `force`, stop an entry's local transcription. */
|
|
330
|
+
cancelLocalTranscript(request: {
|
|
331
|
+
entryId: string;
|
|
332
|
+
force: boolean;
|
|
333
|
+
}): Promise<LocalTranscriptStatus>;
|
|
334
|
+
/** The article's 润色 layer (the agent's translation), when there is one for its current text. */
|
|
335
|
+
polish(request: {
|
|
336
|
+
entryId: string;
|
|
337
|
+
}): Promise<ReaderPolishView | null>;
|
|
338
|
+
/** Show one paragraph's machine translation instead of the 润色 (or back). */
|
|
339
|
+
setPolishOff(request: {
|
|
340
|
+
entryId: string;
|
|
341
|
+
paragraph: number;
|
|
342
|
+
off: boolean;
|
|
343
|
+
}): Promise<ReaderPolishView | null>;
|
|
344
|
+
/** Hand the host the article's original text, block by block, for the model to read. */
|
|
345
|
+
snapshotEntry(request: ReaderEntryIdentity & {
|
|
346
|
+
paragraphs: string[];
|
|
347
|
+
}): Promise<'ok' | 'empty'>;
|
|
230
348
|
}
|
|
231
349
|
export default ReaderRemoteService;
|
|
232
350
|
//# sourceMappingURL=remote.d.ts.map
|
package/lib/types/remote.js
CHANGED
|
@@ -69,6 +69,26 @@ let ReaderRemoteService = (() => {
|
|
|
69
69
|
let _listRecent_decorators;
|
|
70
70
|
let _clearRecent_decorators;
|
|
71
71
|
let _quoteToSideChat_decorators;
|
|
72
|
+
let _entryNotes_decorators;
|
|
73
|
+
let _noteCounts_decorators;
|
|
74
|
+
let _addNote_decorators;
|
|
75
|
+
let _updateNote_decorators;
|
|
76
|
+
let _deleteNote_decorators;
|
|
77
|
+
let _recordDiscussion_decorators;
|
|
78
|
+
let _addReply_decorators;
|
|
79
|
+
let _editReply_decorators;
|
|
80
|
+
let _markSynced_decorators;
|
|
81
|
+
let _deleteDiscussion_decorators;
|
|
82
|
+
let _mediaTranscript_decorators;
|
|
83
|
+
let _startLocalTranscript_decorators;
|
|
84
|
+
let _localTranscript_decorators;
|
|
85
|
+
let _speakerNames_decorators;
|
|
86
|
+
let _nameSpeaker_decorators;
|
|
87
|
+
let _mediaStates_decorators;
|
|
88
|
+
let _cancelLocalTranscript_decorators;
|
|
89
|
+
let _polish_decorators;
|
|
90
|
+
let _setPolishOff_decorators;
|
|
91
|
+
let _snapshotEntry_decorators;
|
|
72
92
|
return class ReaderRemoteService extends _classSuper {
|
|
73
93
|
static {
|
|
74
94
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
@@ -104,6 +124,26 @@ let ReaderRemoteService = (() => {
|
|
|
104
124
|
_listRecent_decorators = [Remote('listRecent')];
|
|
105
125
|
_clearRecent_decorators = [Remote('clearRecent')];
|
|
106
126
|
_quoteToSideChat_decorators = [Remote('quoteToSideChat')];
|
|
127
|
+
_entryNotes_decorators = [Remote('entryNotes')];
|
|
128
|
+
_noteCounts_decorators = [Remote('noteCounts')];
|
|
129
|
+
_addNote_decorators = [Remote('addNote')];
|
|
130
|
+
_updateNote_decorators = [Remote('updateNote')];
|
|
131
|
+
_deleteNote_decorators = [Remote('deleteNote')];
|
|
132
|
+
_recordDiscussion_decorators = [Remote('recordDiscussion')];
|
|
133
|
+
_addReply_decorators = [Remote('addReply')];
|
|
134
|
+
_editReply_decorators = [Remote('editReply')];
|
|
135
|
+
_markSynced_decorators = [Remote('markSynced')];
|
|
136
|
+
_deleteDiscussion_decorators = [Remote('deleteDiscussion')];
|
|
137
|
+
_mediaTranscript_decorators = [Remote('mediaTranscript')];
|
|
138
|
+
_startLocalTranscript_decorators = [Remote('startLocalTranscript')];
|
|
139
|
+
_localTranscript_decorators = [Remote('localTranscript')];
|
|
140
|
+
_speakerNames_decorators = [Remote('speakerNames')];
|
|
141
|
+
_nameSpeaker_decorators = [Remote('nameSpeaker')];
|
|
142
|
+
_mediaStates_decorators = [Remote('mediaStates')];
|
|
143
|
+
_cancelLocalTranscript_decorators = [Remote('cancelLocalTranscript')];
|
|
144
|
+
_polish_decorators = [Remote('polish')];
|
|
145
|
+
_setPolishOff_decorators = [Remote('setPolishOff')];
|
|
146
|
+
_snapshotEntry_decorators = [Remote('snapshotEntry')];
|
|
107
147
|
__esDecorate(this, null, _capabilities_decorators, { kind: "method", name: "capabilities", static: false, private: false, access: { has: obj => "capabilities" in obj, get: obj => obj.capabilities }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
108
148
|
__esDecorate(this, null, _listSources_decorators, { kind: "method", name: "listSources", static: false, private: false, access: { has: obj => "listSources" in obj, get: obj => obj.listSources }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
109
149
|
__esDecorate(this, null, _addSource_decorators, { kind: "method", name: "addSource", static: false, private: false, access: { has: obj => "addSource" in obj, get: obj => obj.addSource }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -136,9 +176,29 @@ let ReaderRemoteService = (() => {
|
|
|
136
176
|
__esDecorate(this, null, _listRecent_decorators, { kind: "method", name: "listRecent", static: false, private: false, access: { has: obj => "listRecent" in obj, get: obj => obj.listRecent }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
137
177
|
__esDecorate(this, null, _clearRecent_decorators, { kind: "method", name: "clearRecent", static: false, private: false, access: { has: obj => "clearRecent" in obj, get: obj => obj.clearRecent }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
138
178
|
__esDecorate(this, null, _quoteToSideChat_decorators, { kind: "method", name: "quoteToSideChat", static: false, private: false, access: { has: obj => "quoteToSideChat" in obj, get: obj => obj.quoteToSideChat }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
179
|
+
__esDecorate(this, null, _entryNotes_decorators, { kind: "method", name: "entryNotes", static: false, private: false, access: { has: obj => "entryNotes" in obj, get: obj => obj.entryNotes }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
180
|
+
__esDecorate(this, null, _noteCounts_decorators, { kind: "method", name: "noteCounts", static: false, private: false, access: { has: obj => "noteCounts" in obj, get: obj => obj.noteCounts }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
181
|
+
__esDecorate(this, null, _addNote_decorators, { kind: "method", name: "addNote", static: false, private: false, access: { has: obj => "addNote" in obj, get: obj => obj.addNote }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
182
|
+
__esDecorate(this, null, _updateNote_decorators, { kind: "method", name: "updateNote", static: false, private: false, access: { has: obj => "updateNote" in obj, get: obj => obj.updateNote }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
183
|
+
__esDecorate(this, null, _deleteNote_decorators, { kind: "method", name: "deleteNote", static: false, private: false, access: { has: obj => "deleteNote" in obj, get: obj => obj.deleteNote }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
184
|
+
__esDecorate(this, null, _recordDiscussion_decorators, { kind: "method", name: "recordDiscussion", static: false, private: false, access: { has: obj => "recordDiscussion" in obj, get: obj => obj.recordDiscussion }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
185
|
+
__esDecorate(this, null, _addReply_decorators, { kind: "method", name: "addReply", static: false, private: false, access: { has: obj => "addReply" in obj, get: obj => obj.addReply }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
186
|
+
__esDecorate(this, null, _editReply_decorators, { kind: "method", name: "editReply", static: false, private: false, access: { has: obj => "editReply" in obj, get: obj => obj.editReply }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
187
|
+
__esDecorate(this, null, _markSynced_decorators, { kind: "method", name: "markSynced", static: false, private: false, access: { has: obj => "markSynced" in obj, get: obj => obj.markSynced }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
188
|
+
__esDecorate(this, null, _deleteDiscussion_decorators, { kind: "method", name: "deleteDiscussion", static: false, private: false, access: { has: obj => "deleteDiscussion" in obj, get: obj => obj.deleteDiscussion }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
189
|
+
__esDecorate(this, null, _mediaTranscript_decorators, { kind: "method", name: "mediaTranscript", static: false, private: false, access: { has: obj => "mediaTranscript" in obj, get: obj => obj.mediaTranscript }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
190
|
+
__esDecorate(this, null, _startLocalTranscript_decorators, { kind: "method", name: "startLocalTranscript", static: false, private: false, access: { has: obj => "startLocalTranscript" in obj, get: obj => obj.startLocalTranscript }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
191
|
+
__esDecorate(this, null, _localTranscript_decorators, { kind: "method", name: "localTranscript", static: false, private: false, access: { has: obj => "localTranscript" in obj, get: obj => obj.localTranscript }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
192
|
+
__esDecorate(this, null, _speakerNames_decorators, { kind: "method", name: "speakerNames", static: false, private: false, access: { has: obj => "speakerNames" in obj, get: obj => obj.speakerNames }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
193
|
+
__esDecorate(this, null, _nameSpeaker_decorators, { kind: "method", name: "nameSpeaker", static: false, private: false, access: { has: obj => "nameSpeaker" in obj, get: obj => obj.nameSpeaker }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
194
|
+
__esDecorate(this, null, _mediaStates_decorators, { kind: "method", name: "mediaStates", static: false, private: false, access: { has: obj => "mediaStates" in obj, get: obj => obj.mediaStates }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
195
|
+
__esDecorate(this, null, _cancelLocalTranscript_decorators, { kind: "method", name: "cancelLocalTranscript", static: false, private: false, access: { has: obj => "cancelLocalTranscript" in obj, get: obj => obj.cancelLocalTranscript }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
196
|
+
__esDecorate(this, null, _polish_decorators, { kind: "method", name: "polish", static: false, private: false, access: { has: obj => "polish" in obj, get: obj => obj.polish }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
197
|
+
__esDecorate(this, null, _setPolishOff_decorators, { kind: "method", name: "setPolishOff", static: false, private: false, access: { has: obj => "setPolishOff" in obj, get: obj => obj.setPolishOff }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
198
|
+
__esDecorate(this, null, _snapshotEntry_decorators, { kind: "method", name: "snapshotEntry", static: false, private: false, access: { has: obj => "snapshotEntry" in obj, get: obj => obj.snapshotEntry }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
139
199
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
140
200
|
}
|
|
141
|
-
static inject = ['reader'];
|
|
201
|
+
static inject = ['reader', 'readerNotes'];
|
|
142
202
|
constructor(ctx, _config = {}) {
|
|
143
203
|
super(ctx, 'readerRemote', { namespace: 'reader' });
|
|
144
204
|
__runInitializers(this, _instanceExtraInitializers);
|
|
@@ -147,6 +207,10 @@ let ReaderRemoteService = (() => {
|
|
|
147
207
|
get core() {
|
|
148
208
|
return this.ctx.reader;
|
|
149
209
|
}
|
|
210
|
+
/** The notes store this face delegates to. */
|
|
211
|
+
get notes() {
|
|
212
|
+
return this.ctx.readerNotes;
|
|
213
|
+
}
|
|
150
214
|
/** Capability handshake: what the browser may rely on in this composition. */
|
|
151
215
|
capabilities() {
|
|
152
216
|
return this.core.capabilities();
|
|
@@ -280,6 +344,92 @@ let ReaderRemoteService = (() => {
|
|
|
280
344
|
quoteToSideChat(request) {
|
|
281
345
|
return this.core.quoteToSideChat(request);
|
|
282
346
|
}
|
|
347
|
+
/* ------------------------------------------------------------------ notes */
|
|
348
|
+
/** One article's notes and the conversations that discussed it. */
|
|
349
|
+
async entryNotes(request) {
|
|
350
|
+
const entry = this.notes.entry(request.entryId);
|
|
351
|
+
return entry === undefined ? {} : { entry };
|
|
352
|
+
}
|
|
353
|
+
/** How many notes each article carries. */
|
|
354
|
+
async noteCounts() {
|
|
355
|
+
return { counts: this.notes.counts() };
|
|
356
|
+
}
|
|
357
|
+
/** Keep one excerpt (and its comment). */
|
|
358
|
+
addNote(request) {
|
|
359
|
+
return this.notes.addNote(request);
|
|
360
|
+
}
|
|
361
|
+
/** Change or clear one note's comment. */
|
|
362
|
+
updateNote(request) {
|
|
363
|
+
return this.notes.updateNote(request);
|
|
364
|
+
}
|
|
365
|
+
/** Delete one note. */
|
|
366
|
+
deleteNote(request) {
|
|
367
|
+
return this.notes.deleteNote(request);
|
|
368
|
+
}
|
|
369
|
+
/** Remember that a conversation discussed this article. */
|
|
370
|
+
recordDiscussion(request) {
|
|
371
|
+
return this.notes.recordSession(request);
|
|
372
|
+
}
|
|
373
|
+
/** Add the reader's own line under a note. */
|
|
374
|
+
addReply(request) {
|
|
375
|
+
return this.notes.addReply({ ...request, by: 'user' });
|
|
376
|
+
}
|
|
377
|
+
/** Rewrite (or, with empty text, remove) one line under a note. */
|
|
378
|
+
editReply(request) {
|
|
379
|
+
return this.notes.editReply(request);
|
|
380
|
+
}
|
|
381
|
+
/** Remember that a note or a discussion note became a canvas card. */
|
|
382
|
+
markSynced(request) {
|
|
383
|
+
return this.notes.markSynced(request);
|
|
384
|
+
}
|
|
385
|
+
/** Delete one discussion note. */
|
|
386
|
+
deleteDiscussion(request) {
|
|
387
|
+
return this.notes.deleteDiscussion(request);
|
|
388
|
+
}
|
|
389
|
+
/** A video entry's transcript from its platform captions (stored; `none` when it has none). */
|
|
390
|
+
mediaTranscript(request) {
|
|
391
|
+
return this.core.mediaTranscript(request);
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Start (or rejoin) local transcription of an entry without captions.
|
|
395
|
+
* Answers `unavailable` without the transcription plugin and `needs-models`
|
|
396
|
+
* until the first model download is confirmed.
|
|
397
|
+
*/
|
|
398
|
+
startLocalTranscript(request) {
|
|
399
|
+
return this.core.local.start(request);
|
|
400
|
+
}
|
|
401
|
+
/** Where an entry's local transcription stands, with the transcript so far. */
|
|
402
|
+
localTranscript(request) {
|
|
403
|
+
return Promise.resolve(this.core.local.status(request.entryId));
|
|
404
|
+
}
|
|
405
|
+
/** The reader's names for a transcript's speakers, by index. */
|
|
406
|
+
speakerNames(request) {
|
|
407
|
+
return Promise.resolve(this.core.speakerNames(request));
|
|
408
|
+
}
|
|
409
|
+
/** Name one speaker of a transcript (empty: back to 说话人 A…); answers all the names. */
|
|
410
|
+
nameSpeaker(request) {
|
|
411
|
+
return Promise.resolve(this.core.nameSpeaker(request));
|
|
412
|
+
}
|
|
413
|
+
/** The wall's video / audio cards: what each one's transcript is (captions, local, transcribing…). */
|
|
414
|
+
mediaStates(request) {
|
|
415
|
+
return Promise.resolve(this.core.mediaStates(request));
|
|
416
|
+
}
|
|
417
|
+
/** Leave (withdraws a queued job) or, with `force`, stop an entry's local transcription. */
|
|
418
|
+
cancelLocalTranscript(request) {
|
|
419
|
+
return Promise.resolve(this.core.local.cancel(request.entryId, request.force));
|
|
420
|
+
}
|
|
421
|
+
/** The article's 润色 layer (the agent's translation), when there is one for its current text. */
|
|
422
|
+
polish(request) {
|
|
423
|
+
return Promise.resolve(this.notes.polishView(request.entryId) ?? null);
|
|
424
|
+
}
|
|
425
|
+
/** Show one paragraph's machine translation instead of the 润色 (or back). */
|
|
426
|
+
setPolishOff(request) {
|
|
427
|
+
return Promise.resolve(this.notes.setPolishOff(request.entryId, request.paragraph, request.off) ?? null);
|
|
428
|
+
}
|
|
429
|
+
/** Hand the host the article's original text, block by block, for the model to read. */
|
|
430
|
+
snapshotEntry(request) {
|
|
431
|
+
return this.notes.snapshot(request);
|
|
432
|
+
}
|
|
283
433
|
};
|
|
284
434
|
})();
|
|
285
435
|
export { ReaderRemoteService };
|
package/lib/types/service.d.ts
CHANGED
|
@@ -5,9 +5,12 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Two seams shape the whole module:
|
|
7
7
|
*
|
|
8
|
-
* - **Fetch
|
|
9
|
-
*
|
|
10
|
-
* byte cap and a timeout.
|
|
8
|
+
* - **Fetch rides the official HTTP provider** — `ctx.web` is the permission
|
|
9
|
+
* (nothing is fetched without it), and its default `http` provider brings
|
|
10
|
+
* public-address resolution, connection pinning, a byte cap and a timeout.
|
|
11
|
+
* On the official web service the reader runs its own instance of that
|
|
12
|
+
* provider (`document-fetch.ts`), because the host's selected provider may
|
|
13
|
+
* answer Markdown instead of the document (seam registry S22). Its provider caps the decoded body at 100 000
|
|
11
14
|
* characters by default, so a payload that comes back `truncated` is stored
|
|
12
15
|
* as-is and FLAGGED; nothing here pretends it is a whole document. A
|
|
13
16
|
* truncated feed cannot be parsed and a truncated page yields half an
|
|
@@ -35,7 +38,10 @@
|
|
|
35
38
|
* @module @khorsheed/dsh-reader/service
|
|
36
39
|
*/
|
|
37
40
|
import type { Context } from '@deepseek-ai/cordis';
|
|
38
|
-
import { type ReaderAddFailure, type ReaderAddOutcome, type ReaderAddRefusal, type ReaderAnnotationOutcome, type ReaderBackfillCandidate, type ReaderEntryBodyView, type ReaderBody, type ReaderCapabilities, type ReaderMutationOutcome, type ReaderEntryFetchState, type ReaderEntryTranslationView, type ReaderPreviewFailure, type ReaderPreviewFailureCode, type ReaderImageResult, type ReaderRecentEntry, type ReaderRefreshResult, type ReaderSentenceLearn, type ReaderSourceSummary, type ReaderStorageStats, type ReaderTag } from './types.ts';
|
|
41
|
+
import { type ReaderAddFailure, type ReaderAddOutcome, type ReaderAddRefusal, type ReaderAnnotationOutcome, type ReaderBackfillCandidate, type ReaderEntryBodyView, type ReaderBody, type ReaderCapabilities, type ReaderMutationOutcome, type ReaderEntryFetchState, type ReaderEntryTranslationView, type ReaderPreviewFailure, type ReaderPreviewFailureCode, type ReaderImageResult, type ReaderRecentEntry, type ReaderRefreshResult, type ReaderSentenceLearn, type ReaderSourceSummary, type ReaderStorageStats, type ReaderTag, type MediaCardStates } from './types.ts';
|
|
42
|
+
import { type DocumentFetchLimits } from './document-fetch.ts';
|
|
43
|
+
import { LocalTranscriber } from './local-transcribe.ts';
|
|
44
|
+
import { ReaderMediaHost } from './media-host.ts';
|
|
39
45
|
/**
|
|
40
46
|
* How many entries one automatic backfill run may fetch.
|
|
41
47
|
*
|
|
@@ -46,6 +52,15 @@ import { type ReaderAddFailure, type ReaderAddOutcome, type ReaderAddRefusal, ty
|
|
|
46
52
|
export declare const BACKFILL_MAX_PER_RUN = 8;
|
|
47
53
|
/** How long a FAILED fetch is left alone before it may be retried (6 hours). */
|
|
48
54
|
export declare const BACKFILL_RETRY_MS: number;
|
|
55
|
+
/**
|
|
56
|
+
* How many sources one refresh fetches at once.
|
|
57
|
+
*
|
|
58
|
+
* A strictly sequential loop made one dead source (a full 30 s timeout) stall
|
|
59
|
+
* every source behind it — the "refresh takes minutes" half of the slow-load
|
|
60
|
+
* report. Three at a time is the politeness ceiling this package applies to
|
|
61
|
+
* other people's servers everywhere (the backfill runs at two).
|
|
62
|
+
*/
|
|
63
|
+
export declare const REFRESH_CONCURRENCY = 3;
|
|
49
64
|
/**
|
|
50
65
|
* Thrown when the FETCH itself failed — a refused connection, a timeout, a
|
|
51
66
|
* response over the seam's byte cap. Carries the seam's own message: the
|
|
@@ -73,6 +88,10 @@ export declare function classifyPayload(raw: string): 'feed' | 'page';
|
|
|
73
88
|
/** The reader service. */
|
|
74
89
|
export declare class ReaderService {
|
|
75
90
|
private readonly store;
|
|
91
|
+
/** Video and audio entries: synthetic pages, channel feeds, transcripts. */
|
|
92
|
+
readonly media: ReaderMediaHost;
|
|
93
|
+
/** Local transcription of entries without captions (the optional `transcribe` engine). */
|
|
94
|
+
readonly local: LocalTranscriber;
|
|
76
95
|
private readonly ctx;
|
|
77
96
|
private timer;
|
|
78
97
|
private disposed;
|
|
@@ -80,12 +99,16 @@ export declare class ReaderService {
|
|
|
80
99
|
private memoryDoc;
|
|
81
100
|
/** Rescued images, by URL — a pane remount re-fails every blocked image, and this is what keeps that a memory read. */
|
|
82
101
|
private readonly imageCache;
|
|
102
|
+
/** Feeds and pages, as the origin served them (see `document-fetch.ts`). */
|
|
103
|
+
private readonly documents;
|
|
83
104
|
/**
|
|
84
105
|
* @param ctx - owning context.
|
|
85
106
|
* @param config - optional state-root override.
|
|
86
107
|
*/
|
|
87
108
|
constructor(ctx: Context, config?: {
|
|
88
109
|
stateRoot?: string;
|
|
110
|
+
ytdlpPath?: string;
|
|
111
|
+
fetchLimits?: DocumentFetchLimits;
|
|
89
112
|
});
|
|
90
113
|
/** Capabilities the browser may rely on. */
|
|
91
114
|
capabilities(): Promise<ReaderCapabilities>;
|
|
@@ -323,6 +346,8 @@ export declare class ReaderService {
|
|
|
323
346
|
title?: string;
|
|
324
347
|
/** A short excerpt (abstract / first paragraph), with the title. */
|
|
325
348
|
excerpt?: string;
|
|
349
|
+
/** Keep regardless of the cache TTL (a transcript costs a yt-dlp run, not a page fetch). */
|
|
350
|
+
keep?: boolean;
|
|
326
351
|
}): Promise<ReaderEntryBodyView>;
|
|
327
352
|
/**
|
|
328
353
|
* Which entries still need their full text, and which may be retried.
|
|
@@ -558,8 +583,6 @@ export declare class ReaderService {
|
|
|
558
583
|
* known-unreadable verdict) still answers.
|
|
559
584
|
*/
|
|
560
585
|
private resolvePaper;
|
|
561
|
-
/** The probed web seam (no host import, no boot-time dependency). */
|
|
562
|
-
private web;
|
|
563
586
|
/** The probed side-chat service. */
|
|
564
587
|
private sideChat;
|
|
565
588
|
/**
|
|
@@ -591,6 +614,58 @@ export declare class ReaderService {
|
|
|
591
614
|
* @returns the final URL and its decoded payload.
|
|
592
615
|
*/
|
|
593
616
|
private fetchFollowing;
|
|
617
|
+
/**
|
|
618
|
+
* Fetch a source's payload, media-aware (media-host.ts).
|
|
619
|
+
*
|
|
620
|
+
* A YouTube channel is fetched as YouTube's own channel feed; a Xiaoyuzhou
|
|
621
|
+
* podcast page as the RSS document it is turned into; a single video or
|
|
622
|
+
* Xiaoyuzhou episode as a synthetic page carrying its media description.
|
|
623
|
+
* Everything else is the ordinary {@link fetchFollowing}.
|
|
624
|
+
*
|
|
625
|
+
* @param url - the source URL.
|
|
626
|
+
*/
|
|
627
|
+
private fetchSource;
|
|
628
|
+
/**
|
|
629
|
+
* A video entry's transcript: the stored one, else the platform captions
|
|
630
|
+
* fetched now and kept (no TTL — it costs a yt-dlp run). A video known to
|
|
631
|
+
* have no captions answers so without running yt-dlp again.
|
|
632
|
+
*
|
|
633
|
+
* @param request - the entry and its video page URL.
|
|
634
|
+
* @returns the transcript markup, `none`, or why it failed.
|
|
635
|
+
*/
|
|
636
|
+
mediaTranscript(request: {
|
|
637
|
+
entryId: string;
|
|
638
|
+
url: string;
|
|
639
|
+
}): Promise<{
|
|
640
|
+
entryId: string;
|
|
641
|
+
html?: string;
|
|
642
|
+
captions: 'platform' | 'none' | 'failed';
|
|
643
|
+
language?: string;
|
|
644
|
+
error?: string;
|
|
645
|
+
}>;
|
|
646
|
+
/** The reader's names for an entry's speakers, by index. */
|
|
647
|
+
speakerNames(request: {
|
|
648
|
+
entryId: string;
|
|
649
|
+
}): Record<string, string>;
|
|
650
|
+
/**
|
|
651
|
+
* Name one speaker of an entry's transcript (an empty name restores the default).
|
|
652
|
+
*
|
|
653
|
+
* @param request - the entry, the speaker's index, the name.
|
|
654
|
+
*/
|
|
655
|
+
nameSpeaker(request: {
|
|
656
|
+
entryId: string;
|
|
657
|
+
speaker: number;
|
|
658
|
+
name: string;
|
|
659
|
+
}): Record<string, string>;
|
|
660
|
+
/**
|
|
661
|
+
* The wall's media cards: a live local job first, else what the captions
|
|
662
|
+
* record says (platform captions, a stored local transcript, none).
|
|
663
|
+
*
|
|
664
|
+
* @param request - the card ids on screen.
|
|
665
|
+
*/
|
|
666
|
+
mediaStates(request: {
|
|
667
|
+
entryIds: readonly string[];
|
|
668
|
+
}): MediaCardStates;
|
|
594
669
|
/** Arm (or re-arm) the daily refresh timer against the current document. */
|
|
595
670
|
private armSchedule;
|
|
596
671
|
}
|