@tita-agent/dsh-data-table 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +172 -2
- package/cordis.patch.yml +7 -0
- package/lib/client.js +16766 -0
- package/lib/contract-envelope.d.ts +91 -0
- package/lib/contract-envelope.js +106 -0
- package/lib/contract-layout.d.ts +130 -0
- package/lib/contract-layout.js +138 -0
- package/lib/contract-refs.d.ts +39 -0
- package/lib/contract-refs.js +9 -0
- package/lib/contract-version.d.ts +311 -0
- package/lib/contract-version.js +270 -0
- package/lib/contract-wire.d.ts +147 -0
- package/lib/contract-wire.js +99 -0
- package/lib/contracts.d.ts +12 -0
- package/lib/contracts.js +12 -0
- package/lib/types/audit.d.ts +42 -0
- package/lib/types/audit.js +39 -0
- package/lib/types/client/ProjectImportMenu.d.ts +30 -0
- package/lib/types/client/ProjectImportMenu.js +70 -0
- package/lib/types/client/SheetPanel.d.ts +33 -0
- package/lib/types/client/SheetPanel.js +1766 -0
- package/lib/types/client/SheetToggle.d.ts +18 -0
- package/lib/types/client/SheetToggle.js +26 -0
- package/lib/types/client/index.d.ts +15 -0
- package/lib/types/client/index.js +110 -0
- package/lib/types/client/persistence/changes.d.ts +15 -0
- package/lib/types/client/persistence/changes.js +51 -0
- package/lib/types/client/persistence/ids.d.ts +34 -0
- package/lib/types/client/persistence/ids.js +48 -0
- package/lib/types/client/persistence/merge.d.ts +35 -0
- package/lib/types/client/persistence/merge.js +362 -0
- package/lib/types/client/store.d.ts +61 -0
- package/lib/types/client/store.js +152 -0
- package/lib/types/client/surface-context.d.ts +27 -0
- package/lib/types/client/surface-context.js +104 -0
- package/lib/types/client/surface-control.d.ts +2 -0
- package/lib/types/client/surface-control.js +12 -0
- package/lib/types/client/transport/workbookApi.d.ts +159 -0
- package/lib/types/client/transport/workbookApi.js +246 -0
- package/lib/types/client/univer/StandaloneWorkbookPage.d.ts +5 -0
- package/lib/types/client/univer/StandaloneWorkbookPage.js +7 -0
- package/lib/types/client/univer/WorkbookCanvas.d.ts +40 -0
- package/lib/types/client/univer/WorkbookCanvas.js +87 -0
- package/lib/types/client/univer/WorkbookView.d.ts +3 -0
- package/lib/types/client/univer/WorkbookView.js +2 -0
- package/lib/types/client/univer/loader.d.ts +18 -0
- package/lib/types/client/univer/loader.js +81 -0
- package/lib/types/client/univer/standalone-entry.d.ts +1 -0
- package/lib/types/client/univer/standalone-entry.js +19 -0
- package/lib/types/client/versions/VersionChrome.d.ts +33 -0
- package/lib/types/client/versions/VersionChrome.js +21 -0
- package/lib/types/client/versions/inspect.d.ts +70 -0
- package/lib/types/client/versions/inspect.js +88 -0
- package/lib/types/client/versions/preview-decoration.d.ts +11 -0
- package/lib/types/client/versions/preview-decoration.js +54 -0
- package/lib/types/client/versions/records.d.ts +19 -0
- package/lib/types/client/versions/records.js +70 -0
- package/lib/types/client/workspace-host.d.ts +61 -0
- package/lib/types/client/workspace-host.js +124 -0
- package/lib/types/collaboration-hub.d.ts +31 -0
- package/lib/types/collaboration-hub.js +69 -0
- package/lib/types/contract/ids.d.ts +24 -0
- package/lib/types/contract/ids.js +46 -0
- package/lib/types/contract/mutations.d.ts +25 -0
- package/lib/types/contract/mutations.js +782 -0
- package/lib/types/contract/operations.d.ts +54 -0
- package/lib/types/contract/operations.js +203 -0
- package/lib/types/contract/snapshots.d.ts +176 -0
- package/lib/types/contract/snapshots.js +351 -0
- package/lib/types/contract/univer-api-catalog.d.ts +29 -0
- package/lib/types/contract/univer-api-catalog.js +264 -0
- package/lib/types/errors.d.ts +8 -0
- package/lib/types/errors.js +12 -0
- package/lib/types/http/assets-routes.d.ts +3 -0
- package/lib/types/http/assets-routes.js +169 -0
- package/lib/types/http/collaboration.d.ts +10 -0
- package/lib/types/http/collaboration.js +154 -0
- package/lib/types/http/history.d.ts +15 -0
- package/lib/types/http/history.js +134 -0
- package/lib/types/http/project-files.d.ts +79 -0
- package/lib/types/http/project-files.js +206 -0
- package/lib/types/http/project-scope.d.ts +50 -0
- package/lib/types/http/project-scope.js +52 -0
- package/lib/types/http/routes.d.ts +98 -0
- package/lib/types/http/routes.js +323 -0
- package/lib/types/http/standalone.d.ts +9 -0
- package/lib/types/http/standalone.js +31 -0
- package/lib/types/http/trunk.d.ts +10 -0
- package/lib/types/http/trunk.js +322 -0
- package/lib/types/http/worktree.d.ts +9 -0
- package/lib/types/http/worktree.js +145 -0
- package/lib/types/index.d.ts +18 -0
- package/lib/types/index.js +156 -0
- package/lib/types/invariant.d.ts +15 -0
- package/lib/types/invariant.js +15 -0
- package/lib/types/request-params.d.ts +21 -0
- package/lib/types/request-params.js +76 -0
- package/lib/types/store/paths.d.ts +68 -0
- package/lib/types/store/paths.js +148 -0
- package/lib/types/store/project.d.ts +88 -0
- package/lib/types/store/project.js +120 -0
- package/lib/types/store/read.d.ts +110 -0
- package/lib/types/store/read.js +404 -0
- package/lib/types/store/retention.d.ts +27 -0
- package/lib/types/store/retention.js +111 -0
- package/lib/types/store/write.d.ts +22 -0
- package/lib/types/store/write.js +210 -0
- package/lib/types/tools/arguments.d.ts +40 -0
- package/lib/types/tools/arguments.js +130 -0
- package/lib/types/tools/cells.d.ts +50 -0
- package/lib/types/tools/cells.js +298 -0
- package/lib/types/tools/index.d.ts +2 -0
- package/lib/types/tools/index.js +250 -0
- package/lib/types/tools/render.d.ts +47 -0
- package/lib/types/tools/render.js +290 -0
- package/lib/types/tools/univer-api.d.ts +18 -0
- package/lib/types/tools/univer-api.js +198 -0
- package/lib/types/tools/workbook-catalog.d.ts +3 -0
- package/lib/types/tools/workbook-catalog.js +83 -0
- package/lib/types/tools/workbook-edit.d.ts +192 -0
- package/lib/types/tools/workbook-edit.js +912 -0
- package/lib/types/tools/workbook-find.d.ts +11 -0
- package/lib/types/tools/workbook-find.js +89 -0
- package/lib/types/tools/workbook-history.d.ts +2 -0
- package/lib/types/tools/workbook-history.js +59 -0
- package/lib/types/tools/workbook-read.d.ts +21 -0
- package/lib/types/tools/workbook-read.js +204 -0
- package/lib/types/types.d.ts +377 -0
- package/lib/types/types.js +34 -0
- package/lib/types/univer/apply-operation.d.ts +14 -0
- package/lib/types/univer/apply-operation.js +398 -0
- package/lib/types/univer/chunk.d.ts +68 -0
- package/lib/types/univer/chunk.js +16 -0
- package/lib/types/univer/decoration.d.ts +34 -0
- package/lib/types/univer/decoration.js +88 -0
- package/lib/types/univer/diagnostics.d.ts +31 -0
- package/lib/types/univer/diagnostics.js +141 -0
- package/lib/types/univer/engine.d.ts +33 -0
- package/lib/types/univer/engine.js +338 -0
- package/lib/types/univer/entry.d.ts +8 -0
- package/lib/types/univer/entry.js +11 -0
- package/lib/types/univer/facade.d.ts +107 -0
- package/lib/types/univer/facade.js +1 -0
- package/lib/types/univer/fonts.d.ts +202 -0
- package/lib/types/univer/fonts.js +140 -0
- package/lib/types/univer/plugins/collaboration.d.ts +23 -0
- package/lib/types/univer/plugins/collaboration.js +47 -0
- package/lib/types/univer/plugins/export.d.ts +39 -0
- package/lib/types/univer/plugins/export.js +246 -0
- package/lib/types/univer/plugins/history.d.ts +24 -0
- package/lib/types/univer/plugins/history.js +50 -0
- package/lib/types/univer/plugins/version.d.ts +13 -0
- package/lib/types/univer/plugins/version.js +13 -0
- package/lib/types/version/diff.d.ts +36 -0
- package/lib/types/version/diff.js +156 -0
- package/lib/types/version/grouping.d.ts +7 -0
- package/lib/types/version/grouping.js +94 -0
- package/lib/types/version/records.d.ts +17 -0
- package/lib/types/version/records.js +102 -0
- package/lib/types/version/session.d.ts +36 -0
- package/lib/types/version/session.js +89 -0
- package/lib/types/version/summary.d.ts +24 -0
- package/lib/types/version/summary.js +111 -0
- package/lib/types/workbook-manager.d.ts +191 -0
- package/lib/types/workbook-manager.js +935 -0
- package/lib/types/xlsx-export-worker.d.ts +5 -0
- package/lib/types/xlsx-export-worker.js +24 -0
- package/lib/types/xlsx-export.d.ts +21 -0
- package/lib/types/xlsx-export.js +371 -0
- package/lib/types/xlsx-import-worker.d.ts +1 -0
- package/lib/types/xlsx-import-worker.js +19 -0
- package/lib/univer-client.js +690 -0
- package/lib/workbook-page.js +23826 -0
- package/lib/xlsx-export-worker.js +104 -0
- package/lib/xlsx-import-worker.js +46 -0
- package/package.json +106 -3
- package/src/audit.ts +58 -0
- package/src/client/ProjectImportMenu.tsx +100 -0
- package/src/client/SheetPanel.module.css +1578 -0
- package/src/client/SheetPanel.tsx +1934 -0
- package/src/client/SheetToggle.module.css +73 -0
- package/src/client/SheetToggle.tsx +65 -0
- package/src/client/contract.d.ts +19 -0
- package/src/client/index.ts +131 -0
- package/src/client/persistence/changes.ts +58 -0
- package/src/client/persistence/ids.ts +60 -0
- package/src/client/persistence/merge.ts +392 -0
- package/src/client/store.ts +188 -0
- package/src/client/surface-context.ts +123 -0
- package/src/client/surface-control.ts +13 -0
- package/src/client/transport/workbookApi.ts +355 -0
- package/src/client/univer/SheetView.module.css +110 -0
- package/src/client/univer/StandaloneWorkbookPage.module.css +8 -0
- package/src/client/univer/StandaloneWorkbookPage.tsx +15 -0
- package/src/client/univer/WorkbookCanvas.tsx +128 -0
- package/src/client/univer/WorkbookView.module.css +30 -0
- package/src/client/univer/WorkbookView.tsx +3 -0
- package/src/client/univer/loader.ts +90 -0
- package/src/client/univer/react-dom-client.d.ts +10 -0
- package/src/client/univer/standalone-entry.tsx +19 -0
- package/src/client/univer/standalone.css +12 -0
- package/src/client/univer/univer-locales.d.ts +89 -0
- package/src/client/univer/univer-modules.d.ts +26 -0
- package/src/client/versions/VersionChrome.tsx +114 -0
- package/src/client/versions/inspect.ts +138 -0
- package/src/client/versions/preview-decoration.ts +54 -0
- package/src/client/versions/records.ts +78 -0
- package/src/client/workspace-host.ts +147 -0
- package/src/collaboration-hub.ts +83 -0
- package/src/contract/ids.ts +50 -0
- package/src/contract/mutations.ts +791 -0
- package/src/contract/operations.ts +221 -0
- package/src/contract/snapshots.ts +383 -0
- package/src/contract/univer-api-catalog.ts +289 -0
- package/src/css-modules.d.ts +6 -0
- package/src/errors.ts +25 -0
- package/src/http/assets-routes.ts +177 -0
- package/src/http/collaboration.ts +144 -0
- package/src/http/history.ts +151 -0
- package/src/http/project-files.ts +227 -0
- package/src/http/project-scope.ts +77 -0
- package/src/http/routes.ts +364 -0
- package/src/http/standalone.ts +32 -0
- package/src/http/trunk.ts +322 -0
- package/src/http/worktree.ts +119 -0
- package/src/index.ts +165 -0
- package/src/invariant.ts +17 -0
- package/src/request-params.ts +92 -0
- package/src/store/paths.ts +165 -0
- package/src/store/project.ts +137 -0
- package/src/store/read.ts +454 -0
- package/src/store/retention.ts +106 -0
- package/src/store/write.ts +230 -0
- package/src/tools/arguments.ts +128 -0
- package/src/tools/cells.ts +298 -0
- package/src/tools/index.ts +274 -0
- package/src/tools/render.ts +301 -0
- package/src/tools/univer-api.ts +243 -0
- package/src/tools/workbook-catalog.ts +94 -0
- package/src/tools/workbook-edit.ts +987 -0
- package/src/tools/workbook-find.ts +80 -0
- package/src/tools/workbook-history.ts +63 -0
- package/src/tools/workbook-read.ts +210 -0
- package/src/types.ts +432 -0
- package/src/univer/apply-operation.ts +369 -0
- package/src/univer/chunk.ts +77 -0
- package/src/univer/decoration.ts +111 -0
- package/src/univer/diagnostics.ts +136 -0
- package/src/univer/engine.ts +370 -0
- package/src/univer/entry.ts +14 -0
- package/src/univer/facade.ts +91 -0
- package/src/univer/fonts.ts +148 -0
- package/src/univer/overrides.css +33 -0
- package/src/univer/plugins/collaboration.ts +47 -0
- package/src/univer/plugins/export.ts +236 -0
- package/src/univer/plugins/history.ts +49 -0
- package/src/univer/plugins/version.ts +13 -0
- package/src/version/diff.ts +169 -0
- package/src/version/grouping.ts +96 -0
- package/src/version/records.ts +113 -0
- package/src/version/session.ts +90 -0
- package/src/version/summary.ts +117 -0
- package/src/workbook-manager.ts +1111 -0
- package/src/xlsx-export-worker.ts +34 -0
- package/src/xlsx-export.ts +373 -0
- package/src/xlsx-import-worker.ts +30 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-header toggle for dsh-data-table: the top-right entry
|
|
3
|
+
* button flipping the right sheet column (AppFrame `details`).
|
|
4
|
+
* @module dsh-data-table/client/SheetToggle
|
|
5
|
+
*/
|
|
6
|
+
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
7
|
+
type ToggleProps = PropsRuntime<'conversation.session.header.utilities'> & {
|
|
8
|
+
/** Bound toggle action (registration inject). */
|
|
9
|
+
toggleSheet: () => void;
|
|
10
|
+
/** Reopens the layout column after a session switch when the feature was open. */
|
|
11
|
+
ensureSheetOpen: () => void;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Header utility button: opens/closes the sheet column (top-right corner).
|
|
15
|
+
* @param props - standard session header utility share.
|
|
16
|
+
*/
|
|
17
|
+
export declare function SheetToggle({ toggleSheet, ensureSheetOpen }: ToggleProps): import("react").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Session-header toggle for dsh-data-table: the top-right entry
|
|
4
|
+
* button flipping the right sheet column (AppFrame `details`).
|
|
5
|
+
* @module dsh-data-table/client/SheetToggle
|
|
6
|
+
*/
|
|
7
|
+
import { useEffect } from 'react';
|
|
8
|
+
import { useSheetOpen } from "./store.js";
|
|
9
|
+
import styles from './SheetToggle.module.css';
|
|
10
|
+
/** Small spreadsheet glyph: a header row plus a quiet 2×3 cell grid. */
|
|
11
|
+
function SheetIcon() {
|
|
12
|
+
return (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", focusable: "false", children: [_jsx("rect", { x: "1.75", y: "2.25", width: "12.5", height: "11.5", rx: "2", stroke: "currentColor", strokeWidth: "1.25" }), _jsx("path", { d: "M2.25 5.75H13.75", stroke: "currentColor", strokeWidth: "1.25" }), _jsx("path", { d: "M5.75 5.75V13.25M10.25 5.75V13.25", stroke: "currentColor", strokeWidth: "1.1" }), _jsx("path", { d: "M3.5 3.65H12", stroke: "currentColor", strokeWidth: "1.1", strokeLinecap: "round", opacity: "0.55" })] }));
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Header utility button: opens/closes the sheet column (top-right corner).
|
|
16
|
+
* @param props - standard session header utility share.
|
|
17
|
+
*/
|
|
18
|
+
export function SheetToggle({ toggleSheet, ensureSheetOpen }) {
|
|
19
|
+
const open = useSheetOpen();
|
|
20
|
+
const label = open ? '关闭 Table' : '打开 Table';
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (open)
|
|
23
|
+
ensureSheetOpen();
|
|
24
|
+
}, [open, ensureSheetOpen]);
|
|
25
|
+
return (_jsxs("button", { type: "button", className: styles.toggle, "data-open": open, "aria-label": label, "aria-pressed": open, title: label, onClick: toggleSheet, children: [_jsx("span", { className: styles.icon, "aria-hidden": "true", children: _jsx(SheetIcon, {}) }), _jsx("span", { className: styles.label, children: open ? '关闭' : 'Table' })] }));
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser half of dsh-data-table.
|
|
3
|
+
*
|
|
4
|
+
* The workbook is a first-class extension of DSH's official right Sidebar:
|
|
5
|
+
* the tab type is registered in `sidebarRightTabs`, while the body is mounted
|
|
6
|
+
* through the keyed `sidebar.right.pane.tab` seat. Keeping those two steps
|
|
7
|
+
* separate means the plugin never reaches into the Sidebar's layout store and
|
|
8
|
+
* can be published to the upstream datastudio/dsh extension surface.
|
|
9
|
+
* @module dsh-data-table/client
|
|
10
|
+
*/
|
|
11
|
+
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
12
|
+
/** Required services for the official two-stage Sidebar extension path. */
|
|
13
|
+
export declare const inject: readonly ["slots", "sidebarRightTabs", "sidebarRight", "surfaceBridge"];
|
|
14
|
+
/** Register the type and its keyed body; both registrations are disposable. */
|
|
15
|
+
export declare function apply(ctx: ClientContext): void;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser half of dsh-data-table.
|
|
3
|
+
*
|
|
4
|
+
* The workbook is a first-class extension of DSH's official right Sidebar:
|
|
5
|
+
* the tab type is registered in `sidebarRightTabs`, while the body is mounted
|
|
6
|
+
* through the keyed `sidebar.right.pane.tab` seat. Keeping those two steps
|
|
7
|
+
* separate means the plugin never reaches into the Sidebar's layout store and
|
|
8
|
+
* can be published to the upstream datastudio/dsh extension surface.
|
|
9
|
+
* @module dsh-data-table/client
|
|
10
|
+
*/
|
|
11
|
+
import { startSurfaceOperationLoop } from '@tita-agent/dsh-surface-bridge/client/loop';
|
|
12
|
+
import { Table2 } from '@tita-agent/ui/icons';
|
|
13
|
+
import { createElement, useEffect, useLayoutEffect, useRef } from 'react';
|
|
14
|
+
import { createRoot } from 'react-dom/client';
|
|
15
|
+
import { WorkbookWorkspace } from "./SheetPanel.js";
|
|
16
|
+
import { setSheetVisible, useSheetVisible } from "./store.js";
|
|
17
|
+
import { adoptWorkspaceHost, parkWorkspaceHost } from "./workspace-host.js";
|
|
18
|
+
import { setDshSessionId } from "./transport/workbookApi.js";
|
|
19
|
+
import { DATA_SHEET_SURFACE_ID } from "./surface-context.js";
|
|
20
|
+
import { focusDataSheetItem } from "./surface-control.js";
|
|
21
|
+
import styles from './SheetPanel.module.css';
|
|
22
|
+
/** This package's identity in the official right-Sidebar registry. */
|
|
23
|
+
const DATA_SHEET_ID = 'dsh-data-table';
|
|
24
|
+
const DATA_SHEET_KIND = 'data-sheet';
|
|
25
|
+
/** Stage one: describe the page type and its entry in the official guide. */
|
|
26
|
+
function dataSheetDefinition() {
|
|
27
|
+
return {
|
|
28
|
+
id: DATA_SHEET_ID,
|
|
29
|
+
kind: DATA_SHEET_KIND,
|
|
30
|
+
priority: 'extension',
|
|
31
|
+
title: () => 'Table',
|
|
32
|
+
guide: [{ id: `${DATA_SHEET_ID}-guide`, order: 45, title: () => 'Table', icon: Table2 }],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The resident workspace: one React tree for the whole page life.
|
|
37
|
+
*
|
|
38
|
+
* `open` is true because the workspace stays live while parked off-screen;
|
|
39
|
+
* `visible` carries the pane's real visibility to the few behaviours that must
|
|
40
|
+
* be tied to it (the window-level save shortcut).
|
|
41
|
+
*/
|
|
42
|
+
function ResidentWorkspace({ bridge }) {
|
|
43
|
+
const visible = useSheetVisible();
|
|
44
|
+
return createElement(WorkbookWorkspace, { open: true, visible, bridge });
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create the workspace root; called once per workspace lifetime.
|
|
48
|
+
* @returns the disposer that releases the React tree again.
|
|
49
|
+
*/
|
|
50
|
+
function mountResidentWorkspace(container, bridge) {
|
|
51
|
+
const root = createRoot(container);
|
|
52
|
+
root.render(createElement(ResidentWorkspace, { bridge }));
|
|
53
|
+
return () => { root.unmount(); };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Stage two: render the workbook for the active right-Sidebar tab.
|
|
57
|
+
*
|
|
58
|
+
* The pane body is only a frame: the dock unmounts it whenever another tab
|
|
59
|
+
* becomes active, so the workspace itself is adopted from a resident container
|
|
60
|
+
* instead of being rendered here. That is what stops a tab switch from
|
|
61
|
+
* disposing the Univer engine and reloading the workbook.
|
|
62
|
+
*/
|
|
63
|
+
function DataSheetTab({ sessionId, useTabInfo, bridge }) {
|
|
64
|
+
const { tab } = useTabInfo();
|
|
65
|
+
const frameRef = useRef(null);
|
|
66
|
+
// Bind the transport to this Session's project for as long as the tab exists:
|
|
67
|
+
// every workbook read and write resolves to `<project>/storages/data-table`.
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
setDshSessionId(sessionId);
|
|
70
|
+
return () => { setDshSessionId(undefined); };
|
|
71
|
+
}, [sessionId]);
|
|
72
|
+
// Layout effect: its cleanup runs while the pane DOM is still connected, so
|
|
73
|
+
// the workspace can be moved out before the browser reports a 0x0 resize.
|
|
74
|
+
useLayoutEffect(() => {
|
|
75
|
+
const frame = frameRef.current;
|
|
76
|
+
if (frame === null)
|
|
77
|
+
return;
|
|
78
|
+
adoptWorkspaceHost(frame, container => mountResidentWorkspace(container, bridge));
|
|
79
|
+
return () => { parkWorkspaceHost(); };
|
|
80
|
+
}, [bridge]);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
setSheetVisible(tab.visible);
|
|
83
|
+
bridge.setVisible(DATA_SHEET_SURFACE_ID, tab.visible);
|
|
84
|
+
if (!tab.visible)
|
|
85
|
+
return;
|
|
86
|
+
const stop = startSurfaceOperationLoop(sessionId, DATA_SHEET_SURFACE_ID, bridge);
|
|
87
|
+
return () => {
|
|
88
|
+
stop();
|
|
89
|
+
bridge.setVisible(DATA_SHEET_SURFACE_ID, false);
|
|
90
|
+
setSheetVisible(false);
|
|
91
|
+
};
|
|
92
|
+
}, [bridge, sessionId, tab.visible]);
|
|
93
|
+
return createElement('div', { ref: frameRef, className: styles.sidebarTab, 'data-data-table-frame': '' });
|
|
94
|
+
}
|
|
95
|
+
/** Required services for the official two-stage Sidebar extension path. */
|
|
96
|
+
export const inject = ['slots', 'sidebarRightTabs', 'sidebarRight', 'surfaceBridge'];
|
|
97
|
+
/** Register the type and its keyed body; both registrations are disposable. */
|
|
98
|
+
export function apply(ctx) {
|
|
99
|
+
const bridge = ctx.surfaceBridge;
|
|
100
|
+
ctx.effect(() => ctx.sidebarRightTabs.register(dataSheetDefinition()), 'data-sheet: right Sidebar type');
|
|
101
|
+
ctx.effect(() => bridge.registerContext({
|
|
102
|
+
id: DATA_SHEET_SURFACE_ID,
|
|
103
|
+
label: 'Table',
|
|
104
|
+
icon: Table2,
|
|
105
|
+
order: 20,
|
|
106
|
+
reveal: () => { ctx.sidebarRight.openTab(DATA_SHEET_KIND); },
|
|
107
|
+
focusItem: focusDataSheetItem,
|
|
108
|
+
}), 'data-sheet: composer context source');
|
|
109
|
+
ctx.effect(() => ctx.slots.inject('sidebar.right.pane.tab', () => ctx.slots.register({ name: 'sidebar.right.pane.tab', key: DATA_SHEET_ID, inject: () => ({ bridge }) }, DataSheetTab)), 'data-sheet: right Sidebar body');
|
|
110
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deciding what may be applied from elsewhere (docs/issue/0022 P5).
|
|
3
|
+
*
|
|
4
|
+
* A remote operation arriving while the user has unsaved local edits is the one
|
|
5
|
+
* genuinely concurrent case in this plugin: either the operation touches
|
|
6
|
+
* different cells and can be applied on top, or it overlaps and the pane has to
|
|
7
|
+
* fall back to a snapshot reload. These are the predicates that decide.
|
|
8
|
+
*/
|
|
9
|
+
import type { WorkbookLocalChange, WorkbookOperation } from '../../types.ts';
|
|
10
|
+
/** Return cell coordinates for the subset that can be safely rebased live. */
|
|
11
|
+
export declare function operationCellKeys(operation: WorkbookOperation, target?: Set<string>): Set<string> | null;
|
|
12
|
+
export declare function canApplyRemoteWhileEditing(operation: WorkbookOperation, snapshotFallback: boolean): boolean;
|
|
13
|
+
export declare function coalesceLocalChanges(changes: WorkbookLocalChange[]): WorkbookLocalChange[];
|
|
14
|
+
/** Keep the Univer snapshot name aligned with the Datasheet workbook name. */
|
|
15
|
+
export declare function withWorkbookName(snapshot: object, name: string): object;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Return cell coordinates for the subset that can be safely rebased live. */
|
|
2
|
+
export function operationCellKeys(operation, target = new Set()) {
|
|
3
|
+
if (operation.type === 'update_cells') {
|
|
4
|
+
const sheetId = operation.payload.sheetId ?? operation.payload.sheetName;
|
|
5
|
+
if (sheetId === undefined || operation.payload.cells === undefined || operation.payload.cells.length === 0)
|
|
6
|
+
return null;
|
|
7
|
+
for (const cell of operation.payload.cells)
|
|
8
|
+
target.add(`${sheetId}:${cell.row}:${cell.column}`);
|
|
9
|
+
return target;
|
|
10
|
+
}
|
|
11
|
+
if (operation.type === 'batch') {
|
|
12
|
+
const children = operation.payload.operations ?? [];
|
|
13
|
+
if (children.length === 0)
|
|
14
|
+
return null;
|
|
15
|
+
for (const child of children) {
|
|
16
|
+
const childKeys = operationCellKeys({ ...operation, type: child.type, payload: child.payload }, target);
|
|
17
|
+
if (childKeys === null)
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return target;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
export function canApplyRemoteWhileEditing(operation, snapshotFallback) {
|
|
25
|
+
// The Host already serializes cell operations and applies the later
|
|
26
|
+
// revision to the latest snapshot. Keep all cell-only operations visible in
|
|
27
|
+
// the canvas; the pending local changes are replayed immediately after the
|
|
28
|
+
// remote projection and are then submitted as the later revision — which is
|
|
29
|
+
// why this needs no view of them. It used to take them and `void` them.
|
|
30
|
+
if (snapshotFallback)
|
|
31
|
+
return false;
|
|
32
|
+
return operationCellKeys(operation) !== null;
|
|
33
|
+
}
|
|
34
|
+
export function coalesceLocalChanges(changes) {
|
|
35
|
+
const sheets = new Map();
|
|
36
|
+
for (const change of changes) {
|
|
37
|
+
const cells = sheets.get(change.payload.sheetId) ?? new Map();
|
|
38
|
+
for (const cell of change.payload.cells)
|
|
39
|
+
cells.set(`${cell.row}:${cell.column}`, cell);
|
|
40
|
+
sheets.set(change.payload.sheetId, cells);
|
|
41
|
+
}
|
|
42
|
+
return [...sheets.entries()].map(([sheetId, cells]) => ({
|
|
43
|
+
type: 'update_cells',
|
|
44
|
+
payload: { sheetId, cells: [...cells.values()] },
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
/** Keep the Univer snapshot name aligned with the Datasheet workbook name. */
|
|
48
|
+
export function withWorkbookName(snapshot, name) {
|
|
49
|
+
const root = snapshot;
|
|
50
|
+
return { ...root, name: name.trim() || root.name || 'workbook' };
|
|
51
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ids the browser mints for its own writes (docs/issue/0022 P5).
|
|
3
|
+
*
|
|
4
|
+
* An opId makes a retried save idempotent and a versionId keeps one editing
|
|
5
|
+
* session together across requests; both are the client's to name because the
|
|
6
|
+
* Host cannot tell a retry from a new edit.
|
|
7
|
+
*/
|
|
8
|
+
export declare function nextUserOpId(workbookId: string): string;
|
|
9
|
+
export declare function nextUserVersionId(workbookId: string): string;
|
|
10
|
+
export interface OwnOpLog {
|
|
11
|
+
/** Mint the op id for a write this browser is about to make, and remember it. */
|
|
12
|
+
next: (workbookId: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Claim an op id that came back. True when this browser minted it — i.e. the
|
|
15
|
+
* operation is this client's own write being echoed, not a peer's edit.
|
|
16
|
+
*/
|
|
17
|
+
take: (opId: string) => boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The op ids this browser has sent and not yet seen come back (GUI feedback
|
|
21
|
+
* 2026-09-20).
|
|
22
|
+
*
|
|
23
|
+
* The collaboration stream echoes a write to **every** client on the workbook,
|
|
24
|
+
* the one that made it included, and the echo can arrive before the POST's own
|
|
25
|
+
* response — the Host publishes as soon as it has written. Without this log the
|
|
26
|
+
* Table panel read its own `snapshot_replace` as a foreign one and answered it
|
|
27
|
+
* the only way that operation can be answered, by re-downloading the snapshot
|
|
28
|
+
* and remounting the canvas: 「保存版本」 flashed the grid on every save, even
|
|
29
|
+
* though the canvas was already showing exactly the revision just stored.
|
|
30
|
+
*
|
|
31
|
+
* Bounded, because a save whose answer never comes back — a dropped connection —
|
|
32
|
+
* must not grow this for the life of the page.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createOwnOpLog(limit?: number): OwnOpLog;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ids the browser mints for its own writes (docs/issue/0022 P5).
|
|
3
|
+
*
|
|
4
|
+
* An opId makes a retried save idempotent and a versionId keeps one editing
|
|
5
|
+
* session together across requests; both are the client's to name because the
|
|
6
|
+
* Host cannot tell a retry from a new edit.
|
|
7
|
+
*/
|
|
8
|
+
export function nextUserOpId(workbookId) {
|
|
9
|
+
const suffix = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
10
|
+
return `user:${workbookId}:${suffix}`;
|
|
11
|
+
}
|
|
12
|
+
export function nextUserVersionId(workbookId) {
|
|
13
|
+
const suffix = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
14
|
+
return `user-version:${workbookId}:${suffix}`;
|
|
15
|
+
}
|
|
16
|
+
/** How many unclaimed op ids one page remembers before the oldest is dropped. */
|
|
17
|
+
const OWN_OP_LIMIT = 64;
|
|
18
|
+
/**
|
|
19
|
+
* The op ids this browser has sent and not yet seen come back (GUI feedback
|
|
20
|
+
* 2026-09-20).
|
|
21
|
+
*
|
|
22
|
+
* The collaboration stream echoes a write to **every** client on the workbook,
|
|
23
|
+
* the one that made it included, and the echo can arrive before the POST's own
|
|
24
|
+
* response — the Host publishes as soon as it has written. Without this log the
|
|
25
|
+
* Table panel read its own `snapshot_replace` as a foreign one and answered it
|
|
26
|
+
* the only way that operation can be answered, by re-downloading the snapshot
|
|
27
|
+
* and remounting the canvas: 「保存版本」 flashed the grid on every save, even
|
|
28
|
+
* though the canvas was already showing exactly the revision just stored.
|
|
29
|
+
*
|
|
30
|
+
* Bounded, because a save whose answer never comes back — a dropped connection —
|
|
31
|
+
* must not grow this for the life of the page.
|
|
32
|
+
*/
|
|
33
|
+
export function createOwnOpLog(limit = OWN_OP_LIMIT) {
|
|
34
|
+
const ids = new Set();
|
|
35
|
+
return {
|
|
36
|
+
next: (workbookId) => {
|
|
37
|
+
const opId = nextUserOpId(workbookId);
|
|
38
|
+
ids.add(opId);
|
|
39
|
+
if (ids.size > limit) {
|
|
40
|
+
const oldest = ids.values().next().value;
|
|
41
|
+
if (oldest !== undefined)
|
|
42
|
+
ids.delete(oldest);
|
|
43
|
+
}
|
|
44
|
+
return opId;
|
|
45
|
+
},
|
|
46
|
+
take: (opId) => ids.delete(opId),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three-way merge for Univer workbook snapshots.
|
|
3
|
+
*
|
|
4
|
+
* The browser keeps the last server snapshot as the base. When a user save
|
|
5
|
+
* races an Agent/user write, this module compares base/local/remote at cell
|
|
6
|
+
* granularity, adopts one-sided changes automatically, and keeps local values
|
|
7
|
+
* for true conflicts while adding a visible conflict style.
|
|
8
|
+
*/
|
|
9
|
+
import type { WorkbookLocalChange, WorkbookOperation } from '../../types.ts';
|
|
10
|
+
export interface MergeConflict {
|
|
11
|
+
kind: 'cell' | 'structure' | 'sheet';
|
|
12
|
+
sheetId?: string;
|
|
13
|
+
sheetName?: string;
|
|
14
|
+
row?: number;
|
|
15
|
+
column?: number;
|
|
16
|
+
address?: string;
|
|
17
|
+
baseValue?: unknown;
|
|
18
|
+
localValue?: unknown;
|
|
19
|
+
remoteValue?: unknown;
|
|
20
|
+
description: string;
|
|
21
|
+
}
|
|
22
|
+
export interface WorkbookMergeResult {
|
|
23
|
+
snapshot: object;
|
|
24
|
+
conflicts: MergeConflict[];
|
|
25
|
+
autoMergedCells: number;
|
|
26
|
+
conflictStyleMap: Record<string, string | null>;
|
|
27
|
+
}
|
|
28
|
+
/** Merge local and remote snapshots against the last common base snapshot. */
|
|
29
|
+
export declare function mergeWorkbookSnapshots(baseSnapshot: object, localSnapshot: object, remoteSnapshot: object): WorkbookMergeResult;
|
|
30
|
+
/** Remove temporary conflict styles before a merged snapshot is persisted. */
|
|
31
|
+
export declare function stripConflictMarkers(snapshot: object, conflictStyleMap: Record<string, string | null>): object;
|
|
32
|
+
/** Apply ordinary cell edits to the merge base without cloning the workbook. */
|
|
33
|
+
export declare function applyIncrementalChangesToSnapshot(snapshot: object, changes: WorkbookLocalChange[]): void;
|
|
34
|
+
/** Patch a merge base from a replayable operation log; false means fallback. */
|
|
35
|
+
export declare function applyIncrementalOperationsToSnapshot(snapshot: object, operations: WorkbookOperation[]): boolean;
|