@beyondwork/docx-react-component 1.0.41 → 1.0.42
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/package.json +13 -1
- package/src/api/awareness-identity-types.ts +35 -0
- package/src/api/comment-negotiation-types.ts +130 -0
- package/src/api/comment-presentation-types.ts +106 -0
- package/src/api/external-custody-types.ts +74 -0
- package/src/api/participants-types.ts +18 -0
- package/src/api/public-types.ts +347 -4
- package/src/api/scope-metadata-resolver-types.ts +88 -0
- package/src/core/commands/formatting-commands.ts +1 -1
- package/src/core/commands/index.ts +568 -1
- package/src/index.ts +118 -1
- package/src/io/export/escape-xml-attribute.ts +26 -0
- package/src/io/export/external-send.ts +188 -0
- package/src/io/export/serialize-comments.ts +13 -16
- package/src/io/export/serialize-footnotes.ts +17 -24
- package/src/io/export/serialize-headers-footers.ts +17 -24
- package/src/io/export/serialize-main-document.ts +59 -62
- package/src/io/export/serialize-numbering.ts +20 -27
- package/src/io/export/serialize-runtime-revisions.ts +2 -9
- package/src/io/export/serialize-tables.ts +8 -15
- package/src/io/export/table-properties-xml.ts +25 -32
- package/src/io/import/external-reimport.ts +40 -0
- package/src/io/ooxml/bw-xml.ts +244 -0
- package/src/io/ooxml/canonicalize-payload.ts +301 -0
- package/src/io/ooxml/comment-negotiation-payload.ts +288 -0
- package/src/io/ooxml/comment-presentation-payload.ts +311 -0
- package/src/io/ooxml/external-custody-payload.ts +102 -0
- package/src/io/ooxml/participants-payload.ts +97 -0
- package/src/io/ooxml/payload-signature.ts +112 -0
- package/src/io/ooxml/workflow-payload-validator.ts +271 -0
- package/src/io/ooxml/workflow-payload.ts +146 -7
- package/src/runtime/awareness-identity.ts +173 -0
- package/src/runtime/collab/event-types.ts +27 -0
- package/src/runtime/collab-session-bridge.ts +157 -0
- package/src/runtime/collab-session-facet.ts +193 -0
- package/src/runtime/collab-session.ts +273 -0
- package/src/runtime/comment-negotiation-sync.ts +91 -0
- package/src/runtime/comment-negotiation.ts +158 -0
- package/src/runtime/comment-presentation.ts +223 -0
- package/src/runtime/document-runtime.ts +280 -93
- package/src/runtime/external-send-runtime.ts +117 -0
- package/src/runtime/layout/docx-font-loader.ts +11 -30
- package/src/runtime/layout/inert-layout-facet.ts +2 -0
- package/src/runtime/layout/layout-engine-instance.ts +122 -12
- package/src/runtime/layout/page-graph.ts +79 -7
- package/src/runtime/layout/paginated-layout-engine.ts +230 -34
- package/src/runtime/layout/public-facet.ts +185 -13
- package/src/runtime/layout/table-row-split.ts +316 -0
- package/src/runtime/markdown-sanitizer.ts +132 -0
- package/src/runtime/participants.ts +134 -0
- package/src/runtime/resign-payload.ts +120 -0
- package/src/runtime/tamper-gate.ts +157 -0
- package/src/runtime/workflow-markup.ts +9 -0
- package/src/runtime/workflow-rail-segments.ts +244 -5
- package/src/ui/WordReviewEditor.tsx +587 -0
- package/src/ui/editor-runtime-boundary.ts +1 -0
- package/src/ui/editor-shell-view.tsx +11 -0
- package/src/ui-tailwind/chrome/chrome-preset-model.ts +28 -0
- package/src/ui-tailwind/chrome/collab-audience-chip.tsx +73 -0
- package/src/ui-tailwind/chrome/collab-negotiation-action-bar.tsx +244 -0
- package/src/ui-tailwind/chrome/collab-presence-strip.tsx +150 -0
- package/src/ui-tailwind/chrome/collab-role-chip.tsx +62 -0
- package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +68 -0
- package/src/ui-tailwind/chrome/collab-send-to-supplier-modal.tsx +149 -0
- package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +68 -0
- package/src/ui-tailwind/chrome/forward-non-drag-click.ts +104 -0
- package/src/ui-tailwind/chrome/tw-mode-dock.tsx +1 -0
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +7 -1
- package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +1 -38
- package/src/ui-tailwind/chrome-overlay/index.ts +6 -0
- package/src/ui-tailwind/chrome-overlay/scope-card-role-model.ts +78 -0
- package/src/ui-tailwind/chrome-overlay/scope-keyboard-cycle.ts +49 -0
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +58 -0
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +527 -0
- package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +120 -22
- package/src/ui-tailwind/chrome-overlay/tw-scope-card.tsx +310 -32
- package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +93 -14
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +35 -1
- package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +86 -3
- package/src/ui-tailwind/editor-surface/pm-schema.ts +15 -13
- package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +20 -3
- package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +15 -14
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +66 -0
- package/src/ui-tailwind/index.ts +32 -0
- package/src/ui-tailwind/review/tw-review-rail-footer.tsx +29 -3
- package/src/ui-tailwind/status/tw-status-bar.tsx +52 -1
- package/src/ui-tailwind/theme/editor-theme.css +25 -0
- package/src/ui-tailwind/tw-review-workspace.tsx +293 -34
package/src/api/public-types.ts
CHANGED
|
@@ -3,6 +3,19 @@ import type { CanonicalParagraphFormatting, CanonicalRunFormatting } from "../mo
|
|
|
3
3
|
import type { WordReviewEditorLayoutFacet } from "../runtime/layout/public-facet.ts";
|
|
4
4
|
import type { RenderFrameRect } from "../runtime/render/index.ts";
|
|
5
5
|
import type { ScopeRailPosture } from "../runtime/workflow-rail-segments.ts";
|
|
6
|
+
import type {
|
|
7
|
+
MetadataPersistenceMode,
|
|
8
|
+
ScopeMetadataPersistence,
|
|
9
|
+
ScopeMetadataResolver,
|
|
10
|
+
ScopeMetadataStorageRef,
|
|
11
|
+
} from "./scope-metadata-resolver-types.ts";
|
|
12
|
+
|
|
13
|
+
export type {
|
|
14
|
+
MetadataPersistenceMode,
|
|
15
|
+
ScopeMetadataPersistence,
|
|
16
|
+
ScopeMetadataResolver,
|
|
17
|
+
ScopeMetadataStorageRef,
|
|
18
|
+
};
|
|
6
19
|
|
|
7
20
|
export type { CanonicalParagraphFormatting, CanonicalRunFormatting };
|
|
8
21
|
|
|
@@ -360,6 +373,38 @@ export interface SuggestionEntrySnapshot {
|
|
|
360
373
|
preserveOnlyReason?: string;
|
|
361
374
|
excerpt?: string;
|
|
362
375
|
detail?: string;
|
|
376
|
+
/**
|
|
377
|
+
* R3 — scope-card-overlay P2. When present, links this entry to a
|
|
378
|
+
* `SuggestionGroup` via `SuggestionsSnapshot.groups[].groupId`.
|
|
379
|
+
* A single issue may fan out to multiple suggestions via the group.
|
|
380
|
+
*/
|
|
381
|
+
groupId?: string;
|
|
382
|
+
/**
|
|
383
|
+
* R3 — origin of the suggestion's rationale (used by the card's
|
|
384
|
+
* suggestion row for attribution hints).
|
|
385
|
+
*/
|
|
386
|
+
rationaleSource?: "playbook" | "agent" | "host" | "user";
|
|
387
|
+
/**
|
|
388
|
+
* R3 — tier within a preferred/fallback_1/fallback_2/escalate_only
|
|
389
|
+
* ladder. Hosts render this as the chip label in the scope card.
|
|
390
|
+
*/
|
|
391
|
+
tier?: "preferred" | "fallback_1" | "fallback_2" | "escalate_only";
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* R3 — scope-card-overlay P2. Groups `SuggestionEntrySnapshot`
|
|
396
|
+
* entries under a single issue so the scope card exposes atomic
|
|
397
|
+
* accept/reject actions. One issue → N suggestions → N revisions on
|
|
398
|
+
* accept, committed as a single runtime transaction.
|
|
399
|
+
*/
|
|
400
|
+
export interface SuggestionGroup {
|
|
401
|
+
groupId: string;
|
|
402
|
+
issueId?: string;
|
|
403
|
+
ruleId?: string;
|
|
404
|
+
rationale?: string;
|
|
405
|
+
severity?: IssueSeverity;
|
|
406
|
+
tier?: "preferred" | "fallback_1" | "fallback_2" | "escalate_only";
|
|
407
|
+
suggestionIds: string[];
|
|
363
408
|
}
|
|
364
409
|
|
|
365
410
|
export interface SuggestionsSnapshot {
|
|
@@ -371,6 +416,8 @@ export interface SuggestionsSnapshot {
|
|
|
371
416
|
rejectedSuggestionIds: string[];
|
|
372
417
|
detachedSuggestionIds: string[];
|
|
373
418
|
suggestions: SuggestionEntrySnapshot[];
|
|
419
|
+
/** R3 — optional groups keying into `suggestions` by `groupId`. */
|
|
420
|
+
groups?: SuggestionGroup[];
|
|
374
421
|
}
|
|
375
422
|
|
|
376
423
|
export type FormattingAlignment = "left" | "center" | "right" | "justify";
|
|
@@ -1622,12 +1669,31 @@ export interface WorkflowScope {
|
|
|
1622
1669
|
domain?: "legal" | "commercial" | "finance" | "other";
|
|
1623
1670
|
metadataRefs?: string[];
|
|
1624
1671
|
metadata?: WorkflowScopeMetadataField[];
|
|
1672
|
+
/**
|
|
1673
|
+
* Schema 1.1 — override the overlay default for this scope.
|
|
1674
|
+
* `"inherit"` defers to the overlay; absent is equivalent to
|
|
1675
|
+
* `"inherit"`.
|
|
1676
|
+
*/
|
|
1677
|
+
metadataPersistence?: ScopeMetadataPersistence;
|
|
1625
1678
|
}
|
|
1626
1679
|
|
|
1627
1680
|
export interface WorkflowScopeMetadataField {
|
|
1628
1681
|
key: string;
|
|
1629
1682
|
valueType?: "string" | "number" | "boolean" | "json";
|
|
1630
1683
|
value?: string | number | boolean | Record<string, unknown>;
|
|
1684
|
+
/**
|
|
1685
|
+
* Schema 1.1 — per-field override. Resolution order:
|
|
1686
|
+
* field > scope > overlay > "internal" default.
|
|
1687
|
+
*/
|
|
1688
|
+
metadataPersistence?: ScopeMetadataPersistence;
|
|
1689
|
+
storageRef?: ScopeMetadataStorageRef;
|
|
1690
|
+
/**
|
|
1691
|
+
* Schema 1.1 — monotonically-increasing version hint. Internal-mode
|
|
1692
|
+
* writes bump this; external-mode writes read it from the
|
|
1693
|
+
* resolver's `publish` result. Used by readers to detect divergence
|
|
1694
|
+
* between embedded and resolver-returned values.
|
|
1695
|
+
*/
|
|
1696
|
+
metadataVersion?: number;
|
|
1631
1697
|
}
|
|
1632
1698
|
|
|
1633
1699
|
export interface WorkflowWorkItem {
|
|
@@ -1645,6 +1711,12 @@ export interface WorkflowOverlay {
|
|
|
1645
1711
|
scopes: WorkflowScope[];
|
|
1646
1712
|
workItems?: WorkflowWorkItem[];
|
|
1647
1713
|
activeWorkItemId?: string | null;
|
|
1714
|
+
/**
|
|
1715
|
+
* Schema 1.1 — overlay-level default for metadata persistence. When
|
|
1716
|
+
* absent, readers treat as `"internal"`. Per-scope / per-entry /
|
|
1717
|
+
* per-field overrides can opt in or out of the default.
|
|
1718
|
+
*/
|
|
1719
|
+
metadataPersistence?: MetadataPersistenceMode;
|
|
1648
1720
|
}
|
|
1649
1721
|
|
|
1650
1722
|
export type WorkflowMetadataPersistence =
|
|
@@ -1670,6 +1742,23 @@ export interface WorkflowMetadataEntry {
|
|
|
1670
1742
|
value?: Record<string, unknown>;
|
|
1671
1743
|
scopeId?: string;
|
|
1672
1744
|
workItemId?: string;
|
|
1745
|
+
/**
|
|
1746
|
+
* Schema 1.1 — per-entry override. `"inherit"` (or absent) defers
|
|
1747
|
+
* to the effective scope or overlay default.
|
|
1748
|
+
*/
|
|
1749
|
+
metadataPersistence?: ScopeMetadataPersistence;
|
|
1750
|
+
/**
|
|
1751
|
+
* Schema 1.1 — opaque host reference when effective persistence
|
|
1752
|
+
* resolves to `"external"`. Absent when inline.
|
|
1753
|
+
*/
|
|
1754
|
+
storageRef?: ScopeMetadataStorageRef;
|
|
1755
|
+
/**
|
|
1756
|
+
* Schema 1.1 — monotonically-increasing version hint. Internal-mode
|
|
1757
|
+
* writes bump this; external-mode writes read it from the
|
|
1758
|
+
* resolver's `publish` result. Used by readers to detect divergence
|
|
1759
|
+
* between embedded and resolver-returned values.
|
|
1760
|
+
*/
|
|
1761
|
+
metadataVersion?: number;
|
|
1673
1762
|
}
|
|
1674
1763
|
|
|
1675
1764
|
export interface WorkflowMetadataSnapshot {
|
|
@@ -1748,6 +1837,41 @@ export type ScopeIssueAction =
|
|
|
1748
1837
|
| "escalate"
|
|
1749
1838
|
| "acknowledge";
|
|
1750
1839
|
|
|
1840
|
+
// ---------------------------------------------------------------------------
|
|
1841
|
+
// K1-light — review-action audit trail (scope-card-overlay P2)
|
|
1842
|
+
// ---------------------------------------------------------------------------
|
|
1843
|
+
|
|
1844
|
+
/**
|
|
1845
|
+
* Canonical metadata id for append-only review actions. Hosts push
|
|
1846
|
+
* one `WorkflowMetadataEntry` per review decision; the scope card's
|
|
1847
|
+
* timeline reads entries whose value matches the attached issue.
|
|
1848
|
+
*
|
|
1849
|
+
* Round-trip through `src/io/ooxml/workflow-payload.ts` lands with a
|
|
1850
|
+
* later K1 phase; for P2 the entries live in the session snapshot.
|
|
1851
|
+
*/
|
|
1852
|
+
export const REVIEW_ACTION_METADATA_ID =
|
|
1853
|
+
"workflow.metadata.review_action" as const;
|
|
1854
|
+
|
|
1855
|
+
export type ReviewActionKind =
|
|
1856
|
+
| "include"
|
|
1857
|
+
| "edit"
|
|
1858
|
+
| "discard"
|
|
1859
|
+
| "escalate"
|
|
1860
|
+
| "acknowledge"
|
|
1861
|
+
| "resolve"
|
|
1862
|
+
| "waive";
|
|
1863
|
+
|
|
1864
|
+
export interface ReviewActionMetadataValue {
|
|
1865
|
+
reviewActionId: string;
|
|
1866
|
+
action: ReviewActionKind;
|
|
1867
|
+
actor: string;
|
|
1868
|
+
actorRole: IssueOwner | "agent";
|
|
1869
|
+
issueId?: string;
|
|
1870
|
+
suggestedRedlineId?: string;
|
|
1871
|
+
payload?: Record<string, unknown>;
|
|
1872
|
+
createdAt: string;
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1751
1875
|
/**
|
|
1752
1876
|
* Scope card projection consumed by the chrome overlay's card layer.
|
|
1753
1877
|
* Joins a `WorkflowScope` with its attached issue metadata (R2),
|
|
@@ -1765,11 +1889,19 @@ export interface ScopeCardModel {
|
|
|
1765
1889
|
label: string;
|
|
1766
1890
|
primaryAnchorRect: RenderFrameRect | null;
|
|
1767
1891
|
issue?: IssueMetadataValue;
|
|
1768
|
-
/**
|
|
1892
|
+
/** Id-only lookup; `suggestionGroups` holds the full entries. */
|
|
1769
1893
|
suggestionGroupIds: readonly string[];
|
|
1770
|
-
/**
|
|
1894
|
+
/** R3 — full group entries attached to the scope's issue. */
|
|
1895
|
+
suggestionGroups: readonly SuggestionGroup[];
|
|
1896
|
+
/** K1 — count of review actions attached to the scope's issue. */
|
|
1771
1897
|
reviewActionCount: number;
|
|
1772
|
-
/**
|
|
1898
|
+
/** K1 — newest-first review-action entries for the card timeline. */
|
|
1899
|
+
reviewActions: readonly ReviewActionMetadataValue[];
|
|
1900
|
+
/**
|
|
1901
|
+
* K2 — true when a `WorkflowCandidateRange` with `source: "ai"`
|
|
1902
|
+
* overlaps the scope. Drives the rail-layer's agent-pending
|
|
1903
|
+
* shimmer.
|
|
1904
|
+
*/
|
|
1773
1905
|
agentPending: boolean;
|
|
1774
1906
|
}
|
|
1775
1907
|
|
|
@@ -1863,6 +1995,25 @@ export interface WorkflowMetadataMarkup extends WorkflowMarkupBase {
|
|
|
1863
1995
|
value?: Record<string, unknown>;
|
|
1864
1996
|
scopeId?: string;
|
|
1865
1997
|
workItemId?: string;
|
|
1998
|
+
/**
|
|
1999
|
+
* Schema 1.1 — mirrors `WorkflowMetadataEntry.metadataPersistence`.
|
|
2000
|
+
* Lets the card layer detect external entries without re-consulting the
|
|
2001
|
+
* entry snapshot. `"external"` means the inline `value` is empty and the
|
|
2002
|
+
* real value lives in the host rowstore; `"internal"` (or absent) means
|
|
2003
|
+
* `value` is the authoritative copy.
|
|
2004
|
+
*/
|
|
2005
|
+
metadataPersistence?: ScopeMetadataPersistence;
|
|
2006
|
+
/**
|
|
2007
|
+
* Schema 1.1 — opaque host reference when `metadataPersistence === "external"`.
|
|
2008
|
+
* Passed verbatim to `ScopeMetadataResolver.resolve`; the editor never
|
|
2009
|
+
* parses this string.
|
|
2010
|
+
*/
|
|
2011
|
+
storageRef?: ScopeMetadataStorageRef;
|
|
2012
|
+
/**
|
|
2013
|
+
* Schema 1.1 — monotonically-increasing version hint. Used by readers to
|
|
2014
|
+
* detect divergence between the embedded value and the resolver-returned one.
|
|
2015
|
+
*/
|
|
2016
|
+
metadataVersion?: number;
|
|
1866
2017
|
}
|
|
1867
2018
|
|
|
1868
2019
|
export interface WorkflowCommentMarkup extends WorkflowMarkupBase {
|
|
@@ -2314,6 +2465,61 @@ export type WordReviewEditorEvent =
|
|
|
2314
2465
|
scopeId: string;
|
|
2315
2466
|
issueId: string;
|
|
2316
2467
|
action: ScopeIssueAction;
|
|
2468
|
+
}
|
|
2469
|
+
| {
|
|
2470
|
+
/**
|
|
2471
|
+
* K2 — scope card "Ask review agent" was clicked. Host routes
|
|
2472
|
+
* the request to the CCEP contract review agent (or equivalent)
|
|
2473
|
+
* with the scope's anchor + story + surrounding text; when the
|
|
2474
|
+
* agent responds, the host pushes an issue + suggestion group
|
|
2475
|
+
* through the existing R2/R3 paths and clears any
|
|
2476
|
+
* `WorkflowCandidateRange` it used as the pending marker.
|
|
2477
|
+
*/
|
|
2478
|
+
type: "agent-on-selection-requested";
|
|
2479
|
+
documentId: string;
|
|
2480
|
+
requestId: string;
|
|
2481
|
+
scopeId?: string;
|
|
2482
|
+
anchor: EditorAnchorProjection;
|
|
2483
|
+
storyTarget?: EditorStoryTarget;
|
|
2484
|
+
selectionText: string;
|
|
2485
|
+
surroundingText?: string;
|
|
2486
|
+
reviewSessionId?: string;
|
|
2487
|
+
}
|
|
2488
|
+
| {
|
|
2489
|
+
type: "metadata_persistence_mode_changed";
|
|
2490
|
+
documentId: string;
|
|
2491
|
+
mode: MetadataPersistenceMode;
|
|
2492
|
+
}
|
|
2493
|
+
| {
|
|
2494
|
+
/**
|
|
2495
|
+
* Emitted when a per-scope persistence override changes. `scopeId`
|
|
2496
|
+
* is `"*"` when `setAllScopesMetadataPersistence` fires the event.
|
|
2497
|
+
*/
|
|
2498
|
+
type: "scope_metadata_persistence_changed";
|
|
2499
|
+
documentId: string;
|
|
2500
|
+
scopeId: string;
|
|
2501
|
+
persistence: ScopeMetadataPersistence;
|
|
2502
|
+
}
|
|
2503
|
+
| {
|
|
2504
|
+
/**
|
|
2505
|
+
* Emitted when the editor detects divergence between the
|
|
2506
|
+
* docx-embedded value / version and the resolver-returned
|
|
2507
|
+
* value / version. Host resolves via `resolveMetadataConflict`.
|
|
2508
|
+
*/
|
|
2509
|
+
type: "metadata_conflict_detected";
|
|
2510
|
+
documentId: string;
|
|
2511
|
+
scopeId?: string;
|
|
2512
|
+
entryId?: string;
|
|
2513
|
+
fieldKey?: string;
|
|
2514
|
+
embedded: {
|
|
2515
|
+
value?: Record<string, unknown>;
|
|
2516
|
+
version?: number;
|
|
2517
|
+
} | null;
|
|
2518
|
+
external: {
|
|
2519
|
+
value?: Record<string, unknown>;
|
|
2520
|
+
version?: number;
|
|
2521
|
+
} | null;
|
|
2522
|
+
defaultPolicy: MetadataConflictPolicy;
|
|
2317
2523
|
};
|
|
2318
2524
|
|
|
2319
2525
|
export interface LoadResult {
|
|
@@ -2385,6 +2591,16 @@ export interface WordReviewEditorRef {
|
|
|
2385
2591
|
rejectChange(changeId: string): void;
|
|
2386
2592
|
acceptAllChanges(): void;
|
|
2387
2593
|
rejectAllChanges(): void;
|
|
2594
|
+
/**
|
|
2595
|
+
* R3 — scope-card-overlay P2. Accept every `changeId` attached to
|
|
2596
|
+
* the group's `suggestionIds` as a single logical action. The
|
|
2597
|
+
* runtime batches the individual `acceptChange` calls inside one
|
|
2598
|
+
* commit boundary so the group lands atomically. No-op when the
|
|
2599
|
+
* group id is not present in the current `SuggestionsSnapshot`.
|
|
2600
|
+
*/
|
|
2601
|
+
acceptSuggestionGroup(groupId: string): void;
|
|
2602
|
+
/** R3 — rejects every member of the group. */
|
|
2603
|
+
rejectSuggestionGroup(groupId: string): void;
|
|
2388
2604
|
exportDocx(options?: ExportDocxOptions): Promise<ExportResult>;
|
|
2389
2605
|
getSessionState(): EditorSessionState;
|
|
2390
2606
|
getSnapshot(): PersistedEditorSnapshot;
|
|
@@ -2495,6 +2711,62 @@ export interface WordReviewEditorRef {
|
|
|
2495
2711
|
setWorkflowMetadataEntries(entries: WorkflowMetadataEntry[]): void;
|
|
2496
2712
|
clearWorkflowMetadataEntries(): void;
|
|
2497
2713
|
getWorkflowMetadataSnapshot(): WorkflowMetadataSnapshot;
|
|
2714
|
+
/**
|
|
2715
|
+
* Schema 1.1 — set the overlay default for metadata persistence.
|
|
2716
|
+
* Author-only per collab-master-plan §7 role-gating matrix;
|
|
2717
|
+
* observers / reviewers receive `command_blocked` with
|
|
2718
|
+
* `collab_role_restricted`. Throws `MetadataResolverMissingError`
|
|
2719
|
+
* synchronously when called with `"external"` before a resolver has
|
|
2720
|
+
* been registered via `setScopeMetadataResolver`.
|
|
2721
|
+
*/
|
|
2722
|
+
setMetadataPersistenceMode(mode: MetadataPersistenceMode): void;
|
|
2723
|
+
getMetadataPersistenceMode(): MetadataPersistenceMode;
|
|
2724
|
+
/**
|
|
2725
|
+
* Toggle a single scope's persistence override. Reviewers may toggle
|
|
2726
|
+
* scopes they own (`workItemId` matches their active work item);
|
|
2727
|
+
* authors may toggle any scope.
|
|
2728
|
+
*/
|
|
2729
|
+
setScopeMetadataPersistence(
|
|
2730
|
+
scopeId: string,
|
|
2731
|
+
persistence: ScopeMetadataPersistence,
|
|
2732
|
+
): void;
|
|
2733
|
+
getScopeMetadataPersistence(scopeId: string): ScopeMetadataPersistence;
|
|
2734
|
+
/**
|
|
2735
|
+
* Bulk toggle — apply `persistence` to every scope in the active
|
|
2736
|
+
* overlay. Author-only. `"inherit"` clears all per-scope overrides so
|
|
2737
|
+
* scopes fall back to the overlay default.
|
|
2738
|
+
*/
|
|
2739
|
+
setAllScopesMetadataPersistence(persistence: ScopeMetadataPersistence): void;
|
|
2740
|
+
/**
|
|
2741
|
+
* Register (or clear) the host-supplied resolver. Must be set before
|
|
2742
|
+
* any external-mode operation; if absent, switching to `"external"`
|
|
2743
|
+
* throws `MetadataResolverMissingError` synchronously.
|
|
2744
|
+
*/
|
|
2745
|
+
setScopeMetadataResolver(resolver: ScopeMetadataResolver | null): void;
|
|
2746
|
+
/**
|
|
2747
|
+
* Resolve a pending `metadata_conflict_detected` event. The host
|
|
2748
|
+
* picks a `choice` and the editor writes the chosen value back
|
|
2749
|
+
* through the normal overlay-mutation path + re-sign.
|
|
2750
|
+
*/
|
|
2751
|
+
resolveMetadataConflict(input: ResolveMetadataConflictInput): void;
|
|
2752
|
+
/**
|
|
2753
|
+
* Migrate external-mode entries on the listed scopes back to
|
|
2754
|
+
* internal: for each entry / field whose effective persistence is
|
|
2755
|
+
* `"external"`, call `resolver.resolve(ref)`, inline the returned
|
|
2756
|
+
* value, clear `storageRef`, preserve `metadataVersion` as a hint.
|
|
2757
|
+
* Call this before exporting a docx outside the resolver's reach
|
|
2758
|
+
* (e.g., sending to an external supplier).
|
|
2759
|
+
*/
|
|
2760
|
+
convertScopesToInternal(scopeIds: string[]): Promise<void>;
|
|
2761
|
+
/**
|
|
2762
|
+
* Migrate internal-mode entries on the listed scopes to external:
|
|
2763
|
+
* for each entry / field whose effective persistence is
|
|
2764
|
+
* `"internal"`, call `resolver.publish(...)`, set `storageRef` +
|
|
2765
|
+
* `metadataVersion` from the return value, clear the inline body.
|
|
2766
|
+
* Throws `MetadataResolverMissingError` when no resolver is
|
|
2767
|
+
* registered.
|
|
2768
|
+
*/
|
|
2769
|
+
convertScopesToExternal(scopeIds: string[]): Promise<void>;
|
|
2498
2770
|
setHostAnnotationOverlay(overlay: HostAnnotationOverlay): void;
|
|
2499
2771
|
clearHostAnnotationOverlay(): void;
|
|
2500
2772
|
getHostAnnotationSnapshot(): HostAnnotationSnapshot;
|
|
@@ -2547,7 +2819,8 @@ export type WordReviewEditorChromePreset =
|
|
|
2547
2819
|
| "simple"
|
|
2548
2820
|
| "advanced"
|
|
2549
2821
|
| "review"
|
|
2550
|
-
| "workflow"
|
|
2822
|
+
| "workflow"
|
|
2823
|
+
| "collab";
|
|
2551
2824
|
|
|
2552
2825
|
export interface WordReviewEditorChromeOptions {
|
|
2553
2826
|
/**
|
|
@@ -2566,6 +2839,26 @@ export interface WordReviewEditorChromeOptions {
|
|
|
2566
2839
|
*/
|
|
2567
2840
|
showSectionTagAction: boolean;
|
|
2568
2841
|
showReviewRail: boolean;
|
|
2842
|
+
/**
|
|
2843
|
+
* Collab preset (P9a). When `true` the chrome mounts the collab
|
|
2844
|
+
* top nav: presence strip, role + audience chips, tamper banner,
|
|
2845
|
+
* negotiation action bar, and send-to-supplier button. Requires a
|
|
2846
|
+
* `CollabSession` to be wired via the host; the components are
|
|
2847
|
+
* defensive and render empty / disabled when the session is
|
|
2848
|
+
* absent or detached.
|
|
2849
|
+
*/
|
|
2850
|
+
showCollabTopNav?: boolean;
|
|
2851
|
+
/** Collab preset (P9b) — presence strip sub-visibility flag. */
|
|
2852
|
+
showCollabPresenceStrip?: boolean;
|
|
2853
|
+
/** Collab preset (P9c) — role + audience chips. */
|
|
2854
|
+
showCollabRoleChip?: boolean;
|
|
2855
|
+
showCollabAudienceChip?: boolean;
|
|
2856
|
+
/** Collab preset (P9d) — metadata-tamper banner. */
|
|
2857
|
+
showCollabTamperBanner?: boolean;
|
|
2858
|
+
/** Collab preset (P9e) — per-state negotiation action bar. */
|
|
2859
|
+
showCollabNegotiationActionBar?: boolean;
|
|
2860
|
+
/** Collab preset (P9f) — "Send to supplier" button + modal. */
|
|
2861
|
+
showCollabSendToSupplier?: boolean;
|
|
2569
2862
|
}
|
|
2570
2863
|
|
|
2571
2864
|
export interface WordReviewEditorProps {
|
|
@@ -2670,3 +2963,53 @@ export interface TextCommandAck {
|
|
|
2670
2963
|
/** Tag touches the runtime applied so the lane can redraw decorations without a PM rebuild. */
|
|
2671
2964
|
scopeTagTouches?: readonly ScopeTagTouch[];
|
|
2672
2965
|
}
|
|
2966
|
+
|
|
2967
|
+
// ---------------------------------------------------------------------------
|
|
2968
|
+
// Schema 1.1 — metadata-persistence conflict types (P17 Task 3b)
|
|
2969
|
+
// ---------------------------------------------------------------------------
|
|
2970
|
+
|
|
2971
|
+
/**
|
|
2972
|
+
* How the host wants `metadata_conflict_detected` events resolved by
|
|
2973
|
+
* default. `"prompt"` means the host handles each event manually
|
|
2974
|
+
* (e.g., show a dialog); the other three let the editor compute a
|
|
2975
|
+
* default choice and suggest it in the event's `defaultPolicy` field.
|
|
2976
|
+
*/
|
|
2977
|
+
export type MetadataConflictPolicy =
|
|
2978
|
+
| "prefer-embedded"
|
|
2979
|
+
| "prefer-external"
|
|
2980
|
+
| "prefer-latest"
|
|
2981
|
+
| "prompt";
|
|
2982
|
+
|
|
2983
|
+
/**
|
|
2984
|
+
* Input shape for `WordReviewEditorRef.resolveMetadataConflict`.
|
|
2985
|
+
* At least one of `scopeId` / `entryId` / `fieldKey` MUST be set — it
|
|
2986
|
+
* identifies which pending conflict to resolve. `choice` is the
|
|
2987
|
+
* host's final decision; `mergedValue` is only consulted when
|
|
2988
|
+
* `choice === "merge"`.
|
|
2989
|
+
*/
|
|
2990
|
+
export interface ResolveMetadataConflictInput {
|
|
2991
|
+
scopeId?: string;
|
|
2992
|
+
entryId?: string;
|
|
2993
|
+
fieldKey?: string;
|
|
2994
|
+
choice: "embedded" | "external" | "merge";
|
|
2995
|
+
mergedValue?: Record<string, unknown>;
|
|
2996
|
+
}
|
|
2997
|
+
|
|
2998
|
+
// ---------------------------------------------------------------------------
|
|
2999
|
+
// Schema 1.1 — metadata-persistence errors (P17)
|
|
3000
|
+
// ---------------------------------------------------------------------------
|
|
3001
|
+
|
|
3002
|
+
/**
|
|
3003
|
+
* Thrown synchronously when a caller switches to `"external"` persistence
|
|
3004
|
+
* mode before registering a host resolver via `setScopeMetadataResolver`.
|
|
3005
|
+
* Follows the fail-closed policy in collab-master-plan §1.6.
|
|
3006
|
+
*/
|
|
3007
|
+
export class MetadataResolverMissingError extends Error {
|
|
3008
|
+
constructor() {
|
|
3009
|
+
super(
|
|
3010
|
+
"setMetadataPersistenceMode('external') requires a resolver — call " +
|
|
3011
|
+
"setScopeMetadataResolver(...) first.",
|
|
3012
|
+
);
|
|
3013
|
+
this.name = "MetadataResolverMissingError";
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata persistence mode — overlay-level default.
|
|
3
|
+
*
|
|
4
|
+
* - `"internal"`: every entry / field is inlined in the bw:workflowPayload
|
|
5
|
+
* XML body. Self-contained docx; no host callback required.
|
|
6
|
+
* - `"external"`: entries / fields are stored by reference via a host-owned
|
|
7
|
+
* ScopeMetadataResolver; the docx carries only a `storageRef` string.
|
|
8
|
+
*
|
|
9
|
+
* Unknown values → preserve-only (spec §8.2). Readers must never silently
|
|
10
|
+
* coerce to a known value.
|
|
11
|
+
*/
|
|
12
|
+
export type MetadataPersistenceMode = "internal" | "external";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Per-scope / per-entry / per-field override. `"inherit"` defers to the
|
|
16
|
+
* parent (entry inherits scope; scope inherits overlay; overlay inherits
|
|
17
|
+
* the default `"internal"`).
|
|
18
|
+
*/
|
|
19
|
+
export type ScopeMetadataPersistence = "internal" | "external" | "inherit";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Opaque host-owned reference for externally-stored metadata values. The
|
|
23
|
+
* editor never parses this string — it is passed verbatim to the
|
|
24
|
+
* resolver. Host examples:
|
|
25
|
+
*
|
|
26
|
+
* "clm-workblock-row:wb-123:row-42:v-3"
|
|
27
|
+
* "https://rowstore.internal/metadata/abc"
|
|
28
|
+
* "s3://bucket/tenant-1/scope-metadata/e91a.json"
|
|
29
|
+
*/
|
|
30
|
+
export type ScopeMetadataStorageRef = string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Host-supplied resolver. The editor calls `resolve` whenever it needs
|
|
34
|
+
* the actual value of an external entry / field; it calls `publish` when
|
|
35
|
+
* toggling a scope / entry from `"internal"` to `"external"` and needs
|
|
36
|
+
* to hand the current inline value off to the host's store.
|
|
37
|
+
*
|
|
38
|
+
* All methods are async so the host can make network calls. An
|
|
39
|
+
* `undefined` return from `resolve` signals a missing or revoked ref;
|
|
40
|
+
* the editor surfaces this as a non-fatal warning and renders the entry
|
|
41
|
+
* as detached in the scope card. `undefined` (rather than `null`)
|
|
42
|
+
* matches the shipped `ExternalCustodyResolver.restore` convention (P7).
|
|
43
|
+
*
|
|
44
|
+
* `delete` is optional — hosts that don't need cleanup on toggle may
|
|
45
|
+
* omit it. The editor only calls it when transitioning a scope from
|
|
46
|
+
* `"external"` back to `"internal"` (hand the value back inline, then
|
|
47
|
+
* release the ref).
|
|
48
|
+
*/
|
|
49
|
+
export interface ScopeMetadataResolver {
|
|
50
|
+
/**
|
|
51
|
+
* Fetch the value for an opaque storageRef. Returns `undefined`
|
|
52
|
+
* when the ref is unknown or revoked — the editor surfaces this as
|
|
53
|
+
* a non-fatal warning and renders the entry as detached in the
|
|
54
|
+
* scope card. `version` (when present) is the rowstore's current
|
|
55
|
+
* version; the editor compares it against the docx's embedded
|
|
56
|
+
* `metadataVersion` hint and emits `metadata_conflict_detected` on
|
|
57
|
+
* mismatch. Matches the `ExternalCustodyResolver.restore`
|
|
58
|
+
* convention (P7) — prefer `undefined` over `null` for consistency.
|
|
59
|
+
*/
|
|
60
|
+
resolve(ref: ScopeMetadataStorageRef): Promise<
|
|
61
|
+
| { value: Record<string, unknown>; version?: number }
|
|
62
|
+
| undefined
|
|
63
|
+
>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Publish an inline value to the host store. `expectedVersion`
|
|
67
|
+
* (when set) enables optimistic concurrency: the host rejects the
|
|
68
|
+
* write if the stored row has advanced past the expected version,
|
|
69
|
+
* throwing a host-defined error that the editor surfaces via
|
|
70
|
+
* `metadata_conflict_detected`.
|
|
71
|
+
*
|
|
72
|
+
* Returns the opaque ref plus the version the store recorded for
|
|
73
|
+
* this write. The editor embeds this version on the XML element.
|
|
74
|
+
*/
|
|
75
|
+
publish(input: {
|
|
76
|
+
scopeId: string;
|
|
77
|
+
metadataId: string;
|
|
78
|
+
entryId?: string;
|
|
79
|
+
fieldKey?: string;
|
|
80
|
+
value: Record<string, unknown>;
|
|
81
|
+
expectedVersion?: number;
|
|
82
|
+
}): Promise<{
|
|
83
|
+
ref: ScopeMetadataStorageRef;
|
|
84
|
+
version: number;
|
|
85
|
+
}>;
|
|
86
|
+
|
|
87
|
+
delete?(ref: ScopeMetadataStorageRef): Promise<void>;
|
|
88
|
+
}
|
|
@@ -188,7 +188,7 @@ type ToggleFormattingMark =
|
|
|
188
188
|
| "strikethrough"
|
|
189
189
|
| "superscript"
|
|
190
190
|
| "subscript";
|
|
191
|
-
type FormattingOperation =
|
|
191
|
+
export type FormattingOperation =
|
|
192
192
|
| { type: "toggle"; mark: ToggleFormattingMark }
|
|
193
193
|
| { type: "set-font-family"; fontFamily: string | null }
|
|
194
194
|
| { type: "set-font-size"; size: number | null }
|