@adminide-stack/yantra-mobile 12.0.129-alpha.0 → 12.0.129-alpha.1
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/lib/compute.js +57 -1
- package/lib/compute.js.map +1 -1
- package/lib/features/agent-chat/NativeAgentChat.js +3 -2
- package/lib/features/agent-chat/NativeAgentChat.js.map +1 -1
- package/lib/features/apps/AppsCatalog.js +10 -0
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/apps/mobileAppCatalog.js +11 -0
- package/lib/features/apps/mobileAppCatalog.js.map +1 -1
- package/lib/features/canvas/AudioEditorExperience.js +448 -105
- package/lib/features/canvas/AudioEditorExperience.js.map +1 -1
- package/lib/features/canvas/CanvasAgentChatPane.js +33 -14
- package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -1
- package/lib/features/canvas/CanvasBoardsGrid.js +493 -41
- package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
- package/lib/features/canvas/CanvasChatResultCard.js.map +1 -1
- package/lib/features/canvas/CanvasEditToolsPanel.js +37 -1
- package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -1
- package/lib/features/canvas/CanvasExperience.js +237 -22
- package/lib/features/canvas/CanvasExperience.js.map +1 -1
- package/lib/features/canvas/CanvasGeneratePanel.js +119 -26
- package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -1
- package/lib/features/canvas/CanvasLooksPanel.js +17 -6
- package/lib/features/canvas/CanvasLooksPanel.js.map +1 -1
- package/lib/features/canvas/CanvasTasksPanel.js +18 -1
- package/lib/features/canvas/CanvasTasksPanel.js.map +1 -1
- package/lib/features/canvas/DesignCategoryGallery.js +423 -0
- package/lib/features/canvas/DesignCategoryGallery.js.map +1 -0
- package/lib/features/canvas/ImageEditorExperience.js +763 -187
- package/lib/features/canvas/ImageEditorExperience.js.map +1 -1
- package/lib/features/canvas/SetStudioExperience.js +199 -11
- package/lib/features/canvas/SetStudioExperience.js.map +1 -1
- package/lib/features/canvas/VideoEditorExperience.js +59 -40
- package/lib/features/canvas/VideoEditorExperience.js.map +1 -1
- package/lib/features/canvas/VideoGeneratorExperience.js +134 -34
- package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -1
- package/lib/features/canvas/aiEdit.js +4 -2
- package/lib/features/canvas/aiEdit.js.map +1 -1
- package/lib/features/canvas/audioEditor/AudioWaveform.js +96 -0
- package/lib/features/canvas/audioEditor/AudioWaveform.js.map +1 -0
- package/lib/features/canvas/audioEditor/audioPeaks.js +93 -0
- package/lib/features/canvas/audioEditor/audioPeaks.js.map +1 -0
- package/lib/features/canvas/canvasTaskSync.js +34 -7
- package/lib/features/canvas/canvasTaskSync.js.map +1 -1
- package/lib/features/canvas/canvasTasks.js +23 -3
- package/lib/features/canvas/canvasTasks.js.map +1 -1
- package/lib/features/canvas/canvasTheme.js +10 -24
- package/lib/features/canvas/canvasTheme.js.map +1 -1
- package/lib/features/canvas/canvasUi.js +1 -1
- package/lib/features/canvas/canvasUi.js.map +1 -1
- package/lib/features/canvas/createTiles.js +17 -9
- package/lib/features/canvas/createTiles.js.map +1 -1
- package/lib/features/canvas/deepLinks.js +35 -5
- package/lib/features/canvas/deepLinks.js.map +1 -1
- package/lib/features/canvas/designCatalog.js +165 -0
- package/lib/features/canvas/designCatalog.js.map +1 -0
- package/lib/features/canvas/designCategories.js +262 -0
- package/lib/features/canvas/designCategories.js.map +1 -0
- package/lib/features/canvas/editorControls.js +406 -0
- package/lib/features/canvas/editorControls.js.map +1 -0
- package/lib/features/canvas/generationModels.js +5 -3
- package/lib/features/canvas/generationModels.js.map +1 -1
- package/lib/features/canvas/generationTasks.js +162 -0
- package/lib/features/canvas/generationTasks.js.map +1 -0
- package/lib/features/canvas/generator/BottomSheet.js +167 -0
- package/lib/features/canvas/generator/BottomSheet.js.map +1 -0
- package/lib/features/canvas/generator/BusinessCardChatCard.js +155 -0
- package/lib/features/canvas/generator/BusinessCardChatCard.js.map +1 -0
- package/lib/features/canvas/generator/DirectorSheet.js +163 -0
- package/lib/features/canvas/generator/DirectorSheet.js.map +1 -0
- package/lib/features/canvas/generator/ReframePreview.js +122 -0
- package/lib/features/canvas/generator/ReframePreview.js.map +1 -0
- package/lib/features/canvas/generator/RunLogCard.js +119 -0
- package/lib/features/canvas/generator/RunLogCard.js.map +1 -0
- package/lib/features/canvas/generator/ShotPanel.js +261 -0
- package/lib/features/canvas/generator/ShotPanel.js.map +1 -0
- package/lib/features/canvas/generator/businessCardWidget.js +117 -0
- package/lib/features/canvas/generator/businessCardWidget.js.map +1 -0
- package/lib/features/canvas/generator/cameraVocabulary.js +142 -0
- package/lib/features/canvas/generator/cameraVocabulary.js.map +1 -0
- package/lib/features/canvas/generator/cinematicVocabulary.js +416 -0
- package/lib/features/canvas/generator/cinematicVocabulary.js.map +1 -0
- package/lib/features/canvas/generator/direction.js +41 -0
- package/lib/features/canvas/generator/direction.js.map +1 -0
- package/lib/features/canvas/generator/reframeGeometry.js +108 -0
- package/lib/features/canvas/generator/reframeGeometry.js.map +1 -0
- package/lib/features/canvas/generator/runLog.js +71 -0
- package/lib/features/canvas/generator/runLog.js.map +1 -0
- package/lib/features/canvas/generator/shot.js +133 -0
- package/lib/features/canvas/generator/shot.js.map +1 -0
- package/lib/features/canvas/generator/useShotSpec.js +87 -0
- package/lib/features/canvas/generator/useShotSpec.js.map +1 -0
- package/lib/features/canvas/home/HeroComposer.js +214 -0
- package/lib/features/canvas/home/HeroComposer.js.map +1 -0
- package/lib/features/canvas/home/HeroMonitor.js +225 -0
- package/lib/features/canvas/home/HeroMonitor.js.map +1 -0
- package/lib/features/canvas/home/LookDetail.js +185 -0
- package/lib/features/canvas/home/LookDetail.js.map +1 -0
- package/lib/features/canvas/home/LoopingVideo.js +37 -0
- package/lib/features/canvas/home/LoopingVideo.js.map +1 -0
- package/lib/features/canvas/home/TemplatesGallery.js +253 -0
- package/lib/features/canvas/home/TemplatesGallery.js.map +1 -0
- package/lib/features/canvas/home/heroShots.js +100 -0
- package/lib/features/canvas/home/heroShots.js.map +1 -0
- package/lib/features/canvas/homeWork.js +62 -3
- package/lib/features/canvas/homeWork.js.map +1 -1
- package/lib/features/canvas/imageEditor/ImageMarkup.js +195 -0
- package/lib/features/canvas/imageEditor/ImageMarkup.js.map +1 -0
- package/lib/features/canvas/imageEditor/imageEditOps.js +367 -0
- package/lib/features/canvas/imageEditor/imageEditOps.js.map +1 -0
- package/lib/features/canvas/nativeViewerRegistry.js.map +1 -1
- package/lib/features/canvas/rankedCatalogSearch.js +375 -0
- package/lib/features/canvas/rankedCatalogSearch.js.map +1 -0
- package/lib/features/canvas/recorder/CameraRecorderExperience.js +68 -20
- package/lib/features/canvas/recorder/CameraRecorderExperience.js.map +1 -1
- package/lib/features/canvas/recorder/RecordingReview.js +272 -0
- package/lib/features/canvas/recorder/RecordingReview.js.map +1 -0
- package/lib/features/canvas/recorder/RecordingsList.js +179 -0
- package/lib/features/canvas/recorder/RecordingsList.js.map +1 -0
- package/lib/features/canvas/recorder/recorderOps.js +99 -0
- package/lib/features/canvas/recorder/recorderOps.js.map +1 -0
- package/lib/features/canvas/seedanceShowcase.js +314 -0
- package/lib/features/canvas/seedanceShowcase.js.map +1 -0
- package/lib/features/canvas/serverTasks.js +149 -15
- package/lib/features/canvas/serverTasks.js.map +1 -1
- package/lib/features/canvas/sessionRenewal.js +114 -0
- package/lib/features/canvas/sessionRenewal.js.map +1 -0
- package/lib/features/canvas/set/SetViewportWebView.js +34 -1
- package/lib/features/canvas/set/SetViewportWebView.js.map +1 -1
- package/lib/features/canvas/set/agent/setTurn.js +4 -2
- package/lib/features/canvas/set/agent/setTurn.js.map +1 -1
- package/lib/features/canvas/set/setPresets.js +85 -0
- package/lib/features/canvas/set/setPresets.js.map +1 -0
- package/lib/features/canvas/set/setProject.js +4 -1
- package/lib/features/canvas/set/setProject.js.map +1 -1
- package/lib/features/canvas/studioCatalog.js +59 -4
- package/lib/features/canvas/studioCatalog.js.map +1 -1
- package/lib/features/canvas/studioLooks.js +31 -4
- package/lib/features/canvas/studioLooks.js.map +1 -1
- package/lib/features/canvas/surfaceIndex.js +1 -14
- package/lib/features/canvas/surfaceIndex.js.map +1 -1
- package/lib/features/canvas/templateSearch.js +489 -0
- package/lib/features/canvas/templateSearch.js.map +1 -0
- package/lib/features/canvas/useCanvasSession.js +28 -6
- package/lib/features/canvas/useCanvasSession.js.map +1 -1
- package/lib/features/canvas/useStudioCatalogTemplates.js +41 -5
- package/lib/features/canvas/useStudioCatalogTemplates.js.map +1 -1
- package/lib/features/canvas/videoEditor/EditorPanels.js +531 -0
- package/lib/features/canvas/videoEditor/EditorPanels.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +48 -4
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/agentLoop.js +2 -0
- package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/brainClient.js +97 -27
- package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/cutTools.js +707 -3
- package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -1
- package/lib/features/canvas/videoEditor/audioServices.js +165 -0
- package/lib/features/canvas/videoEditor/audioServices.js.map +1 -0
- package/lib/features/canvas/videoEditor/captions.js +144 -0
- package/lib/features/canvas/videoEditor/captions.js.map +1 -0
- package/lib/features/canvas/videoEditor/compileTimeline.js +24 -16
- package/lib/features/canvas/videoEditor/compileTimeline.js.map +1 -1
- package/lib/features/canvas/videoEditor/editorModel.js +12 -2
- package/lib/features/canvas/videoEditor/editorModel.js.map +1 -1
- package/lib/features/canvas/videoEditor/exportTask.js +89 -7
- package/lib/features/canvas/videoEditor/exportTask.js.map +1 -1
- package/lib/features/canvas/videoEditor/layers.js +117 -0
- package/lib/features/canvas/videoEditor/layers.js.map +1 -0
- package/lib/features/canvas/videoEditor/remoteMediaClient.js +45 -18
- package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -1
- package/lib/features/canvas/videoEditor/renderTimeline.js +18 -6
- package/lib/features/canvas/videoEditor/renderTimeline.js.map +1 -1
- package/lib/features/canvas/videoEditor/revoice.js +138 -0
- package/lib/features/canvas/videoEditor/revoice.js.map +1 -0
- package/lib/features/canvas/videoEditor/storageUpload.js +34 -0
- package/lib/features/canvas/videoEditor/storageUpload.js.map +1 -0
- package/lib/features/canvas/videoEditor/textMotion.js +109 -0
- package/lib/features/canvas/videoEditor/textMotion.js.map +1 -0
- package/lib/features/canvas/videoEditor/transitions.js +31 -0
- package/lib/features/canvas/videoEditor/transitions.js.map +1 -0
- package/lib/features/chat/TemplatesChatCards.js +8 -3
- package/lib/features/chat/TemplatesChatCards.js.map +1 -1
- package/lib/features/design/DesignEditorExperience.js +674 -644
- package/lib/features/design/DesignEditorExperience.js.map +1 -1
- package/lib/features/design/DesignExperience.js +285 -538
- package/lib/features/design/DesignExperience.js.map +1 -1
- package/lib/features/design/designCore.js +2 -212
- package/lib/features/design/designCore.js.map +1 -1
- package/lib/features/design/designIndex.js +1 -50
- package/lib/features/design/designIndex.js.map +1 -1
- package/lib/features/design/doc/aiDesign.js +247 -0
- package/lib/features/design/doc/aiDesign.js.map +1 -0
- package/lib/features/design/doc/artifacts.js +280 -0
- package/lib/features/design/doc/artifacts.js.map +1 -0
- package/lib/features/design/doc/chart.js +98 -0
- package/lib/features/design/doc/chart.js.map +1 -0
- package/lib/features/design/doc/crop.js +104 -0
- package/lib/features/design/doc/crop.js.map +1 -0
- package/lib/features/design/doc/curve.js +49 -0
- package/lib/features/design/doc/curve.js.map +1 -0
- package/lib/features/design/doc/docOps.js +397 -0
- package/lib/features/design/doc/docOps.js.map +1 -0
- package/lib/features/design/doc/findReplace.js +112 -0
- package/lib/features/design/doc/findReplace.js.map +1 -0
- package/lib/features/design/doc/fonts.js +79 -0
- package/lib/features/design/doc/fonts.js.map +1 -0
- package/lib/features/design/doc/frames.js +17 -0
- package/lib/features/design/doc/frames.js.map +1 -0
- package/lib/features/design/doc/geometry.js +133 -0
- package/lib/features/design/doc/geometry.js.map +1 -0
- package/lib/features/design/doc/imageAdjust.js +203 -0
- package/lib/features/design/doc/imageAdjust.js.map +1 -0
- package/lib/features/design/doc/legacyDoc.js +107 -0
- package/lib/features/design/doc/legacyDoc.js.map +1 -0
- package/lib/features/design/doc/newDoc.js +335 -0
- package/lib/features/design/doc/newDoc.js.map +1 -0
- package/lib/features/design/doc/pageRange.js +17 -0
- package/lib/features/design/doc/pageRange.js.map +1 -0
- package/lib/features/design/doc/pathScale.js +68 -0
- package/lib/features/design/doc/pathScale.js.map +1 -0
- package/lib/features/design/doc/qr.js +62 -0
- package/lib/features/design/doc/qr.js.map +1 -0
- package/lib/features/design/doc/shapes.js +366 -0
- package/lib/features/design/doc/shapes.js.map +1 -0
- package/lib/features/design/doc/sizes.js +230 -0
- package/lib/features/design/doc/sizes.js.map +1 -0
- package/lib/features/design/doc/textEffects.js +134 -0
- package/lib/features/design/doc/textEffects.js.map +1 -0
- package/lib/features/design/doc/textLayout.js +182 -0
- package/lib/features/design/doc/textLayout.js.map +1 -0
- package/lib/features/design/doc/types.js +30 -0
- package/lib/features/design/doc/types.js.map +1 -0
- package/lib/features/design/editor/AiPanel.js +194 -0
- package/lib/features/design/editor/AiPanel.js.map +1 -0
- package/lib/features/design/editor/ChartDataPanel.js +182 -0
- package/lib/features/design/editor/ChartDataPanel.js.map +1 -0
- package/lib/features/design/editor/CropOverlay.js +199 -0
- package/lib/features/design/editor/CropOverlay.js.map +1 -0
- package/lib/features/design/editor/DesignCanvas.js +363 -0
- package/lib/features/design/editor/DesignCanvas.js.map +1 -0
- package/lib/features/design/editor/ExportSheet.js +123 -0
- package/lib/features/design/editor/ExportSheet.js.map +1 -0
- package/lib/features/design/editor/FindReplacePanel.js +93 -0
- package/lib/features/design/editor/FindReplacePanel.js.map +1 -0
- package/lib/features/design/editor/ImageTools.js +188 -0
- package/lib/features/design/editor/ImageTools.js.map +1 -0
- package/lib/features/design/editor/LayerTools.js +485 -0
- package/lib/features/design/editor/LayerTools.js.map +1 -0
- package/lib/features/design/editor/PageStrip.js +203 -0
- package/lib/features/design/editor/PageStrip.js.map +1 -0
- package/lib/features/design/editor/Slideshow.js +97 -0
- package/lib/features/design/editor/Slideshow.js.map +1 -0
- package/lib/features/design/editor/ToolPanels.js +695 -0
- package/lib/features/design/editor/ToolPanels.js.map +1 -0
- package/lib/features/design/editor/controls.js +630 -0
- package/lib/features/design/editor/controls.js.map +1 -0
- package/lib/features/design/editor/useDesignSave.js +91 -0
- package/lib/features/design/editor/useDesignSave.js.map +1 -0
- package/lib/features/design/export/exportDesign.js +170 -0
- package/lib/features/design/export/exportDesign.js.map +1 -0
- package/lib/features/design/export/pdf.js +143 -0
- package/lib/features/design/export/pdf.js.map +1 -0
- package/lib/features/design/home/DesignHome.js +688 -0
- package/lib/features/design/home/DesignHome.js.map +1 -0
- package/lib/features/design/home/studioHome.js +61 -0
- package/lib/features/design/home/studioHome.js.map +1 -0
- package/lib/features/design/pickDesignImage.js +60 -0
- package/lib/features/design/pickDesignImage.js.map +1 -0
- package/lib/features/design/render/DesignPageView.js +69 -0
- package/lib/features/design/render/DesignPageView.js.map +1 -0
- package/lib/features/design/render/PageCapture.js +288 -0
- package/lib/features/design/render/PageCapture.js.map +1 -0
- package/lib/features/design/render/TextMeasure.js +115 -0
- package/lib/features/design/render/TextMeasure.js.map +1 -0
- package/lib/features/design/render/fontRegistry.js +110 -0
- package/lib/features/design/render/fontRegistry.js.map +1 -0
- package/lib/features/design/render/layers.js +392 -0
- package/lib/features/design/render/layers.js.map +1 -0
- package/lib/features/design/render/svg.js +35 -0
- package/lib/features/design/render/svg.js.map +1 -0
- package/lib/features/design/render/svgParts.js +435 -0
- package/lib/features/design/render/svgParts.js.map +1 -0
- package/lib/features/design/surface/BoardScreen.js +529 -0
- package/lib/features/design/surface/BoardScreen.js.map +1 -0
- package/lib/features/design/surface/CompareView.js +138 -0
- package/lib/features/design/surface/CompareView.js.map +1 -0
- package/lib/features/design/surface/CreationScreen.js +294 -0
- package/lib/features/design/surface/CreationScreen.js.map +1 -0
- package/lib/features/design/surface/DesignAgentChatPane.js +444 -0
- package/lib/features/design/surface/DesignAgentChatPane.js.map +1 -0
- package/lib/features/design/surface/DesignBoards.js +441 -0
- package/lib/features/design/surface/DesignBoards.js.map +1 -0
- package/lib/features/design/surface/DesignPreview.js +159 -0
- package/lib/features/design/surface/DesignPreview.js.map +1 -0
- package/lib/features/design/surface/DesignSurfaceExperience.js +80 -0
- package/lib/features/design/surface/DesignSurfaceExperience.js.map +1 -0
- package/lib/features/design/surface/FullScreenPreview.js +59 -0
- package/lib/features/design/surface/FullScreenPreview.js.map +1 -0
- package/lib/features/design/surface/NewSystemDialog.js +122 -0
- package/lib/features/design/surface/NewSystemDialog.js.map +1 -0
- package/lib/features/design/surface/PickerSheet.js +175 -0
- package/lib/features/design/surface/PickerSheet.js.map +1 -0
- package/lib/features/design/surface/TemplatesGallery.js +156 -0
- package/lib/features/design/surface/TemplatesGallery.js.map +1 -0
- package/lib/features/design/surface/WetPaint.js +140 -0
- package/lib/features/design/surface/WetPaint.js.map +1 -0
- package/lib/features/design/surface/agentTurn.js +229 -0
- package/lib/features/design/surface/agentTurn.js.map +1 -0
- package/lib/features/design/surface/designBoard.js +218 -0
- package/lib/features/design/surface/designBoard.js.map +1 -0
- package/lib/features/design/surface/designChannel.js +186 -0
- package/lib/features/design/surface/designChannel.js.map +1 -0
- package/lib/features/design/surface/designChat.js +141 -0
- package/lib/features/design/surface/designChat.js.map +1 -0
- package/lib/features/design/surface/designConnector.js +266 -0
- package/lib/features/design/surface/designConnector.js.map +1 -0
- package/lib/features/design/surface/designDocument.js +40 -0
- package/lib/features/design/surface/designDocument.js.map +1 -0
- package/lib/features/design/surface/designExport.js +55 -0
- package/lib/features/design/surface/designExport.js.map +1 -0
- package/lib/features/design/surface/designLinks.js +64 -0
- package/lib/features/design/surface/designLinks.js.map +1 -0
- package/lib/features/design/surface/designPalette.js +24 -0
- package/lib/features/design/surface/designPalette.js.map +1 -0
- package/lib/features/design/surface/designRun.js +161 -0
- package/lib/features/design/surface/designRun.js.map +1 -0
- package/lib/features/design/surface/designTheme.js +119 -0
- package/lib/features/design/surface/designTheme.js.map +1 -0
- package/lib/features/design/surface/execStream.js +206 -0
- package/lib/features/design/surface/execStream.js.map +1 -0
- package/lib/features/design/surface/metaball.js +48 -0
- package/lib/features/design/surface/metaball.js.map +1 -0
- package/lib/features/design/surface/pickReferenceFiles.js +35 -0
- package/lib/features/design/surface/pickReferenceFiles.js.map +1 -0
- package/lib/features/design/surface/useDesignSurface.js +379 -0
- package/lib/features/design/surface/useDesignSurface.js.map +1 -0
- package/lib/features/docs/DocBlockRow.js +336 -0
- package/lib/features/docs/DocBlockRow.js.map +1 -0
- package/lib/features/docs/DocsEditorExperience.js +949 -0
- package/lib/features/docs/DocsEditorExperience.js.map +1 -0
- package/lib/features/docs/DocsToolbar.js +247 -0
- package/lib/features/docs/DocsToolbar.js.map +1 -0
- package/lib/features/docs/blocks.js +560 -0
- package/lib/features/docs/blocks.js.map +1 -0
- package/lib/features/docs/docArtifacts.js +129 -0
- package/lib/features/docs/docArtifacts.js.map +1 -0
- package/lib/features/docs/docEdits.js +201 -0
- package/lib/features/docs/docEdits.js.map +1 -0
- package/lib/features/docs/docExport.js +235 -0
- package/lib/features/docs/docExport.js.map +1 -0
- package/lib/features/docs/docShare.js +62 -0
- package/lib/features/docs/docShare.js.map +1 -0
- package/lib/features/links/openInApp.js +38 -2
- package/lib/features/links/openInApp.js.map +1 -1
- package/lib/routes.json +54 -0
- package/lib/screens/DesignNative/index.js +35 -0
- package/lib/screens/DesignNative/index.js.map +1 -0
- package/package.json +3 -3
- package/lib/features/design/exportDesign.js +0 -133
- package/lib/features/design/exportDesign.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverTasks.js","sources":["../../../src/features/canvas/serverTasks.ts"],"sourcesContent":["/**\n * Server-backed canvas tasks - native twin of surface-kit `tasks/serverJob`,\n * `tasks/remoteTasks`, `tasks/remoteRecord` and canvas `tasks/serverJobs`.\n *\n * A job is recorded on the Task API BEFORE its work is submitted, so the cdecli\n * agent that runs the work can report progress, the verdict and the result to\n * that row - and the result lands whether or not this phone is still open.\n * The exec request carries `job` ({@link SurfaceJobRef}); an older agent\n * ignores the field and the phone follows the work itself, as it always did.\n *\n * Rows are owner-scoped (`getSurfaceJobs` / `getSurfaceJob` answer with the\n * caller's own jobs), keyed `canvas:<local id>` exactly like the web canvas's,\n * so a run started on the web shows here and one started here shows there.\n *\n * Transport: the canvas session token (the surface JWT) against the backend\n * GraphQL the index URL names (`deriveBackendGraphqlUrl`). The report token\n * lives in memory only - never in AsyncStorage.\n *\n * Every call degrades: no session, an older backend (\"Cannot query field\"),\n * or no answer within two seconds, and the run goes out exactly as before.\n */\nimport type { CanvasTask } from './canvasTasks';\nimport {\n PRODUCE_STATUS_ACTION,\n PROMO_CONNECTOR,\n PROMO_POLL_EVERY_MS,\n promoRunTimeoutMs,\n type PromoRunOptions,\n} from './promoVideo';\nimport type { MediaConnector, RunMediaAction } from './videoEditor/mediaActions';\nimport {\n deriveBackendGraphqlUrl,\n runActionAcceptsJob,\n type RunMediaActionWithBody,\n} from './videoEditor/remoteMediaClient';\nimport { tokenClaims } from './sessionIdentity';\n\nexport const CANVAS_SURFACE = 'canvas';\nexport const PROMO_LANE = 'promo';\nexport const EXPORT_LANE = 'video-export';\nexport const LIPSYNC_LANE = 'lipsync';\nexport const SURFACE_JOB_KIND = 'surface-job';\n\n// ── The record ───────────────────────────────────────────────────────────────\n\nexport type JobState = 'running' | 'succeeded' | 'failed';\nexport type JobVerdictBy = 'agent' | 'browser' | 'deadline';\n\nexport interface JobStage {\n label: string;\n index: number;\n total: number;\n detail?: string;\n}\n\nexport interface JobResult {\n url: string;\n kind: 'image' | 'video' | 'audio' | 'text';\n title?: string;\n}\n\nexport interface JobInput {\n prompt?: string;\n model?: string;\n aspectRatio?: string;\n references?: string[];\n connector?: string;\n action?: string;\n params?: Record<string, unknown>;\n}\n\n/** A job as every store can express it, and as the Tasks panel reads it. */\nexport interface JobRecord {\n id: string;\n surface: string;\n lane: string;\n title: string;\n brief: string;\n state: JobState;\n createdAt: number;\n startedAt?: number;\n endedAt?: number;\n progress?: string;\n stage?: JobStage;\n results?: JobResult[];\n error?: string;\n delivered?: boolean;\n owner?: string;\n pageUrl?: string;\n input?: JobInput;\n handle?: Record<string, unknown>;\n remoteId?: string;\n deadlineAt?: number;\n agentOwned?: boolean;\n verdictBy?: JobVerdictBy;\n result?: unknown;\n hasResult?: boolean;\n resultUrl?: string;\n updatedAt?: number;\n}\n\n/** The server sweep's word for a job that ran past its deadline with nothing reporting on it. */\nexport const DEADLINE_VERDICT_ERROR = 'Stopped responding before it finished';\n/** Added to every lane's budget for its deadline. */\nexport const JOB_DEADLINE_GRACE_MS = 10 * 60_000;\n/** How long a handed-over job may go without the agent reporting before the phone follows it itself. */\nexport const AGENT_OWNED_GRACE_MS = 2 * 60_000;\n/** How long a job may wait on its own record before it is submitted without one. */\nexport const SERVER_JOB_BUDGET_MS = 2_000;\n/** A row recorded before deadlines existed reads as stale a day after it was created. */\nexport const LEGACY_JOB_DEADLINE_MS = 24 * 60 * 60_000;\n/** Lip sync: speech, then a provider queue measured at four minutes; the agent follows it for fifteen. */\nexport const LIPSYNC_BUDGET_MS = 15 * 60_000;\n\nexport const jobDeadlineAt = (startedAt: number, budgetMs: number): number =>\n startedAt + budgetMs + JOB_DEADLINE_GRACE_MS;\nexport const jobKey = (job: Pick<JobRecord, 'surface' | 'id'>): string => `${job.surface}:${job.id}`;\nexport const canvasJobKey = (localId: string): string => `${CANVAS_SURFACE}:${localId}`;\n\nexport function jobDeadline(job: Pick<JobRecord, 'deadlineAt' | 'createdAt'>): number {\n return job.deadlineAt ?? job.createdAt + LEGACY_JOB_DEADLINE_MS;\n}\n\n/** Running past its deadline: nothing is going to settle it any more. */\nexport function isStaleJob(job: Pick<JobRecord, 'state' | 'deadlineAt' | 'createdAt'>, now = Date.now()): boolean {\n return job.state === 'running' && now > jobDeadline(job);\n}\n\n/** Failed by the server's deadline sweep. */\nexport const isDeadlineVerdict = (record: { state: string; verdictBy?: string }): boolean =>\n record.state === 'failed' && record.verdictBy === 'deadline';\n\n/** The board a job's result belongs on, when its surface recorded one. */\nexport function jobBoardId(job: Pick<JobRecord, 'handle'>): string | undefined {\n const handle = job.handle;\n if (!handle) return undefined;\n if (typeof handle.boardId === 'string' && handle.boardId) return handle.boardId;\n return handle.kind === 'channel' && typeof handle.channelId === 'string' && handle.channelId\n ? handle.channelId\n : undefined;\n}\n\n/** A stable 24-hex ObjectId from a key (three FNV-1a passes) - identical to the kit's, so rows line up. */\nexport function objectIdFromKey(key: string): string {\n const fnv = (seed: number): string => {\n let h = seed >>> 0;\n for (let i = 0; i < key.length; i += 1) {\n h ^= key.charCodeAt(i);\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n return h.toString(16).padStart(8, '0');\n };\n return fnv(0x811c9dc5) + fnv(0x9747b28c) + fnv(0x5bd1e995);\n}\n\nconst isWebUrl = (value: unknown): value is string => typeof value === 'string' && /^https?:\\/\\//i.test(value);\nconst WIRE_FIELD_MAX_CHARS = 16 * 1024;\nconst fits = (value: unknown): boolean => {\n try {\n return JSON.stringify(value).length <= WIRE_FIELD_MAX_CHARS;\n } catch {\n return false;\n }\n};\n\n/** The job as a client may write it: no server/agent-owned fields, web URLs only, bounded input. */\nexport function browserDetails(job: JobRecord): Record<string, unknown> {\n const {\n remoteId: _remoteId,\n agentOwned: _agentOwned,\n verdictBy: _verdictBy,\n result: _result,\n hasResult: _hasResult,\n resultUrl: _resultUrl,\n updatedAt: _updatedAt,\n results,\n pageUrl,\n input,\n handle,\n ...rest\n } = job;\n const webResults = results?.filter((r) => isWebUrl(r.url)).slice(0, 50);\n const keptInput = input\n ? fits(input)\n ? input\n : input.prompt\n ? { prompt: input.prompt.slice(0, 4_000) }\n : undefined\n : undefined;\n return {\n ...rest,\n ...(webResults?.length ? { results: webResults } : {}),\n ...(isWebUrl(pageUrl) ? { pageUrl } : {}),\n ...(keptInput ? { input: keptInput } : {}),\n ...(handle && fits(handle) ? { handle } : {}),\n };\n}\n\n/** What the panels render of a job, so an unchanged reading sends nothing. */\nexport function jobFingerprint(job: JobRecord): string {\n return JSON.stringify([\n job.state,\n job.title,\n job.brief,\n job.progress ?? '',\n job.stage ? [job.stage.index, job.stage.total, job.stage.label, job.stage.detail ?? ''] : null,\n job.results ?? [],\n job.error ?? '',\n job.delivered ?? false,\n job.startedAt ?? 0,\n job.endedAt ?? 0,\n ]);\n}\n\n/** The subset of a `Task` row the reader needs. */\nexport interface RemoteTaskRow {\n id?: string | null;\n title?: string | null;\n description?: string | null;\n status?: string | null;\n source?: { type?: string | null; id?: string | null; details?: unknown } | null;\n createdAt?: string | null;\n updatedAt?: string | number | null;\n}\n\nexport function jobStateFor(status: string | null | undefined): JobState {\n if (status === 'COMPLETED') return 'succeeded';\n if (status === 'IN_PROGRESS' || status === 'NOT_STARTED') return 'running';\n return 'failed';\n}\n\nconst num = (v: unknown): number | undefined => (typeof v === 'number' && Number.isFinite(v) ? v : undefined);\nconst str = (v: unknown): string | undefined => (typeof v === 'string' && v ? v : undefined);\n\nfunction timestampMs(value: unknown): number | undefined {\n if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;\n if (typeof value !== 'string' || !value) return undefined;\n const ms = /^\\d+$/.test(value) ? Number(value) : Date.parse(value);\n return Number.isFinite(ms) ? ms : undefined;\n}\n\nfunction parseResults(v: unknown): JobResult[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const out: JobResult[] = [];\n for (const item of v) {\n if (!item || typeof item !== 'object') continue;\n const r = item as Record<string, unknown>;\n const url = str(r.url);\n if (!url) continue;\n const kind =\n r.kind === 'image' || r.kind === 'video' || r.kind === 'audio' || r.kind === 'text' ? r.kind : 'text';\n out.push({ url, kind, ...(str(r.title) ? { title: str(r.title) } : {}) });\n }\n return out.length ? out : undefined;\n}\n\nfunction parseStage(v: unknown): JobStage | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const s = v as Record<string, unknown>;\n const label = str(s.label);\n if (!label) return undefined;\n return {\n label,\n index: num(s.index) ?? 1,\n total: Math.max(1, num(s.total) ?? 1),\n ...(str(s.detail) ? { detail: str(s.detail) } : {}),\n };\n}\n\nfunction parseInput(v: unknown): JobInput | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const i = v as Record<string, unknown>;\n const refs = Array.isArray(i.references)\n ? i.references.filter((r): r is string => typeof r === 'string' && !!r)\n : [];\n const input: JobInput = {\n ...(str(i.prompt) ? { prompt: str(i.prompt) } : {}),\n ...(str(i.model) ? { model: str(i.model) } : {}),\n ...(str(i.aspectRatio) ? { aspectRatio: str(i.aspectRatio) } : {}),\n ...(refs.length ? { references: refs } : {}),\n ...(str(i.connector) ? { connector: str(i.connector) } : {}),\n ...(str(i.action) ? { action: str(i.action) } : {}),\n ...(i.params && typeof i.params === 'object' ? { params: i.params as Record<string, unknown> } : {}),\n };\n return Object.keys(input).length ? input : undefined;\n}\n\n/** A job from a server row, or null when the row is some other kind of task. The row's status wins. */\nexport function jobFromTaskRow(row: RemoteTaskRow | null | undefined): JobRecord | null {\n const details = row?.source?.details;\n if (!details || typeof details !== 'object') return null;\n const d = details as Record<string, unknown>;\n if (d.kind !== SURFACE_JOB_KIND) return null;\n const id = str(d.id);\n const surface = str(d.surface);\n if (!id || !surface) return null;\n const stored = str(d.state);\n const state: JobState = row?.status\n ? jobStateFor(row.status)\n : stored === 'running' || stored === 'succeeded' || stored === 'failed'\n ? stored\n : 'running';\n const createdAt = num(d.createdAt) ?? timestampMs(row?.createdAt) ?? 0;\n const results = parseResults(d.results);\n const stage = parseStage(d.stage);\n const input = parseInput(d.input);\n const handle = d.handle && typeof d.handle === 'object' ? (d.handle as Record<string, unknown>) : undefined;\n const verdictBy =\n d.verdictBy === 'agent' || d.verdictBy === 'browser' || d.verdictBy === 'deadline' ? d.verdictBy : undefined;\n const updatedAt = timestampMs(row?.updatedAt);\n return {\n id,\n surface,\n lane: str(d.lane) ?? 'job',\n title: str(d.title) ?? str(row?.title) ?? 'Job',\n brief: str(d.brief) ?? str(row?.description) ?? '',\n state,\n createdAt,\n ...(num(d.startedAt) !== undefined ? { startedAt: num(d.startedAt) } : {}),\n ...(num(d.endedAt) !== undefined ? { endedAt: num(d.endedAt) } : {}),\n ...(str(d.progress) ? { progress: str(d.progress) } : {}),\n ...(stage ? { stage } : {}),\n ...(results ? { results } : {}),\n ...(str(d.error) ? { error: str(d.error) } : {}),\n ...(d.delivered === true ? { delivered: true } : {}),\n ...(str(d.owner) ? { owner: str(d.owner) } : {}),\n ...(str(d.pageUrl) ? { pageUrl: str(d.pageUrl) } : {}),\n ...(input ? { input } : {}),\n ...(handle ? { handle } : {}),\n ...(str(row?.id) ? { remoteId: str(row?.id) } : {}),\n ...(num(d.deadlineAt) !== undefined ? { deadlineAt: num(d.deadlineAt) } : {}),\n ...(d.agentOwned === true ? { agentOwned: true } : {}),\n ...(verdictBy ? { verdictBy } : {}),\n ...(d.result !== undefined && d.result !== null ? { result: d.result } : {}),\n ...(d.hasResult === true ? { hasResult: true } : {}),\n ...(str(d.resultUrl) ? { resultUrl: str(d.resultUrl) } : {}),\n ...(updatedAt !== undefined ? { updatedAt } : {}),\n };\n}\n\n/** Newest first, with everything still running ahead of everything finished. */\nexport function sortJobs<T extends Pick<JobRecord, 'state' | 'createdAt'>>(jobs: T[]): T[] {\n return [...jobs].sort((a, b) => {\n const ra = a.state === 'running' ? 0 : 1;\n const rb = b.state === 'running' ? 0 : 1;\n return ra - rb || b.createdAt - a.createdAt;\n });\n}\n\n// ── Canvas tasks as jobs ─────────────────────────────────────────────────────\n\n/** Loose view of a store task: the export lane's extra fields are optional and read defensively. */\ntype AnyCanvasTask = CanvasTask & {\n step?: { index: number; total: number; label: string };\n owner?: string;\n deadlineAt?: number;\n verdictBy?: JobVerdictBy;\n};\n\nexport const isExportTask = (task: Pick<CanvasTask, 'kind'>): boolean =>\n (task.kind as string) === 'export' || (task.kind as string) === 'video-export';\n\n/** The job a store task is (web `canvasTaskToJob`). */\nexport function canvasTaskToJob(task: CanvasTask): JobRecord {\n const t = task as AnyCanvasTask;\n const isExport = isExportTask(task);\n // An export's ids live on its `render` handle; a production's on `handle`.\n const handle = ((isExport ? (t as { render?: unknown }).render : t.handle) ?? {}) as Record<string, unknown>;\n const request = (t.request ?? {}) as unknown as Record<string, unknown>;\n const resultTitle = !isExport ? (t.result as { title?: string } | undefined)?.title : undefined;\n return {\n id: t.id,\n surface: CANVAS_SURFACE,\n lane: isExport ? EXPORT_LANE : PROMO_LANE,\n title: t.title,\n brief: t.brief,\n state: t.state === 'submitting' ? 'running' : t.state,\n createdAt: t.createdAt,\n ...(t.startedAt ? { startedAt: t.startedAt } : {}),\n ...(t.endedAt ? { endedAt: t.endedAt } : {}),\n ...(t.lastLine ? { progress: t.lastLine } : {}),\n ...(t.step ? { stage: { ...t.step } } : {}),\n ...(t.result?.url\n ? {\n results: [\n {\n url: t.result.url,\n kind: isExport && request.media === 'image' ? ('image' as const) : ('video' as const),\n ...(resultTitle ? { title: resultTitle } : {}),\n },\n ],\n }\n : {}),\n ...(t.error ? { error: t.error } : {}),\n ...(t.delivered ? { delivered: true } : {}),\n ...(t.owner ? { owner: t.owner } : {}),\n input: isExport ? { prompt: t.brief } : { prompt: t.brief, params: request },\n handle: {\n boardId: t.boardId,\n ...(typeof handle.projectId === 'string' ? { projectId: handle.projectId } : {}),\n ...(typeof handle.sandboxId === 'string' ? { sandboxId: handle.sandboxId } : {}),\n ...(typeof handle.runId === 'string' ? { runId: handle.runId } : {}),\n },\n ...(t.deadlineAt ? { deadlineAt: t.deadlineAt } : {}),\n ...(t.verdictBy ? { verdictBy: t.verdictBy } : {}),\n };\n}\n\n// ── The wire ─────────────────────────────────────────────────────────────────\n\n/** How the agent follows a SUBMIT/STATUS lane on its own (agent field names, snake_case). */\nexport interface FollowSpec {\n connector: string;\n action: string;\n params: Record<string, string>;\n static_params?: Record<string, unknown>;\n interval_ms: number;\n deadline_ms: number;\n state_key: string;\n succeeded: string[];\n failed: string[];\n}\n\nexport type JobExpectation = 'media' | 'result';\n\n/** The `job` field every request that runs the work carries. */\nexport interface SurfaceJobRef {\n task_id: string;\n report_token: string;\n expects?: JobExpectation;\n follow?: FollowSpec;\n}\n\nexport interface ServerJob {\n remoteId: string;\n status?: string;\n reportToken?: string;\n}\n\n/** How long past its own run budget a production is followed. */\nexport const PROMO_FOLLOW_SLACK_MS = 15 * 60_000;\n\n/** How the agent follows a production it was handed (web `promoFollowSpec`). */\nexport function promoFollowSpec(opts: Pick<PromoRunOptions, 'preset' | 'quality'>): FollowSpec {\n return {\n connector: PROMO_CONNECTOR,\n action: PRODUCE_STATUS_ACTION,\n params: { projectId: 'projectId', sandboxId: 'sandboxId' },\n interval_ms: PROMO_POLL_EVERY_MS,\n deadline_ms: promoRunTimeoutMs(opts) + PROMO_FOLLOW_SLACK_MS,\n state_key: 'state',\n succeeded: ['succeeded'],\n failed: ['failed'],\n };\n}\n\n/** How the agent follows a lip sync it was handed (web `LIPSYNC_FOLLOW`). */\nexport const LIPSYNC_FOLLOW: FollowSpec = {\n connector: 'yantra-audio',\n action: 'YANTRA_AUDIO_LIPSYNC_STATUS',\n params: { statusUrl: 'statusUrl', responseUrl: 'responseUrl' },\n interval_ms: 5_000,\n deadline_ms: 15 * 60_000,\n state_key: 'status',\n succeeded: ['completed'],\n failed: ['failed'],\n};\n\nexport const isSettledStatus = (status: string | undefined): boolean => status === 'COMPLETED' || status === 'BLOCKED';\n\n// ── Transport ────────────────────────────────────────────────────────────────\n\nexport interface GraphqlResult {\n data?: Record<string, any>;\n errors?: { message?: string }[];\n}\n\nexport interface TaskApiTransport {\n post(query: string, variables?: Record<string, unknown>): Promise<GraphqlResult>;\n}\n\n/** fetch against the backend GraphQL with the surface bearer. */\nexport function createTaskApiTransport(token: string, graphqlUrl: string): TaskApiTransport {\n return {\n async post(query, variables = {}) {\n const resp = await fetch(graphqlUrl, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` },\n body: JSON.stringify({ query, variables }),\n });\n const body = (await resp.json().catch(() => ({}))) as GraphqlResult;\n const text = (body.errors ?? []).map((e) => e.message || 'error').join('; ');\n if (!resp.ok) throw new Error(`task api: HTTP ${resp.status}${text ? `: ${text}` : ''}`);\n if (body.errors?.length) throw new Error(`task api: ${text}`);\n return body;\n },\n };\n}\n\nlet transport: TaskApiTransport | null = null;\nlet owner: string | undefined;\n\n/**\n * Point the Task API at this session. CanvasExperience calls it whenever the\n * token or index changes; without a backend the transport is null and every\n * call below answers \"nothing\" rather than throwing.\n */\nexport function configureServerTasks(session: { token?: string | null; indexUrl?: string | null }): void {\n const graphqlUrl = session.indexUrl ? deriveBackendGraphqlUrl(session.indexUrl) : null;\n transport = session.token && graphqlUrl ? createTaskApiTransport(session.token, graphqlUrl) : null;\n const sub = tokenClaims(session.token).sub;\n owner = typeof sub === 'string' && sub ? sub : undefined;\n}\n\n/** Tests only. */\nexport function setTaskApiTransport(next: TaskApiTransport | null): void {\n transport = next;\n}\n\nexport const taskApiTransport = (): TaskApiTransport | null => transport;\n/** The JWT subject of who is signed in, for a job's owner. */\nexport const currentOwner = (): string | undefined => owner;\n\n// ── Capability ───────────────────────────────────────────────────────────────\n\nlet missing = new WeakMap<TaskApiTransport, Set<string>>();\nconst isMissing = (t: TaskApiTransport, field: string): boolean => missing.get(t)?.has(field) === true;\nfunction markMissing(t: TaskApiTransport, field: string): void {\n const set = missing.get(t) ?? new Set<string>();\n set.add(field);\n missing.set(t, set);\n}\nconst isMissingField = (err: unknown, field: string): boolean =>\n new RegExp(`Cannot query field [\"']${field}[\"']`).test(err instanceof Error ? err.message : String(err ?? ''));\n\n/** Ask a field the backend may not have. `undefined` when it does not (now or since). */\nasync function optionalField(\n t: TaskApiTransport,\n field: string,\n query: string,\n variables: Record<string, unknown>,\n): Promise<unknown> {\n if (isMissing(t, field)) return undefined;\n try {\n const res = await t.post(query, variables);\n return res.data?.[field] ?? null;\n } catch (err) {\n if (!isMissingField(err, field)) throw err;\n markMissing(t, field);\n return undefined;\n }\n}\n\n// ── The calls ────────────────────────────────────────────────────────────────\n\nconst ROW = 'id title description status createdAt updatedAt source { type id details }';\n\nconst RECORD = `mutation SurfaceJobRecord($job: JSON!) {\n recordSurfaceJob(job: $job) { id status reportToken }\n}`;\nconst PATCH = `mutation SurfaceJobPatch($id: ID!, $patch: JSON!) {\n updateSurfaceJob(id: $id, patch: $patch)\n}`;\nconst CLAIM = `mutation SurfaceJobClaim($id: ID!) {\n claimSurfaceJobDelivery(id: $id)\n}`;\nconst DELETE = `mutation SurfaceJobDelete($id: ID!) {\n removeSurfaceJob(id: $id)\n}`;\nconst LIST_OWN = `query SurfaceJobsOwn($surface: String, $limit: Int) {\n getSurfaceJobs(surface: $surface, limit: $limit) { ${ROW} }\n}`;\nconst READ_OWN = `query SurfaceJobOne($id: ID!) {\n getSurfaceJob(id: $id) { ${ROW} }\n}`;\n\n/** Record (or find) a job's row. Idempotent: the same local job always lands on the same row. */\nexport async function recordSurfaceJob(t: TaskApiTransport, job: JobRecord): Promise<ServerJob | null> {\n const rec = (await optionalField(t, 'recordSurfaceJob', RECORD, { job: browserDetails(job) })) as\n | {\n id?: unknown;\n status?: unknown;\n reportToken?: unknown;\n }\n | null\n | undefined;\n if (!rec || typeof rec.id !== 'string' || !rec.id) return null;\n return {\n remoteId: rec.id,\n ...(typeof rec.status === 'string' ? { status: rec.status } : {}),\n ...(typeof rec.reportToken === 'string' && rec.reportToken ? { reportToken: rec.reportToken } : {}),\n };\n}\n\nconst PATCH_KEYS = [\n 'progress',\n 'stage',\n 'results',\n 'error',\n 'delivered',\n 'state',\n 'startedAt',\n 'endedAt',\n 'title',\n 'brief',\n 'input',\n 'handle',\n 'deadlineAt',\n] as const;\n\n/** What an update sends: the fields this job HAS, merged into the row field by field. */\nexport function surfaceJobPatch(job: JobRecord): Record<string, unknown> {\n const wire = browserDetails(job);\n const patch: Record<string, unknown> = {};\n for (const key of PATCH_KEYS) if (wire[key] !== undefined) patch[key] = wire[key];\n return patch;\n}\n\n/** Merge a patch into a row. The server ignores a state change once the agent has given its verdict. */\nexport async function updateSurfaceJob(\n t: TaskApiTransport,\n remoteId: string,\n patch: Record<string, unknown>,\n): Promise<boolean> {\n return (await optionalField(t, 'updateSurfaceJob', PATCH, { id: remoteId, patch })) === true;\n}\n\n/**\n * Claim the right to place a finished job's result: true for exactly one\n * caller however many devices have the board open. Undefined when the backend\n * predates claims - the caller then places on its own record's word.\n */\nexport async function claimDelivery(t: TaskApiTransport, remoteId: string): Promise<boolean | undefined> {\n const value = await optionalField(t, 'claimSurfaceJobDelivery', CLAIM, { id: remoteId });\n return value === undefined ? undefined : value === true;\n}\n\nexport async function removeSurfaceJob(t: TaskApiTransport, remoteId: string): Promise<boolean> {\n return (await optionalField(t, 'removeSurfaceJob', DELETE, { id: remoteId })) === true;\n}\n\nfunction rowsOf(value: unknown): RemoteTaskRow[] {\n if (Array.isArray(value)) return value as RemoteTaskRow[];\n const data = (value as { data?: unknown } | null)?.data;\n return Array.isArray(data) ? (data as RemoteTaskRow[]) : [];\n}\n\n/** The caller's own jobs for one surface, newest first. Empty against a backend without them. */\nexport async function listRemoteJobs(t: TaskApiTransport, surface = CANVAS_SURFACE, limit = 100): Promise<JobRecord[]> {\n const own = await optionalField(t, 'getSurfaceJobs', LIST_OWN, { surface, limit });\n if (own === undefined) return [];\n const jobs: JobRecord[] = [];\n for (const row of rowsOf(own)) {\n const job = jobFromTaskRow(row);\n if (job && job.surface === surface) jobs.push(job);\n }\n return jobs;\n}\n\n/** One of the caller's jobs; null when gone or not theirs, undefined when the backend cannot read one row. */\nexport async function getRemoteJob(t: TaskApiTransport, remoteId: string): Promise<JobRecord | null | undefined> {\n const row = await optionalField(t, 'getSurfaceJob', READ_OWN, { id: remoteId });\n if (row === undefined) return undefined;\n return jobFromTaskRow(row as RemoteTaskRow | null);\n}\n\n// ── Recording before the submit ──────────────────────────────────────────────\n\ninterface HeldJob {\n remoteId: string;\n reportToken?: string;\n}\n\nconst pendingJobs = new Map<string, Promise<ServerJob | null>>();\nconst heldJobs = new Map<string, HeldJob>();\n\n/** Record a job before its work is submitted; null after the budget, or without a backend. */\nexport async function recordServerJob(\n t: TaskApiTransport,\n job: JobRecord,\n budgetMs = SERVER_JOB_BUDGET_MS,\n): Promise<ServerJob | null> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const outOfTime = new Promise<null>((resolve) => {\n timer = setTimeout(() => resolve(null), budgetMs);\n });\n try {\n return await Promise.race([recordSurfaceJob(t, job).catch(() => null), outOfTime]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Record a local job on the server and hold its report token for\n * {@link serverJobRef}. `exists` is asked once the answer is in: a record\n * dismissed meanwhile takes its row down rather than leaving an orphan.\n */\nexport function recordLocalJob(\n job: JobRecord,\n options: { exists?: () => boolean; budgetMs?: number; transport?: TaskApiTransport | null } = {},\n): Promise<ServerJob | null> {\n const t = options.transport === undefined ? transport : options.transport;\n const key = jobKey(job);\n if (!t) return Promise.resolve(null);\n const recorded = recordServerJob(t, job, options.budgetMs)\n .then((server) => {\n if (!server) return null;\n if (options.exists && !options.exists()) {\n void removeSurfaceJob(t, server.remoteId).catch(() => undefined);\n return null;\n }\n heldJobs.set(key, {\n remoteId: server.remoteId,\n // A row already settled keeps its verdict: no request may hand it out again.\n ...(server.reportToken && !isSettledStatus(server.status) ? { reportToken: server.reportToken } : {}),\n });\n return server;\n })\n .catch(() => null);\n pendingJobs.set(key, recorded);\n return recorded;\n}\n\n/**\n * The `job` field for the request whose outcome IS this job's outcome, or\n * undefined to send none. Waits for the job's recording (its budget at most).\n */\nexport async function serverJobRef(\n key: string,\n extras: { expects?: JobExpectation; follow?: FollowSpec } = {},\n): Promise<SurfaceJobRef | undefined> {\n await pendingJobs.get(key);\n const held = heldJobs.get(key);\n if (!held?.reportToken) return undefined;\n return {\n task_id: held.remoteId,\n report_token: held.reportToken,\n ...(extras.expects ? { expects: extras.expects } : {}),\n ...(extras.follow ? { follow: extras.follow } : {}),\n };\n}\n\n/** A canvas job's server id from the listing - for a run whose token a restart dropped. */\nexport async function lookupRemoteJobId(localId: string): Promise<string | undefined> {\n const t = transport;\n if (!t) return undefined;\n const jobs = await listRemoteJobs(t, CANVAS_SURFACE);\n return jobs.find((job) => job.id === localId)?.remoteId;\n}\n\n/** The server id a recorded job landed on, once it has. */\nexport const serverJobId = (key: string): string | undefined => heldJobs.get(key)?.remoteId;\n\n/** Drop a settled job's token. */\nexport function forgetServerJob(key: string): void {\n pendingJobs.delete(key);\n heldJobs.delete(key);\n}\n\n/** Tests only. */\nexport function resetServerTasks(): void {\n pendingJobs.clear();\n heldJobs.clear();\n missing = new WeakMap();\n transport = null;\n owner = undefined;\n}\n\n// ── Running the work with the job ────────────────────────────────────────────\n\n/**\n * Run a connector action carrying `job` when the runner can put it on the exec\n * body. Answers whether the job actually went out - a host seam that predates\n * the field cannot carry it, and then nobody will report on the job.\n */\nexport async function runWithJob(\n run: RunMediaAction,\n connector: MediaConnector,\n action: string,\n params: Record<string, unknown>,\n job: SurfaceJobRef | undefined,\n): Promise<{ result: Record<string, unknown>; handed: boolean }> {\n if (job && runActionAcceptsJob(run)) {\n return { result: await (run as RunMediaActionWithBody)(connector, action, params, { job }), handed: true };\n }\n return { result: await run(connector, action, params), handed: false };\n}\n\n// ── Waiting on the agent ─────────────────────────────────────────────────────\n\nexport const AGENT_VERDICT_INTERVAL_MS = 5_000;\nconst MAX_READ_MISSES = 6;\n\nexport interface AwaitAgentVerdictOptions {\n submittedAt: number;\n deadlineAt: number;\n intervalMs?: number;\n graceMs?: number;\n onProgress?: (job: JobRecord) => void;\n sleep?: (ms: number) => Promise<void>;\n now?: () => number;\n transport?: TaskApiTransport | null;\n}\n\n/**\n * Wait for the agent's verdict on one job by reading its row - for a phone\n * that is open while the agent follows the work, and so must NOT poll it too\n * (a promo sandbox dies on the first terminal STATUS answer). Resolves the row\n * once terminal; null when the agent never reported within the grace or the\n * row cannot be read - the caller then follows the work itself.\n */\nexport async function awaitAgentVerdict(\n remoteId: string,\n options: AwaitAgentVerdictOptions,\n): Promise<JobRecord | null> {\n const t = options.transport === undefined ? transport : options.transport;\n if (!t) return null;\n const {\n submittedAt,\n deadlineAt,\n intervalMs = AGENT_VERDICT_INTERVAL_MS,\n graceMs = AGENT_OWNED_GRACE_MS,\n onProgress,\n sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),\n now = () => Date.now(),\n } = options;\n let misses = 0;\n for (;;) {\n await sleep(intervalMs);\n let job: JobRecord | null | undefined;\n try {\n job = await getRemoteJob(t, remoteId);\n misses = 0;\n } catch {\n if (++misses >= MAX_READ_MISSES) return null;\n continue;\n }\n if (!job) return null;\n if (job.state !== 'running') return job;\n const at = now();\n if (job.agentOwned) onProgress?.(job);\n else if (at - submittedAt >= graceMs) return null;\n if (at >= deadlineAt) throw new Error(DEADLINE_VERDICT_ERROR);\n }\n}\n\n/** A row's latest line: its stage, else its progress. */\nexport function serverProgressLine(job: Pick<JobRecord, 'stage' | 'progress'>): string | undefined {\n if (job.stage) {\n const step = `Step ${job.stage.index} of ${job.stage.total}`;\n return job.stage.detail ? `${step} · ${job.stage.detail}` : `${step} · ${job.stage.label}`;\n }\n return job.progress;\n}\n\n// ── Promo ────────────────────────────────────────────────────────────────────\n\n/** The production's video from its verdict row: its results, else the STATUS answer the agent kept. */\nexport function promoVideoFromVerdict(\n job: Pick<JobRecord, 'results' | 'result'>,\n): { url: string; title?: string } | undefined {\n const video = job.results?.find((r) => r.kind === 'video' && r.url) ?? job.results?.find((r) => r.url);\n if (video) return { url: video.url, ...(video.title ? { title: video.title } : {}) };\n const answer = (job.result ?? {}) as Record<string, unknown>;\n const inner = (answer.data && typeof answer.data === 'object' ? answer.data : answer) as Record<string, unknown>;\n const nested = (inner.result && typeof inner.result === 'object' ? inner.result : inner) as Record<string, unknown>;\n const url = str(nested.url) ?? str(nested.videoUrl) ?? str(nested.video_url);\n return url ? { url, ...(str(nested.title) ? { title: str(nested.title) } : {}) } : undefined;\n}\n\n/**\n * Record a production's job and hand back the ref its SUBMIT carries (with\n * the follow spec). Undefined when there is no backend, an older one, or it\n * did not answer in two seconds.\n */\nexport async function registerPromoJob(task: CanvasTask, exists: () => boolean): Promise<SurfaceJobRef | undefined> {\n const job = canvasTaskToJob(task);\n const withOwner = owner ? { ...job, owner } : job;\n await recordLocalJob(withOwner, { exists });\n return serverJobRef(canvasJobKey(task.id), { follow: promoFollowSpec(task.request) });\n}\n\n// ── Lip sync ─────────────────────────────────────────────────────────────────\n\n/** The synced clip in an agent's verdict: its results, else the STATUS answer it kept. */\nexport function lipSyncVideoFromVerdict(verdict: Pick<JobRecord, 'results' | 'result'>): string {\n const fromResults = verdict.results?.find((r) => r.kind === 'video' && r.url)?.url;\n if (fromResults) return fromResults;\n const answer = (verdict.result ?? {}) as Record<string, unknown>;\n const inner = (answer.data && typeof answer.data === 'object' ? answer.data : answer) as Record<string, unknown>;\n return typeof inner.videoUrl === 'string' ? inner.videoUrl : '';\n}\n\nlet lipSeq = 0;\n\nexport interface TrackedLipSync {\n /** The job's id (the local half of its key). */\n id: string;\n /** The `job` for the SUBMIT, with {@link LIPSYNC_FOLLOW}; undefined when there is no record. */\n job?: SurfaceJobRef;\n /** Wait on the agent's verdict instead of polling the queue beside it; null when the agent never took it. */\n awaitAgent: (startedAt: number) => Promise<JobRecord | null>;\n /** Settle the row with the phone's own verdict (when the phone followed the queue itself). */\n settle: (outcome: { videoUrl?: string; error?: string }) => void;\n}\n\n/**\n * Record a lip sync as a canvas job so it shows in every Tasks panel and the\n * agent can finish it if the phone goes away. Never throws.\n */\nexport async function trackLipSync(input: {\n videoUrl: string;\n text?: string;\n boardId?: string | null;\n}): Promise<TrackedLipSync> {\n const id = `lipsync-${Date.now().toString(36)}-${(lipSeq++).toString(36)}`;\n const createdAt = Date.now();\n const base: JobRecord = {\n id,\n surface: CANVAS_SURFACE,\n lane: LIPSYNC_LANE,\n title: 'Lip sync',\n brief: input.text?.trim() || 'Lip sync',\n state: 'running',\n createdAt,\n startedAt: createdAt,\n deadlineAt: jobDeadlineAt(createdAt, LIPSYNC_BUDGET_MS),\n input: {\n ...(input.text ? { prompt: input.text } : {}),\n connector: 'yantra-audio',\n action: 'YANTRA_AUDIO_LIPSYNC_SUBMIT',\n params: { videoUrl: input.videoUrl, ...(input.text ? { text: input.text } : {}) },\n },\n ...(input.boardId ? { handle: { boardId: input.boardId } } : {}),\n ...(owner ? { owner } : {}),\n };\n const key = jobKey(base);\n const server = await recordLocalJob(base).catch(() => null);\n const job = server ? await serverJobRef(key, { follow: LIPSYNC_FOLLOW, expects: 'media' }) : undefined;\n return {\n id,\n ...(job ? { job } : {}),\n awaitAgent: (startedAt) =>\n server\n ? awaitAgentVerdict(server.remoteId, { submittedAt: startedAt, deadlineAt: base.deadlineAt! })\n : Promise.resolve(null),\n settle: ({ videoUrl, error }) => {\n const t = transport;\n forgetServerJob(key);\n if (!server || !t) return;\n const done: JobRecord = {\n ...base,\n state: videoUrl ? 'succeeded' : 'failed',\n endedAt: Date.now(),\n ...(videoUrl ? { results: [{ url: videoUrl, kind: 'video' as const }], delivered: true } : {}),\n ...(error ? { error } : {}),\n };\n void updateSurfaceJob(t, server.remoteId, surfaceJobPatch(done)).catch(() => undefined);\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"serverTasks.js","sources":["../../../src/features/canvas/serverTasks.ts"],"sourcesContent":["/**\n * Server-backed canvas tasks - native twin of surface-kit `tasks/serverJob`,\n * `tasks/remoteTasks`, `tasks/remoteRecord` and canvas `tasks/serverJobs`.\n *\n * A job is recorded on the Task API BEFORE its work is submitted, so the cdecli\n * agent that runs the work can report progress, the verdict and the result to\n * that row - and the result lands whether or not this phone is still open.\n * The exec request carries `job` ({@link SurfaceJobRef}); an older agent\n * ignores the field and the phone follows the work itself, as it always did.\n *\n * Rows are owner-scoped (`getSurfaceJobs` / `getSurfaceJob` answer with the\n * caller's own jobs), keyed `canvas:<local id>` exactly like the web canvas's,\n * so a run started on the web shows here and one started here shows there.\n *\n * Transport: the canvas session token (the surface JWT) against the backend\n * GraphQL the index URL names (`deriveBackendGraphqlUrl`). The report token\n * lives in memory only - never in AsyncStorage.\n *\n * Every call degrades: no session, an older backend (\"Cannot query field\"),\n * or no answer within two seconds, and the run goes out exactly as before.\n */\nimport type { CanvasTask } from './canvasTasks';\nimport {\n PRODUCE_STATUS_ACTION,\n PROMO_CONNECTOR,\n PROMO_POLL_EVERY_MS,\n promoRunTimeoutMs,\n type PromoRunOptions,\n} from './promoVideo';\nimport type { MediaConnector, RunMediaAction } from './videoEditor/mediaActions';\nimport {\n deriveBackendGraphqlUrl,\n runActionAcceptsJob,\n type RunMediaActionWithBody,\n} from './videoEditor/remoteMediaClient';\nimport { tokenClaims } from './sessionIdentity';\nimport {\n RENDER_POLL_EVERY_MS,\n RENDER_POLL_MAX_MS,\n RENDER_STATUS_ACTION,\n VIDEO_EDIT_CONNECTOR,\n} from './videoEditor/renderTimeline';\n\nexport const CANVAS_SURFACE = 'canvas';\nexport const PROMO_LANE = 'promo';\nexport const EXPORT_LANE = 'video-export';\nexport const LIPSYNC_LANE = 'lipsync';\n/** A generation's lane is the media it makes (web `registerRun({ lane: kind })`). */\nexport const GENERATION_LANES = ['image', 'video', 'audio'] as const;\nexport const SURFACE_JOB_KIND = 'surface-job';\n\n// ── The record ───────────────────────────────────────────────────────────────\n\nexport type JobState = 'running' | 'succeeded' | 'failed';\nexport type JobVerdictBy = 'agent' | 'browser' | 'deadline';\n\nexport interface JobStage {\n label: string;\n index: number;\n total: number;\n detail?: string;\n}\n\nexport interface JobResult {\n url: string;\n kind: 'image' | 'video' | 'audio' | 'text';\n title?: string;\n}\n\nexport interface JobInput {\n prompt?: string;\n model?: string;\n aspectRatio?: string;\n references?: string[];\n connector?: string;\n action?: string;\n params?: Record<string, unknown>;\n}\n\n/** A job as every store can express it, and as the Tasks panel reads it. */\nexport interface JobRecord {\n id: string;\n surface: string;\n lane: string;\n title: string;\n brief: string;\n state: JobState;\n createdAt: number;\n startedAt?: number;\n endedAt?: number;\n progress?: string;\n stage?: JobStage;\n results?: JobResult[];\n error?: string;\n delivered?: boolean;\n owner?: string;\n pageUrl?: string;\n input?: JobInput;\n handle?: Record<string, unknown>;\n remoteId?: string;\n deadlineAt?: number;\n agentOwned?: boolean;\n verdictBy?: JobVerdictBy;\n /** The agent's exec run id, for diagnostics. Server-written. */\n runId?: string;\n result?: unknown;\n hasResult?: boolean;\n resultUrl?: string;\n updatedAt?: number;\n}\n\n/** The server sweep's word for a job that ran past its deadline with nothing reporting on it. */\nexport const DEADLINE_VERDICT_ERROR = 'Stopped responding before it finished';\n/** Added to every lane's budget for its deadline. */\nexport const JOB_DEADLINE_GRACE_MS = 10 * 60_000;\n/** How long a handed-over job may go without the agent reporting before the phone follows it itself. */\nexport const AGENT_OWNED_GRACE_MS = 2 * 60_000;\n/** How long a job may wait on its own record before it is submitted without one. */\nexport const SERVER_JOB_BUDGET_MS = 2_000;\n/** A row recorded before deadlines existed reads as stale a day after it was created. */\nexport const LEGACY_JOB_DEADLINE_MS = 24 * 60 * 60_000;\n/** A generation: the web's durable-turn budget (the direct exec's own is at most ten minutes). */\nexport const GENERATION_BUDGET_MS = 30 * 60_000;\n/** Lip sync: speech, then a provider queue measured at four minutes; the agent follows it for fifteen. */\nexport const LIPSYNC_BUDGET_MS = 15 * 60_000;\n\nexport const jobDeadlineAt = (startedAt: number, budgetMs: number): number =>\n startedAt + budgetMs + JOB_DEADLINE_GRACE_MS;\nexport const jobKey = (job: Pick<JobRecord, 'surface' | 'id'>): string => `${job.surface}:${job.id}`;\nexport const canvasJobKey = (localId: string): string => `${CANVAS_SURFACE}:${localId}`;\n\nexport function jobDeadline(job: Pick<JobRecord, 'deadlineAt' | 'createdAt'>): number {\n return job.deadlineAt ?? job.createdAt + LEGACY_JOB_DEADLINE_MS;\n}\n\n/** Running past its deadline: nothing is going to settle it any more. */\nexport function isStaleJob(job: Pick<JobRecord, 'state' | 'deadlineAt' | 'createdAt'>, now = Date.now()): boolean {\n return job.state === 'running' && now > jobDeadline(job);\n}\n\n/** The agent took the job: it reported on it, ran it, or gave it a verdict (kit `agentHasJob`). */\nexport const agentHasJob = (server: Pick<JobRecord, 'agentOwned' | 'runId' | 'verdictBy'>): boolean =>\n server.agentOwned === true || Boolean(server.runId) || server.verdictBy === 'agent';\n\n/** Failed by the server's deadline sweep. */\nexport const isDeadlineVerdict = (record: { state: string; verdictBy?: string }): boolean =>\n record.state === 'failed' && record.verdictBy === 'deadline';\n\n/** The board a job's result belongs on, when its surface recorded one. */\nexport function jobBoardId(job: Pick<JobRecord, 'handle'>): string | undefined {\n const handle = job.handle;\n if (!handle) return undefined;\n if (typeof handle.boardId === 'string' && handle.boardId) return handle.boardId;\n return handle.kind === 'channel' && typeof handle.channelId === 'string' && handle.channelId\n ? handle.channelId\n : undefined;\n}\n\n/** A stable 24-hex ObjectId from a key (three FNV-1a passes) - identical to the kit's, so rows line up. */\nexport function objectIdFromKey(key: string): string {\n const fnv = (seed: number): string => {\n let h = seed >>> 0;\n for (let i = 0; i < key.length; i += 1) {\n h ^= key.charCodeAt(i);\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n return h.toString(16).padStart(8, '0');\n };\n return fnv(0x811c9dc5) + fnv(0x9747b28c) + fnv(0x5bd1e995);\n}\n\nconst isWebUrl = (value: unknown): value is string => typeof value === 'string' && /^https?:\\/\\//i.test(value);\n\n// ── What the server keeps (kit tasks/remoteRecord) ──────────────────────────\n// Result and page URLs are http(s) only, at most 50 results, and `input` /\n// `handle` at most 16 KiB each. A job is written within them rather than\n// refused for exceeding them.\n\n/** The most a record's `input` or `handle` may weigh. */\nexport const WIRE_FIELD_MAX_BYTES = 16 * 1024;\n/** The most results a record keeps. */\nexport const WIRE_RESULTS_MAX = 50;\n\n/** UTF-8 length of a string - TextEncoder is not on every Hermes build. */\nfunction utf8Length(text: string): number {\n let bytes = 0;\n for (let i = 0; i < text.length; i += 1) {\n const code = text.charCodeAt(i);\n if (code < 0x80) bytes += 1;\n else if (code < 0x800) bytes += 2;\n else if (code >= 0xd800 && code <= 0xdbff && i + 1 < text.length) {\n const next = text.charCodeAt(i + 1);\n if (next >= 0xdc00 && next <= 0xdfff) {\n bytes += 4;\n i += 1;\n } else bytes += 3;\n } else bytes += 3;\n }\n return bytes;\n}\n\nexport function byteSize(value: unknown): number {\n try {\n const json = JSON.stringify(value);\n return json === undefined ? 0 : utf8Length(json);\n } catch {\n return Number.POSITIVE_INFINITY;\n }\n}\n\n/**\n * An input that fits: the call's raw params go first (the retry form reads\n * the named fields), then the references; the prompt is kept to the last,\n * cut short only if it alone is too long.\n */\nexport function boundedInput(input: JobInput): JobInput | undefined {\n if (byteSize(input) <= WIRE_FIELD_MAX_BYTES) return input;\n const { params: _params, ...named } = input;\n if (byteSize(named) <= WIRE_FIELD_MAX_BYTES) return named;\n const { references: _references, ...bare } = named;\n if (byteSize(bare) <= WIRE_FIELD_MAX_BYTES) return bare;\n // Four bytes a character at worst: 4,000 characters always fit.\n return bare.prompt ? { prompt: bare.prompt.slice(0, 4_000) } : undefined;\n}\n\n/** A handle is ids; one that somehow outgrew the limit keeps its plain values only. */\nexport function boundedHandle(handle: Record<string, unknown>): Record<string, unknown> | undefined {\n if (byteSize(handle) <= WIRE_FIELD_MAX_BYTES) return handle;\n const plain = Object.fromEntries(\n Object.entries(handle).filter(([, v]) => typeof v !== 'object' && String(v).length <= 512),\n );\n return byteSize(plain) <= WIRE_FIELD_MAX_BYTES ? plain : undefined;\n}\n\n/** The job as a client may write it: no server/agent-owned fields, web URLs only, bounded input. */\nexport function browserDetails(job: JobRecord): Record<string, unknown> {\n const {\n remoteId: _remoteId,\n agentOwned: _agentOwned,\n verdictBy: _verdictBy,\n runId: _runId,\n result: _result,\n hasResult: _hasResult,\n resultUrl: _resultUrl,\n updatedAt: _updatedAt,\n results,\n pageUrl,\n input,\n handle,\n ...rest\n } = job;\n const webResults = results?.filter((r) => isWebUrl(r.url)).slice(0, WIRE_RESULTS_MAX);\n const keptInput = input ? boundedInput(input) : undefined;\n const keptHandle = handle ? boundedHandle(handle) : undefined;\n return {\n ...rest,\n ...(webResults?.length ? { results: webResults } : {}),\n ...(isWebUrl(pageUrl) ? { pageUrl } : {}),\n ...(keptInput ? { input: keptInput } : {}),\n ...(keptHandle ? { handle: keptHandle } : {}),\n };\n}\n\n/** What the panels render of a job, so an unchanged reading sends nothing. */\nexport function jobFingerprint(job: JobRecord): string {\n return JSON.stringify([\n job.state,\n job.title,\n job.brief,\n job.progress ?? '',\n job.stage ? [job.stage.index, job.stage.total, job.stage.label, job.stage.detail ?? ''] : null,\n job.results ?? [],\n job.error ?? '',\n job.delivered ?? false,\n job.startedAt ?? 0,\n job.endedAt ?? 0,\n ]);\n}\n\n/** The subset of a `Task` row the reader needs. */\nexport interface RemoteTaskRow {\n id?: string | null;\n title?: string | null;\n description?: string | null;\n status?: string | null;\n source?: { type?: string | null; id?: string | null; details?: unknown } | null;\n createdAt?: string | null;\n updatedAt?: string | number | null;\n}\n\nexport function jobStateFor(status: string | null | undefined): JobState {\n if (status === 'COMPLETED') return 'succeeded';\n if (status === 'IN_PROGRESS' || status === 'NOT_STARTED') return 'running';\n return 'failed';\n}\n\nconst num = (v: unknown): number | undefined => (typeof v === 'number' && Number.isFinite(v) ? v : undefined);\nconst str = (v: unknown): string | undefined => (typeof v === 'string' && v ? v : undefined);\n\nfunction timestampMs(value: unknown): number | undefined {\n if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;\n if (typeof value !== 'string' || !value) return undefined;\n const ms = /^\\d+$/.test(value) ? Number(value) : Date.parse(value);\n return Number.isFinite(ms) ? ms : undefined;\n}\n\nfunction parseResults(v: unknown): JobResult[] | undefined {\n if (!Array.isArray(v)) return undefined;\n const out: JobResult[] = [];\n for (const item of v) {\n if (!item || typeof item !== 'object') continue;\n const r = item as Record<string, unknown>;\n const url = str(r.url);\n if (!url) continue;\n const kind =\n r.kind === 'image' || r.kind === 'video' || r.kind === 'audio' || r.kind === 'text' ? r.kind : 'text';\n out.push({ url, kind, ...(str(r.title) ? { title: str(r.title) } : {}) });\n }\n return out.length ? out : undefined;\n}\n\nfunction parseStage(v: unknown): JobStage | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const s = v as Record<string, unknown>;\n const label = str(s.label);\n if (!label) return undefined;\n return {\n label,\n index: num(s.index) ?? 1,\n total: Math.max(1, num(s.total) ?? 1),\n ...(str(s.detail) ? { detail: str(s.detail) } : {}),\n };\n}\n\nfunction parseInput(v: unknown): JobInput | undefined {\n if (!v || typeof v !== 'object') return undefined;\n const i = v as Record<string, unknown>;\n const refs = Array.isArray(i.references)\n ? i.references.filter((r): r is string => typeof r === 'string' && !!r)\n : [];\n const input: JobInput = {\n ...(str(i.prompt) ? { prompt: str(i.prompt) } : {}),\n ...(str(i.model) ? { model: str(i.model) } : {}),\n ...(str(i.aspectRatio) ? { aspectRatio: str(i.aspectRatio) } : {}),\n ...(refs.length ? { references: refs } : {}),\n ...(str(i.connector) ? { connector: str(i.connector) } : {}),\n ...(str(i.action) ? { action: str(i.action) } : {}),\n ...(i.params && typeof i.params === 'object' ? { params: i.params as Record<string, unknown> } : {}),\n };\n return Object.keys(input).length ? input : undefined;\n}\n\n/** A job from a server row, or null when the row is some other kind of task. The row's status wins. */\nexport function jobFromTaskRow(row: RemoteTaskRow | null | undefined): JobRecord | null {\n const details = row?.source?.details;\n if (!details || typeof details !== 'object') return null;\n const d = details as Record<string, unknown>;\n if (d.kind !== SURFACE_JOB_KIND) return null;\n const id = str(d.id);\n const surface = str(d.surface);\n if (!id || !surface) return null;\n const stored = str(d.state);\n const state: JobState = row?.status\n ? jobStateFor(row.status)\n : stored === 'running' || stored === 'succeeded' || stored === 'failed'\n ? stored\n : 'running';\n const createdAt = num(d.createdAt) ?? timestampMs(row?.createdAt) ?? 0;\n const results = parseResults(d.results);\n const stage = parseStage(d.stage);\n const input = parseInput(d.input);\n const handle = d.handle && typeof d.handle === 'object' ? (d.handle as Record<string, unknown>) : undefined;\n const verdictBy =\n d.verdictBy === 'agent' || d.verdictBy === 'browser' || d.verdictBy === 'deadline' ? d.verdictBy : undefined;\n const updatedAt = timestampMs(row?.updatedAt);\n return {\n id,\n surface,\n lane: str(d.lane) ?? 'job',\n title: str(d.title) ?? str(row?.title) ?? 'Job',\n brief: str(d.brief) ?? str(row?.description) ?? '',\n state,\n createdAt,\n ...(num(d.startedAt) !== undefined ? { startedAt: num(d.startedAt) } : {}),\n ...(num(d.endedAt) !== undefined ? { endedAt: num(d.endedAt) } : {}),\n ...(str(d.progress) ? { progress: str(d.progress) } : {}),\n ...(stage ? { stage } : {}),\n ...(results ? { results } : {}),\n ...(str(d.error) ? { error: str(d.error) } : {}),\n ...(d.delivered === true ? { delivered: true } : {}),\n ...(str(d.owner) ? { owner: str(d.owner) } : {}),\n ...(str(d.pageUrl) ? { pageUrl: str(d.pageUrl) } : {}),\n ...(input ? { input } : {}),\n ...(handle ? { handle } : {}),\n ...(str(row?.id) ? { remoteId: str(row?.id) } : {}),\n ...(num(d.deadlineAt) !== undefined ? { deadlineAt: num(d.deadlineAt) } : {}),\n ...(d.agentOwned === true ? { agentOwned: true } : {}),\n ...(verdictBy ? { verdictBy } : {}),\n ...(str(d.runId) ? { runId: str(d.runId) } : {}),\n ...(d.result !== undefined && d.result !== null ? { result: d.result } : {}),\n ...(d.hasResult === true ? { hasResult: true } : {}),\n ...(str(d.resultUrl) ? { resultUrl: str(d.resultUrl) } : {}),\n ...(updatedAt !== undefined ? { updatedAt } : {}),\n };\n}\n\n/** Newest first, with everything still running ahead of everything finished. */\nexport function sortJobs<T extends Pick<JobRecord, 'state' | 'createdAt'>>(jobs: T[]): T[] {\n return [...jobs].sort((a, b) => {\n const ra = a.state === 'running' ? 0 : 1;\n const rb = b.state === 'running' ? 0 : 1;\n return ra - rb || b.createdAt - a.createdAt;\n });\n}\n\n// ── Canvas tasks as jobs ─────────────────────────────────────────────────────\n\n/** Loose view of a store task: the export lane's extra fields are optional and read defensively. */\ntype AnyCanvasTask = CanvasTask & {\n step?: { index: number; total: number; label: string };\n owner?: string;\n deadlineAt?: number;\n verdictBy?: JobVerdictBy;\n};\n\nexport const isExportTask = (task: Pick<CanvasTask, 'kind'>): boolean =>\n (task.kind as string) === 'export' || (task.kind as string) === 'video-export';\n\nexport const isGenerateTask = (task: Pick<CanvasTask, 'kind'>): boolean => (task.kind as string) === 'generate';\n\n/** A generation task as a job: lane = its media, input = the call as sent, result = what it made. */\nfunction generationTaskToJob(t: AnyCanvasTask): JobRecord {\n const media = t.media ?? 'image';\n const input = t.input;\n return {\n id: t.id,\n surface: CANVAS_SURFACE,\n lane: media,\n title: t.title,\n brief: t.brief,\n state: t.state === 'submitting' ? 'running' : t.state,\n createdAt: t.createdAt,\n ...(t.startedAt ? { startedAt: t.startedAt } : {}),\n ...(t.endedAt ? { endedAt: t.endedAt } : {}),\n ...(t.lastLine ? { progress: t.lastLine } : {}),\n ...(t.result?.url ? { results: [{ url: t.result.url, kind: media }] } : {}),\n ...(t.error ? { error: t.error } : {}),\n ...(t.delivered ? { delivered: true } : {}),\n ...(t.owner ? { owner: t.owner } : {}),\n input: input\n ? {\n prompt: input.prompt,\n connector: input.connector,\n action: input.action,\n params: input.params,\n ...(input.model ? { model: input.model } : {}),\n ...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),\n ...(input.references?.length ? { references: input.references } : {}),\n }\n : { prompt: t.brief },\n handle: { boardId: t.boardId },\n ...(t.deadlineAt ? { deadlineAt: t.deadlineAt } : {}),\n ...(t.verdictBy ? { verdictBy: t.verdictBy } : {}),\n };\n}\n\n/** The job a store task is (web `canvasTaskToJob`). */\nexport function canvasTaskToJob(task: CanvasTask): JobRecord {\n const t = task as AnyCanvasTask;\n if (isGenerateTask(task)) return generationTaskToJob(t);\n const isExport = isExportTask(task);\n // An export's ids live on its `render` handle; a production's on `handle`.\n const handle = ((isExport ? (t as { render?: unknown }).render : t.handle) ?? {}) as Record<string, unknown>;\n const request = (t.request ?? {}) as unknown as Record<string, unknown>;\n const resultTitle = !isExport ? (t.result as { title?: string } | undefined)?.title : undefined;\n return {\n id: t.id,\n surface: CANVAS_SURFACE,\n lane: isExport ? EXPORT_LANE : PROMO_LANE,\n title: t.title,\n brief: t.brief,\n state: t.state === 'submitting' ? 'running' : t.state,\n createdAt: t.createdAt,\n ...(t.startedAt ? { startedAt: t.startedAt } : {}),\n ...(t.endedAt ? { endedAt: t.endedAt } : {}),\n ...(t.lastLine ? { progress: t.lastLine } : {}),\n ...(t.step ? { stage: { ...t.step } } : {}),\n ...(t.result?.url\n ? {\n results: [\n {\n url: t.result.url,\n kind: isExport && request.media === 'image' ? ('image' as const) : ('video' as const),\n ...(resultTitle ? { title: resultTitle } : {}),\n },\n ],\n }\n : {}),\n ...(t.error ? { error: t.error } : {}),\n ...(t.delivered ? { delivered: true } : {}),\n ...(t.owner ? { owner: t.owner } : {}),\n input: isExport ? { prompt: t.brief } : { prompt: t.brief, params: request },\n handle: {\n boardId: t.boardId,\n ...(typeof handle.projectId === 'string' ? { projectId: handle.projectId } : {}),\n ...(typeof handle.sandboxId === 'string' ? { sandboxId: handle.sandboxId } : {}),\n ...(typeof handle.runId === 'string' ? { runId: handle.runId } : {}),\n },\n ...(t.deadlineAt ? { deadlineAt: t.deadlineAt } : {}),\n ...(t.verdictBy ? { verdictBy: t.verdictBy } : {}),\n };\n}\n\n// ── The wire ─────────────────────────────────────────────────────────────────\n\n/** How the agent follows a SUBMIT/STATUS lane on its own (agent field names, snake_case). */\nexport interface FollowSpec {\n connector: string;\n action: string;\n params: Record<string, string>;\n static_params?: Record<string, unknown>;\n interval_ms: number;\n deadline_ms: number;\n state_key: string;\n succeeded: string[];\n failed: string[];\n}\n\nexport type JobExpectation = 'media' | 'result';\n\n/** The `job` field every request that runs the work carries. */\nexport interface SurfaceJobRef {\n task_id: string;\n report_token: string;\n expects?: JobExpectation;\n follow?: FollowSpec;\n}\n\nexport interface ServerJob {\n remoteId: string;\n status?: string;\n reportToken?: string;\n}\n\n/** How long past its own run budget a production is followed. */\nexport const PROMO_FOLLOW_SLACK_MS = 15 * 60_000;\n\n/** How the agent follows a production it was handed (web `promoFollowSpec`). */\nexport function promoFollowSpec(opts: Pick<PromoRunOptions, 'preset' | 'quality'>): FollowSpec {\n return {\n connector: PROMO_CONNECTOR,\n action: PRODUCE_STATUS_ACTION,\n params: { projectId: 'projectId', sandboxId: 'sandboxId' },\n interval_ms: PROMO_POLL_EVERY_MS,\n deadline_ms: promoRunTimeoutMs(opts) + PROMO_FOLLOW_SLACK_MS,\n state_key: 'state',\n succeeded: ['succeeded'],\n failed: ['failed'],\n };\n}\n\n/** How the agent follows a lip sync it was handed (web `LIPSYNC_FOLLOW`). */\nexport const LIPSYNC_FOLLOW: FollowSpec = {\n connector: 'yantra-audio',\n action: 'YANTRA_AUDIO_LIPSYNC_STATUS',\n params: { statusUrl: 'statusUrl', responseUrl: 'responseUrl' },\n interval_ms: 5_000,\n deadline_ms: 15 * 60_000,\n state_key: 'status',\n succeeded: ['completed'],\n failed: ['failed'],\n};\n\n/**\n * How the agent follows a render it was handed (web `RENDER_FOLLOW`): STATUS\n * with the SUBMIT handle's snake_case ids, every ten seconds, for the plan's\n * hour and a bit - the lease is only known once the SUBMIT answers, and the\n * agent's deadline is set before that.\n */\nexport const RENDER_FOLLOW: FollowSpec = {\n connector: VIDEO_EDIT_CONNECTOR,\n action: RENDER_STATUS_ACTION,\n params: { sandbox_id: 'sandbox_id', run_id: 'run_id' },\n interval_ms: RENDER_POLL_EVERY_MS,\n deadline_ms: RENDER_POLL_MAX_MS,\n state_key: 'state',\n succeeded: ['succeeded'],\n failed: ['failed'],\n};\n\nexport const isSettledStatus = (status: string | undefined): boolean => status === 'COMPLETED' || status === 'BLOCKED';\n\n// ── Transport ────────────────────────────────────────────────────────────────\n\nexport interface GraphqlResult {\n data?: Record<string, any>;\n errors?: { message?: string }[];\n}\n\nexport interface TaskApiTransport {\n post(query: string, variables?: Record<string, unknown>): Promise<GraphqlResult>;\n}\n\n/** fetch against the backend GraphQL with the surface bearer. */\nexport function createTaskApiTransport(token: string, graphqlUrl: string): TaskApiTransport {\n return {\n async post(query, variables = {}) {\n const resp = await fetch(graphqlUrl, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` },\n body: JSON.stringify({ query, variables }),\n });\n const body = (await resp.json().catch(() => ({}))) as GraphqlResult;\n const text = (body.errors ?? []).map((e) => e.message || 'error').join('; ');\n if (!resp.ok) throw new Error(`task api: HTTP ${resp.status}${text ? `: ${text}` : ''}`);\n if (body.errors?.length) throw new Error(`task api: ${text}`);\n return body;\n },\n };\n}\n\nlet transport: TaskApiTransport | null = null;\nlet owner: string | undefined;\n\n/**\n * Point the Task API at this session. CanvasExperience calls it whenever the\n * token or index changes; without a backend the transport is null and every\n * call below answers \"nothing\" rather than throwing.\n */\nexport function configureServerTasks(session: { token?: string | null; indexUrl?: string | null }): void {\n const graphqlUrl = session.indexUrl ? deriveBackendGraphqlUrl(session.indexUrl) : null;\n transport = session.token && graphqlUrl ? createTaskApiTransport(session.token, graphqlUrl) : null;\n const sub = tokenClaims(session.token).sub;\n owner = typeof sub === 'string' && sub ? sub : undefined;\n}\n\n/** Tests only. */\nexport function setTaskApiTransport(next: TaskApiTransport | null): void {\n transport = next;\n}\n\nexport const taskApiTransport = (): TaskApiTransport | null => transport;\n/** The JWT subject of who is signed in, for a job's owner. */\nexport const currentOwner = (): string | undefined => owner;\n\n// ── Capability ───────────────────────────────────────────────────────────────\n\nlet missing = new WeakMap<TaskApiTransport, Set<string>>();\nconst isMissing = (t: TaskApiTransport, field: string): boolean => missing.get(t)?.has(field) === true;\nfunction markMissing(t: TaskApiTransport, field: string): void {\n const set = missing.get(t) ?? new Set<string>();\n set.add(field);\n missing.set(t, set);\n}\nconst isMissingField = (err: unknown, field: string): boolean =>\n new RegExp(`Cannot query field [\"']${field}[\"']`).test(err instanceof Error ? err.message : String(err ?? ''));\n\n/** Ask a field the backend may not have. `undefined` when it does not (now or since). */\nasync function optionalField(\n t: TaskApiTransport,\n field: string,\n query: string,\n variables: Record<string, unknown>,\n): Promise<unknown> {\n if (isMissing(t, field)) return undefined;\n try {\n const res = await t.post(query, variables);\n return res.data?.[field] ?? null;\n } catch (err) {\n if (!isMissingField(err, field)) throw err;\n markMissing(t, field);\n return undefined;\n }\n}\n\n// ── The calls ────────────────────────────────────────────────────────────────\n\nconst ROW = 'id title description status createdAt updatedAt source { type id details }';\n\nconst RECORD = `mutation SurfaceJobRecord($job: JSON!) {\n recordSurfaceJob(job: $job) { id status reportToken }\n}`;\nconst PATCH = `mutation SurfaceJobPatch($id: ID!, $patch: JSON!) {\n updateSurfaceJob(id: $id, patch: $patch)\n}`;\nconst CLAIM = `mutation SurfaceJobClaim($id: ID!) {\n claimSurfaceJobDelivery(id: $id)\n}`;\nconst DELETE = `mutation SurfaceJobDelete($id: ID!) {\n removeSurfaceJob(id: $id)\n}`;\nconst LIST_OWN = `query SurfaceJobsOwn($surface: String, $limit: Int) {\n getSurfaceJobs(surface: $surface, limit: $limit) { ${ROW} }\n}`;\nconst READ_OWN = `query SurfaceJobOne($id: ID!) {\n getSurfaceJob(id: $id) { ${ROW} }\n}`;\n\n/** Record (or find) a job's row. Idempotent: the same local job always lands on the same row. */\nexport async function recordSurfaceJob(t: TaskApiTransport, job: JobRecord): Promise<ServerJob | null> {\n const rec = (await optionalField(t, 'recordSurfaceJob', RECORD, { job: browserDetails(job) })) as\n | {\n id?: unknown;\n status?: unknown;\n reportToken?: unknown;\n }\n | null\n | undefined;\n if (!rec || typeof rec.id !== 'string' || !rec.id) return null;\n return {\n remoteId: rec.id,\n ...(typeof rec.status === 'string' ? { status: rec.status } : {}),\n ...(typeof rec.reportToken === 'string' && rec.reportToken ? { reportToken: rec.reportToken } : {}),\n };\n}\n\nconst PATCH_KEYS = [\n 'progress',\n 'stage',\n 'results',\n 'error',\n 'delivered',\n 'state',\n 'startedAt',\n 'endedAt',\n 'title',\n 'brief',\n 'input',\n 'handle',\n 'deadlineAt',\n] as const;\n\n/** What an update sends: the fields this job HAS, merged into the row field by field. */\nexport function surfaceJobPatch(job: JobRecord): Record<string, unknown> {\n const wire = browserDetails(job);\n const patch: Record<string, unknown> = {};\n for (const key of PATCH_KEYS) if (wire[key] !== undefined) patch[key] = wire[key];\n return patch;\n}\n\n/** Merge a patch into a row. The server ignores a state change once the agent has given its verdict. */\nexport async function updateSurfaceJob(\n t: TaskApiTransport,\n remoteId: string,\n patch: Record<string, unknown>,\n): Promise<boolean> {\n return (await optionalField(t, 'updateSurfaceJob', PATCH, { id: remoteId, patch })) === true;\n}\n\n/**\n * Claim the right to place a finished job's result: true for exactly one\n * caller however many devices have the board open. Undefined when the backend\n * predates claims - the caller then places on its own record's word.\n */\nexport async function claimDelivery(t: TaskApiTransport, remoteId: string): Promise<boolean | undefined> {\n const value = await optionalField(t, 'claimSurfaceJobDelivery', CLAIM, { id: remoteId });\n return value === undefined ? undefined : value === true;\n}\n\nexport async function removeSurfaceJob(t: TaskApiTransport, remoteId: string): Promise<boolean> {\n return (await optionalField(t, 'removeSurfaceJob', DELETE, { id: remoteId })) === true;\n}\n\nfunction rowsOf(value: unknown): RemoteTaskRow[] {\n if (Array.isArray(value)) return value as RemoteTaskRow[];\n const data = (value as { data?: unknown } | null)?.data;\n return Array.isArray(data) ? (data as RemoteTaskRow[]) : [];\n}\n\n/** The caller's own jobs for one surface, newest first. Empty against a backend without them. */\nexport async function listRemoteJobs(t: TaskApiTransport, surface = CANVAS_SURFACE, limit = 100): Promise<JobRecord[]> {\n const own = await optionalField(t, 'getSurfaceJobs', LIST_OWN, { surface, limit });\n if (own === undefined) return [];\n const jobs: JobRecord[] = [];\n for (const row of rowsOf(own)) {\n const job = jobFromTaskRow(row);\n if (job && job.surface === surface) jobs.push(job);\n }\n return jobs;\n}\n\n/** One of the caller's jobs; null when gone or not theirs, undefined when the backend cannot read one row. */\nexport async function getRemoteJob(t: TaskApiTransport, remoteId: string): Promise<JobRecord | null | undefined> {\n const row = await optionalField(t, 'getSurfaceJob', READ_OWN, { id: remoteId });\n if (row === undefined) return undefined;\n return jobFromTaskRow(row as RemoteTaskRow | null);\n}\n\n// ── Recording before the submit ──────────────────────────────────────────────\n\ninterface HeldJob {\n remoteId: string;\n reportToken?: string;\n}\n\nconst pendingJobs = new Map<string, Promise<ServerJob | null>>();\nconst heldJobs = new Map<string, HeldJob>();\n\n/** Record a job before its work is submitted; null after the budget, or without a backend. */\nexport async function recordServerJob(\n t: TaskApiTransport,\n job: JobRecord,\n budgetMs = SERVER_JOB_BUDGET_MS,\n): Promise<ServerJob | null> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const outOfTime = new Promise<null>((resolve) => {\n timer = setTimeout(() => resolve(null), budgetMs);\n });\n try {\n return await Promise.race([recordSurfaceJob(t, job).catch(() => null), outOfTime]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Record a local job on the server and hold its report token for\n * {@link serverJobRef}. `exists` is asked once the answer is in: a record\n * dismissed meanwhile takes its row down rather than leaving an orphan.\n */\nexport function recordLocalJob(\n job: JobRecord,\n options: { exists?: () => boolean; budgetMs?: number; transport?: TaskApiTransport | null } = {},\n): Promise<ServerJob | null> {\n const t = options.transport === undefined ? transport : options.transport;\n const key = jobKey(job);\n if (!t) return Promise.resolve(null);\n const recorded = recordServerJob(t, job, options.budgetMs)\n .then((server) => {\n if (!server) return null;\n if (options.exists && !options.exists()) {\n void removeSurfaceJob(t, server.remoteId).catch(() => undefined);\n return null;\n }\n heldJobs.set(key, {\n remoteId: server.remoteId,\n // A row already settled keeps its verdict: no request may hand it out again.\n ...(server.reportToken && !isSettledStatus(server.status) ? { reportToken: server.reportToken } : {}),\n });\n return server;\n })\n .catch(() => null);\n pendingJobs.set(key, recorded);\n return recorded;\n}\n\n/**\n * The `job` field for the request whose outcome IS this job's outcome, or\n * undefined to send none. Waits for the job's recording (its budget at most).\n */\nexport async function serverJobRef(\n key: string,\n extras: { expects?: JobExpectation; follow?: FollowSpec } = {},\n): Promise<SurfaceJobRef | undefined> {\n await pendingJobs.get(key);\n const held = heldJobs.get(key);\n if (!held?.reportToken) return undefined;\n return {\n task_id: held.remoteId,\n report_token: held.reportToken,\n ...(extras.expects ? { expects: extras.expects } : {}),\n ...(extras.follow ? { follow: extras.follow } : {}),\n };\n}\n\n/** A canvas job's server id from the listing - for a run whose token a restart dropped. */\nexport async function lookupRemoteJobId(localId: string): Promise<string | undefined> {\n const t = transport;\n if (!t) return undefined;\n const jobs = await listRemoteJobs(t, CANVAS_SURFACE);\n return jobs.find((job) => job.id === localId)?.remoteId;\n}\n\n/** The server id a recorded job landed on, once it has. */\nexport const serverJobId = (key: string): string | undefined => heldJobs.get(key)?.remoteId;\n\n/** Drop a settled job's token. */\nexport function forgetServerJob(key: string): void {\n pendingJobs.delete(key);\n heldJobs.delete(key);\n}\n\n/** Tests only. */\nexport function resetServerTasks(): void {\n pendingJobs.clear();\n heldJobs.clear();\n missing = new WeakMap();\n transport = null;\n owner = undefined;\n}\n\n// ── Running the work with the job ────────────────────────────────────────────\n\n/**\n * Run a connector action carrying `job` when the runner can put it on the exec\n * body. Answers whether the job actually went out - a host seam that predates\n * the field cannot carry it, and then nobody will report on the job.\n */\nexport async function runWithJob(\n run: RunMediaAction,\n connector: MediaConnector,\n action: string,\n params: Record<string, unknown>,\n job: SurfaceJobRef | undefined,\n): Promise<{ result: Record<string, unknown>; handed: boolean }> {\n if (job && runActionAcceptsJob(run)) {\n return { result: await (run as RunMediaActionWithBody)(connector, action, params, { job }), handed: true };\n }\n return { result: await run(connector, action, params), handed: false };\n}\n\n// ── Waiting on the agent ─────────────────────────────────────────────────────\n\nexport const AGENT_VERDICT_INTERVAL_MS = 5_000;\nconst MAX_READ_MISSES = 6;\n\nexport interface AwaitAgentVerdictOptions {\n submittedAt: number;\n deadlineAt: number;\n intervalMs?: number;\n graceMs?: number;\n onProgress?: (job: JobRecord) => void;\n sleep?: (ms: number) => Promise<void>;\n now?: () => number;\n transport?: TaskApiTransport | null;\n}\n\n/**\n * Wait for the agent's verdict on one job by reading its row - for a phone\n * that is open while the agent follows the work, and so must NOT poll it too\n * (a promo sandbox dies on the first terminal STATUS answer). Resolves the row\n * once terminal; null when the agent never reported within the grace or the\n * row cannot be read - the caller then follows the work itself.\n */\nexport async function awaitAgentVerdict(\n remoteId: string,\n options: AwaitAgentVerdictOptions,\n): Promise<JobRecord | null> {\n const t = options.transport === undefined ? transport : options.transport;\n if (!t) return null;\n const {\n submittedAt,\n deadlineAt,\n intervalMs = AGENT_VERDICT_INTERVAL_MS,\n graceMs = AGENT_OWNED_GRACE_MS,\n onProgress,\n sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),\n now = () => Date.now(),\n } = options;\n let misses = 0;\n for (;;) {\n await sleep(intervalMs);\n let job: JobRecord | null | undefined;\n try {\n job = await getRemoteJob(t, remoteId);\n misses = 0;\n } catch {\n if (++misses >= MAX_READ_MISSES) return null;\n continue;\n }\n if (!job) return null;\n if (job.state !== 'running') return job;\n const at = now();\n if (agentHasJob(job)) onProgress?.(job);\n else if (at - submittedAt >= graceMs) return null;\n if (at >= deadlineAt) throw new Error(DEADLINE_VERDICT_ERROR);\n }\n}\n\n/** A row's latest line: its stage, else its progress. */\nexport function serverProgressLine(job: Pick<JobRecord, 'stage' | 'progress'>): string | undefined {\n if (job.stage) {\n const step = `Step ${job.stage.index} of ${job.stage.total}`;\n return job.stage.detail ? `${step} · ${job.stage.detail}` : `${step} · ${job.stage.label}`;\n }\n return job.progress;\n}\n\n// ── Promo ────────────────────────────────────────────────────────────────────\n\n/** The production's video from its verdict row: its results, else the STATUS answer the agent kept. */\nexport function promoVideoFromVerdict(\n job: Pick<JobRecord, 'results' | 'result'>,\n): { url: string; title?: string } | undefined {\n const video = job.results?.find((r) => r.kind === 'video' && r.url) ?? job.results?.find((r) => r.url);\n if (video) return { url: video.url, ...(video.title ? { title: video.title } : {}) };\n const answer = (job.result ?? {}) as Record<string, unknown>;\n const inner = (answer.data && typeof answer.data === 'object' ? answer.data : answer) as Record<string, unknown>;\n const nested = (inner.result && typeof inner.result === 'object' ? inner.result : inner) as Record<string, unknown>;\n const url = str(nested.url) ?? str(nested.videoUrl) ?? str(nested.video_url);\n return url ? { url, ...(str(nested.title) ? { title: str(nested.title) } : {}) } : undefined;\n}\n\n/**\n * Record a production's job and hand back the ref its SUBMIT carries (with\n * the follow spec). Undefined when there is no backend, an older one, or it\n * did not answer in two seconds.\n */\nexport async function registerPromoJob(task: CanvasTask, exists: () => boolean): Promise<SurfaceJobRef | undefined> {\n const job = canvasTaskToJob(task);\n const withOwner = owner ? { ...job, owner } : job;\n await recordLocalJob(withOwner, { exists });\n return serverJobRef(canvasJobKey(task.id), { follow: promoFollowSpec(task.request) });\n}\n\n// ── Lip sync ─────────────────────────────────────────────────────────────────\n\n/** The synced clip in an agent's verdict: its results, else the STATUS answer it kept. */\nexport function lipSyncVideoFromVerdict(verdict: Pick<JobRecord, 'results' | 'result'>): string {\n const fromResults = verdict.results?.find((r) => r.kind === 'video' && r.url)?.url;\n if (fromResults) return fromResults;\n const answer = (verdict.result ?? {}) as Record<string, unknown>;\n const inner = (answer.data && typeof answer.data === 'object' ? answer.data : answer) as Record<string, unknown>;\n return typeof inner.videoUrl === 'string' ? inner.videoUrl : '';\n}\n\nlet lipSeq = 0;\n\nexport interface TrackedLipSync {\n /** The job's id (the local half of its key). */\n id: string;\n /** The `job` for the SUBMIT, with {@link LIPSYNC_FOLLOW}; undefined when there is no record. */\n job?: SurfaceJobRef;\n /** Wait on the agent's verdict instead of polling the queue beside it; null when the agent never took it. */\n awaitAgent: (startedAt: number) => Promise<JobRecord | null>;\n /** Settle the row with the phone's own verdict (when the phone followed the queue itself). */\n settle: (outcome: { videoUrl?: string; error?: string }) => void;\n}\n\n/**\n * Record a lip sync as a canvas job so it shows in every Tasks panel and the\n * agent can finish it if the phone goes away. Never throws.\n */\nexport async function trackLipSync(input: {\n videoUrl: string;\n text?: string;\n boardId?: string | null;\n}): Promise<TrackedLipSync> {\n const id = `lipsync-${Date.now().toString(36)}-${(lipSeq++).toString(36)}`;\n const createdAt = Date.now();\n const base: JobRecord = {\n id,\n surface: CANVAS_SURFACE,\n lane: LIPSYNC_LANE,\n title: 'Lip sync',\n brief: input.text?.trim() || 'Lip sync',\n state: 'running',\n createdAt,\n startedAt: createdAt,\n deadlineAt: jobDeadlineAt(createdAt, LIPSYNC_BUDGET_MS),\n input: {\n ...(input.text ? { prompt: input.text } : {}),\n connector: 'yantra-audio',\n action: 'YANTRA_AUDIO_LIPSYNC_SUBMIT',\n params: { videoUrl: input.videoUrl, ...(input.text ? { text: input.text } : {}) },\n },\n ...(input.boardId ? { handle: { boardId: input.boardId } } : {}),\n ...(owner ? { owner } : {}),\n };\n const key = jobKey(base);\n const server = await recordLocalJob(base).catch(() => null);\n const job = server ? await serverJobRef(key, { follow: LIPSYNC_FOLLOW, expects: 'media' }) : undefined;\n return {\n id,\n ...(job ? { job } : {}),\n awaitAgent: (startedAt) =>\n server\n ? awaitAgentVerdict(server.remoteId, { submittedAt: startedAt, deadlineAt: base.deadlineAt! })\n : Promise.resolve(null),\n settle: ({ videoUrl, error }) => {\n const t = transport;\n forgetServerJob(key);\n if (!server || !t) return;\n const done: JobRecord = {\n ...base,\n state: videoUrl ? 'succeeded' : 'failed',\n endedAt: Date.now(),\n ...(videoUrl ? { results: [{ url: videoUrl, kind: 'video' as const }], delivered: true } : {}),\n ...(error ? { error } : {}),\n };\n void updateSurfaceJob(t, server.remoteId, surfaceJobPatch(done)).catch(() => undefined);\n },\n };\n}\n\n// ── Video export ─────────────────────────────────────────────────────────────\n\n/**\n * Record an export's job and hand back the ref its SUBMIT carries (with\n * {@link RENDER_FOLLOW}). Undefined when there is no backend, an older one, or\n * it did not answer in two seconds - the phone then follows the render itself.\n */\nexport async function registerExportJob(task: CanvasTask, exists: () => boolean): Promise<SurfaceJobRef | undefined> {\n const job = canvasTaskToJob(task);\n await recordLocalJob(owner ? { ...job, owner } : job, { exists });\n return serverJobRef(canvasJobKey(task.id), { follow: RENDER_FOLLOW });\n}\n\n/** The finished file in an export's verdict row: its results, else the STATUS answer the agent kept. */\nexport function exportUrlFromVerdict(job: Pick<JobRecord, 'results' | 'result'>): string | undefined {\n const hit = job.results?.find((r) => r.url);\n if (hit) return hit.url;\n const answer = (job.result ?? {}) as Record<string, unknown>;\n const inner = (answer.data && typeof answer.data === 'object' ? answer.data : answer) as Record<string, unknown>;\n return str(inner.output_url) ?? str(inner.outputUrl) ?? str(inner.url);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
const RENEWER_KEY = "__yantraCanvasSessionRenewer__";
|
|
5
|
+
function registerSessionRenewer(renewer) {
|
|
6
|
+
const holder = globalThis;
|
|
7
|
+
holder[RENEWER_KEY] = renewer;
|
|
8
|
+
return () => {
|
|
9
|
+
if (holder[RENEWER_KEY] === renewer) delete holder[RENEWER_KEY];
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function sessionRenewer() {
|
|
13
|
+
return globalThis[RENEWER_KEY];
|
|
14
|
+
}
|
|
15
|
+
class ExecFailure extends Error {
|
|
16
|
+
constructor(message, details) {
|
|
17
|
+
var _a;
|
|
18
|
+
super(message);
|
|
19
|
+
__publicField(this, "status");
|
|
20
|
+
__publicField(this, "exitCode");
|
|
21
|
+
__publicField(this, "stderr");
|
|
22
|
+
this.name = "ExecFailure";
|
|
23
|
+
this.status = details.status;
|
|
24
|
+
this.exitCode = details.exitCode;
|
|
25
|
+
this.stderr = (_a = details.stderr) != null ? _a : "";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const DOWNSTREAM_401 = /\bHTTP 401\b|\b401 Unauthorized\b|\bstatus(?: code)? 401\b/i;
|
|
29
|
+
function isAuthRefusal(err) {
|
|
30
|
+
if (!(err instanceof ExecFailure)) return false;
|
|
31
|
+
if (err.status === 401) return true;
|
|
32
|
+
if (err.status !== 200 || err.exitCode === void 0 || err.exitCode === 0) return false;
|
|
33
|
+
return DOWNSTREAM_401.test(err.message) || DOWNSTREAM_401.test(err.stderr);
|
|
34
|
+
}
|
|
35
|
+
function execFailureReason(stderr) {
|
|
36
|
+
const seen = /* @__PURE__ */ new Set();
|
|
37
|
+
const lines = [];
|
|
38
|
+
for (const raw of stderr.split("\n")) {
|
|
39
|
+
const line = raw.replace(/^\s*Error: exit status -?\d+:?\s*/, "").trim();
|
|
40
|
+
if (!line || line.startsWith("Executing:") || seen.has(line)) continue;
|
|
41
|
+
seen.add(line);
|
|
42
|
+
lines.push(line);
|
|
43
|
+
}
|
|
44
|
+
return lines.join("\n");
|
|
45
|
+
}
|
|
46
|
+
async function probeBearer(token, backend, fetchImpl = fetch, timeoutMs = 1e4) {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
if (!token || !backend) return "unreachable";
|
|
49
|
+
const controller = new AbortController();
|
|
50
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
51
|
+
try {
|
|
52
|
+
const r = await fetchImpl(backend, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: {
|
|
55
|
+
"content-type": "application/json",
|
|
56
|
+
authorization: `Bearer ${token}`
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify({
|
|
59
|
+
query: "query { getUserAccount { id } }"
|
|
60
|
+
}),
|
|
61
|
+
signal: controller.signal
|
|
62
|
+
});
|
|
63
|
+
if (r.status === 401 || r.status === 403) return "rejected";
|
|
64
|
+
if (!r.ok) return "unreachable";
|
|
65
|
+
const j = await r.json().catch(() => ({}));
|
|
66
|
+
return ((_b = (_a = j == null ? void 0 : j.data) == null ? void 0 : _a.getUserAccount) == null ? void 0 : _b.id) ? "valid" : "rejected";
|
|
67
|
+
} catch (e) {
|
|
68
|
+
return "unreachable";
|
|
69
|
+
} finally {
|
|
70
|
+
clearTimeout(timer);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const renewals = /* @__PURE__ */ new Map();
|
|
74
|
+
const replaced = /* @__PURE__ */ new Map();
|
|
75
|
+
function latestBearer(token) {
|
|
76
|
+
let current = token;
|
|
77
|
+
for (let hops = 0; hops < 8; hops += 1) {
|
|
78
|
+
const next = replaced.get(current);
|
|
79
|
+
if (!next || next === current) break;
|
|
80
|
+
current = next;
|
|
81
|
+
}
|
|
82
|
+
return current;
|
|
83
|
+
}
|
|
84
|
+
function renewRefusedBearer(sent, backend, deps = {}) {
|
|
85
|
+
var _a, _b;
|
|
86
|
+
const renewer = (_a = deps.renewer) != null ? _a : sessionRenewer();
|
|
87
|
+
if (!sent || !renewer) return Promise.resolve(null);
|
|
88
|
+
const pending = renewals.get(sent);
|
|
89
|
+
if (pending) return pending;
|
|
90
|
+
const probe = (_b = deps.probe) != null ? _b : ((token, url) => probeBearer(token, url));
|
|
91
|
+
const renewal = (async () => {
|
|
92
|
+
const current = renewer.current();
|
|
93
|
+
if (current && current !== sent) return current;
|
|
94
|
+
if (await probe(sent, backend || renewer.graphqlUrl) !== "rejected") return null;
|
|
95
|
+
const fresh = await renewer.renew().catch(() => null);
|
|
96
|
+
return fresh && fresh !== sent ? fresh : null;
|
|
97
|
+
})().then((next) => {
|
|
98
|
+
if (next) replaced.set(sent, next);
|
|
99
|
+
return next;
|
|
100
|
+
}).catch(() => null).finally(() => renewals.delete(sent));
|
|
101
|
+
renewals.set(sent, renewal);
|
|
102
|
+
return renewal;
|
|
103
|
+
}
|
|
104
|
+
async function withRenewedSignIn(sent, backend, attempt, deps = {}) {
|
|
105
|
+
const bearer = latestBearer(sent);
|
|
106
|
+
try {
|
|
107
|
+
return await attempt(bearer);
|
|
108
|
+
} catch (err) {
|
|
109
|
+
if (!isAuthRefusal(err)) throw err;
|
|
110
|
+
const next = await renewRefusedBearer(bearer, backend, deps);
|
|
111
|
+
if (!next) throw err;
|
|
112
|
+
return attempt(next);
|
|
113
|
+
}
|
|
114
|
+
}export{DOWNSTREAM_401,ExecFailure,execFailureReason,isAuthRefusal,latestBearer,probeBearer,registerSessionRenewer,renewRefusedBearer,sessionRenewer,withRenewedSignIn};//# sourceMappingURL=sessionRenewal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionRenewal.js","sources":["../../../src/features/canvas/sessionRenewal.ts"],"sourcesContent":["/**\n * Renewed sign-in retry - native twin of surface-kit `agentExec`\n * `renewRefusedBearer` / `execFailureReason` and `auth.probeToken` (kit 36a1d0f0).\n *\n * The system token is one row per user, so a workspace switch or a regenerate\n * elsewhere revokes the copy this phone holds. The agent checks only the\n * bearer's signature and still runs the connector; the platform backend\n * refuses the connector's call, and that 401 arrives INSIDE a successful exec\n * stream. So on an exec failure carrying a 401 the transport asks the backend\n * whether the bearer is really dead (probe), and only then re-mints and runs\n * the action once more. A 401 from a vendor (a bad API key) leaves the sign-in\n * alone: re-minting a token the backend still accepts revokes and re-creates\n * it, signing the person's other devices out.\n *\n * The bridge between the transport (remote) and the session (host,\n * useCanvasSession) is a renewer kept on `globalThis`, so the host bundle and\n * the federated remote share one even when each carries its own copy of this\n * module. A binary whose host registers none simply never renews.\n */\n\n/** What the session half provides: the bearer it holds now, and a forced fresh mint. */\nexport interface SessionRenewer {\n /** The token the session holds right now (may already be newer than one a runner captured). */\n current: () => string | null;\n /** Mint a fresh token (single-flight in the session); null when it could not. */\n renew: () => Promise<string | null>;\n /** The backend the session's tokens are minted against - what a probe asks. */\n graphqlUrl?: string;\n}\n\nconst RENEWER_KEY = '__yantraCanvasSessionRenewer__';\n\ntype RenewerHolder = { [RENEWER_KEY]?: SessionRenewer };\n\n/** Register the session's renewer; the returned function unregisters it (only if still the current one). */\nexport function registerSessionRenewer(renewer: SessionRenewer): () => void {\n const holder = globalThis as unknown as RenewerHolder;\n holder[RENEWER_KEY] = renewer;\n return () => {\n if (holder[RENEWER_KEY] === renewer) delete holder[RENEWER_KEY];\n };\n}\n\nexport function sessionRenewer(): SessionRenewer | undefined {\n return (globalThis as unknown as RenewerHolder)[RENEWER_KEY];\n}\n\n// ── The failure ──────────────────────────────────────────────────────────────\n\n/** An exec failure with what a retry decision needs: the agent's status, the run's exit code, its stderr. */\nexport class ExecFailure extends Error {\n readonly status: number;\n readonly exitCode?: number;\n readonly stderr: string;\n constructor(message: string, details: { status: number; exitCode?: number; stderr?: string }) {\n super(message);\n this.name = 'ExecFailure';\n this.status = details.status;\n this.exitCode = details.exitCode;\n this.stderr = details.stderr ?? '';\n }\n}\n\n/** How connectors report an HTTP 401 from whatever they called. */\nexport const DOWNSTREAM_401 = /\\bHTTP 401\\b|\\b401 Unauthorized\\b|\\bstatus(?: code)? 401\\b/i;\n\n/**\n * An exec failure carrying a 401: the agent refusing the bearer (HTTP 401), or\n * a connector run that failed with a 401 from something it called. Pure.\n */\nexport function isAuthRefusal(err: unknown): boolean {\n if (!(err instanceof ExecFailure)) return false;\n if (err.status === 401) return true;\n if (err.status !== 200 || err.exitCode === undefined || err.exitCode === 0) return false;\n return DOWNSTREAM_401.test(err.message) || DOWNSTREAM_401.test(err.stderr);\n}\n\n/**\n * The connector's own words, once. The agent ends a failed run with\n * `Error: exit status N: <the connector's last line>`, which repeats what the\n * connector already printed, and banners every action with an `Executing:`\n * line; neither tells a reader anything. Every distinct line is kept, in order.\n */\nexport function execFailureReason(stderr: string): string {\n const seen = new Set<string>();\n const lines: string[] = [];\n for (const raw of stderr.split('\\n')) {\n const line = raw.replace(/^\\s*Error: exit status -?\\d+:?\\s*/, '').trim();\n if (!line || line.startsWith('Executing:') || seen.has(line)) continue;\n seen.add(line);\n lines.push(line);\n }\n return lines.join('\\n');\n}\n\n// ── The probe ────────────────────────────────────────────────────────────────\n\nexport type ProbeResult = 'valid' | 'rejected' | 'unreachable';\n\n/**\n * Ask the backend whose `token` is. Only an explicit auth refusal condemns\n * it: 401/403, or a 200 that names no account. 5xx, offline or a timeout is\n * `unreachable` - the deployment's problem, not the token's.\n */\nexport async function probeBearer(\n token: string,\n backend: string | null | undefined,\n fetchImpl: typeof fetch = fetch,\n timeoutMs = 10_000,\n): Promise<ProbeResult> {\n if (!token || !backend) return 'unreachable';\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const r = await fetchImpl(backend, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` },\n body: JSON.stringify({ query: 'query { getUserAccount { id } }' }),\n signal: controller.signal,\n });\n if (r.status === 401 || r.status === 403) return 'rejected';\n if (!r.ok) return 'unreachable';\n const j = (await r.json().catch(() => ({}))) as { data?: { getUserAccount?: { id?: string } | null } };\n return j?.data?.getUserAccount?.id ? 'valid' : 'rejected';\n } catch {\n return 'unreachable';\n } finally {\n clearTimeout(timer);\n }\n}\n\n// ── The renewal ──────────────────────────────────────────────────────────────\n\nexport interface RenewDeps {\n renewer?: SessionRenewer;\n probe?: (token: string, backend: string | null | undefined) => Promise<ProbeResult>;\n}\n\nconst renewals = new Map<string, Promise<string | null>>();\n/** A refused bearer -> the one that replaced it, so a runner built on the old one sends the new one next time. */\nconst replaced = new Map<string, string>();\n\n/** The newest bearer known to replace `token` (itself when none did). */\nexport function latestBearer(token: string): string {\n let current = token;\n for (let hops = 0; hops < 8; hops += 1) {\n const next = replaced.get(current);\n if (!next || next === current) break;\n current = next;\n }\n return current;\n}\n\n/**\n * The bearer to run once more with after `sent` was refused, or null to give\n * up with the original error. Single-flight per refused bearer: a screen load\n * fails several actions at once, and they share one probe and one mint.\n */\nexport function renewRefusedBearer(\n sent: string,\n backend: string | null | undefined,\n deps: RenewDeps = {},\n): Promise<string | null> {\n const renewer = deps.renewer ?? sessionRenewer();\n if (!sent || !renewer) return Promise.resolve(null);\n const pending = renewals.get(sent);\n if (pending) return pending;\n const probe = deps.probe ?? ((token: string, url: string | null | undefined) => probeBearer(token, url));\n const renewal = (async () => {\n // Renewed elsewhere while this run was in flight.\n const current = renewer.current();\n if (current && current !== sent) return current;\n if ((await probe(sent, backend || renewer.graphqlUrl)) !== 'rejected') return null;\n const fresh = await renewer.renew().catch(() => null);\n return fresh && fresh !== sent ? fresh : null;\n })()\n .then((next) => {\n if (next) replaced.set(sent, next);\n return next;\n })\n .catch(() => null)\n .finally(() => renewals.delete(sent));\n renewals.set(sent, renewal);\n return renewal;\n}\n\n/**\n * Run `attempt` with `sent`; on a 401 failure whose bearer the backend\n * condemns, re-mint and run it exactly once more with the fresh bearer.\n */\nexport async function withRenewedSignIn<T>(\n sent: string,\n backend: string | null | undefined,\n attempt: (bearer: string) => Promise<T>,\n deps: RenewDeps = {},\n): Promise<T> {\n const bearer = latestBearer(sent);\n try {\n return await attempt(bearer);\n } catch (err) {\n if (!isAuthRefusal(err)) throw err;\n const next = await renewRefusedBearer(bearer, backend, deps);\n if (!next) throw err;\n return attempt(next);\n }\n}\n\n/** Tests only. */\nexport function resetSessionRenewal(): void {\n renewals.clear();\n replaced.clear();\n delete (globalThis as unknown as RenewerHolder)[RENEWER_KEY];\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -50,12 +50,27 @@ light.position.set(2,4,3);scene.add(light);
|
|
|
50
50
|
const ambient=new THREE.AmbientLight(0xffffff,0.45);scene.add(ambient);
|
|
51
51
|
const ground=new THREE.Mesh(new THREE.CircleGeometry(4,48),new THREE.MeshStandardMaterial({color:0x2a2a30,roughness:0.9}));
|
|
52
52
|
ground.rotation.x=-Math.PI/2;scene.add(ground);
|
|
53
|
+
const grid=new THREE.GridHelper(8,16,0x4a4a55,0x34343c);grid.position.y=0.002;scene.add(grid);
|
|
53
54
|
function fit(){const w=innerWidth,h=innerHeight;camera.aspect=w/Math.max(1,h);camera.updateProjectionMatrix();renderer.setSize(w,h,false);}
|
|
54
55
|
addEventListener('resize',fit);fit();
|
|
55
56
|
function post(type,payload){window.ReactNativeWebView&&window.ReactNativeWebView.postMessage(JSON.stringify({type,...payload}));}
|
|
56
57
|
/* A generated model or world that will not load must say so, not draw nothing. */
|
|
57
58
|
function failed(what){return ()=>post('loadError',{what});}
|
|
58
|
-
|
|
59
|
+
/* The panorama rides an inside-out sphere rather than scene.background, so
|
|
60
|
+
"Turn the world" is a plain rotation (three 0.160 has no backgroundRotation). */
|
|
61
|
+
let worldSphere=null;let worldRot=0;
|
|
62
|
+
if(worldUrl){new THREE.TextureLoader().load(worldUrl,tex=>{
|
|
63
|
+
tex.colorSpace=THREE.SRGBColorSpace;
|
|
64
|
+
const geo=new THREE.SphereGeometry(90,64,32);geo.scale(-1,1,1);
|
|
65
|
+
worldSphere=new THREE.Mesh(geo,new THREE.MeshBasicMaterial({map:tex}));
|
|
66
|
+
worldSphere.rotation.y=worldRot;scene.add(worldSphere);
|
|
67
|
+
const env=tex.clone();env.mapping=THREE.EquirectangularReflectionMapping;env.needsUpdate=true;scene.environment=env;
|
|
68
|
+
},undefined,failed('world'));}
|
|
69
|
+
function setWorld(w){
|
|
70
|
+
worldRot=(w.rotationDeg||0)*D2R;if(worldSphere)worldSphere.rotation.y=worldRot;
|
|
71
|
+
if(!worldUrl&&typeof w.background==='string'){try{scene.background=new THREE.Color(w.background);}catch(e){}}
|
|
72
|
+
const g=w.showGround!==false;ground.visible=g;grid.visible=g;
|
|
73
|
+
}
|
|
59
74
|
let gltfLoader=null;
|
|
60
75
|
function loadGlb(url,ok,bad){
|
|
61
76
|
(gltfLoader?Promise.resolve(gltfLoader):import('three/addons/loaders/GLTFLoader.js').then(({GLTFLoader})=>(gltfLoader=new GLTFLoader())))
|
|
@@ -168,6 +183,7 @@ function onMessage(ev){
|
|
|
168
183
|
if(msg.type==='moveObject'&&msg.object){const rec=live.get(msg.object.id);if(rec)place(rec.holder,msg.object);}
|
|
169
184
|
if(msg.type==='removeObject'&&msg.id)removeObject(msg.id);
|
|
170
185
|
if(msg.type==='setLight'&&msg.lighting)setLight(msg.lighting);
|
|
186
|
+
if(msg.type==='setWorld'&&msg.world)setWorld(msg.world);
|
|
171
187
|
if(msg.type==='frameObject'&&msg.id)frameObject(msg.id);
|
|
172
188
|
}
|
|
173
189
|
addEventListener('message',onMessage);
|
|
@@ -181,6 +197,7 @@ function SetViewportWebView({
|
|
|
181
197
|
camera,
|
|
182
198
|
objects,
|
|
183
199
|
lighting,
|
|
200
|
+
world,
|
|
184
201
|
onFrame,
|
|
185
202
|
onLoadError,
|
|
186
203
|
webRef
|
|
@@ -193,6 +210,8 @@ function SetViewportWebView({
|
|
|
193
210
|
objectsRef.current = objects;
|
|
194
211
|
const lightingRef = useRef(lighting);
|
|
195
212
|
lightingRef.current = lighting;
|
|
213
|
+
const worldRef = useRef(world);
|
|
214
|
+
worldRef.current = world;
|
|
196
215
|
const html = useMemo(() => setViewportHtml({
|
|
197
216
|
worldUrl,
|
|
198
217
|
meshOrImageUrl: propUrl,
|
|
@@ -240,6 +259,10 @@ function SetViewportWebView({
|
|
|
240
259
|
type: "setLight",
|
|
241
260
|
lighting: l
|
|
242
261
|
}),
|
|
262
|
+
setWorld: (w) => send({
|
|
263
|
+
type: "setWorld",
|
|
264
|
+
world: w
|
|
265
|
+
}),
|
|
243
266
|
frameObject: (id) => send({
|
|
244
267
|
type: "frameObject",
|
|
245
268
|
id
|
|
@@ -258,6 +281,12 @@ function SetViewportWebView({
|
|
|
258
281
|
lighting
|
|
259
282
|
});
|
|
260
283
|
}, [lighting]);
|
|
284
|
+
useEffect(() => {
|
|
285
|
+
if (world) send({
|
|
286
|
+
type: "setWorld",
|
|
287
|
+
world
|
|
288
|
+
});
|
|
289
|
+
}, [world == null ? void 0 : world.rotationDeg, world == null ? void 0 : world.background, world == null ? void 0 : world.showGround]);
|
|
261
290
|
const firstCamera = useRef(true);
|
|
262
291
|
useEffect(() => {
|
|
263
292
|
if (firstCamera.current) {
|
|
@@ -285,6 +314,10 @@ function SetViewportWebView({
|
|
|
285
314
|
type: "setLight",
|
|
286
315
|
lighting: (_a = lightingRef.current) != null ? _a : DEFAULT_LIGHTING
|
|
287
316
|
});
|
|
317
|
+
if (worldRef.current) send({
|
|
318
|
+
type: "setWorld",
|
|
319
|
+
world: worldRef.current
|
|
320
|
+
});
|
|
288
321
|
if ((_b = objectsRef.current) == null ? void 0 : _b.length) send({
|
|
289
322
|
type: "objects",
|
|
290
323
|
objects: objectsRef.current
|