@deepseek-ai/dsh-client-ui-sidebar-documentpreview 0.1.6-alpha.1 → 0.1.6-alpha.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/README.i18n.yaml +2 -2
- package/README.md +39 -6
- package/README.zh.md +39 -6
- package/lib/client.js +1821 -25130
- package/lib/client.pdf.js +32609 -0
- package/lib/index.js +26 -4
- package/lib/types/client/TextPreview.d.ts +1 -1
- package/lib/types/client/document/contract.d.ts +21 -11
- package/lib/types/client/document/registry.d.ts +2 -2
- package/lib/types/client/document/tab-lifetime.d.ts +10 -0
- package/lib/types/client/face.d.ts +9 -0
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/office/FontNotice.d.ts +16 -0
- package/lib/types/client/office/OfficeBody.d.ts +44 -0
- package/lib/types/client/office/cache.d.ts +70 -0
- package/lib/types/client/office/index.d.ts +16 -0
- package/lib/types/client/office/locales.d.ts +43 -0
- package/lib/types/client/office/store.d.ts +32 -0
- package/lib/types/client/pdf/LazyPdfBody.d.ts +10 -0
- package/lib/types/client/pdf/document.d.ts +8 -2
- package/lib/types/client/pdf/index.d.ts +13 -0
- package/lib/types/client/pdf/{PdfBody.d.ts → pdf.d.ts} +2 -2
- package/lib/types/client/pdf/store.d.ts +0 -2
- package/lib/types/client/pdf/text.d.ts +10 -0
- package/lib/types/client/rpc.d.ts +2 -2
- package/lib/types/client/store.d.ts +6 -1
- package/lib/types/config.d.ts +21 -0
- package/lib/types/index.d.ts +10 -3
- package/package.json +26 -18
package/lib/index.js
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
//#region lib/types/config.js
|
|
3
|
+
/** Cache limits shared by the Host configuration and browser document previews. */
|
|
4
|
+
/** Deployment limits applied before Office preview registration. */
|
|
5
|
+
const Config = z.object({ office: z.object({
|
|
6
|
+
maxCachedEntries: z.natural().min(1).max(Number.MAX_SAFE_INTEGER).default(8),
|
|
7
|
+
maxCachedBytes: z.natural().min(1).max(Number.MAX_SAFE_INTEGER).default(64 * 1024 * 1024),
|
|
8
|
+
maxPending: z.natural().min(1).max(Number.MAX_SAFE_INTEGER).default(8),
|
|
9
|
+
maxReaders: z.natural().min(1).max(Number.MAX_SAFE_INTEGER).default(32)
|
|
10
|
+
}) });
|
|
11
|
+
//#endregion
|
|
1
12
|
//#region lib/types/index.js
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Embed validated preview settings in browser pages.
|
|
15
|
+
* @param ctx - Host context serving browser pages.
|
|
16
|
+
* @param config - Cache limits adopted when the page loads.
|
|
17
|
+
*/
|
|
18
|
+
function apply(ctx, config) {
|
|
19
|
+
ctx.on("webserver/index-inject", (table) => {
|
|
20
|
+
table.push({
|
|
21
|
+
kind: "global",
|
|
22
|
+
name: "__DSH_DOCUMENT_PREVIEW_CONFIG__",
|
|
23
|
+
value: config
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
5
27
|
//#endregion
|
|
6
|
-
export { apply };
|
|
28
|
+
export { Config, apply };
|
|
@@ -19,5 +19,5 @@ export type TextPreviewProps = PropsRuntime<'sidebar.right.pane.tab'> & PropsRen
|
|
|
19
19
|
* @param props - composed slot props.
|
|
20
20
|
* @returns the content read so far with its controls, or a progress line.
|
|
21
21
|
*/
|
|
22
|
-
export declare function TextPreview({ useTabInfo, useResource, useStore, actions, loadPage, reloadPages, loadAll, reloadAll, useDocumentPreviews, renderSlot, t, }: TextPreviewProps): ReactNode;
|
|
22
|
+
export declare function TextPreview({ useTabInfo, useResource, useStore, actions, loadPage, reloadPages, loadAll, reloadAll, prepareRenderer, useDocumentPreviews, renderSlot, t, }: TextPreviewProps): ReactNode;
|
|
23
23
|
//# sourceMappingURL=TextPreview.d.ts.map
|
|
@@ -9,7 +9,7 @@ export interface DocumentTextPage {
|
|
|
9
9
|
readonly lines: number;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Ordinary file contents, or a request for the selected renderer to load its content.
|
|
13
13
|
* Byte arrays are transient UI input, never persisted layout or Session data.
|
|
14
14
|
*/
|
|
15
15
|
export type DocumentContent = {
|
|
@@ -20,23 +20,33 @@ export type DocumentContent = {
|
|
|
20
20
|
} | {
|
|
21
21
|
readonly kind: 'bytes';
|
|
22
22
|
readonly data: Uint8Array<ArrayBuffer>;
|
|
23
|
+
} | {
|
|
24
|
+
readonly kind: 'renderer';
|
|
25
|
+
/** Changes on reload or implementation replacement; retained contents belong to one revision. */
|
|
26
|
+
readonly revision: number;
|
|
27
|
+
/** Report the displayed source version; stale revisions cannot update the owner. @param version - loaded source version. */
|
|
28
|
+
readonly loaded: (version: string) => void;
|
|
29
|
+
/** Cancel the current load and start a new revision. */
|
|
30
|
+
readonly reload: () => void;
|
|
23
31
|
};
|
|
32
|
+
/** Content and viewing inputs shared by document bodies and nested PDF presentation. */
|
|
33
|
+
export interface DocumentBodyOwner {
|
|
34
|
+
/** Original file address, also readable through the standard useResource hook. */
|
|
35
|
+
readonly resourceAddress: string;
|
|
36
|
+
/** Ordinary file content or a renderer-owned loading request; text accumulates until eof. */
|
|
37
|
+
readonly content: DocumentContent;
|
|
38
|
+
/** The document toolbar's current wrapping preference. */
|
|
39
|
+
readonly wrap: boolean;
|
|
40
|
+
/** Report a renderer-owned scrollport; passing `null` restores the shared body as the owner. */
|
|
41
|
+
readonly scrollportRef: RefCallback<HTMLElement>;
|
|
42
|
+
}
|
|
24
43
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
25
44
|
interface SlotMap {
|
|
26
45
|
/** Document body selected by a registered implementation id. */
|
|
27
46
|
'sidebar.right.tab.document': {
|
|
28
47
|
kind: 'keyed';
|
|
29
48
|
scope: 'session';
|
|
30
|
-
owner:
|
|
31
|
-
/** Original file address, also readable through the standard useResource hook. */
|
|
32
|
-
readonly resourceAddress: string;
|
|
33
|
-
/** Loaded content; text is an accumulated prefix until eof. */
|
|
34
|
-
readonly content: DocumentContent;
|
|
35
|
-
/** The document toolbar's current wrapping preference. */
|
|
36
|
-
readonly wrap: boolean;
|
|
37
|
-
/** Report a renderer-owned scrollport; passing `null` restores the shared body as the owner. */
|
|
38
|
-
readonly scrollportRef: RefCallback<HTMLElement>;
|
|
39
|
-
};
|
|
49
|
+
owner: DocumentBodyOwner;
|
|
40
50
|
hookContext: UseSidebarRightTabInfo;
|
|
41
51
|
inject: {
|
|
42
52
|
hooks: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export type DocumentLoadMode = 'text-pages' | 'bytes-complete';
|
|
1
|
+
/** Shared text or byte reads, or content loading owned by the renderer. */
|
|
2
|
+
export type DocumentLoadMode = 'text-pages' | 'bytes-complete' | 'renderer';
|
|
3
3
|
/** One renderer implementation, independent of its component registration. */
|
|
4
4
|
export interface DocumentPreviewDefinition {
|
|
5
5
|
/** Unique implementation name, also used as the document slot key. */
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Document view state belongs to tab records, including while their bodies are hidden. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { TabId } from '@deepseek-ai/dsh-client-ui-dockkit';
|
|
4
|
+
/**
|
|
5
|
+
* Release retained view state on tab closure or plugin disposal.
|
|
6
|
+
* @param ctx - owning preview plugin context.
|
|
7
|
+
* @returns a callback accepting the tab, its lifetime signal, and its store's forget action; repeated holds share one listener.
|
|
8
|
+
*/
|
|
9
|
+
export declare function retainDocumentTabs(ctx: Context): (tabId: TabId, signal: AbortSignal, forget: (tabId: TabId) => void) => void;
|
|
10
|
+
//# sourceMappingURL=tab-lifetime.d.ts.map
|
|
@@ -61,6 +61,15 @@ export interface TextInjected {
|
|
|
61
61
|
* @param observedVersion - metadata version observed at read start.
|
|
62
62
|
*/
|
|
63
63
|
readonly reloadAll: (tabId: TabId, file: SessionFile, signal: AbortSignal, observedVersion?: string) => void;
|
|
64
|
+
/**
|
|
65
|
+
* Begin a renderer-owned load without reading source bytes.
|
|
66
|
+
* @param tabId - owning tab.
|
|
67
|
+
* @param signal - tab lifetime.
|
|
68
|
+
* @param rendererId - selected implementation.
|
|
69
|
+
* @param observedVersion - metadata version observed at request start.
|
|
70
|
+
* @param reload - discard the previous content revision.
|
|
71
|
+
*/
|
|
72
|
+
readonly prepareRenderer: (tabId: TabId, signal: AbortSignal, rendererId: string, observedVersion?: string, reload?: boolean) => void;
|
|
64
73
|
}
|
|
65
74
|
/**
|
|
66
75
|
* Bind the preview's face to one paged read and one complete-byte read.
|
|
@@ -16,7 +16,7 @@ import { DocumentPreviewRegistry } from './document/registry.ts';
|
|
|
16
16
|
export type { SidebarDocumentPreviewKey } from './locales.ts';
|
|
17
17
|
export type { TextPreviewProps } from './TextPreview.tsx';
|
|
18
18
|
export type { TextInjected } from './face.ts';
|
|
19
|
-
export type { ReadWorkspaceFilePage, SessionFile, WorkspaceFilesReadRemote } from './rpc.ts';
|
|
19
|
+
export type { ReadDocumentBytes, DocumentFileBytes, ReadWorkspaceFilePage, SessionFile, WorkspaceFilesReadRemote } from './rpc.ts';
|
|
20
20
|
export type { TextPage, TextState, TextStore, TextTabState } from './store.ts';
|
|
21
21
|
export type { DocumentContent, DocumentPreviewProps, DocumentTextPage } from './document/contract.ts';
|
|
22
22
|
export type { DocumentLoadMode, DocumentPreviewDefinition } from './document/registry.ts';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Missing-font notice and a non-modal details panel for one source version. */
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
|
+
/** Notice inputs supplied by the document owner and Office locale registration. */
|
|
5
|
+
export type FontNoticeProps = PropsLocale<'sidebarOffice'> & {
|
|
6
|
+
readonly resourceAddress: string;
|
|
7
|
+
readonly sourceVersion: string;
|
|
8
|
+
readonly fonts: readonly string[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Show missing fonts; dismissal applies to the same source version while this component stays mounted.
|
|
12
|
+
* @param props - source identity, converted content, and localized copy.
|
|
13
|
+
* @returns a collapsible notice and its anchored details, or nothing when fonts are available.
|
|
14
|
+
*/
|
|
15
|
+
export declare function FontNotice({ resourceAddress, sourceVersion, fonts, t }: FontNoticeProps): ReactNode;
|
|
16
|
+
//# sourceMappingURL=FontNotice.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Office owns source loading, conversion failures, and font notices around the shared PDF view. */
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { PropsLocale, PropsRenderSlots, PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
|
+
import type { RemoteFailure } from '@deepseek-ai/dsh-api-remotes/client';
|
|
5
|
+
import type { TabId } from '@deepseek-ai/dsh-client-ui-dockkit';
|
|
6
|
+
import type { UseSidebarRightTabInfo } from '@deepseek-ai/dsh-client-ui-sidebar-right/client';
|
|
7
|
+
import type { DocumentBodyOwner, DocumentPreviewProps } from '../document/contract.ts';
|
|
8
|
+
import type { ReadOfficeDocument } from './cache.ts';
|
|
9
|
+
import type { OfficeStore } from './store.ts';
|
|
10
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
11
|
+
interface SlotMap {
|
|
12
|
+
/** PDF presentation supplied with Office-owned converted bytes. */
|
|
13
|
+
'sidebar.right.tab.document.office.pdf': {
|
|
14
|
+
kind: 'keyed';
|
|
15
|
+
scope: 'session';
|
|
16
|
+
owner: DocumentBodyOwner;
|
|
17
|
+
hookContext: UseSidebarRightTabInfo;
|
|
18
|
+
inject: {
|
|
19
|
+
hooks: {
|
|
20
|
+
tabInfo: SlotHookFactory<'sidebar.right.tab.document', UseSidebarRightTabInfo>;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Office loading callbacks supplied by the registration's services. */
|
|
27
|
+
export interface OfficeBodyInjected {
|
|
28
|
+
readonly read: ReadOfficeDocument;
|
|
29
|
+
/** @param failure - declared file-read failure or conversion exception message. @returns localized display text. */
|
|
30
|
+
readonly describeFailure: (failure: RemoteFailure | {
|
|
31
|
+
readonly message: string;
|
|
32
|
+
}) => string;
|
|
33
|
+
/** @param tab - owning tab. @param signal - tab lifetime, including hidden bodies. */
|
|
34
|
+
readonly retainTab: (tab: TabId, signal: AbortSignal) => void;
|
|
35
|
+
}
|
|
36
|
+
/** Office body inputs and its private PDF child. */
|
|
37
|
+
export type OfficeBodyProps = DocumentPreviewProps & PropsStore<OfficeStore> & OfficeBodyInjected & PropsLocale<'sidebarOffice'> & PropsRenderSlots<'sidebar.right.tab.document.office.pdf'>;
|
|
38
|
+
/**
|
|
39
|
+
* Load one Office revision and preserve its result while its tab remains open.
|
|
40
|
+
* @param props - renderer loading request, tab state, conversion callbacks, and PDF slot.
|
|
41
|
+
* @returns conversion status or the font notice and PDF scrollport.
|
|
42
|
+
*/
|
|
43
|
+
export declare function OfficeBody(props: OfficeBodyProps): ReactNode;
|
|
44
|
+
//# sourceMappingURL=OfficeBody.d.ts.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** Session-authorized, version-checked Office bytes shared by concurrent preview reads. */
|
|
2
|
+
import type { OfficeToPdfPriority, OfficeToPdfGeneration } from '@deepseek-ai/dsh-office-to-pdf/types';
|
|
3
|
+
import type { RemoteResult } from '@deepseek-ai/dsh-api-remotes/client';
|
|
4
|
+
import type { WorkspaceFileStat } from '@deepseek-ai/dsh-api-workspace-files/types';
|
|
5
|
+
import type { DocumentFileBytes, SessionFile } from '../rpc.ts';
|
|
6
|
+
/** PDF bytes and conversion metadata owned by Office preview. */
|
|
7
|
+
export type OfficeFileBytes = DocumentFileBytes & {
|
|
8
|
+
readonly missingFonts: readonly string[];
|
|
9
|
+
readonly generation: OfficeToPdfGeneration;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Load authorized PDF contents for one Office source.
|
|
13
|
+
* @param file - Session and source path.
|
|
14
|
+
* @param signal - this reader's lifetime.
|
|
15
|
+
* @returns converted PDF bytes or a declared source-access failure.
|
|
16
|
+
*/
|
|
17
|
+
export type ReadOfficeDocument = (file: SessionFile, signal: AbortSignal) => Promise<RemoteResult<OfficeFileBytes>>;
|
|
18
|
+
/** Authorized cached reads carry explicit scheduling intent to the Host. */
|
|
19
|
+
export type ReadOfficeBytes = (file: SessionFile, signal: AbortSignal, priority: OfficeToPdfPriority) => ReturnType<ReadOfficeDocument>;
|
|
20
|
+
type Result = Awaited<ReturnType<ReadOfficeDocument>>;
|
|
21
|
+
type Stat = (file: SessionFile, signal: AbortSignal) => Promise<RemoteResult<WorkspaceFileStat>>;
|
|
22
|
+
/** Bounded successful results; each caller reauthorizes and checks source freshness before reuse. */
|
|
23
|
+
export declare class OfficePreviewCache {
|
|
24
|
+
private readonly stat;
|
|
25
|
+
private readonly convert;
|
|
26
|
+
private readonly maxEntries;
|
|
27
|
+
private readonly maxBytes;
|
|
28
|
+
private readonly maxPending;
|
|
29
|
+
private readonly maxReaders;
|
|
30
|
+
private readonly currentGeneration;
|
|
31
|
+
private readonly busy;
|
|
32
|
+
private readonly ready;
|
|
33
|
+
private readonly pending;
|
|
34
|
+
private bytes;
|
|
35
|
+
private readers;
|
|
36
|
+
private generation;
|
|
37
|
+
private generationQuery;
|
|
38
|
+
private acceptedQuery;
|
|
39
|
+
private readonly superseded;
|
|
40
|
+
private readonly lifetime;
|
|
41
|
+
private readonly tasks;
|
|
42
|
+
private readonly reads;
|
|
43
|
+
/**
|
|
44
|
+
* @param stat - authorized source metadata lookup.
|
|
45
|
+
* @param convert - Host render Remote returning binary PDF bytes borrowed read-only by callers.
|
|
46
|
+
* @param maxEntries - maximum completed results retained.
|
|
47
|
+
* @param maxBytes - maximum retained PDF byteLength.
|
|
48
|
+
* @param maxPending - maximum unsettled Host conversion requests, including cancellation teardown.
|
|
49
|
+
* @param maxReaders - maximum readers, including metadata lookups.
|
|
50
|
+
* @param generation - current Host renderer generation, checked before cached reuse.
|
|
51
|
+
* @param busy - localized capacity failure.
|
|
52
|
+
*/
|
|
53
|
+
constructor(stat: Stat, convert: ReadOfficeBytes, maxEntries: number, maxBytes: number, maxPending: number, maxReaders: number, currentGeneration: (signal: AbortSignal) => Promise<RemoteResult<OfficeToPdfGeneration>>, busy: () => Error);
|
|
54
|
+
/**
|
|
55
|
+
* Share a conversion without letting one caller cancel another caller's work.
|
|
56
|
+
* Renderer replacement retries authorization once; repeated replacement reports localized capacity failure.
|
|
57
|
+
* @param file - Session authorization scope and source path.
|
|
58
|
+
* @param signal - this caller's lifetime.
|
|
59
|
+
* @param priority - foreground preview or speculative read.
|
|
60
|
+
* @returns current PDF bytes borrowed read-only, or a declared source-read failure; cancellation rejects.
|
|
61
|
+
*/
|
|
62
|
+
read(file: SessionFile, signal: AbortSignal, priority?: OfficeToPdfPriority): Promise<Result>;
|
|
63
|
+
private lookup;
|
|
64
|
+
private lookupGeneration;
|
|
65
|
+
/** Clear retained bytes, cancel outstanding conversions, and await their completion. */
|
|
66
|
+
dispose(): Promise<void>;
|
|
67
|
+
private retain;
|
|
68
|
+
}
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Office preview registration backed by authorized Host rendering and the existing PDF body. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import { type OfficePreviewKey } from './locales.ts';
|
|
4
|
+
import type { Config } from '../../config.ts';
|
|
5
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
6
|
+
interface LocaleNamespaceMap {
|
|
7
|
+
sidebarOffice: OfficePreviewKey;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Register Office previews with versioned PDF reuse and missing-font notices.
|
|
12
|
+
* @param ctx - Client renderer registry, localized copy, and optional Host Remotes.
|
|
13
|
+
* @param config - Resolved Office preview cache limits.
|
|
14
|
+
*/
|
|
15
|
+
export declare function apply(ctx: Context, config: Config['office']): void;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Office preview copy and Host render configuration guidance. */
|
|
2
|
+
export declare const zh: {
|
|
3
|
+
title: string;
|
|
4
|
+
loading: string;
|
|
5
|
+
retry: string;
|
|
6
|
+
missingFonts: string;
|
|
7
|
+
showMore: string;
|
|
8
|
+
dismissNotice: string;
|
|
9
|
+
missingFontsTitle: string;
|
|
10
|
+
missingFontsDescription: string;
|
|
11
|
+
missingFontsCount: string;
|
|
12
|
+
closeDetails: string;
|
|
13
|
+
unavailable: string;
|
|
14
|
+
invalid: string;
|
|
15
|
+
tooLarge: string;
|
|
16
|
+
failed: string;
|
|
17
|
+
timeout: string;
|
|
18
|
+
busy: string;
|
|
19
|
+
changed: string;
|
|
20
|
+
};
|
|
21
|
+
/** Office preview locale keys. */
|
|
22
|
+
export type OfficePreviewKey = keyof typeof zh;
|
|
23
|
+
/** English translations checked against the Chinese key set. */
|
|
24
|
+
export declare const en: {
|
|
25
|
+
title: string;
|
|
26
|
+
loading: string;
|
|
27
|
+
retry: string;
|
|
28
|
+
missingFonts: string;
|
|
29
|
+
showMore: string;
|
|
30
|
+
dismissNotice: string;
|
|
31
|
+
missingFontsTitle: string;
|
|
32
|
+
missingFontsDescription: string;
|
|
33
|
+
missingFontsCount: string;
|
|
34
|
+
closeDetails: string;
|
|
35
|
+
unavailable: string;
|
|
36
|
+
invalid: string;
|
|
37
|
+
tooLarge: string;
|
|
38
|
+
failed: string;
|
|
39
|
+
timeout: string;
|
|
40
|
+
busy: string;
|
|
41
|
+
changed: string;
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Loaded Office previews survive body remounts until reload or tab closure. */
|
|
2
|
+
import { type EngineStoreHandle } from '@deepseek-ai/dsh-client-store';
|
|
3
|
+
import type { TabId } from '@deepseek-ai/dsh-client-ui-dockkit';
|
|
4
|
+
import type { OfficeFileBytes } from './cache.ts';
|
|
5
|
+
/** One requested source revision and its settled preview. */
|
|
6
|
+
export interface OfficeView {
|
|
7
|
+
readonly revision: number;
|
|
8
|
+
readonly file?: OfficeFileBytes;
|
|
9
|
+
readonly failure?: {
|
|
10
|
+
readonly code: string;
|
|
11
|
+
readonly message: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Office-owned content, isolated by tab identity. */
|
|
15
|
+
export interface OfficeState {
|
|
16
|
+
byTab: Record<TabId, OfficeView>;
|
|
17
|
+
}
|
|
18
|
+
type OfficeActions = {
|
|
19
|
+
loading: (state: OfficeState, tab: TabId, revision: number) => void;
|
|
20
|
+
complete: (state: OfficeState, tab: TabId, revision: number, file: OfficeFileBytes) => void;
|
|
21
|
+
failed: (state: OfficeState, tab: TabId, revision: number, failure: NonNullable<OfficeView['failure']>) => void;
|
|
22
|
+
forget: (state: OfficeState, tab: TabId) => void;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Retain Office contents across body remounts within a Session.
|
|
26
|
+
* @returns the tab-content store declaration.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createOfficeStore(): EngineStoreHandle<OfficeState, OfficeActions>;
|
|
29
|
+
/** Store declaration used by the Office body. */
|
|
30
|
+
export type OfficeStore = ReturnType<typeof createOfficeStore>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Load the PDF renderer only after a PDF body is mounted. */
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { PdfBodyProps } from './pdf.tsx';
|
|
4
|
+
/**
|
|
5
|
+
* Suspend while the package-local PDF chunk arrives.
|
|
6
|
+
* @param props - PDF body props supplied by the document slot.
|
|
7
|
+
* @returns the deferred PDF renderer.
|
|
8
|
+
*/
|
|
9
|
+
export declare function LazyPdfBody(props: PdfBodyProps): ReactNode;
|
|
10
|
+
//# sourceMappingURL=LazyPdfBody.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Canvas rendering with cancellation and page cleanup, shared by the PDF body and real-library smoke. */
|
|
2
|
-
import type { PDFDocumentProxy } from 'pdfjs-dist';
|
|
2
|
+
import type { PDFDocumentProxy, PDFPageProxy, PageViewport } from 'pdfjs-dist';
|
|
3
3
|
/** The document operations used by one mounted PDF body. */
|
|
4
4
|
export type PdfDocument = Pick<PDFDocumentProxy, 'numPages' | 'getPage'>;
|
|
5
5
|
/** One in-flight PDF load and its complete cleanup operation. */
|
|
@@ -17,6 +17,11 @@ export interface PdfPageSize {
|
|
|
17
17
|
readonly width: number;
|
|
18
18
|
readonly height: number;
|
|
19
19
|
}
|
|
20
|
+
/** Optional DOM text rendering that shares the canvas page's cleanup barrier. */
|
|
21
|
+
export type RenderPdfText = (page: PDFPageProxy, viewport: PageViewport) => {
|
|
22
|
+
readonly promise: Promise<void>;
|
|
23
|
+
cancel(): void;
|
|
24
|
+
};
|
|
20
25
|
/**
|
|
21
26
|
* Render one page into an exclusively owned canvas. Cancellation cannot write
|
|
22
27
|
* dimensions after a delayed getPage; active render tasks are cancelled and
|
|
@@ -26,7 +31,8 @@ export interface PdfPageSize {
|
|
|
26
31
|
* @param canvas - canvas owned by this render only.
|
|
27
32
|
* @param signal - render lifetime.
|
|
28
33
|
* @param pixelRatio - display pixel ratio.
|
|
34
|
+
* @param renderText - optional selectable text layer sharing this page and viewport.
|
|
29
35
|
* @returns the page's CSS dimensions after rendering completes.
|
|
30
36
|
*/
|
|
31
|
-
export declare function renderPdfPage(document: PdfDocument, pageNumber: number, canvas: HTMLCanvasElement, signal: AbortSignal, pixelRatio: number): Promise<PdfPageSize>;
|
|
37
|
+
export declare function renderPdfPage(document: PdfDocument, pageNumber: number, canvas: HTMLCanvasElement, signal: AbortSignal, pixelRatio: number, renderText?: RenderPdfText): Promise<PdfPageSize>;
|
|
32
38
|
//# sourceMappingURL=document.d.ts.map
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/** Builtin PDF registration through document metadata and the keyed body slot. */
|
|
2
2
|
import type { Context } from '@deepseek-ai/cordis';
|
|
3
3
|
import type { DocumentPreviewDefinition } from '../document/registry.ts';
|
|
4
|
+
import type { PdfBodyInjected } from './pdf.tsx';
|
|
5
|
+
import type { BoundActions } from '@deepseek-ai/dsh-client-store';
|
|
6
|
+
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
7
|
+
import { type PdfStore } from './store.ts';
|
|
4
8
|
/** PDF metadata and keyed body share this package-local implementation identity. */
|
|
5
9
|
export declare const PDF_BODY_ID = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/pdf";
|
|
6
10
|
/**
|
|
@@ -11,4 +15,13 @@ export declare const PDF_BODY_ID = "@deepseek-ai/dsh-client-ui-sidebar-documentp
|
|
|
11
15
|
export declare function pdfBodyDefinition(title: () => string): DocumentPreviewDefinition;
|
|
12
16
|
/** @param ctx - context carrying the locale, document registry, and slot registry. */
|
|
13
17
|
export declare function apply(ctx: Context): void;
|
|
18
|
+
/**
|
|
19
|
+
* Retain PDF viewing state for a document entry's tab lifetime.
|
|
20
|
+
* @param ctx - owning registration context.
|
|
21
|
+
* @returns the store and injection shared by ordinary and Office PDF registrations.
|
|
22
|
+
*/
|
|
23
|
+
export declare function pdfBodyRegistration(ctx: Context): {
|
|
24
|
+
store: PdfStore;
|
|
25
|
+
inject: (sessionId: SessionId, actions: BoundActions<PdfStore>) => PdfBodyInjected;
|
|
26
|
+
};
|
|
14
27
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -3,7 +3,7 @@ import { type ReactNode } from 'react';
|
|
|
3
3
|
import type { PropsLocale, PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
4
|
import type { TabId } from '@deepseek-ai/dsh-client-ui-dockkit';
|
|
5
5
|
import type { DocumentPreviewProps } from '../document/contract.ts';
|
|
6
|
-
import {
|
|
6
|
+
import type { PdfStore } from './store.ts';
|
|
7
7
|
/** A record's viewing preferences survive body unmounts and leave with the tab. */
|
|
8
8
|
export interface PdfBodyInjected {
|
|
9
9
|
/**
|
|
@@ -21,4 +21,4 @@ export type PdfBodyProps = DocumentPreviewProps & PropsLocale<'sidebarPdf'> & Pr
|
|
|
21
21
|
* @returns the PDF reader.
|
|
22
22
|
*/
|
|
23
23
|
export declare function PdfBody(props: PdfBodyProps): ReactNode;
|
|
24
|
-
//# sourceMappingURL=
|
|
24
|
+
//# sourceMappingURL=pdf.d.ts.map
|
|
@@ -5,8 +5,6 @@ import type { TabId } from '@deepseek-ai/dsh-client-ui-dockkit';
|
|
|
5
5
|
export interface PdfView {
|
|
6
6
|
readonly page: number;
|
|
7
7
|
}
|
|
8
|
-
/** Initial viewing position before a tab reaches another page. */
|
|
9
|
-
export declare const DEFAULT_PDF_VIEW: PdfView;
|
|
10
8
|
/** Page state isolated by the owning tab record. */
|
|
11
9
|
export interface PdfState {
|
|
12
10
|
byTab: Record<TabId, PdfView>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** PDF.js's viewer owns selection boundaries and copy normalization; the overlay follows its canvas. */
|
|
2
|
+
import 'pdfjs-dist';
|
|
3
|
+
import type { RenderPdfText } from './document.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Create a selectable overlay in a component-owned host.
|
|
6
|
+
* @param host - absolute overlay matching the displayed canvas dimensions.
|
|
7
|
+
* @returns renderer whose cancellation also releases its resize observer and DOM.
|
|
8
|
+
*/
|
|
9
|
+
export declare function pdfTextRenderer(host: HTMLDivElement): RenderPdfText;
|
|
10
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -65,9 +65,9 @@ export type DocumentFileBytes = Omit<WorkspaceFileBytes, 'data'> & {
|
|
|
65
65
|
* Read a complete file through the Host endpoint.
|
|
66
66
|
* @param file - Session and path decoded from the tab address.
|
|
67
67
|
* @param signal - owning tab lifetime.
|
|
68
|
-
* @returns complete
|
|
68
|
+
* @returns complete binary bytes, including declared failures.
|
|
69
69
|
*/
|
|
70
|
-
export type ReadDocumentBytes = (file: SessionFile, signal: AbortSignal) => Promise<RemoteResult<
|
|
70
|
+
export type ReadDocumentBytes = (file: SessionFile, signal: AbortSignal) => Promise<RemoteResult<DocumentFileBytes>>;
|
|
71
71
|
/**
|
|
72
72
|
* Decode one successful Remote byte result for document renderers.
|
|
73
73
|
* @param file - Host byte result with base64 data.
|
|
@@ -33,6 +33,10 @@ export interface TextTabState {
|
|
|
33
33
|
rendererId?: string;
|
|
34
34
|
/** Current display-loading mode; absent before the first read. */
|
|
35
35
|
mode?: DocumentLoadMode;
|
|
36
|
+
/** Implementation owning source loading; absent for ordinary file reads. */
|
|
37
|
+
contentRendererId?: string;
|
|
38
|
+
/** Current content revision, incremented whenever loaded content is discarded. */
|
|
39
|
+
loadRevision: number;
|
|
36
40
|
/** Full byte result used by complete-file renderers. */
|
|
37
41
|
complete?: DocumentFileBytes;
|
|
38
42
|
/** The file version the loaded pages belong to; absent before the first page. */
|
|
@@ -66,7 +70,8 @@ export declare function fresh(): TextTabState;
|
|
|
66
70
|
/** The preview store's write set; every action names the tab it writes. */
|
|
67
71
|
type TextActions = {
|
|
68
72
|
selected: (draft: TextState, tabId: TabId, rendererId: string | undefined) => void;
|
|
69
|
-
loading: (draft: TextState, tabId: TabId, mode?: DocumentLoadMode, observedVersion?: string) => void;
|
|
73
|
+
loading: (draft: TextState, tabId: TabId, mode?: DocumentLoadMode, observedVersion?: string, contentRendererId?: string) => void;
|
|
74
|
+
rendered: (draft: TextState, tabId: TabId, revision: number, version: string) => void;
|
|
70
75
|
complete: (draft: TextState, tabId: TabId, file: DocumentFileBytes) => void;
|
|
71
76
|
page: (draft: TextState, tabId: TabId, page: WorkspaceFileText) => void;
|
|
72
77
|
failed: (draft: TextState, tabId: TabId, failure: RemoteFailure) => void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Cache limits shared by the Host configuration and browser document previews. */
|
|
2
|
+
import z from '@deepseek-ai/schemastery';
|
|
3
|
+
/** Transient Office conversion reuse within one Client connection. */
|
|
4
|
+
export interface Config {
|
|
5
|
+
/** Retained PDF limits; pending conversions share cancellation by reader lifetime. */
|
|
6
|
+
office: {
|
|
7
|
+
/** Maximum retained completed PDFs. */
|
|
8
|
+
maxCachedEntries: number;
|
|
9
|
+
/** Maximum retained PDF bytes, counted by each binary buffer's byteLength. */
|
|
10
|
+
maxCachedBytes: number;
|
|
11
|
+
/** Maximum unsettled Host conversion RPCs, including cancellation teardown. */
|
|
12
|
+
maxPending: number;
|
|
13
|
+
/** Maximum readers including source and renderer metadata lookups. */
|
|
14
|
+
maxReaders: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Deployment limits applied before Office preview registration. */
|
|
18
|
+
export declare const Config: z<{
|
|
19
|
+
office?: Partial<Config['office']>;
|
|
20
|
+
}, Config>;
|
|
21
|
+
//# sourceMappingURL=config.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/** Host configuration for browser document previews. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { Config } from './config.ts';
|
|
4
|
+
export { Config } from './config.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Embed validated preview settings in browser pages.
|
|
7
|
+
* @param ctx - Host context serving browser pages.
|
|
8
|
+
* @param config - Cache limits adopted when the page loads.
|
|
9
|
+
*/
|
|
10
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
4
11
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-sidebar-documentpreview",
|
|
3
|
-
"description": "Extensible document previews for Sidebar files: Markdown, highlighted code, images, PDF, HTML, and plain text",
|
|
4
|
-
"version": "0.1.6-alpha.
|
|
3
|
+
"description": "Extensible document previews for Sidebar files: Office, Markdown, highlighted code, images, PDF, HTML, and plain text",
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"@deepseek-ai/dsh-api-workspace-files",
|
|
33
33
|
"@deepseek-ai/dsh-client-ui-sidebar-right",
|
|
34
34
|
"@deepseek-ai/dsh-client-ui-session",
|
|
35
|
-
"@deepseek-ai/dsh-api-remotes"
|
|
35
|
+
"@deepseek-ai/dsh-api-remotes",
|
|
36
|
+
"@deepseek-ai/dsh-client-locale"
|
|
36
37
|
],
|
|
37
38
|
"platform": "web"
|
|
38
39
|
}
|
|
@@ -49,28 +50,35 @@
|
|
|
49
50
|
"pdfjs-dist": "6.3.289",
|
|
50
51
|
"react": "^18.2.0",
|
|
51
52
|
"react-dom": "^18.2.0",
|
|
53
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-api-workspace-files": "^0.1.6-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-api-gateway": "^0.1.6-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-client-resources": "^0.1.6-alpha.2",
|
|
52
58
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/dsh-client-
|
|
57
|
-
"@deepseek-ai/dsh-client-
|
|
58
|
-
"@deepseek-ai/dsh-
|
|
59
|
-
"@deepseek-ai/dsh-client-
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
61
|
-
"@deepseek-ai/dsh-
|
|
62
|
-
"@deepseek-ai/dsh-
|
|
63
|
-
"@deepseek-ai/dsh-client-
|
|
64
|
-
"@deepseek-ai/dsh-client-ui-
|
|
65
|
-
"@deepseek-ai/dsh-client-ui-
|
|
66
|
-
"@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
|
|
67
|
-
"@deepseek-ai/dsh-util-workspace-path": "^0.1.6-alpha.1"
|
|
59
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-dockkit": "^0.1.6-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.6-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.6-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-util-workspace-path": "^0.1.6-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-office-to-pdf": "^0.1.6-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-client-store": "^0.1.6-alpha.2",
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.2",
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "^0.1.6-alpha.2"
|
|
68
72
|
},
|
|
69
73
|
"files": [
|
|
70
74
|
"lib/index.js",
|
|
71
75
|
"lib/client.js",
|
|
76
|
+
"lib/client.*.js",
|
|
72
77
|
"lib/types/**/*.d.ts"
|
|
73
78
|
],
|
|
79
|
+
"dependencies": {
|
|
80
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
81
|
+
},
|
|
74
82
|
"scripts": {
|
|
75
83
|
"bundle": "tsdown",
|
|
76
84
|
"watch": "tsdown --watch"
|