@agent-native/core-corpus 0.216.0 → 0.217.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 (149) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +61 -1
  3. package/corpus/templates/analytics/AGENTS.md +1 -1
  4. package/corpus/templates/analytics/CHANGELOG.md +1 -0
  5. package/corpus/templates/analytics/actions/get-session-replay-summary.ts +9 -65
  6. package/corpus/templates/analytics/actions/list-event-catalog.ts +1 -1
  7. package/corpus/templates/analytics/actions/list-session-outputs.ts +40 -0
  8. package/corpus/templates/analytics/actions/list-session-recordings.ts +17 -4
  9. package/corpus/templates/analytics/actions/view-screen.ts +29 -3
  10. package/corpus/templates/analytics/app/i18n/en-US.ts +27 -0
  11. package/corpus/templates/analytics/app/pages/sessions/EventCatalogPage.tsx +18 -1
  12. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +3 -1
  13. package/corpus/templates/analytics/app/pages/sessions/SessionOutputs.tsx +197 -0
  14. package/corpus/templates/analytics/app/pages/sessions/SessionsTriagePage.tsx +114 -4
  15. package/corpus/templates/analytics/changelog/2026-10-15-sessions-can-find-people-who-made-a-slides-deck-but-didn-t-p.md +6 -0
  16. package/corpus/templates/analytics/changelog/2026-10-16-the-activation-funnel-counts-visitors-who-decline-analytics-.md +6 -0
  17. package/corpus/templates/analytics/server/db/schema.ts +67 -0
  18. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +9 -0
  19. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +28 -22
  20. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +36 -1
  21. package/corpus/templates/analytics/server/lib/output-outcomes.ts +712 -0
  22. package/corpus/templates/analytics/server/lib/replay-origins.ts +33 -0
  23. package/corpus/templates/analytics/server/lib/session-event-index.ts +20 -0
  24. package/corpus/templates/analytics/server/lib/session-performance.ts +6 -40
  25. package/corpus/templates/analytics/server/lib/session-recording-associations.ts +30 -1
  26. package/corpus/templates/analytics/server/lib/session-replay-triage.ts +99 -0
  27. package/corpus/templates/analytics/server/lib/session-replay.ts +45 -31
  28. package/corpus/templates/analytics/server/lib/sessions-triage-lab.ts +8 -2
  29. package/corpus/templates/analytics/server/plugins/db.ts +46 -0
  30. package/corpus/templates/analytics/shared/output-use.ts +205 -0
  31. package/corpus/templates/analytics/shared/session-events.ts +6 -0
  32. package/corpus/templates/calendar/CHANGELOG.md +6 -0
  33. package/corpus/templates/calendar/actions/create-event.ts +2 -4
  34. package/corpus/templates/calendar/actions/update-event.ts +35 -6
  35. package/corpus/templates/calendar/changelog/2026-10-21-solo-events-avoid-notification-approval.md +6 -0
  36. package/corpus/templates/community/qr/package.json +1 -1
  37. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +6 -3
  38. package/corpus/templates/content/CHANGELOG.md +8 -0
  39. package/corpus/templates/content/actions/_browser-document-save-attempt.ts +23 -1
  40. package/corpus/templates/content/actions/_builder-cms-blob-custody.ts +467 -0
  41. package/corpus/templates/content/actions/_builder-cms-execution-lease.ts +17 -0
  42. package/corpus/templates/content/actions/_builder-cms-intent-lookup.ts +5 -0
  43. package/corpus/templates/content/actions/_builder-cms-read-client.ts +881 -21
  44. package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +28 -2
  45. package/corpus/templates/content/actions/_builder-cms-write-client.ts +109 -11
  46. package/corpus/templates/content/actions/_builder-docs-client.ts +1 -0
  47. package/corpus/templates/content/actions/_builder-private-blob.test-fixture.ts +90 -0
  48. package/corpus/templates/content/actions/_builder-source-execution-guard.ts +48 -0
  49. package/corpus/templates/content/actions/_content-save-outcomes.ts +5 -0
  50. package/corpus/templates/content/actions/_database-source-utils.ts +290 -8
  51. package/corpus/templates/content/actions/_database-utils.ts +93 -7
  52. package/corpus/templates/content/actions/_database-view-setup.ts +21 -2
  53. package/corpus/templates/content/actions/_delete-content-space.ts +8 -1
  54. package/corpus/templates/content/actions/_github-source-freshness.ts +30 -4
  55. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +23 -6
  56. package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +110 -26
  57. package/corpus/templates/content/actions/change-content-database-source-role.ts +51 -7
  58. package/corpus/templates/content/actions/delete-document.ts +41 -3
  59. package/corpus/templates/content/actions/disconnect-content-database-source.ts +68 -2
  60. package/corpus/templates/content/actions/disconnect-local-folder-source.ts +33 -2
  61. package/corpus/templates/content/actions/execute-builder-source-execution.ts +900 -140
  62. package/corpus/templates/content/actions/get-document.ts +2 -0
  63. package/corpus/templates/content/actions/permanently-delete-document.ts +6 -0
  64. package/corpus/templates/content/actions/prepare-builder-source-execution.ts +155 -13
  65. package/corpus/templates/content/actions/prepare-builder-source-review.ts +299 -73
  66. package/corpus/templates/content/actions/set-live-body-switch.ts +45 -0
  67. package/corpus/templates/content/actions/update-document.ts +139 -20
  68. package/corpus/templates/content/actions/validate-builder-source-execution.ts +135 -26
  69. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +23 -0
  70. package/corpus/templates/content/app/components/editor/database/GitHubSourceStatusLine.tsx +27 -2
  71. package/corpus/templates/content/app/components/editor/database/ListItemLayout.tsx +32 -8
  72. package/corpus/templates/content/app/components/editor/database/ListItemRow.tsx +27 -2
  73. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +1 -0
  74. package/corpus/templates/content/app/hooks/use-content-database.ts +40 -2
  75. package/corpus/templates/content/app/hooks/use-documents.ts +14 -0
  76. package/corpus/templates/content/app/i18n-data.ts +1 -0
  77. package/corpus/templates/content/changelog/2026-10-17-builder-content-avoids-retrying-a-write-when-builder-accepte.md +6 -0
  78. package/corpus/templates/content/changelog/2026-10-18-link-a-new-collection-to-a-github-folder-from-its-sources.md +1 -1
  79. package/corpus/templates/content/changelog/2026-10-20-builder-content-sync-keeps-read-and-write-status-accurate-wh.md +6 -0
  80. package/corpus/templates/content/changelog/2026-10-21-list-rows-can-show-each-pages-first-lines.md +6 -0
  81. package/corpus/templates/content/changelog/2026-10-22-a-collection-linked-to-a-big-github-folder-fills-faster-and-p.md +6 -0
  82. package/corpus/templates/content/docs/product/capabilities/content.source.adapters.md +29 -0
  83. package/corpus/templates/content/parity/matrix.md +42 -42
  84. package/corpus/templates/content/parity/matrix.ts +3 -1
  85. package/corpus/templates/content/server/db/schema.ts +20 -0
  86. package/corpus/templates/content/server/lib/content-trash-purge.ts +15 -1
  87. package/corpus/templates/content/server/lib/live-body-writer.ts +138 -26
  88. package/corpus/templates/content/server/live-copy/binding.ts +31 -0
  89. package/corpus/templates/content/server/live-copy/bounded-task.d.ts +6 -0
  90. package/corpus/templates/content/server/live-copy/exec-db.ts +1 -0
  91. package/corpus/templates/content/server/live-copy/holds.ts +59 -0
  92. package/corpus/templates/content/server/live-copy/persist.ts +656 -0
  93. package/corpus/templates/content/server/live-copy/switch.ts +136 -0
  94. package/corpus/templates/content/server/live-copy/task-names.ts +4 -0
  95. package/corpus/templates/content/server/live-copy/tasks.ts +183 -0
  96. package/corpus/templates/content/server/live-copy/write-cause.ts +85 -0
  97. package/corpus/templates/content/server/live-copy/write.ts +85 -0
  98. package/corpus/templates/content/server/plugins/builder-private-payload-cleanup.ts +22 -0
  99. package/corpus/templates/content/server/plugins/collab.ts +3 -0
  100. package/corpus/templates/content/server/plugins/db.ts +28 -0
  101. package/corpus/templates/content/shared/api.ts +30 -1
  102. package/corpus/templates/content/shared/database-item-layout.ts +54 -22
  103. package/corpus/templates/content/shared/document-intent-merge.ts +16 -9
  104. package/corpus/templates/content/shared/og-description.ts +258 -36
  105. package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +5 -1
  106. package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +25 -4
  107. package/corpus/templates/design/CHANGELOG.md +2 -0
  108. package/corpus/templates/design/actions/get-getting-started.ts +53 -0
  109. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +10 -0
  110. package/corpus/templates/design/app/components/design/bridge/native-shader-runtime.bridge.ts +132 -79
  111. package/corpus/templates/design/app/components/design/bridge/native-source-provider.ts +268 -130
  112. package/corpus/templates/design/app/components/design/bridge/native-worker-scene-host.ts +122 -42
  113. package/corpus/templates/design/app/components/design/bridge/shader-runtime.bridge.ts +41 -4
  114. package/corpus/templates/design/app/components/design/design-canvas/text-content-change-result.ts +46 -12
  115. package/corpus/templates/design/app/components/home/DesignHomeLibrary.tsx +15 -8
  116. package/corpus/templates/design/app/components/layout/GettingStarted.tsx +50 -0
  117. package/corpus/templates/design/app/components/layout/Sidebar.tsx +3 -0
  118. package/corpus/templates/design/app/components/templates/DesignTemplateGrid.tsx +163 -0
  119. package/corpus/templates/design/app/components/templates/DesignTemplateLibrary.tsx +65 -78
  120. package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +6 -2
  121. package/corpus/templates/design/app/global.css +6 -0
  122. package/corpus/templates/design/app/i18n/en-US.ts +17 -0
  123. package/corpus/templates/design/app/lib/canvas-load-outcome.ts +147 -0
  124. package/corpus/templates/design/app/lib/canvas-outcome-tracking.ts +531 -0
  125. package/corpus/templates/design/app/lib/canvas-style-kind.ts +50 -0
  126. package/corpus/templates/design/app/pages/Index.tsx +10 -3
  127. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +86 -29
  128. package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +38 -3
  129. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-core.ts +9 -0
  130. package/corpus/templates/design/app/pages/design-editor/domains/use-editor-files-and-saving.ts +2 -0
  131. package/corpus/templates/design/changelog/2026-10-21-a-getting-started-checklist-at-the-bottom-of-the-sidebar-tra.md +6 -0
  132. package/corpus/templates/design/changelog/2026-10-21-templates-now-open-a-read-only-preview-from-the-card-and-the.md +6 -0
  133. package/corpus/templates/design/changelog/2026-10-22-collapsed-shader-layers-no-longer-interrupt-other-shaders-on.md +6 -0
  134. package/corpus/templates/design/changelog/2026-10-22-shader-fills-keep-rendering-when-other-screen-content-cannot.md +6 -0
  135. package/corpus/templates/design/scripts/design-export-validation/export-baseline.json +24 -0
  136. package/corpus/templates/design/server/lib/getting-started.ts +267 -0
  137. package/corpus/templates/design/server/plugins/getting-started.ts +5 -0
  138. package/corpus/templates/design/shared/design-template-presets/analytics-dashboard.ts +127 -0
  139. package/corpus/templates/design/shared/design-template-presets/design-studio.ts +98 -0
  140. package/corpus/templates/design/shared/design-template-presets/messaging-app.ts +101 -0
  141. package/corpus/templates/design/shared/design-template-presets/project-tasks.ts +120 -0
  142. package/corpus/templates/design/shared/design-template-presets.ts +8 -0
  143. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -1
  144. package/corpus/templates/slides/CHANGELOG.md +6 -0
  145. package/corpus/templates/slides/actions/delete-deck.ts +7 -0
  146. package/corpus/templates/slides/changelog/2026-10-21-connected-deck-deletion-requires-approval.md +6 -0
  147. package/corpus/templates/slides/scripts/edit-fidelity/client-action.ts +61 -0
  148. package/corpus/templates/slides/scripts/edit-fidelity/run.ts +10 -0
  149. package/package.json +1 -1
@@ -79,6 +79,7 @@ import {
79
79
  type ReviewFocusRequest,
80
80
  } from "@/components/visual-editor";
81
81
  import { sendToDesignAgentChatAndConfirm } from "@/lib/agent-chat";
82
+ import { useCanvasLoadOutcome } from "@/lib/canvas-load-outcome";
82
83
  import {
83
84
  resolveDesktopDesignSnapshotLayer,
84
85
  useDesktopDesignNativePreview,
@@ -2336,6 +2337,12 @@ export function DesignCanvas({
2336
2337
  const liveEditRestartAttemptRef = useRef(0);
2337
2338
  const liveEditSameInstanceElapsedMsRef = useRef(0);
2338
2339
  const liveEditSameInstanceDelayRef = useRef(LIVE_EDIT_READY_TIMEOUT_MS);
2340
+ // Snapshots and localhost or Fusion previews may never report ready; timing
2341
+ // them would count a missing bridge as a stalled load.
2342
+ const markCanvasLoadReady = useCanvasLoadOutcome({
2343
+ designId,
2344
+ measure: !snapshotOnly && (sourceType ?? "inline") === "inline",
2345
+ });
2339
2346
  const liveEditSameInstanceRearmTimerRef = useRef<number | undefined>(
2340
2347
  undefined,
2341
2348
  );
@@ -4614,6 +4621,7 @@ export function DesignCanvas({
4614
4621
  if (trustedCurrentFrame && !bridgeReadyRef.current) {
4615
4622
  bridgeReadyRef.current = true;
4616
4623
  onBridgeReady?.();
4624
+ markCanvasLoadReady();
4617
4625
  setReadyIframeDocumentIdentity(readyDocumentIdentity);
4618
4626
  flushPendingOneShotMessages();
4619
4627
  }
@@ -4741,6 +4749,7 @@ export function DesignCanvas({
4741
4749
  bridgeReadyRef.current = true;
4742
4750
  editorChromeReadyRef.current = true;
4743
4751
  onBridgeReady?.();
4752
+ markCanvasLoadReady();
4744
4753
  setReadyIframeDocumentIdentity(readyDocumentIdentity);
4745
4754
  if (shouldRefreshRuntimeLayerSnapshot) {
4746
4755
  refreshRuntimeLayerSnapshotAfterReady();
@@ -6225,6 +6234,7 @@ export function DesignCanvas({
6225
6234
  bridgeReadyRef.current = true;
6226
6235
  editorChromeReadyRef.current = true;
6227
6236
  onBridgeReady?.();
6237
+ markCanvasLoadReady();
6228
6238
  refreshRuntimeLayerSnapshotAfterReady();
6229
6239
  flushPendingOneShotMessages();
6230
6240
  }
@@ -367,6 +367,7 @@ import {
367
367
  import { NativeWorkerHostError } from "./native-worker-host";
368
368
  import {
369
369
  NativeWorkerSceneHost,
370
+ NativeWorkerSceneSourceError,
370
371
  type NativeWorkerSceneEntry,
371
372
  } from "./native-worker-scene-host";
372
373
 
@@ -1204,6 +1205,8 @@ class NativeShaderRuntime {
1204
1205
  private workerPreviewBase: EffectInstance | null = null;
1205
1206
  private legacyDraftSession = false;
1206
1207
  private workerCapabilityBlocked = false;
1208
+ private workerRootSourceBlocked = false;
1209
+ private workerSourceRetryTimer = 0;
1207
1210
  private workerRecoveryAttempts = 0;
1208
1211
  private workerRecoveryQueued = false;
1209
1212
  private cameraReportedState = "idle";
@@ -5201,6 +5204,88 @@ class NativeShaderRuntime {
5201
5204
  );
5202
5205
  }
5203
5206
 
5207
+ private hasWorkerPresentationToRetire(): boolean {
5208
+ return Boolean(
5209
+ this.retiringWorkerScene || this.mounts.size || this.scenePresentation,
5210
+ );
5211
+ }
5212
+
5213
+ private prepareWorkerSceneCommit(): void {
5214
+ if (this.retiringWorkerScene) {
5215
+ this.retiringWorkerScene.dispose({ preservePresentationState: true });
5216
+ this.retiringWorkerScene = null;
5217
+ }
5218
+ for (const [id, mount] of this.mounts) {
5219
+ this.unmount(mount);
5220
+ this.mounts.delete(id);
5221
+ }
5222
+ if (this.scenePresentation) this.releaseScenePresentation();
5223
+ }
5224
+
5225
+ private onWorkerSceneFailure = (error: Error): void => {
5226
+ const code =
5227
+ error instanceof NativeWorkerSceneSourceError
5228
+ ? error.captureFailure.code
5229
+ : error instanceof NativeSourceError ||
5230
+ error instanceof NativeWorkerHostError
5231
+ ? error.code
5232
+ : "worker-scene-failed";
5233
+ if (
5234
+ error instanceof NativeWorkerSceneSourceError ||
5235
+ [
5236
+ "worker-continuous-source-unsupported",
5237
+ "worker-unavailable",
5238
+ "gpu-unavailable",
5239
+ "canvas-unavailable",
5240
+ ].includes(code)
5241
+ ) {
5242
+ if (error instanceof NativeWorkerSceneSourceError) {
5243
+ this.workerRootSourceBlocked = true;
5244
+ clearTimeout(this.workerSourceRetryTimer);
5245
+ this.workerSourceRetryTimer = 0;
5246
+ } else this.workerCapabilityBlocked = true;
5247
+ queueMicrotask(() => this.requestScan());
5248
+ }
5249
+ if (
5250
+ [
5251
+ "gpu-device-lost",
5252
+ "gpu-uncaptured-error",
5253
+ "worker-failed",
5254
+ "worker-init-timeout",
5255
+ ].includes(code) &&
5256
+ this.workerRecoveryAttempts < 2 &&
5257
+ !this.workerRecoveryQueued
5258
+ ) {
5259
+ this.workerRecoveryAttempts += 1;
5260
+ this.workerRecoveryQueued = true;
5261
+ queueMicrotask(() => {
5262
+ const failed = this.workerScene;
5263
+ if (failed?.committedScene()) {
5264
+ this.retiringWorkerScene?.dispose();
5265
+ this.retiringWorkerScene = failed;
5266
+ failed.holdLastFrame();
5267
+ } else failed?.dispose();
5268
+ if (this.workerScene === failed) this.workerScene = null;
5269
+ this.workerRecoveryQueued = false;
5270
+ window.setTimeout(
5271
+ () => this.requestScan(),
5272
+ 100 * this.workerRecoveryAttempts,
5273
+ );
5274
+ });
5275
+ }
5276
+ this.issue(code, error.message);
5277
+ for (const entry of this.workerEntries) {
5278
+ const status = this.workerScene?.committedScene() ? "last-good" : "error";
5279
+ entry.target.setAttribute("data-an-native-status", status);
5280
+ entry.target.setAttribute("data-an-native-error", code);
5281
+ this.postStatus(entry.instance.id, entry.instance.nodeId, status, {
5282
+ code,
5283
+ message: error.message,
5284
+ instanceId: entry.instance.id,
5285
+ });
5286
+ }
5287
+ };
5288
+
5204
5289
  private scanOnce = async (): Promise<void> => {
5205
5290
  if (this.disposed) return;
5206
5291
  if (this.running) await this.running;
@@ -5549,6 +5634,7 @@ class NativeShaderRuntime {
5549
5634
  this.dynamicRangeRequested === "sdr" &&
5550
5635
  !this.legacyDraftSession &&
5551
5636
  !this.workerCapabilityBlocked &&
5637
+ !this.workerRootSourceBlocked &&
5552
5638
  !window.frameElement?.hasAttribute(
5553
5639
  "data-native-catalog-preview-renderer",
5554
5640
  ) &&
@@ -5597,20 +5683,6 @@ class NativeShaderRuntime {
5597
5683
  },
5598
5684
  (_publication, message) => {
5599
5685
  this.workerRecoveryAttempts = 0;
5600
- if (this.retiringWorkerScene) {
5601
- this.retiringWorkerScene.dispose({
5602
- preservePresentationState: true,
5603
- });
5604
- this.retiringWorkerScene = null;
5605
- }
5606
- if (this.mounts.size || this.scenePresentation) {
5607
- for (const [id, mount] of this.mounts) {
5608
- this.unmount(mount);
5609
- this.mounts.delete(id);
5610
- }
5611
- if (this.scenePresentation) this.releaseScenePresentation();
5612
- this.workerScene?.setEntries(this.workerEntries);
5613
- }
5614
5686
  if (message.contentChanged)
5615
5687
  for (const committed of message.committedInstances) {
5616
5688
  const entry = this.workerEntries.find(
@@ -5624,69 +5696,7 @@ class NativeShaderRuntime {
5624
5696
  );
5625
5697
  }
5626
5698
  },
5627
- (error) => {
5628
- const code =
5629
- error instanceof NativeSourceError ||
5630
- error instanceof NativeWorkerHostError
5631
- ? error.code
5632
- : "worker-scene-failed";
5633
- if (
5634
- [
5635
- "worker-continuous-source-unsupported",
5636
- "worker-unavailable",
5637
- "gpu-unavailable",
5638
- "canvas-unavailable",
5639
- ].includes(code)
5640
- ) {
5641
- this.workerCapabilityBlocked = true;
5642
- queueMicrotask(() => this.requestScan());
5643
- }
5644
- if (
5645
- [
5646
- "gpu-device-lost",
5647
- "gpu-uncaptured-error",
5648
- "worker-failed",
5649
- "worker-init-timeout",
5650
- ].includes(code) &&
5651
- this.workerRecoveryAttempts < 2 &&
5652
- !this.workerRecoveryQueued
5653
- ) {
5654
- this.workerRecoveryAttempts += 1;
5655
- this.workerRecoveryQueued = true;
5656
- queueMicrotask(() => {
5657
- const failed = this.workerScene;
5658
- if (failed?.committedScene()) {
5659
- this.retiringWorkerScene?.dispose();
5660
- this.retiringWorkerScene = failed;
5661
- failed.holdLastFrame();
5662
- } else failed?.dispose();
5663
- if (this.workerScene === failed) this.workerScene = null;
5664
- this.workerRecoveryQueued = false;
5665
- window.setTimeout(
5666
- () => this.requestScan(),
5667
- 100 * this.workerRecoveryAttempts,
5668
- );
5669
- });
5670
- }
5671
- this.issue(code, error.message);
5672
- for (const entry of this.workerEntries) {
5673
- const status = this.workerScene?.committedScene()
5674
- ? "last-good"
5675
- : "error";
5676
- entry.target.setAttribute("data-an-native-status", status);
5677
- entry.target.setAttribute("data-an-native-error", code);
5678
- this.postStatus(
5679
- entry.instance.id,
5680
- entry.instance.nodeId,
5681
- status,
5682
- {
5683
- code,
5684
- message: error.message,
5685
- instanceId: entry.instance.id,
5686
- },
5687
- );
5688
- }
5689
- },
5699
+ this.onWorkerSceneFailure,
5690
5700
  nativePresentationTargetLayout,
5691
5701
  () => {
5692
5702
  this.refreshPreviewViewport();
@@ -5706,6 +5716,8 @@ class NativeShaderRuntime {
5706
5716
  compact: this.previewPolicy.isOverviewCompact(),
5707
5717
  }),
5708
5718
  () => this.clockOrigin,
5719
+ () => this.hasWorkerPresentationToRetire(),
5720
+ () => this.prepareWorkerSceneCommit(),
5709
5721
  );
5710
5722
  this.workerScene.setVisible(
5711
5723
  document.visibilityState !== "hidden" &&
@@ -20540,6 +20552,30 @@ class NativeShaderRuntime {
20540
20552
  "composition-instance-stale",
20541
20553
  "The requested native scene differs from the worker preview.",
20542
20554
  );
20555
+ const committedScene = workerScene.committedScene();
20556
+ const presentedInstances = new Map(
20557
+ committedScene?.scene.instances.map((instance) => [
20558
+ instance.id,
20559
+ instance,
20560
+ ]),
20561
+ );
20562
+ if (
20563
+ !committedScene ||
20564
+ presentedInstances.size !== committedScene.scene.instances.length ||
20565
+ committedScene.scene.instances.some((instance) => {
20566
+ const current = this.workerEntries.find(
20567
+ (entry) => entry.instance.id === instance.id,
20568
+ );
20569
+ return (
20570
+ !current ||
20571
+ JSON.stringify(current.instance) !== JSON.stringify(instance)
20572
+ );
20573
+ })
20574
+ )
20575
+ throw new NativeSourceError(
20576
+ "composition-instance-stale",
20577
+ "The committed worker scene differs from its authored effects.",
20578
+ );
20543
20579
  const timeSeconds = this.currentTime();
20544
20580
  const exported = await workerScene.captureExportScene({
20545
20581
  cropRect: region.region,
@@ -20565,7 +20601,14 @@ class NativeShaderRuntime {
20565
20601
  ))) ||
20566
20602
  exported.width !== region.width ||
20567
20603
  exported.height !== region.height ||
20568
- exported.rgba.byteLength !== region.width * region.height * 4
20604
+ exported.rgba.byteLength !== region.width * region.height * 4 ||
20605
+ exported.committedInstances.length !== presentedInstances.size ||
20606
+ new Set(
20607
+ exported.committedInstances.map((instance) => instance.instanceId),
20608
+ ).size !== exported.committedInstances.length ||
20609
+ exported.committedInstances.some(
20610
+ (instance) => !presentedInstances.has(instance.instanceId),
20611
+ )
20569
20612
  )
20570
20613
  throw new NativeSourceError(
20571
20614
  "composition-preview-stale",
@@ -20604,7 +20647,7 @@ class NativeShaderRuntime {
20604
20647
  };
20605
20648
  }),
20606
20649
  );
20607
- if (committedInstances.length !== this.workerEntries.length)
20650
+ if (committedInstances.length !== presentedInstances.size)
20608
20651
  throw new NativeSourceError(
20609
20652
  "composition-instance-stale",
20610
20653
  "The worker still omitted a native effect.",
@@ -22674,6 +22717,15 @@ class NativeShaderRuntime {
22674
22717
  record.target !== this.runtimeScript &&
22675
22718
  !isNativeSourceOmittedMutation(record),
22676
22719
  );
22720
+ if (this.workerRootSourceBlocked && authoredRecords.length) {
22721
+ clearTimeout(this.workerSourceRetryTimer);
22722
+ this.workerSourceRetryTimer = window.setTimeout(() => {
22723
+ this.workerSourceRetryTimer = 0;
22724
+ if (this.disposed || !this.workerRootSourceBlocked) return;
22725
+ this.workerRootSourceBlocked = false;
22726
+ this.requestScan();
22727
+ }, 100);
22728
+ }
22677
22729
  if (this.compositionAbort && authoredRecords.length)
22678
22730
  this.compositionAbort.abort(
22679
22731
  new NativeSourceError(
@@ -22902,6 +22954,7 @@ class NativeShaderRuntime {
22902
22954
  this.previewHostParent = null;
22903
22955
  window.removeEventListener("message", this.onMessage);
22904
22956
  clearTimeout(this.rescanTimer);
22957
+ clearTimeout(this.workerSourceRetryTimer);
22905
22958
  clearTimeout(this.deviceRetryTimer);
22906
22959
  if (
22907
22960
  this.scenePresentation &&