@a3s-lab/office 0.12.0 → 0.13.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 (111) hide show
  1. package/README.md +99 -6
  2. package/dist/0~1403.js +20 -12
  3. package/dist/0~2805.js +241 -241
  4. package/dist/0~4980.js +1 -1
  5. package/dist/0~5050.js +1 -20
  6. package/dist/0~5093.js +547 -547
  7. package/dist/0~7048.js +31 -29
  8. package/dist/0~document-editor.js +694 -90
  9. package/dist/0~pdf-viewer.js +41 -10
  10. package/dist/0~presentation-editor.js +8 -6
  11. package/dist/0~spreadsheet-editor.js +11528 -10094
  12. package/dist/0~work-document-import-worker-client.js +237 -0
  13. package/dist/0~work-docx-export.js +1 -1
  14. package/dist/0~work-docx-import.js +1 -1
  15. package/dist/0~work-docx-large-document-import.js +559 -0
  16. package/dist/0~work-office-diagnostics.js +46 -32
  17. package/dist/4104.js +4092 -3210
  18. package/dist/432.js +51 -7
  19. package/dist/4476.js +201 -7
  20. package/dist/5184.js +24 -2
  21. package/dist/{8928.js → 6282.js} +2338 -93
  22. package/dist/8715.js +895 -888
  23. package/dist/9356.js +3 -1
  24. package/dist/core.js +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/internal/features/work/editors/document-editor-support.d.ts +1 -9
  27. package/dist/internal/features/work/editors/document-external-content.d.ts +1 -1
  28. package/dist/internal/features/work/editors/presentation-slide-canvas.d.ts +3 -1
  29. package/dist/internal/features/work/editors/presentation-slide-thumbnail.d.ts +3 -2
  30. package/dist/internal/features/work/editors/presentation-thumbnail-rail.d.ts +2 -1
  31. package/dist/internal/features/work/editors/presentation-workspace.d.ts +2 -1
  32. package/dist/internal/features/work/editors/spreadsheet-border-ribbon.d.ts +5 -0
  33. package/dist/internal/features/work/editors/spreadsheet-calculation-projection.d.ts +10 -0
  34. package/dist/internal/features/work/editors/spreadsheet-cell-border-command.d.ts +3 -0
  35. package/dist/internal/features/work/editors/spreadsheet-cell-border.d.ts +14 -0
  36. package/dist/internal/features/work/editors/spreadsheet-cell-fill-command.d.ts +3 -0
  37. package/dist/internal/features/work/editors/spreadsheet-cell-fill.d.ts +12 -0
  38. package/dist/internal/features/work/editors/spreadsheet-cell-range.d.ts +14 -0
  39. package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +159 -0
  40. package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +8 -4
  41. package/dist/internal/features/work/editors/spreadsheet-editor-support.d.ts +8 -2
  42. package/dist/internal/features/work/editors/spreadsheet-home-format-ribbon.d.ts +10 -0
  43. package/dist/internal/features/work/editors/spreadsheet-in-place-workbook-sync.d.ts +10 -0
  44. package/dist/internal/features/work/editors/spreadsheet-operation-projection.d.ts +14 -0
  45. package/dist/internal/features/work/editors/spreadsheet-structure-selection.d.ts +7 -0
  46. package/dist/internal/features/work/editors/use-document-pagination.d.ts +5 -0
  47. package/dist/internal/features/work/editors/use-presentation-design-commands.d.ts +2 -1
  48. package/dist/internal/features/work/editors/use-spreadsheet-workbook-sync.d.ts +2 -1
  49. package/dist/internal/features/work/spreadsheet-history-value.d.ts +1 -0
  50. package/dist/internal/features/work/spreadsheet-sparse.d.ts +6 -1
  51. package/dist/internal/features/work/work-document-chunk-geometry.d.ts +28 -0
  52. package/dist/internal/features/work/work-document-chunk-node.d.ts +23 -0
  53. package/dist/internal/features/work/work-document-extensions.d.ts +1 -0
  54. package/dist/internal/features/work/work-document-html-fingerprint.d.ts +15 -0
  55. package/dist/internal/features/work/work-document-import-worker-client.d.ts +13 -0
  56. package/dist/internal/features/work/work-document-import-worker-protocol.d.ts +36 -0
  57. package/dist/internal/features/work/work-document-import.worker.d.ts +1 -0
  58. package/dist/internal/features/work/work-document-incremental-layout.d.ts +1 -1
  59. package/dist/internal/features/work/work-document-integrity-index.d.ts +14 -0
  60. package/dist/internal/features/work/work-document-lazy-block.d.ts +3 -0
  61. package/dist/internal/features/work/work-document-lazy-html.d.ts +21 -0
  62. package/dist/internal/features/work/work-document-lazy-model.d.ts +29 -0
  63. package/dist/internal/features/work/work-document-lazy-pagination-measurement.d.ts +3 -0
  64. package/dist/internal/features/work/work-document-lazy-preview.d.ts +21 -0
  65. package/dist/internal/features/work/work-document-lazy-update.d.ts +14 -0
  66. package/dist/internal/features/work/work-document-model.d.ts +18 -2
  67. package/dist/internal/features/work/work-document-page-surface-registry.d.ts +16 -0
  68. package/dist/internal/features/work/work-document-pagination-dom.d.ts +1 -0
  69. package/dist/internal/features/work/work-document-pagination-types.d.ts +1 -0
  70. package/dist/internal/features/work/work-document-pagination.d.ts +1 -1
  71. package/dist/internal/features/work/work-document-text-statistics.d.ts +25 -0
  72. package/dist/internal/features/work/work-document-windowing.d.ts +23 -0
  73. package/dist/internal/features/work/work-docx-large-document-import.d.ts +35 -0
  74. package/dist/internal/features/work/work-docx-large-document-parser.d.ts +29 -0
  75. package/dist/internal/features/work/work-file-import.d.ts +5 -0
  76. package/dist/internal/features/work/work-file-io.d.ts +3 -3
  77. package/dist/internal/features/work/work-file-kind.d.ts +5 -0
  78. package/dist/internal/features/work/work-office-diagnostics.d.ts +10 -1
  79. package/dist/internal/features/work/work-ooxml-package.d.ts +8 -0
  80. package/dist/internal/features/work/work-presentation-layouts.d.ts +7 -1
  81. package/dist/internal/features/work/work-repository.d.ts +1 -0
  82. package/dist/internal/features/work/work-spreadsheet-compatibility-summary.d.ts +10 -0
  83. package/dist/internal/features/work/work-spreadsheet-file-export.d.ts +2 -0
  84. package/dist/internal/features/work/work-spreadsheet-file-import.d.ts +3 -0
  85. package/dist/internal/features/work/work-spreadsheet-import-diagnostics.d.ts +2 -0
  86. package/dist/internal/features/work/work-spreadsheet-import-worker-client.d.ts +6 -0
  87. package/dist/internal/features/work/work-spreadsheet-import-worker-protocol.d.ts +32 -0
  88. package/dist/internal/features/work/work-spreadsheet-import.worker.d.ts +1 -0
  89. package/dist/internal/features/work/work-spreadsheet-matrix-profile.d.ts +64 -0
  90. package/dist/internal/features/work/work-spreadsheet-package-scan-worker-client.d.ts +6 -0
  91. package/dist/internal/features/work/work-spreadsheet-package-scan-worker-protocol.d.ts +49 -0
  92. package/dist/internal/features/work/work-spreadsheet-package-scan.worker.d.ts +1 -0
  93. package/dist/internal/features/work/work-xlsx-formula-diagnostics.d.ts +3 -1
  94. package/dist/internal/features/work/work-xlsx-formulas.d.ts +2 -1
  95. package/dist/internal/features/work/work-xlsx-interop.d.ts +6 -5
  96. package/dist/internal/features/work/work-xlsx-pivot-diagnostics.d.ts +2 -1
  97. package/dist/internal/features/work/work-xlsx-plain-fast-path.d.ts +54 -0
  98. package/dist/internal/features/work/work-xlsx-style-gate.d.ts +1 -0
  99. package/dist/internal/features/work/work-xlsx-worksheet-scan.d.ts +12 -0
  100. package/dist/internal/features/work/work-xlsx-worksheet.d.ts +12 -0
  101. package/dist/office-kernel.wasm +0 -0
  102. package/dist/office-kernel.worker.js +31 -29
  103. package/dist/react.d.ts +7 -1
  104. package/dist/styles.css +440 -3
  105. package/dist/work-document-import.worker.js +558 -0
  106. package/dist/work-spreadsheet-import.worker.js +24745 -0
  107. package/dist/work-spreadsheet-import.worker.js.LICENSE.txt +3 -0
  108. package/dist/work-spreadsheet-package-scan.worker.js +4157 -0
  109. package/dist/work-spreadsheet-package-scan.worker.js.LICENSE.txt +11 -0
  110. package/docs/latest/en/browser-editor-architecture.md +351 -15
  111. package/package.json +19 -1
package/README.md CHANGED
@@ -139,8 +139,34 @@ The images below are committed visual-regression baselines from the real
139
139
  - **Framework choice** — React components, Vue 3 adapters, Custom Elements,
140
140
  and a framework-neutral Core API over the same engine.
141
141
  - **Responsive computation** — Lazy editor chunks, cancellable Workers,
142
+ streamed dense XLSX and eligible large-DOCX parsing in dedicated
143
+ transferable-input Workers, including a fail-closed plain-OOXML path that
144
+ reuses the package Worker's decompressed worksheet XML and aborts speculative
145
+ SheetJS parsing only after package authentication,
142
146
  CSS-compatible font-weight matching, Rust WebAssembly layout and
143
- calculation, and PDFium rendering.
147
+ calculation, and PDFium rendering. Spreadsheet Canvas painting is bounded
148
+ to the visible row and column range. Eligible structurally plain large DOCX
149
+ files retain one complete canonical structured model while TipTap initially
150
+ materializes only two equal-position chunks and hydrates a selected chunk on
151
+ demand. The large-DOCX Worker streams 2,048-item batches and columnar table
152
+ metadata instead of cloning one complete object graph. Pooled semantic
153
+ previews, physical page sheets, and pagination widgets are windowed
154
+ independently. The PDF rail mounts at most 32 thumbnail buttons, aborts the
155
+ exact PDFium task when a thumbnail leaves the window, and uses instant
156
+ long-distance keyboard jumps so the destination retains focus. The checked
157
+ 1,000-page fixture mounts 15 thumbnails and seven main-view pages at
158
+ readiness. Presentation decks above 60 slides use independent thumbnail-node
159
+ and scene windows. The checked 1,000-slide, 9,000-element fixture mounts 18
160
+ thumbnail buttons and 13 full thumbnail scenes, retains about 10.9 MiB of
161
+ JavaScript heap, reaches slide 1,000 in 6.1–13.4 ms, and produces no Long
162
+ Tasks. Design metadata is normalized once per controlled value and each
163
+ visible thumbnail resolves only its own slide. The checked 100,000-block
164
+ fixtures keep
165
+ selection, editing, and export positions in the canonical model instead of
166
+ replacing them with a React-only virtual list; rich and collaborative models
167
+ deliberately retain the complete compatibility path. Consecutive controlled
168
+ edits hash only changed lazy chunks and combine cached fingerprint segments,
169
+ while cloned or persisted models still receive complete HTML verification.
144
170
  - **AI without UI scraping** — Typed agent ports and host-defined selection
145
171
  actions receive structured context and editing commands.
146
172
  - **Automation outside the browser** — The native Rust CLI, standard MCP
@@ -250,6 +276,32 @@ export function ProjectBrief() {
250
276
  The editor owns editing, layout, import/export, and browser rendering. The host
251
277
  owns persistence and decides when, where, and how the emitted content is saved.
252
278
 
279
+ ### Preload an anticipated PDF
280
+
281
+ Editor modules remain lazy. PDFium runtime loading is a separate, explicit
282
+ choice because its unpacked WebAssembly binary is about 4.4 MiB. Warm both only
283
+ from a high-confidence intent, and use the same URL when mounting `PdfViewer`:
284
+
285
+ ```tsx
286
+ import { PdfViewer, preloadOfficeEditor } from '@a3s-lab/office/react';
287
+
288
+ const pdfiumUrl = '/assets/pdfium.wasm';
289
+
290
+ void preloadOfficeEditor('pdf', {
291
+ pdfWasmUrl: pdfiumUrl,
292
+ preloadRuntimeAssets: true,
293
+ });
294
+
295
+ <PdfViewer loadSource={loadPdf} wasmUrl={pdfiumUrl} />;
296
+ ```
297
+
298
+ The preload caches the module and, when the request succeeds, the response
299
+ body. Runtime warming is best effort: a network failure does not block editor
300
+ opening, and a later call retries it. The helper does not create a hidden
301
+ viewer or pre-initialize the PDFium Worker. On the local reference machine it
302
+ improved median shell mount by 41.6 ms but did not improve the viewer-ready
303
+ median, so Worker initialization remains the measured boundary.
304
+
253
305
  ### Persist a structured document snapshot
254
306
 
255
307
  Hosts that round-trip controlled document values across a process or language
@@ -476,7 +528,11 @@ interaction model.
476
528
  commands share the permission-resilient local fallback with their WPS
477
529
  shortcuts, a WPS-style Format Painter with single-use and double-click locked
478
530
  sessions, cross-sheet range-pattern tiling, Escape cancellation, and native
479
- style-only writes, Conditional Formatting under Home and Styles, executable
531
+ style-only writes, a Home and Font cell-border split control with side, all,
532
+ outside, inside, horizontal, vertical, clear, and diagonal targets, ten
533
+ native line styles, exact color selection, compact overlapping range writes,
534
+ single-update undo, and grid-focus restoration, Conditional Formatting under
535
+ Home and Styles, executable
480
536
  sorting plus WPS-style AutoFilter under Data, finite current-region discovery,
481
537
  `Cmd/Ctrl+Shift+L` toggling, an `Alt+ArrowDown` keyboard filter menu,
482
538
  a Home and Cells Rows and Columns menu for inserting above, below, left, or
@@ -487,6 +543,10 @@ interaction model.
487
543
  a Home and Editing Clear menu for independently removing content, formats,
488
544
  comments, hyperlinks, or all cell state while preserving merge geometry,
489
545
  with Delete and Backspace mapped to Clear Contents,
546
+ a Home and Editing Fill menu for Down, Right, Up, and Left with native
547
+ relative-formula and style propagation, WPS `Cmd/Ctrl+D` and `Cmd/Ctrl+R`
548
+ shortcuts, one-step history, protected-range preflight, a 50,000-target-cell
549
+ guard, and sparse-row-safe execution,
490
550
  a View and Window Freeze Panes menu for current-cell, top-row, first-column,
491
551
  and unfreeze patterns with XLSX round trips, and visible F9 workbook
492
552
  recalculation,
@@ -516,9 +576,10 @@ interaction model.
516
576
  - **PDF** — PDFium rendering, navigation, search, form filling, annotations,
517
577
  annotation color, opacity, compatible stroke-width controls, history,
518
578
  a scrollable page-thumbnail rail with current-page synchronization and
519
- focus-synchronized Arrow/Home/End navigation, bounded rendering for long
520
- files, and a dismissible page drawer whose phone trigger stays in the page
521
- controls instead of covering PDF content,
579
+ focus-synchronized Arrow/Home/End navigation, a 32-thumbnail hard window,
580
+ cancellation of stale PDFium bitmap tasks, bounded main-page rendering for
581
+ long files, and a dismissible page drawer whose phone trigger stays in the
582
+ page controls instead of covering PDF content,
522
583
  focus-safe page and search drafts, responsive search-result, navigation, and
523
584
  zoom controls, editor-scoped shortcuts, and a keyboard-operated overflow menu
524
585
  that retains secondary annotation tools and appearance settings on phones.
@@ -579,7 +640,9 @@ import {
579
640
  } from '@a3s-lab/office/core';
580
641
 
581
642
  const controller = new AbortController();
643
+ const shell = createArtifact('blank-document');
582
644
  const imported = await importOfficeFile(file, {
645
+ artifactId: shell.id,
583
646
  signal: controller.signal,
584
647
  onProgress: ({ stage, progress }) => {
585
648
  console.info(stage, `${Math.round(progress * 100)}%`);
@@ -587,12 +650,35 @@ const imported = await importOfficeFile(file, {
587
650
  });
588
651
  const output = await createArtifactBlob(imported);
589
652
  const blankDeck = createArtifact('blank-presentation');
653
+
654
+ const workbookShell = createArtifact('blank-spreadsheet');
655
+ if (workbookShell.content.type !== 'spreadsheet') {
656
+ throw new Error('Expected a Spreadsheet shell.');
657
+ }
658
+ const workbook = await importOfficeFile(spreadsheetFile, {
659
+ artifactId: workbookShell.id,
660
+ spreadsheetSheetIds: workbookShell.content.sheets.flatMap((sheet) =>
661
+ sheet.id ? [sheet.id] : [],
662
+ ),
663
+ });
590
664
  ```
591
665
 
592
666
  Import progress advances monotonically through `reading`, `parsing`,
593
667
  `analyzing`, and `finalizing`. Calling `controller.abort()` rejects with an
594
668
  `AbortError`; large reads and parser checkpoints yield so a host can keep the
595
- progress and Cancel controls responsive.
669
+ progress and Cancel controls responsive. An optional host-reserved
670
+ `artifactId` lets the UI mount an editor shell before parsing finishes and then
671
+ apply the imported controlled value without remounting that surface. The
672
+ Playground uses this boundary to overlap DOCX Worker parsing with editor
673
+ initialization; source-backed export remains attached to the reserved ID. A
674
+ Spreadsheet host can also reserve worksheet identities with
675
+ `spreadsheetSheetIds`. Eligible structurally plain workbooks then replace the
676
+ authenticated frozen matrix inside the mounted Fortune instance instead of
677
+ cloning one million cells through a second mount. Sheet-count or identity
678
+ changes, preview mode, charts, protection, merged or styled geometry, and other
679
+ stateful workbook structures retain the complete remount path. The plain-OOXML
680
+ Worker authenticates row and cell coordinates directly in its XML buffer, so a
681
+ million-cell import does not allocate or regex-match a million address strings.
596
682
 
597
683
  Spreadsheet import and export preserve sparse worksheets up to the XLSX limit
598
684
  of 1,048,576 rows by 16,384 columns. The logical `data.length`, `row`, and
@@ -1341,6 +1427,12 @@ bun run lint
1341
1427
  bun run typecheck
1342
1428
  bun run test
1343
1429
  bun run build
1430
+ bun run test:e2e:large-pdf:check
1431
+ bun run test:e2e:large-pdf
1432
+ bun run performance:pdf
1433
+ bun run test:e2e:large-presentation:check
1434
+ bun run test:e2e:large-presentation
1435
+ bun run performance:presentation
1344
1436
  ```
1345
1437
 
1346
1438
  Start the integration Playground with `bun run playground`. The full pull
@@ -1359,6 +1451,7 @@ without hard-coded return URLs.
1359
1451
 
1360
1452
  - [Live Playground](https://a3s-lab.github.io/Office/)
1361
1453
  - [Documentation center](https://a3s-lab.github.io/Office/docs/)
1454
+ - [A3S Office 0.13.0 documentation](https://a3s-lab.github.io/Office/docs/0.13.0/)
1362
1455
  - [A3S Office 0.12.0 documentation](https://a3s-lab.github.io/Office/docs/0.12.0/)
1363
1456
  - [A3S Office 0.11.0 documentation](https://a3s-lab.github.io/Office/docs/0.11.0/)
1364
1457
  - [A3S Office 0.10.0 documentation](https://a3s-lab.github.io/Office/docs/0.10.0/)
package/dist/0~1403.js CHANGED
@@ -125,6 +125,19 @@ function presentationGroupPath(element) {
125
125
  const DEFAULT_PRESENTATION_MASTER_ID = 'presentation-master-default';
126
126
  const DEFAULT_PRESENTATION_LAYOUT_ID = 'presentation-layout-default';
127
127
  function withPresentationDesign(content) {
128
+ const designContent = withPresentationDesignMetadata(content);
129
+ const layoutIds = new Set(designContent.layouts.map((layout)=>layout.id));
130
+ const firstLayoutId = designContent.layouts[0].id;
131
+ return {
132
+ ...designContent,
133
+ slides: designContent.slides.map((slide)=>({
134
+ ...slide,
135
+ layoutId: slide.layoutId && layoutIds.has(slide.layoutId) ? slide.layoutId : firstLayoutId,
136
+ useLayoutBackground: slide.useLayoutBackground ?? false
137
+ }))
138
+ };
139
+ }
140
+ function withPresentationDesignMetadata(content) {
128
141
  const masters = content.masters?.length ? content.masters : [
129
142
  {
130
143
  id: DEFAULT_PRESENTATION_MASTER_ID,
@@ -146,23 +159,18 @@ function withPresentationDesign(content) {
146
159
  elements: []
147
160
  }
148
161
  ];
149
- const layoutIds = new Set(layouts.map((layout)=>layout.id));
150
- const firstLayoutId = layouts[0].id;
151
162
  return {
152
163
  ...content,
153
164
  masters,
154
- layouts,
155
- slides: content.slides.map((slide)=>({
156
- ...slide,
157
- layoutId: slide.layoutId && layoutIds.has(slide.layoutId) ? slide.layoutId : firstLayoutId,
158
- useLayoutBackground: slide.useLayoutBackground ?? false
159
- }))
165
+ layouts
160
166
  };
161
167
  }
162
168
  function presentationSlideView(content, slide) {
163
- const normalized = withPresentationDesign(content);
164
- const layout = normalized.layouts?.find((candidate)=>candidate.id === slide.layoutId) ?? normalized.layouts?.[0];
165
- const master = normalized.masters?.find((candidate)=>candidate.id === layout?.masterId) ?? normalized.masters?.[0];
169
+ return presentationSlideViewFromDesign(withPresentationDesign(content), slide);
170
+ }
171
+ function presentationSlideViewFromDesign(designContent, slide) {
172
+ const layout = designContent.layouts.find((candidate)=>candidate.id === slide.layoutId) ?? designContent.layouts[0];
173
+ const master = designContent.masters.find((candidate)=>candidate.id === layout?.masterId) ?? designContent.masters[0];
166
174
  const showMasterElements = false !== slide.showMasterElements && layout?.showMasterElements !== false;
167
175
  const masterElements = showMasterElements ? master?.elements ?? [] : [];
168
176
  const layoutElements = layout?.elements ?? [];
@@ -242,4 +250,4 @@ function structuredCopy(value) {
242
250
  if ('function' == typeof structuredClone) return structuredClone(value);
243
251
  return JSON.parse(JSON.stringify(value));
244
252
  }
245
- export { applyPresentationLayout, canGroupPresentationElements, canUngroupPresentationElements, expandPresentationGroupSelection, groupPresentationElements, presentationGroupPath, presentationSelectionUnits, presentationSlideView, remapPresentationGroupPaths, ungroupPresentationElements, withPresentationDesign };
253
+ export { applyPresentationLayout, canGroupPresentationElements, canUngroupPresentationElements, expandPresentationGroupSelection, groupPresentationElements, presentationGroupPath, presentationSelectionUnits, presentationSlideView, presentationSlideViewFromDesign, remapPresentationGroupPaths, ungroupPresentationElements, withPresentationDesign, withPresentationDesignMetadata };