@beyondwork/docx-react-component 1.0.103 → 1.0.105

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 (45) hide show
  1. package/package.json +1 -1
  2. package/src/api/public-types.ts +66 -1
  3. package/src/api/v3/_runtime-handle.ts +2 -0
  4. package/src/api/v3/ai/_pe2-evidence.ts +153 -0
  5. package/src/api/v3/ai/bundle.ts +13 -5
  6. package/src/api/v3/ai/inspect.ts +7 -1
  7. package/src/api/v3/ai/outline.ts +2 -7
  8. package/src/api/v3/ai/replacement.ts +113 -0
  9. package/src/api/v3/runtime/geometry.ts +79 -0
  10. package/src/api/v3/ui/_types.ts +86 -0
  11. package/src/api/v3/ui/index.ts +5 -0
  12. package/src/api/v3/ui/overlays.ts +104 -0
  13. package/src/io/ooxml/parse-drawing.ts +99 -1
  14. package/src/io/ooxml/parse-fields.ts +27 -6
  15. package/src/io/ooxml/parse-shapes.ts +130 -0
  16. package/src/model/canonical-document.ts +34 -3
  17. package/src/model/canonical-layout-inputs.ts +979 -0
  18. package/src/model/layout/index.ts +9 -0
  19. package/src/model/layout/page-graph-types.ts +150 -0
  20. package/src/model/layout/runtime-page-graph-types.ts +23 -0
  21. package/src/runtime/collab/runtime-collab-sync.ts +3 -3
  22. package/src/runtime/debug/build-debug-inspector-snapshot.ts +17 -4
  23. package/src/runtime/document-runtime.ts +30 -14
  24. package/src/runtime/event-refresh-hints.ts +35 -5
  25. package/src/runtime/formatting/formatting-context.ts +110 -9
  26. package/src/runtime/formatting/index.ts +2 -0
  27. package/src/runtime/formatting/layout-inputs.ts +67 -3
  28. package/src/runtime/geometry/caret-geometry.ts +82 -10
  29. package/src/runtime/geometry/geometry-facet.ts +44 -0
  30. package/src/runtime/geometry/geometry-index.ts +1268 -0
  31. package/src/runtime/geometry/geometry-types.ts +227 -1
  32. package/src/runtime/geometry/index.ts +26 -0
  33. package/src/runtime/geometry/inert-geometry-facet.ts +3 -0
  34. package/src/runtime/geometry/object-handles.ts +7 -4
  35. package/src/runtime/geometry/replacement-envelope.ts +41 -2
  36. package/src/runtime/layout/layout-engine-instance.ts +2 -0
  37. package/src/runtime/layout/layout-engine-version.ts +44 -1
  38. package/src/runtime/layout/page-graph.ts +877 -2
  39. package/src/runtime/layout/project-block-fragments.ts +101 -1
  40. package/src/runtime/layout/public-facet.ts +152 -0
  41. package/src/runtime/prerender/graph-canonicalize.ts +44 -0
  42. package/src/runtime/surface-projection.ts +43 -3
  43. package/src/runtime/workflow/coordinator.ts +57 -11
  44. package/src/ui/ui-controller-factory.ts +11 -0
  45. package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +3 -0
@@ -62,6 +62,7 @@ import type {
62
62
  WorkflowMetadataDefinition,
63
63
  WorkflowMetadataEntry,
64
64
  WorkflowMetadataSnapshot,
65
+ WorkflowEventOrigin,
65
66
  WorkflowOverlay,
66
67
  WorkflowScope,
67
68
  WorkflowScopeGuardPolicy,
@@ -100,10 +101,8 @@ import {
100
101
  } from "./visibility-policy.ts";
101
102
  import { type WorkflowMarkupModePolicy } from "./markup-mode-policy.ts";
102
103
 
103
- /** Shape of origin metadata attached to commands. The runtime has a
104
- * richer `CommandOrigin` type; we only pass it through, so we keep an
105
- * open shape here to avoid coupling. */
106
- type CoordinatorCommandOrigin = { readonly source: string; readonly at?: string };
104
+ /** Shape of origin metadata attached to workflow commands/events. */
105
+ type CoordinatorCommandOrigin = WorkflowEventOrigin;
107
106
 
108
107
  /** Document-mutation commands the coordinator emits through `deps.dispatch`. */
109
108
  type CoordinatorDispatchedCommand =
@@ -157,10 +156,17 @@ export interface WorkflowEmittableEvent {
157
156
  readonly type:
158
157
  | "workflow_overlay_changed"
159
158
  | "workflow_active_work_item_changed"
160
- | "workflow_metadata_changed";
159
+ | "workflow_metadata_changed"
160
+ | "workflow_shared_state_changed"
161
+ | "workflow_visibility_policy_changed"
162
+ | "workflow_markup_mode_policy_changed";
161
163
  readonly documentId: string;
162
164
  readonly snapshot?: WorkflowScopeSnapshot | WorkflowMetadataSnapshot | null;
163
165
  readonly activeWorkItemId?: string | null;
166
+ readonly state?: SharedWorkflowState | null;
167
+ readonly kind?: OverlayKind;
168
+ readonly policy?: OverlayVisibilityPolicy | WorkflowMarkupModePolicy | null;
169
+ readonly origin?: CoordinatorCommandOrigin;
164
170
  }
165
171
 
166
172
  export interface PerfCounters {
@@ -276,7 +282,10 @@ export interface WorkflowCoordinator {
276
282
  * seam) so UI surfaces re-fire when policy changes mid-session. */
277
283
  subscribeMarkupModePolicy(listener: () => void): () => void;
278
284
  /* --- collab shared state --- */
279
- setSharedWorkflowState(state: SharedWorkflowState | null): void;
285
+ setSharedWorkflowState(
286
+ state: SharedWorkflowState | null,
287
+ origin?: CoordinatorCommandOrigin,
288
+ ): void;
280
289
  /* --- snapshots (cached) --- */
281
290
  getInteractionGuardSnapshot(): InteractionGuardSnapshot;
282
291
  getWorkflowScopeSnapshot(): WorkflowScopeSnapshot | null;
@@ -1133,12 +1142,21 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1133
1142
  return overlayStore.getMetadataSnapshot();
1134
1143
  }
1135
1144
 
1136
- function setSharedWorkflowState(state: SharedWorkflowState | null): void {
1145
+ function setSharedWorkflowState(
1146
+ state: SharedWorkflowState | null,
1147
+ origin: CoordinatorCommandOrigin = { source: "api", at: clock() },
1148
+ ): void {
1137
1149
  const prior = overlayStore.getSharedWorkflowState();
1138
1150
  if (state === prior) return;
1139
1151
  overlayStore.replaceSharedWorkflowState(state);
1140
1152
  cachedInteractionGuardSnapshot = undefined;
1141
1153
  cachedWorkflowScopeSnapshot = undefined;
1154
+ deps.emitEvent({
1155
+ type: "workflow_shared_state_changed",
1156
+ documentId: deps.getState().documentId,
1157
+ state,
1158
+ origin,
1159
+ });
1142
1160
  }
1143
1161
 
1144
1162
  function setScopeChromeVisibility(state: ScopeChromeVisibilityState): void {
@@ -1161,13 +1179,13 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1161
1179
 
1162
1180
  function setVisibilityPolicy(policy: OverlayVisibilityPolicy): boolean {
1163
1181
  const changed = overlayStore.replaceVisibilityPolicy(policy.kind, policy);
1164
- if (changed) emitVisibilityPolicyChanged();
1182
+ if (changed) emitVisibilityPolicyChanged(policy.kind, policy);
1165
1183
  return changed;
1166
1184
  }
1167
1185
 
1168
1186
  function clearVisibilityPolicy(kind: OverlayKind): boolean {
1169
1187
  const changed = overlayStore.replaceVisibilityPolicy(kind, null);
1170
- if (changed) emitVisibilityPolicyChanged();
1188
+ if (changed) emitVisibilityPolicyChanged(kind, null);
1171
1189
  return changed;
1172
1190
  }
1173
1191
 
@@ -1175,7 +1193,10 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1175
1193
  policies: readonly OverlayVisibilityPolicy[],
1176
1194
  ): boolean {
1177
1195
  const changed = overlayStore.replaceVisibilityPolicies(policies);
1178
- if (changed) emitVisibilityPolicyChanged();
1196
+ if (changed) emitVisibilityPolicyChanged(undefined, undefined, {
1197
+ source: "runtime",
1198
+ at: clock(),
1199
+ });
1179
1200
  return changed;
1180
1201
  }
1181
1202
 
@@ -1195,6 +1216,12 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1195
1216
  const changed = overlayStore.replaceMarkupModePolicy(policy);
1196
1217
  if (changed) {
1197
1218
  overlayStore.notifyMarkupModePolicyChanged();
1219
+ deps.emitEvent({
1220
+ type: "workflow_markup_mode_policy_changed",
1221
+ documentId: deps.getState().documentId,
1222
+ policy,
1223
+ origin: { source: "api", at: clock() },
1224
+ });
1198
1225
  if (deps.telemetryBus.isEnabled("scope")) {
1199
1226
  deps.telemetryBus.emit({
1200
1227
  channel: "scope",
@@ -1211,11 +1238,22 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1211
1238
  return overlayStore.subscribeMarkupModePolicy(listener);
1212
1239
  }
1213
1240
 
1214
- function emitVisibilityPolicyChanged(): void {
1241
+ function emitVisibilityPolicyChanged(
1242
+ kind?: OverlayKind,
1243
+ policy?: OverlayVisibilityPolicy | null,
1244
+ origin: CoordinatorCommandOrigin = { source: "api", at: clock() },
1245
+ ): void {
1215
1246
  // Notify direct subscribers first — L10 X3's ui.overlays.subscribeVisibility
1216
1247
  // chains onto this signal so UI surfaces re-fire when an authoring tool
1217
1248
  // mutates policy mid-session.
1218
1249
  overlayStore.notifyVisibilityPolicyChanged();
1250
+ deps.emitEvent({
1251
+ type: "workflow_visibility_policy_changed",
1252
+ documentId: deps.getState().documentId,
1253
+ ...(kind !== undefined ? { kind } : {}),
1254
+ ...(policy !== undefined ? { policy } : {}),
1255
+ origin,
1256
+ });
1219
1257
  if (!deps.telemetryBus.isEnabled("scope")) return;
1220
1258
  deps.telemetryBus.emit({
1221
1259
  channel: "scope",
@@ -1301,12 +1339,14 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1301
1339
  type: "workflow_overlay_changed",
1302
1340
  documentId,
1303
1341
  snapshot,
1342
+ origin: command.origin,
1304
1343
  });
1305
1344
  if (command.overlay.activeWorkItemId !== undefined) {
1306
1345
  deps.emitEvent({
1307
1346
  type: "workflow_active_work_item_changed",
1308
1347
  documentId,
1309
1348
  activeWorkItemId: command.overlay.activeWorkItemId ?? null,
1349
+ origin: command.origin,
1310
1350
  });
1311
1351
  }
1312
1352
  return warningDelta;
@@ -1323,6 +1363,7 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1323
1363
  type: "workflow_active_work_item_changed",
1324
1364
  documentId,
1325
1365
  activeWorkItemId: null,
1366
+ origin: command.origin,
1326
1367
  });
1327
1368
  deps.emitEvent({
1328
1369
  type: "workflow_overlay_changed",
@@ -1334,6 +1375,7 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1334
1375
  candidates: [],
1335
1376
  blockedReasons: [],
1336
1377
  },
1378
+ origin: command.origin,
1337
1379
  });
1338
1380
  return warningDelta;
1339
1381
  }
@@ -1343,6 +1385,7 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1343
1385
  type: "workflow_metadata_changed",
1344
1386
  documentId,
1345
1387
  snapshot: overlayStore.getMetadataSnapshot(),
1388
+ origin: command.origin,
1346
1389
  });
1347
1390
  return null;
1348
1391
  }
@@ -1352,6 +1395,7 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1352
1395
  type: "workflow_metadata_changed",
1353
1396
  documentId,
1354
1397
  snapshot: overlayStore.getMetadataSnapshot(),
1398
+ origin: command.origin,
1355
1399
  });
1356
1400
  return null;
1357
1401
  }
@@ -1361,6 +1405,7 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1361
1405
  type: "workflow_metadata_changed",
1362
1406
  documentId,
1363
1407
  snapshot: overlayStore.getMetadataSnapshot(),
1408
+ origin: command.origin,
1364
1409
  });
1365
1410
  return null;
1366
1411
  }
@@ -1370,6 +1415,7 @@ export function createWorkflowCoordinator(deps: CoordinatorDeps): WorkflowCoordi
1370
1415
  type: "workflow_metadata_changed",
1371
1416
  documentId,
1372
1417
  snapshot: overlayStore.getMetadataSnapshot(),
1418
+ origin: command.origin,
1373
1419
  });
1374
1420
  return null;
1375
1421
  }
@@ -54,6 +54,8 @@ import type {
54
54
  ChromePosture,
55
55
  GeometryRect,
56
56
  OverlayAnchorQuery,
57
+ UiOverlayLaneKind,
58
+ UiOverlayLaneSnapshot,
57
59
  UiController,
58
60
  UiControllerFactory,
59
61
  UiListener,
@@ -119,6 +121,13 @@ export interface ShellUiControllerDeps {
119
121
  readonly subscribeOverlays?: (
120
122
  listener: UiListener<OverlayAnchorQuery>,
121
123
  ) => UiUnsubscribe;
124
+ /** PE2 overlay-lane snapshot resolver. */
125
+ readonly getOverlayLane?: (kind: UiOverlayLaneKind) => UiOverlayLaneSnapshot;
126
+ /** PE2 overlay-lane subscription channel. */
127
+ readonly subscribeOverlayLane?: (
128
+ kind: UiOverlayLaneKind,
129
+ listener: UiListener<UiOverlayLaneSnapshot>,
130
+ ) => UiUnsubscribe;
122
131
  }
123
132
 
124
133
  /**
@@ -146,6 +155,8 @@ export function makeShellUiControllerFactory(
146
155
  ...(deps.getViewport ? { getViewport: deps.getViewport } : {}),
147
156
  ...(deps.subscribeViewport ? { subscribeViewport: deps.subscribeViewport } : {}),
148
157
  ...(deps.subscribeOverlays ? { subscribeOverlays: deps.subscribeOverlays } : {}),
158
+ ...(deps.getOverlayLane ? { getOverlayLane: deps.getOverlayLane } : {}),
159
+ ...(deps.subscribeOverlayLane ? { subscribeOverlayLane: deps.subscribeOverlayLane } : {}),
149
160
  };
150
161
  return controller;
151
162
  };
@@ -839,6 +839,7 @@ export const TwPageStackOverlayLayer: React.FC<TwPageStackOverlayLayerProps> = (
839
839
  null,
840
840
  );
841
841
  if (geometryRects !== null) {
842
+ incrementInvalidationCounter("overlay.page.geometry.hit");
842
843
  setRectsIfChanged(reconcilePaperRectsWithFlow(geometryRects, pageCount));
843
844
  return;
844
845
  }
@@ -854,6 +855,7 @@ export const TwPageStackOverlayLayer: React.FC<TwPageStackOverlayLayerProps> = (
854
855
  // above via `geometryFacet` or the UI-API resolver. Lines below
855
856
  // fire only before the first render frame.
856
857
  if (origin) {
858
+ incrementInvalidationCounter("overlay.page.dom.degraded");
857
859
  const widgets = measureWidgetsViaBoundingRect(scrollRoot, origin, {
858
860
  pageCount,
859
861
  visiblePageIndexRange: null,
@@ -870,6 +872,7 @@ export const TwPageStackOverlayLayer: React.FC<TwPageStackOverlayLayerProps> = (
870
872
  });
871
873
  setRectsIfChanged(reconcilePaperRectsWithFlow(domRects, pageCount));
872
874
  } else {
875
+ incrementInvalidationCounter("overlay.page.dom.degraded");
873
876
  const widgets = measureWidgetsViaOffsetChain(scrollRoot, {
874
877
  pageCount,
875
878
  visiblePageIndexRange: null,