@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.
Files changed (267) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -2
  3. package/cordis.patch.yml +7 -0
  4. package/lib/client.js +16766 -0
  5. package/lib/contract-envelope.d.ts +91 -0
  6. package/lib/contract-envelope.js +106 -0
  7. package/lib/contract-layout.d.ts +130 -0
  8. package/lib/contract-layout.js +138 -0
  9. package/lib/contract-refs.d.ts +39 -0
  10. package/lib/contract-refs.js +9 -0
  11. package/lib/contract-version.d.ts +311 -0
  12. package/lib/contract-version.js +270 -0
  13. package/lib/contract-wire.d.ts +147 -0
  14. package/lib/contract-wire.js +99 -0
  15. package/lib/contracts.d.ts +12 -0
  16. package/lib/contracts.js +12 -0
  17. package/lib/types/audit.d.ts +42 -0
  18. package/lib/types/audit.js +39 -0
  19. package/lib/types/client/ProjectImportMenu.d.ts +30 -0
  20. package/lib/types/client/ProjectImportMenu.js +70 -0
  21. package/lib/types/client/SheetPanel.d.ts +33 -0
  22. package/lib/types/client/SheetPanel.js +1766 -0
  23. package/lib/types/client/SheetToggle.d.ts +18 -0
  24. package/lib/types/client/SheetToggle.js +26 -0
  25. package/lib/types/client/index.d.ts +15 -0
  26. package/lib/types/client/index.js +110 -0
  27. package/lib/types/client/persistence/changes.d.ts +15 -0
  28. package/lib/types/client/persistence/changes.js +51 -0
  29. package/lib/types/client/persistence/ids.d.ts +34 -0
  30. package/lib/types/client/persistence/ids.js +48 -0
  31. package/lib/types/client/persistence/merge.d.ts +35 -0
  32. package/lib/types/client/persistence/merge.js +362 -0
  33. package/lib/types/client/store.d.ts +61 -0
  34. package/lib/types/client/store.js +152 -0
  35. package/lib/types/client/surface-context.d.ts +27 -0
  36. package/lib/types/client/surface-context.js +104 -0
  37. package/lib/types/client/surface-control.d.ts +2 -0
  38. package/lib/types/client/surface-control.js +12 -0
  39. package/lib/types/client/transport/workbookApi.d.ts +159 -0
  40. package/lib/types/client/transport/workbookApi.js +246 -0
  41. package/lib/types/client/univer/StandaloneWorkbookPage.d.ts +5 -0
  42. package/lib/types/client/univer/StandaloneWorkbookPage.js +7 -0
  43. package/lib/types/client/univer/WorkbookCanvas.d.ts +40 -0
  44. package/lib/types/client/univer/WorkbookCanvas.js +87 -0
  45. package/lib/types/client/univer/WorkbookView.d.ts +3 -0
  46. package/lib/types/client/univer/WorkbookView.js +2 -0
  47. package/lib/types/client/univer/loader.d.ts +18 -0
  48. package/lib/types/client/univer/loader.js +81 -0
  49. package/lib/types/client/univer/standalone-entry.d.ts +1 -0
  50. package/lib/types/client/univer/standalone-entry.js +19 -0
  51. package/lib/types/client/versions/VersionChrome.d.ts +33 -0
  52. package/lib/types/client/versions/VersionChrome.js +21 -0
  53. package/lib/types/client/versions/inspect.d.ts +70 -0
  54. package/lib/types/client/versions/inspect.js +88 -0
  55. package/lib/types/client/versions/preview-decoration.d.ts +11 -0
  56. package/lib/types/client/versions/preview-decoration.js +54 -0
  57. package/lib/types/client/versions/records.d.ts +19 -0
  58. package/lib/types/client/versions/records.js +70 -0
  59. package/lib/types/client/workspace-host.d.ts +61 -0
  60. package/lib/types/client/workspace-host.js +124 -0
  61. package/lib/types/collaboration-hub.d.ts +31 -0
  62. package/lib/types/collaboration-hub.js +69 -0
  63. package/lib/types/contract/ids.d.ts +24 -0
  64. package/lib/types/contract/ids.js +46 -0
  65. package/lib/types/contract/mutations.d.ts +25 -0
  66. package/lib/types/contract/mutations.js +782 -0
  67. package/lib/types/contract/operations.d.ts +54 -0
  68. package/lib/types/contract/operations.js +203 -0
  69. package/lib/types/contract/snapshots.d.ts +176 -0
  70. package/lib/types/contract/snapshots.js +351 -0
  71. package/lib/types/contract/univer-api-catalog.d.ts +29 -0
  72. package/lib/types/contract/univer-api-catalog.js +264 -0
  73. package/lib/types/errors.d.ts +8 -0
  74. package/lib/types/errors.js +12 -0
  75. package/lib/types/http/assets-routes.d.ts +3 -0
  76. package/lib/types/http/assets-routes.js +169 -0
  77. package/lib/types/http/collaboration.d.ts +10 -0
  78. package/lib/types/http/collaboration.js +154 -0
  79. package/lib/types/http/history.d.ts +15 -0
  80. package/lib/types/http/history.js +134 -0
  81. package/lib/types/http/project-files.d.ts +79 -0
  82. package/lib/types/http/project-files.js +206 -0
  83. package/lib/types/http/project-scope.d.ts +50 -0
  84. package/lib/types/http/project-scope.js +52 -0
  85. package/lib/types/http/routes.d.ts +98 -0
  86. package/lib/types/http/routes.js +323 -0
  87. package/lib/types/http/standalone.d.ts +9 -0
  88. package/lib/types/http/standalone.js +31 -0
  89. package/lib/types/http/trunk.d.ts +10 -0
  90. package/lib/types/http/trunk.js +322 -0
  91. package/lib/types/http/worktree.d.ts +9 -0
  92. package/lib/types/http/worktree.js +145 -0
  93. package/lib/types/index.d.ts +18 -0
  94. package/lib/types/index.js +156 -0
  95. package/lib/types/invariant.d.ts +15 -0
  96. package/lib/types/invariant.js +15 -0
  97. package/lib/types/request-params.d.ts +21 -0
  98. package/lib/types/request-params.js +76 -0
  99. package/lib/types/store/paths.d.ts +68 -0
  100. package/lib/types/store/paths.js +148 -0
  101. package/lib/types/store/project.d.ts +88 -0
  102. package/lib/types/store/project.js +120 -0
  103. package/lib/types/store/read.d.ts +110 -0
  104. package/lib/types/store/read.js +404 -0
  105. package/lib/types/store/retention.d.ts +27 -0
  106. package/lib/types/store/retention.js +111 -0
  107. package/lib/types/store/write.d.ts +22 -0
  108. package/lib/types/store/write.js +210 -0
  109. package/lib/types/tools/arguments.d.ts +40 -0
  110. package/lib/types/tools/arguments.js +130 -0
  111. package/lib/types/tools/cells.d.ts +50 -0
  112. package/lib/types/tools/cells.js +298 -0
  113. package/lib/types/tools/index.d.ts +2 -0
  114. package/lib/types/tools/index.js +250 -0
  115. package/lib/types/tools/render.d.ts +47 -0
  116. package/lib/types/tools/render.js +290 -0
  117. package/lib/types/tools/univer-api.d.ts +18 -0
  118. package/lib/types/tools/univer-api.js +198 -0
  119. package/lib/types/tools/workbook-catalog.d.ts +3 -0
  120. package/lib/types/tools/workbook-catalog.js +83 -0
  121. package/lib/types/tools/workbook-edit.d.ts +192 -0
  122. package/lib/types/tools/workbook-edit.js +912 -0
  123. package/lib/types/tools/workbook-find.d.ts +11 -0
  124. package/lib/types/tools/workbook-find.js +89 -0
  125. package/lib/types/tools/workbook-history.d.ts +2 -0
  126. package/lib/types/tools/workbook-history.js +59 -0
  127. package/lib/types/tools/workbook-read.d.ts +21 -0
  128. package/lib/types/tools/workbook-read.js +204 -0
  129. package/lib/types/types.d.ts +377 -0
  130. package/lib/types/types.js +34 -0
  131. package/lib/types/univer/apply-operation.d.ts +14 -0
  132. package/lib/types/univer/apply-operation.js +398 -0
  133. package/lib/types/univer/chunk.d.ts +68 -0
  134. package/lib/types/univer/chunk.js +16 -0
  135. package/lib/types/univer/decoration.d.ts +34 -0
  136. package/lib/types/univer/decoration.js +88 -0
  137. package/lib/types/univer/diagnostics.d.ts +31 -0
  138. package/lib/types/univer/diagnostics.js +141 -0
  139. package/lib/types/univer/engine.d.ts +33 -0
  140. package/lib/types/univer/engine.js +338 -0
  141. package/lib/types/univer/entry.d.ts +8 -0
  142. package/lib/types/univer/entry.js +11 -0
  143. package/lib/types/univer/facade.d.ts +107 -0
  144. package/lib/types/univer/facade.js +1 -0
  145. package/lib/types/univer/fonts.d.ts +202 -0
  146. package/lib/types/univer/fonts.js +140 -0
  147. package/lib/types/univer/plugins/collaboration.d.ts +23 -0
  148. package/lib/types/univer/plugins/collaboration.js +47 -0
  149. package/lib/types/univer/plugins/export.d.ts +39 -0
  150. package/lib/types/univer/plugins/export.js +246 -0
  151. package/lib/types/univer/plugins/history.d.ts +24 -0
  152. package/lib/types/univer/plugins/history.js +50 -0
  153. package/lib/types/univer/plugins/version.d.ts +13 -0
  154. package/lib/types/univer/plugins/version.js +13 -0
  155. package/lib/types/version/diff.d.ts +36 -0
  156. package/lib/types/version/diff.js +156 -0
  157. package/lib/types/version/grouping.d.ts +7 -0
  158. package/lib/types/version/grouping.js +94 -0
  159. package/lib/types/version/records.d.ts +17 -0
  160. package/lib/types/version/records.js +102 -0
  161. package/lib/types/version/session.d.ts +36 -0
  162. package/lib/types/version/session.js +89 -0
  163. package/lib/types/version/summary.d.ts +24 -0
  164. package/lib/types/version/summary.js +111 -0
  165. package/lib/types/workbook-manager.d.ts +191 -0
  166. package/lib/types/workbook-manager.js +935 -0
  167. package/lib/types/xlsx-export-worker.d.ts +5 -0
  168. package/lib/types/xlsx-export-worker.js +24 -0
  169. package/lib/types/xlsx-export.d.ts +21 -0
  170. package/lib/types/xlsx-export.js +371 -0
  171. package/lib/types/xlsx-import-worker.d.ts +1 -0
  172. package/lib/types/xlsx-import-worker.js +19 -0
  173. package/lib/univer-client.js +690 -0
  174. package/lib/workbook-page.js +23826 -0
  175. package/lib/xlsx-export-worker.js +104 -0
  176. package/lib/xlsx-import-worker.js +46 -0
  177. package/package.json +106 -3
  178. package/src/audit.ts +58 -0
  179. package/src/client/ProjectImportMenu.tsx +100 -0
  180. package/src/client/SheetPanel.module.css +1578 -0
  181. package/src/client/SheetPanel.tsx +1934 -0
  182. package/src/client/SheetToggle.module.css +73 -0
  183. package/src/client/SheetToggle.tsx +65 -0
  184. package/src/client/contract.d.ts +19 -0
  185. package/src/client/index.ts +131 -0
  186. package/src/client/persistence/changes.ts +58 -0
  187. package/src/client/persistence/ids.ts +60 -0
  188. package/src/client/persistence/merge.ts +392 -0
  189. package/src/client/store.ts +188 -0
  190. package/src/client/surface-context.ts +123 -0
  191. package/src/client/surface-control.ts +13 -0
  192. package/src/client/transport/workbookApi.ts +355 -0
  193. package/src/client/univer/SheetView.module.css +110 -0
  194. package/src/client/univer/StandaloneWorkbookPage.module.css +8 -0
  195. package/src/client/univer/StandaloneWorkbookPage.tsx +15 -0
  196. package/src/client/univer/WorkbookCanvas.tsx +128 -0
  197. package/src/client/univer/WorkbookView.module.css +30 -0
  198. package/src/client/univer/WorkbookView.tsx +3 -0
  199. package/src/client/univer/loader.ts +90 -0
  200. package/src/client/univer/react-dom-client.d.ts +10 -0
  201. package/src/client/univer/standalone-entry.tsx +19 -0
  202. package/src/client/univer/standalone.css +12 -0
  203. package/src/client/univer/univer-locales.d.ts +89 -0
  204. package/src/client/univer/univer-modules.d.ts +26 -0
  205. package/src/client/versions/VersionChrome.tsx +114 -0
  206. package/src/client/versions/inspect.ts +138 -0
  207. package/src/client/versions/preview-decoration.ts +54 -0
  208. package/src/client/versions/records.ts +78 -0
  209. package/src/client/workspace-host.ts +147 -0
  210. package/src/collaboration-hub.ts +83 -0
  211. package/src/contract/ids.ts +50 -0
  212. package/src/contract/mutations.ts +791 -0
  213. package/src/contract/operations.ts +221 -0
  214. package/src/contract/snapshots.ts +383 -0
  215. package/src/contract/univer-api-catalog.ts +289 -0
  216. package/src/css-modules.d.ts +6 -0
  217. package/src/errors.ts +25 -0
  218. package/src/http/assets-routes.ts +177 -0
  219. package/src/http/collaboration.ts +144 -0
  220. package/src/http/history.ts +151 -0
  221. package/src/http/project-files.ts +227 -0
  222. package/src/http/project-scope.ts +77 -0
  223. package/src/http/routes.ts +364 -0
  224. package/src/http/standalone.ts +32 -0
  225. package/src/http/trunk.ts +322 -0
  226. package/src/http/worktree.ts +119 -0
  227. package/src/index.ts +165 -0
  228. package/src/invariant.ts +17 -0
  229. package/src/request-params.ts +92 -0
  230. package/src/store/paths.ts +165 -0
  231. package/src/store/project.ts +137 -0
  232. package/src/store/read.ts +454 -0
  233. package/src/store/retention.ts +106 -0
  234. package/src/store/write.ts +230 -0
  235. package/src/tools/arguments.ts +128 -0
  236. package/src/tools/cells.ts +298 -0
  237. package/src/tools/index.ts +274 -0
  238. package/src/tools/render.ts +301 -0
  239. package/src/tools/univer-api.ts +243 -0
  240. package/src/tools/workbook-catalog.ts +94 -0
  241. package/src/tools/workbook-edit.ts +987 -0
  242. package/src/tools/workbook-find.ts +80 -0
  243. package/src/tools/workbook-history.ts +63 -0
  244. package/src/tools/workbook-read.ts +210 -0
  245. package/src/types.ts +432 -0
  246. package/src/univer/apply-operation.ts +369 -0
  247. package/src/univer/chunk.ts +77 -0
  248. package/src/univer/decoration.ts +111 -0
  249. package/src/univer/diagnostics.ts +136 -0
  250. package/src/univer/engine.ts +370 -0
  251. package/src/univer/entry.ts +14 -0
  252. package/src/univer/facade.ts +91 -0
  253. package/src/univer/fonts.ts +148 -0
  254. package/src/univer/overrides.css +33 -0
  255. package/src/univer/plugins/collaboration.ts +47 -0
  256. package/src/univer/plugins/export.ts +236 -0
  257. package/src/univer/plugins/history.ts +49 -0
  258. package/src/univer/plugins/version.ts +13 -0
  259. package/src/version/diff.ts +169 -0
  260. package/src/version/grouping.ts +96 -0
  261. package/src/version/records.ts +113 -0
  262. package/src/version/session.ts +90 -0
  263. package/src/version/summary.ts +117 -0
  264. package/src/workbook-manager.ts +1111 -0
  265. package/src/xlsx-export-worker.ts +34 -0
  266. package/src/xlsx-export.ts +373 -0
  267. package/src/xlsx-import-worker.ts +30 -0
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Live-canvas diagnostics and command mapping (docs/issue/0022 P4).
3
+ *
4
+ * Two jobs that both start from a Univer command: turning it into the small DSH
5
+ * change contract the Host persists, and leaving a probe behind so a live
6
+ * workbook can be inspected from the console (`__dshLastCellMutation`). They sit
7
+ * together because both are "what did Univer just do", and neither decides what
8
+ * to persist — `contract/operations.ts` decides that.
9
+ */
10
+ import { normalizeCellFormula } from '../contract/snapshots.ts'
11
+ import type { WorkbookCellUpdate, WorkbookLocalChange, WorkbookPresencePayload } from '../types.ts'
12
+
13
+ /**
14
+ * Diagnostic seam for the incremental-save mapping (PRD v3.1 follow-up).
15
+ *
16
+ * Cell edits that cannot be expressed as a plain value fall back to a whole
17
+ * snapshot save, which is correct but ~230 KB per edit. This records why the
18
+ * last such mutation was not mapped, so the reason can be read from the
19
+ * browser console instead of guessed:
20
+ *
21
+ * __dshLastCellMutation // { commandId, mapped, reason?, keys? }
22
+ */
23
+ let lastCellMutationNote: { reason?: string; keys?: string[] } | undefined
24
+
25
+ /** Why the current mutation could not become an incremental cell change. */
26
+ export function noteCellMutation(_commandId: string, mapped: boolean, detail: { reason?: string; keys?: string[] } = {}): void {
27
+ lastCellMutationNote = mapped ? undefined : detail
28
+ }
29
+
30
+ /**
31
+ * Publish the outcome of one persisted mutation. This runs for *every*
32
+ * mutation the workbook persists, so a command id we do not map is still
33
+ * visible instead of leaving the probe undefined:
34
+ *
35
+ * __dshLastCellMutation // { commandId, mapped, reason?, keys? }
36
+ */
37
+ export function publishMutationAttempt(commandId: string, mapped: boolean): void {
38
+ if (typeof window === 'undefined') return
39
+ ;(window as unknown as { __dshLastCellMutation?: unknown }).__dshLastCellMutation = {
40
+ at: new Date().toISOString(),
41
+ commandId,
42
+ mapped,
43
+ ...(mapped ? {} : (lastCellMutationNote ?? { reason: 'command-not-mapped' })),
44
+ }
45
+ }
46
+
47
+ export function cellKeysOf(cellValue: unknown): string[] {
48
+ if (typeof cellValue !== 'object' || cellValue === null) return []
49
+ const firstRow = Object.values(cellValue as Record<string, unknown>)[0]
50
+ if (typeof firstRow !== 'object' || firstRow === null) return []
51
+ const firstCell = Object.values(firstRow as Record<string, unknown>)[0]
52
+ return typeof firstCell === 'object' && firstCell !== null ? Object.keys(firstCell) : []
53
+ }
54
+
55
+ /**
56
+ * Convert Univer's sparse set-range-values mutation into the small DSH edit
57
+ * contract. Formatting, pasted rich objects, and structural commands return
58
+ * undefined so the browser deliberately falls back to a full snapshot save.
59
+ */
60
+ export function toLocalCellChange(commandInfo: { id: string; params?: unknown }): WorkbookLocalChange | undefined {
61
+ if (commandInfo.id !== 'sheet.mutation.set-range-values') return undefined
62
+ if (typeof commandInfo.params !== 'object' || commandInfo.params === null) {
63
+ noteCellMutation(commandInfo.id, false, { reason: 'params-missing' })
64
+ return undefined
65
+ }
66
+ const params = commandInfo.params as Record<string, unknown>
67
+ if (typeof params.subUnitId !== 'string' || typeof params.cellValue !== 'object' || params.cellValue === null) {
68
+ noteCellMutation(commandInfo.id, false, { reason: 'cellValue-missing', keys: cellKeysOf(params.cellValue) })
69
+ return undefined
70
+ }
71
+ const cells: WorkbookCellUpdate[] = []
72
+ const rows = params.cellValue as Record<string, unknown>
73
+ for (const [rowKey, rowValue] of Object.entries(rows)) {
74
+ const row = Number(rowKey)
75
+ if (!Number.isInteger(row) || typeof rowValue !== 'object' || rowValue === null) return undefined
76
+ for (const [columnKey, cellValue] of Object.entries(rowValue as Record<string, unknown>)) {
77
+ const column = Number(columnKey)
78
+ if (!Number.isInteger(column)) {
79
+ noteCellMutation(commandInfo.id, false, { reason: 'bad-column-key', keys: cellKeysOf(params.cellValue) })
80
+ return undefined
81
+ }
82
+ if (cellValue === null) {
83
+ cells.push({ row, column, value: null })
84
+ continue
85
+ }
86
+ if (typeof cellValue !== 'object' || Array.isArray(cellValue)) {
87
+ noteCellMutation(commandInfo.id, false, { reason: 'cell-not-object', keys: cellKeysOf(params.cellValue) })
88
+ return undefined
89
+ }
90
+ const cell = cellValue as Record<string, unknown>
91
+ const unsupportedKeys = Object.keys(cell).filter(key => !['v', 'f', 't'].includes(key))
92
+ if (unsupportedKeys.length > 0) {
93
+ noteCellMutation(commandInfo.id, false, { reason: 'unsupported-cell-keys', keys: Object.keys(cell) })
94
+ return undefined
95
+ }
96
+ const value = cell.v
97
+ if (value !== undefined && value !== null && typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') return undefined
98
+ const formula = normalizeCellFormula(cell.f)
99
+ cells.push({ row, column, value: value === undefined ? null : value, ...(formula === undefined ? {} : { formula }) })
100
+ }
101
+ }
102
+ if (cells.length === 0) {
103
+ noteCellMutation(commandInfo.id, false, { reason: 'no-cells', keys: cellKeysOf(params.cellValue) })
104
+ return undefined
105
+ }
106
+ noteCellMutation(commandInfo.id, true)
107
+ return { type: 'update_cells', payload: { sheetId: params.subUnitId, cells } }
108
+ }
109
+
110
+ /** Convert selection/focus commands into a compact ephemeral presence event.
111
+ * Unknown commands are intentionally ignored so UI internals never become
112
+ * durable edits or high-volume network traffic. */
113
+ export function toPresence(commandInfo: { id: string; params?: unknown }): WorkbookPresencePayload | undefined {
114
+ const commandId = commandInfo.id.toLowerCase()
115
+ let kind: WorkbookPresencePayload['kind'] | undefined
116
+ if (commandId.includes('selection') || commandId.includes('set-selections')) kind = 'selection'
117
+ else if (commandId.includes('activate') || commandId.includes('active') || commandId.includes('focus') || commandId.includes('current-sheet')) kind = 'active-sheet'
118
+ else return undefined
119
+ const params = typeof commandInfo.params === 'object' && commandInfo.params !== null
120
+ ? commandInfo.params as Record<string, unknown>
121
+ : {}
122
+ const payload: Record<string, unknown> = { commandId }
123
+ for (const key of ['subUnitId', 'unitId', 'sheetId']) {
124
+ if (typeof params[key] === 'string') payload[key] = params[key]
125
+ }
126
+ const range = params.range
127
+ if (typeof range === 'object' && range !== null && !Array.isArray(range)) {
128
+ const candidate = range as Record<string, unknown>
129
+ const safeRange: Record<string, number> = {}
130
+ for (const key of ['startRow', 'startColumn', 'endRow', 'endColumn']) {
131
+ if (typeof candidate[key] === 'number' && Number.isFinite(candidate[key])) safeRange[key] = candidate[key] as number
132
+ }
133
+ if (Object.keys(safeRange).length > 0) payload.range = safeRange
134
+ }
135
+ return { kind, payload }
136
+ }
@@ -0,0 +1,370 @@
1
+ /**
2
+ * Heavy Univer engine for dsh-data-table: the sheets-core preset
3
+ * mount plus the free feature presets (filter/sort/find-replace/conditional
4
+ * formatting/data validation/drawing/hyper-link/note/thread-comment/table)
5
+ * and the Univer-native CSV/Excel export plugin. Bundled as a self-contained IIFE chunk
6
+ * (`lib/univer-client.js`) served on demand by the node half — the ~16MB
7
+ * Univer graph never enters the boot bundle.
8
+ * @module dsh-data-table/univer-engine
9
+ */
10
+
11
+ import {
12
+ createUniver,
13
+ defaultTheme,
14
+ LocaleType,
15
+ merge,
16
+ UniverInstanceType,
17
+ } from '@univerjs/presets'
18
+ // The es-path values carry runtime code; the honest types live in the types tree.
19
+ import { UniverSheetsCorePreset } from '@univerjs/presets/lib/es/preset-sheets-core/index.js'
20
+ import { UniverSheetsFilterPreset } from '@univerjs/presets/lib/es/preset-sheets-filter/index.js'
21
+ import { UniverSheetsSortPreset } from '@univerjs/presets/lib/es/preset-sheets-sort/index.js'
22
+ import { UniverSheetsFindReplacePreset } from '@univerjs/presets/lib/es/preset-sheets-find-replace/index.js'
23
+ import { UniverSheetsConditionalFormattingPreset } from '@univerjs/presets/lib/es/preset-sheets-conditional-formatting/index.js'
24
+ import { UniverSheetsDataValidationPreset } from '@univerjs/presets/lib/es/preset-sheets-data-validation/index.js'
25
+ import { UniverSheetsDrawingPreset } from '@univerjs/presets/lib/es/preset-sheets-drawing/index.js'
26
+ import { UniverSheetsHyperLinkPreset } from '@univerjs/presets/lib/es/preset-sheets-hyper-link/index.js'
27
+ import { UniverSheetsNotePreset } from '@univerjs/presets/lib/es/preset-sheets-note/index.js'
28
+ import { UniverSheetsThreadCommentPreset } from '@univerjs/presets/lib/es/preset-sheets-thread-comment/index.js'
29
+ import { UniverSheetsTablePreset } from '@univerjs/presets/lib/es/preset-sheets-table/index.js'
30
+ import { UniverSheetsCrosshairHighlightPlugin } from '@univerjs/sheets-crosshair-highlight'
31
+ import type {
32
+ WorkbookDecoration,
33
+ WorkbookMount,
34
+ WorkbookMountOptions,
35
+ } from './chunk.ts'
36
+
37
+ // Re-exported so `univer/entry.ts` and the loader keep one name for the mount
38
+ // contract, which lives in `univer/chunk.ts` beside the loader side.
39
+ export type { WorkbookDecoration, WorkbookDecorationCell, WorkbookDecorationTone, WorkbookMount, WorkbookMountOptions } from './chunk.ts'
40
+ import coreZhCN from '@univerjs/presets/lib/es/preset-sheets-core/locales/zh-CN.js'
41
+ import coreEnUS from '@univerjs/presets/lib/es/preset-sheets-core/locales/en-US.js'
42
+ import filterZhCN from '@univerjs/presets/lib/es/preset-sheets-filter/locales/zh-CN.js'
43
+ import filterEnUS from '@univerjs/presets/lib/es/preset-sheets-filter/locales/en-US.js'
44
+ import sortZhCN from '@univerjs/presets/lib/es/preset-sheets-sort/locales/zh-CN.js'
45
+ import sortEnUS from '@univerjs/presets/lib/es/preset-sheets-sort/locales/en-US.js'
46
+ import findReplaceZhCN from '@univerjs/presets/lib/es/preset-sheets-find-replace/locales/zh-CN.js'
47
+ import findReplaceEnUS from '@univerjs/presets/lib/es/preset-sheets-find-replace/locales/en-US.js'
48
+ import condFmtZhCN from '@univerjs/presets/lib/es/preset-sheets-conditional-formatting/locales/zh-CN.js'
49
+ import condFmtEnUS from '@univerjs/presets/lib/es/preset-sheets-conditional-formatting/locales/en-US.js'
50
+ import dataValZhCN from '@univerjs/presets/lib/es/preset-sheets-data-validation/locales/zh-CN.js'
51
+ import dataValEnUS from '@univerjs/presets/lib/es/preset-sheets-data-validation/locales/en-US.js'
52
+ import drawingZhCN from '@univerjs/presets/lib/es/preset-sheets-drawing/locales/zh-CN.js'
53
+ import drawingEnUS from '@univerjs/presets/lib/es/preset-sheets-drawing/locales/en-US.js'
54
+ import hyperLinkZhCN from '@univerjs/presets/lib/es/preset-sheets-hyper-link/locales/zh-CN.js'
55
+ import hyperLinkEnUS from '@univerjs/presets/lib/es/preset-sheets-hyper-link/locales/en-US.js'
56
+ import noteZhCN from '@univerjs/presets/lib/es/preset-sheets-note/locales/zh-CN.js'
57
+ import noteEnUS from '@univerjs/presets/lib/es/preset-sheets-note/locales/en-US.js'
58
+ import threadZhCN from '@univerjs/presets/lib/es/preset-sheets-thread-comment/locales/zh-CN.js'
59
+ import threadEnUS from '@univerjs/presets/lib/es/preset-sheets-thread-comment/locales/en-US.js'
60
+ import tableZhCN from '@univerjs/presets/lib/es/preset-sheets-table/locales/zh-CN.js'
61
+ import tableEnUS from '@univerjs/presets/lib/es/preset-sheets-table/locales/en-US.js'
62
+ import crosshairZhCN from '@univerjs/sheets-crosshair-highlight/locale/zh-CN'
63
+ import crosshairEnUS from '@univerjs/sheets-crosshair-highlight/locale/en-US'
64
+ // Univer ships its styles as separate artifacts; without them the workbench
65
+ // renders unstyled (toolbar stacked vertically). The client build turns these
66
+ // imports into inlined style injections.
67
+ import '@univerjs/presets/lib/styles/preset-sheets-core.css'
68
+ import '@univerjs/presets/lib/styles/preset-sheets-filter.css'
69
+ import '@univerjs/presets/lib/styles/preset-sheets-sort.css'
70
+ import '@univerjs/presets/lib/styles/preset-sheets-find-replace.css'
71
+ import '@univerjs/presets/lib/styles/preset-sheets-conditional-formatting.css'
72
+ import '@univerjs/presets/lib/styles/preset-sheets-data-validation.css'
73
+ import '@univerjs/presets/lib/styles/preset-sheets-drawing.css'
74
+ import '@univerjs/presets/lib/styles/preset-sheets-hyper-link.css'
75
+ import '@univerjs/presets/lib/styles/preset-sheets-note.css'
76
+ import '@univerjs/presets/lib/styles/preset-sheets-thread-comment.css'
77
+ import '@univerjs/presets/lib/styles/preset-sheets-table.css'
78
+ import '@univerjs/sheets-crosshair-highlight/lib/index.css'
79
+ import './overrides.css'
80
+ import type {
81
+ SheetColumn,
82
+ WorkbookCellStyle,
83
+ WorkbookCellUpdate,
84
+ WorkbookLocalChange,
85
+ WorkbookOperation,
86
+ WorkbookOperationPayload,
87
+ WorkbookFocusRange,
88
+ WorkbookRange,
89
+ WorkbookPresencePayload,
90
+ WorkbookSelectionRange,
91
+ } from '../types.ts'
92
+ import { DataSheetExportPlugin } from './plugins/export.ts'
93
+ import { DataSheetCollaborationPlugin } from './plugins/collaboration.ts'
94
+ import { DataSheetHistoryPlugin } from './plugins/history.ts'
95
+ import { getInstalledFontConfigs, withDefaultSheetFont } from './fonts.ts'
96
+ import { shouldPersistUniverMutation } from '../contract/operations.ts'
97
+ import { publishMutationAttempt, toLocalCellChange, toPresence } from './diagnostics.ts'
98
+ import { DEFAULT_SHEET_ROWS, DEFAULT_SHEET_COLUMNS } from '../contract/snapshots.ts'
99
+ import { createDecorationApplier } from './decoration.ts'
100
+ import { createOperationApplier } from './apply-operation.ts'
101
+ import type { SheetsApi, SheetResolver } from './facade.ts'
102
+
103
+ /** Default sheet extent (Univer's own default), so data lands on a full-size grid. */
104
+
105
+ /**
106
+ * Load marker + default probe value.
107
+ *
108
+ * The engine chunk is a classic script the browser may still serve from cache,
109
+ * so "is my bundle current?" was impossible to answer from the console. These
110
+ * two globals are set as soon as the chunk evaluates:
111
+ *
112
+ * __dshDataSheetEngine // { version, loadedAt } — undefined means a stale chunk
113
+ * __dshLastCellMutation // { reason: 'no-persisted-mutation-yet' } until you edit
114
+ */
115
+ if (typeof window !== 'undefined') {
116
+ const win = window as unknown as { __dshDataSheetEngine?: unknown; __dshLastCellMutation?: unknown }
117
+ win.__dshDataSheetEngine = { version: 'v3.2', loadedAt: new Date().toISOString() }
118
+ // One line, so "which engine build is this page running?" is answered by the
119
+ // console itself instead of a hand-typed global.
120
+ console.info('[data-sheet] Univer engine chunk v3.2 loaded · probe: __dshLastCellMutation')
121
+ win.__dshLastCellMutation = { reason: 'no-persisted-mutation-yet' }
122
+ }
123
+
124
+
125
+ /**
126
+ * Mount one resident Univer engine into a container; the container must be in
127
+ * the DOM and the chunk must already be loaded. The workbook data is an
128
+ * Univer snapshot (IWorkbookData-shaped) that the residency renders; `save()`
129
+ * returns the current snapshot for the client half to persist. The client
130
+ * batches ten durable user steps (or flushes on Ctrl/Cmd+S) into one Version.
131
+ */
132
+ export function mountWorkbook(container: HTMLElement, workbookData: object, onDirty?: (change?: WorkbookLocalChange) => void, onPresence?: (presence: WorkbookPresencePayload) => void, options: WorkbookMountOptions = {}, onSelection?: (ranges: readonly WorkbookSelectionRange[]) => void): WorkbookMount {
133
+ const readOnly = options.readOnly === true
134
+ const decoration = options.decoration
135
+ const installedFontConfigs = getInstalledFontConfigs()
136
+ let openHistory: (() => void) | undefined
137
+ let refreshSelection = (): void => {}
138
+ const onUniverMutation = (commandInfo: { id: string; params?: unknown }, options?: { onlyLocal?: boolean; fromChangeset?: boolean; fromCollab?: boolean }): void => {
139
+ if (applier.isApplyingRemote() || options?.onlyLocal || options?.fromChangeset || options?.fromCollab) return
140
+ if (!shouldPersistUniverMutation(commandInfo.id)) {
141
+ const presence = toPresence(commandInfo)
142
+ // A preview is not somebody editing: it publishes no editing presence,
143
+ // so peers do not see a phantom collaborator.
144
+ if (presence !== undefined && !readOnly) onPresence?.(presence)
145
+ return
146
+ }
147
+ // Belt and braces with `setEditable(false)` below: even a command that
148
+ // slipped past the permission interceptor is never reported as a change,
149
+ // so a preview can never fork a Version.
150
+ if (readOnly) return
151
+ onPresence?.({ kind: 'editing', payload: { commandId: commandInfo.id } })
152
+ const change = toLocalCellChange(commandInfo)
153
+ publishMutationAttempt(commandInfo.id, change !== undefined)
154
+ onDirty?.(change)
155
+ refreshSelection()
156
+ }
157
+ const { univer, univerAPI } = createUniver({ // The sheets-core preset renders nothing (silently) without the locale
158
+ // packs and theme; keep both in sync with the official 0.25 usage.
159
+ locale: LocaleType.ZH_CN,
160
+ locales: {
161
+ zhCN: merge({}, coreZhCN, filterZhCN, sortZhCN, findReplaceZhCN, condFmtZhCN, dataValZhCN, drawingZhCN, hyperLinkZhCN, noteZhCN, threadZhCN, tableZhCN, crosshairZhCN),
162
+ enUS: merge({}, coreEnUS, filterEnUS, sortEnUS, findReplaceEnUS, condFmtEnUS, dataValEnUS, drawingEnUS, hyperLinkEnUS, noteEnUS, threadEnUS, tableEnUS, crosshairEnUS),
163
+ },
164
+ theme: defaultTheme,
165
+ plugins: [
166
+ DataSheetExportPlugin,
167
+ [DataSheetHistoryPlugin, { onOpenHistory: () => openHistory?.() }],
168
+ [DataSheetCollaborationPlugin, { onMutation: onUniverMutation }],
169
+ UniverSheetsCrosshairHighlightPlugin,
170
+ ],
171
+ presets: [
172
+ UniverSheetsCorePreset({
173
+ container,
174
+ header: true,
175
+ // A preview shows history: the editing chrome would only invite edits
176
+ // that cannot be saved (PRD v3.3 §7.2). Read-only mode keeps the grid,
177
+ // the headers and the sheet tabs, and drops the rest.
178
+ toolbar: !readOnly,
179
+ formulaBar: !readOnly,
180
+ // (`disableEdit` is deliberately *not* passed here: this preset
181
+ // destructures a fixed key set and would drop it silently. It is not
182
+ // needed either — with the workbook permission off, the cell editor
183
+ // refuses to open, measured.)
184
+ statusBarStatistic: true,
185
+ // The footer carries the sheet tabs. A past Version still has several
186
+ // sheets, so switching between them is navigation and must stay
187
+ // available in a read-only view (GUI feedback 2026-09-19).
188
+ footer: true,
189
+ contextMenu: !readOnly,
190
+ // Register custom families during UI initialization so they are
191
+ // present in the font dropdown (addFonts alone is too late for the
192
+ // initial font-family component in this Univer version).
193
+ customFontFamily: {
194
+ list: installedFontConfigs,
195
+ override: true,
196
+ },
197
+ }),
198
+ // Free feature presets (mirrors the best_excel plugin set). Datasheet
199
+ // collaboration is provided by its own dependency-free adapter above;
200
+ // the commercial Univer collaboration preset is intentionally unused.
201
+ UniverSheetsFilterPreset(),
202
+ UniverSheetsSortPreset(),
203
+ UniverSheetsFindReplacePreset(),
204
+ UniverSheetsConditionalFormattingPreset(),
205
+ UniverSheetsDataValidationPreset(),
206
+ UniverSheetsDrawingPreset(),
207
+ UniverSheetsHyperLinkPreset(),
208
+ UniverSheetsNotePreset(),
209
+ UniverSheetsThreadCommentPreset(),
210
+ UniverSheetsTablePreset(),
211
+ ],
212
+ })
213
+ // Univer does not download these fonts; the browser uses them when the
214
+ // corresponding family is installed on the user's machine.
215
+ univer.createUnit(UniverInstanceType.UNIVER_SHEET, withDefaultSheetFont(workbookData))
216
+ // Debug seam: mounted engines by container, for live workbook inspection.
217
+ {
218
+ const win = window as unknown as { __bestExcelDebugMounts?: Array<{ container: HTMLElement; api: unknown }> }
219
+ win.__bestExcelDebugMounts = win.__bestExcelDebugMounts ?? []
220
+ win.__bestExcelDebugMounts.push({ container, api: univerAPI })
221
+ }
222
+ // The sheets facade augments FUniver with the workbook API; the core type
223
+ // lacks it, so the engine views the facade structurally (see `facade.ts`).
224
+ const sheetsApi = univerAPI as unknown as SheetsApi
225
+ const getSheet: SheetResolver = (sheetRef) => {
226
+ const workbook = sheetsApi.getActiveWorkbook()
227
+ if (workbook === null) return null
228
+ if (sheetRef !== undefined) return workbook.getSheetBySheetId(sheetRef) ?? workbook.getSheetByName(sheetRef)
229
+ return workbook.getSheetBySheetId('sheet1') ?? null
230
+ }
231
+
232
+ let selectionSubscription: { dispose(): void } | undefined
233
+ let currentSelectionRanges: Array<WorkbookRange & { sheetId?: string }> = []
234
+ const projectSelections = (ranges: readonly (WorkbookRange & { sheetId?: string })[]): WorkbookSelectionRange[] => {
235
+ const workbook = sheetsApi.getActiveWorkbook()
236
+ if (workbook === null) return []
237
+ const activeSheetId = workbook.getActiveSheet?.()?.getSheetId?.()
238
+ const projected: WorkbookSelectionRange[] = []
239
+ for (const range of ranges.slice(0, 40)) {
240
+ const sheetId = range.sheetId ?? activeSheetId
241
+ if (sheetId === undefined) continue
242
+ const sheet = workbook.getSheetBySheetId(sheetId)
243
+ if (sheet === null) continue
244
+ const startRow = Math.max(0, Math.floor(range.startRow))
245
+ const startColumn = Math.max(0, Math.floor(range.startColumn))
246
+ const endRow = Math.max(startRow, Math.floor(range.endRow))
247
+ const endColumn = Math.max(startColumn, Math.floor(range.endColumn))
248
+ const values = sheet.getRange(
249
+ startRow,
250
+ startColumn,
251
+ Math.min(endRow - startRow + 1, 10),
252
+ Math.min(endColumn - startColumn + 1, 20),
253
+ ).getValues?.() ?? []
254
+ projected.push({
255
+ sheetId,
256
+ sheetName: sheet.getSheetName?.() ?? sheetId,
257
+ startRow,
258
+ startColumn,
259
+ endRow,
260
+ endColumn,
261
+ values,
262
+ })
263
+ }
264
+ return projected
265
+ }
266
+ const publishSelections = (ranges: readonly (WorkbookRange & { sheetId?: string })[]): void => {
267
+ currentSelectionRanges = [...ranges]
268
+ onSelection?.(projectSelections(currentSelectionRanges))
269
+ }
270
+ refreshSelection = (): void => {
271
+ if (currentSelectionRanges.length > 0) onSelection?.(projectSelections(currentSelectionRanges))
272
+ }
273
+ const bindSelectionWatcher = (): void => {
274
+ selectionSubscription?.dispose()
275
+ selectionSubscription = undefined
276
+ currentSelectionRanges = []
277
+ onSelection?.([])
278
+ const workbook = sheetsApi.getActiveWorkbook()
279
+ if (workbook?.onSelectionChange === undefined) return
280
+ selectionSubscription = workbook.onSelectionChange(ranges => {
281
+ if (sheetsApi.getActiveWorkbook()?.getId() !== workbook.getId()) return
282
+ publishSelections(ranges)
283
+ })
284
+ }
285
+ bindSelectionWatcher()
286
+
287
+
288
+ /**
289
+ * Show a different workbook **without rebuilding Univer** (PRD v3.5 §7.2).
290
+ *
291
+ * Switching the inspected Version used to change the canvas key, which
292
+ * unmounted the residency and called `createUniver` again — re-registering
293
+ * every plugin and rebuilding the whole DI graph for a change that is only
294
+ * "different cells". Swapping the *unit* on the same engine keeps the grid,
295
+ * the sheet tabs and the scroll position, and removes the re-init cost.
296
+ *
297
+ * A fresh unit also means the previous Version's diff tint disappears with
298
+ * it, so there is nothing to un-paint.
299
+ */
300
+ const decoration_ = createDecorationApplier({ sheetsApi, getSheet, readOnly })
301
+ // Paint on the **mount** path too, not only in `swapWorkbook`. Entering inspect
302
+ // remounts the canvas (`preview === null` means there is no residency to swap),
303
+ // so the mount is the *first* preview a reader ever sees. Applying the plan
304
+ // only when swapping dropped both the diff tint and the read-only lock on that
305
+ // first look — the cells were counted in the bar but nothing was painted, and
306
+ // the unit stayed editable. Restores the pre-split behaviour, where the mount
307
+ // called the same thing (`if (readOnly || decoration !== undefined) apply…`).
308
+ if (readOnly || decoration !== undefined) decoration_.apply(decoration)
309
+ const applier = createOperationApplier({ sheetsApi, getSheet })
310
+
311
+ const swapWorkbook = (next: object, options: { decoration?: WorkbookDecoration } = {}): boolean => {
312
+ const previousId = sheetsApi.getActiveWorkbook()?.getId()
313
+ try {
314
+ univer.createUnit(UniverInstanceType.UNIVER_SHEET, withDefaultSheetFont(next))
315
+ } catch {
316
+ return false
317
+ }
318
+ bindSelectionWatcher()
319
+ decoration_.apply(options.decoration)
320
+ if (previousId !== undefined) {
321
+ try {
322
+ sheetsApi.disposeUnit?.(previousId)
323
+ } catch {
324
+ // A unit that refuses to dispose is a leak, not a broken canvas.
325
+ }
326
+ }
327
+ return true
328
+ }
329
+
330
+ return {
331
+ swapWorkbook,
332
+ save: () => {
333
+ const wb = sheetsApi.getActiveWorkbook()
334
+ if (wb === null) return workbookData
335
+ const snapshot = wb.getSnapshot()
336
+ if (typeof snapshot === 'object' && snapshot !== null && typeof (snapshot as { sheets?: unknown }).sheets === 'object') {
337
+ const sheets = (snapshot as { sheets: Record<string, Record<string, unknown>> }).sheets
338
+ for (const [sheetId, meta] of applier.liveSheetMetadata.entries()) {
339
+ const sheet = sheets[sheetId]
340
+ if (sheet !== undefined) sheet.dataSheetMeta = meta
341
+ }
342
+ }
343
+ return snapshot
344
+ },
345
+ applyOperation: applier.apply,
346
+ focusRange: (target: WorkbookFocusRange): boolean => {
347
+ const workbook = sheetsApi.getActiveWorkbook()
348
+ const sheet = workbook?.getSheetBySheetId(target.sheetId)
349
+ if (workbook === null || workbook === undefined || sheet === null || sheet === undefined || workbook.setActiveRange === undefined) return false
350
+ workbook.setActiveSheet?.(sheet)
351
+ const range = sheet.getRange(
352
+ target.startRow,
353
+ target.startColumn,
354
+ target.endRow - target.startRow + 1,
355
+ target.endColumn - target.startColumn + 1,
356
+ )
357
+ workbook.setActiveRange(range)
358
+ return true
359
+ },
360
+ dispose: () => {
361
+ selectionSubscription?.dispose()
362
+ selectionSubscription = undefined
363
+ univer.dispose()
364
+ const win = window as unknown as { __bestExcelDebugMounts?: Array<{ container: HTMLElement; api: unknown }> }
365
+ if (win.__bestExcelDebugMounts !== undefined) {
366
+ win.__bestExcelDebugMounts = win.__bestExcelDebugMounts.filter(entry => entry.container !== container)
367
+ }
368
+ },
369
+ }
370
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Chunk entry for dsh-data-table. Built as a self-contained IIFE
3
+ * (`lib/univer-client.js`, Univer fully inlined) and loaded as a classic
4
+ * script on first sheet render; it hands the engine surface to the client
5
+ * half through a global so the ~16MB graph never enters the boot bundle.
6
+ * @module dsh-data-table/univer/entry
7
+ */
8
+
9
+ import type { UniverChunkApi } from './chunk.ts'
10
+ import { mountWorkbook } from './engine.ts'
11
+
12
+ // The interface and the `window` global live in ./chunk.ts so the loader
13
+ // in the client bundle cannot drift from the chunk it loads.
14
+ window.__bestExcelUniver = { mountWorkbook } satisfies UniverChunkApi
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The Univer facade surface this adapter actually uses (docs/issue/0022 P4).
3
+ *
4
+ * The sheets facade augments `FUniver` with `getActiveWorkbook`/`getSnapshot`,
5
+ * which the core type does not declare, so the engine views it structurally. It
6
+ * is declared once here because three modules need the same view of it —
7
+ * decoration, the operation applier and the engine — and three copies would
8
+ * drift the moment one of them used a facade method the others did not declare.
9
+ */
10
+ import type { WorkbookRange } from '../types.ts'
11
+
12
+ export interface UniverRange {
13
+ getValue?(): unknown
14
+ getValues?(): unknown[][]
15
+ setValue(value: unknown): unknown
16
+ clearContent(): unknown
17
+ setValues(value: unknown): unknown
18
+ getRange?(): WorkbookRange
19
+ /** Tint one cell; the diff overlay's only painting primitive. */
20
+ setBackgroundColor?(color: string): unknown | Promise<unknown>
21
+ setFontColor?(color: string): unknown
22
+ setFontFamily?(family: string): unknown
23
+ setFontSize?(size: number): unknown
24
+ setFontWeight?(weight: 'bold' | 'normal' | null): unknown
25
+ setFontStyle?(style: 'italic' | 'normal' | null): unknown
26
+ setFontLine?(line: 'underline' | 'line-through' | 'none' | null): unknown
27
+ setHorizontalAlignment?(alignment: 'left' | 'center' | 'normal'): unknown
28
+ setVerticalAlignment?(alignment: 'top' | 'middle' | 'bottom'): unknown
29
+ setTextRotation?(rotation: number): unknown
30
+ sort?(column: number | { column: number; ascending: boolean }): unknown
31
+ merge?(options?: { defaultMerge?: boolean; isForceMerge?: boolean }): unknown
32
+ breakApart?(): unknown
33
+ /** 0 = shift cells left, 1 = shift cells up (Univer facade enum). */
34
+ deleteCells?: (direction: 0 | 1) => unknown
35
+ setHyperLink?(url: string, label?: string): Promise<boolean>
36
+ cancelHyperLink?(): boolean
37
+ }
38
+
39
+ export interface UniverSheet {
40
+ getSheetId?: () => string
41
+ getSheetName?: () => string
42
+ getRange(row: number, column: number, numRows?: number, numColumns?: number): UniverRange
43
+ deleteRows?: (rowPosition: number, howMany?: number) => unknown
44
+ insertRows?: (rowIndex: number, numRows?: number) => unknown
45
+ deleteColumns?: (columnPosition: number, howMany?: number) => unknown
46
+ insertColumns?: (columnIndex: number, numColumns?: number) => unknown
47
+ setName?: (name: string) => unknown
48
+ setColumnWidth?: (columnPosition: number, width: number) => unknown
49
+ setRowHeight?: (rowPosition: number, height: number) => unknown
50
+ setFreeze?: (freeze: { startRow: number; startColumn: number; xSplit: number; ySplit: number }) => unknown
51
+ cancelFreeze?: () => unknown
52
+ getLastRow?: () => number
53
+ getMaxColumns?: () => number
54
+ getMaxRows?: () => number
55
+ setColumnCount?: (count: number) => unknown
56
+ setRowCount?: (count: number) => unknown
57
+ }
58
+
59
+ export interface UniverWorkbook {
60
+ getId(): string
61
+ getSnapshot(): unknown
62
+ getSheetBySheetId(sheetId: string): UniverSheet | null
63
+ getSheetByName(name: string): UniverSheet | null
64
+ getActiveSheet?(): UniverSheet | null
65
+ onSelectionChange?(listener: (ranges: readonly (WorkbookRange & { sheetId?: string })[]) => void): { dispose(): void }
66
+ create(name: string, rows: number, columns: number, options?: { sheet?: { id?: string } }): unknown
67
+ deleteSheet?(sheet: string | UniverSheet): unknown
68
+ /** Workbook-level edit permission (docs/issue/0002 PRD v3.2 §7.2). */
69
+ setEditable?(value: boolean): unknown
70
+ /**
71
+ * The permission facade behind that call, for *reading back* what was set.
72
+ * `canEdit()` is the only way to tell whether the lock actually landed — see
73
+ * `lockWorkbook` in `decoration.ts` for why that question is not rhetorical.
74
+ */
75
+ getWorkbookPermission?(): { canEdit?(): boolean } | null
76
+ /** Select a range; the facade scrolls the active range into view. */
77
+ setActiveRange?(range: unknown): unknown
78
+ /** Activate a sheet before selecting a range on it. */
79
+ setActiveSheet?(sheet: unknown): unknown
80
+ }
81
+
82
+ /** The facade's workbook-scoped API, as this adapter uses it. */
83
+ export interface SheetsApi {
84
+ /** Dispose a unit without tearing the engine down (used by `swapWorkbook`). */
85
+ disposeUnit?(unitId: string): boolean
86
+ getActiveWorkbook(): UniverWorkbook | null
87
+ executeCommand(id: string, params: unknown, options?: unknown): Promise<unknown>
88
+ }
89
+
90
+ /** Resolve a sheet by id, by name, or the default first sheet. */
91
+ export type SheetResolver = (sheetRef: string | undefined) => UniverSheet | null