@hypit/hypit 0.1.3 → 0.1.5
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/README.md +5 -3
- package/dist/public/caption.d.ts +206 -183
- package/dist/public/composition.d.ts +25 -3
- package/dist/public/endpoint-kit.d.ts +24 -2
- package/dist/public/generation.d.ts +5 -1
- package/dist/public/hyperframes.d.ts +19 -1
- package/dist/public/narrative.d.ts +17 -3
- package/dist/public/performance.d.ts +1590 -0
- package/dist/public/program-space.d.ts +179 -32
- package/dist/public/runtime-kit.d.ts +21 -8
- package/dist/public/sound.d.ts +822 -0
- package/dist/public/speech.d.ts +41 -0
- package/dist/public/studio-adapter.d.ts +107 -16
- package/dist/public/temporal-markup.d.ts +9 -44
- package/dist/public/temporal.d.ts +37 -28
- package/dist/public/{semantic-track.d.ts → timeline.d.ts} +62 -49
- package/examples/README.md +18 -10
- package/examples/minimal-author-package/packages/example-component/preview/preview.svml +19 -12
- package/examples/minimal-author-package/packages/example-component/src/component.ts +5 -5
- package/examples/minimal-author-package/packages/example-component/src/fragment.ts +3 -5
- package/examples/minimal-author-package/packages/example-component/src/manifest.ts +8 -10
- package/examples/minimal-author-package/packages/example-component/src/surface.ts +2 -2
- package/examples/provider-package/README.md +78 -0
- package/examples/provider-package/hypit.runtime.json +12 -0
- package/examples/provider-package/packages/provider-images/package.json +11 -0
- package/examples/provider-package/packages/provider-images/src/activation.ts +24 -0
- package/examples/provider-package/packages/provider-images/src/provider.ts +122 -0
- package/examples/provider-package/packages/provider-images/tsconfig.json +9 -0
- package/examples/semantic-composition/README.md +6 -0
- package/examples/semantic-composition/chat.svml +6 -5
- package/examples/semantic-composition/packages/chat-scene/README.md +3 -3
- package/examples/semantic-composition/packages/chat-scene/src/activation.ts +18 -21
- package/examples/semantic-composition/packages/chat-scene/src/render.ts +4 -4
- package/examples/semantic-composition/packages/performance-styles/README.md +42 -0
- package/examples/semantic-composition/packages/performance-styles/package.json +25 -0
- package/examples/semantic-composition/packages/performance-styles/src/activation.ts +57 -0
- package/examples/semantic-composition/packages/performance-styles/src/render.ts +54 -0
- package/examples/semantic-composition/packages/performance-styles/src/studio.ts +28 -0
- package/examples/semantic-composition/packages/performance-styles/tsconfig.json +18 -0
- package/examples/semantic-composition/packages/responsive-explainer/README.md +16 -9
- package/examples/semantic-composition/packages/responsive-explainer/src/activation.ts +12 -12
- package/examples/semantic-composition/packages/responsive-explainer/src/render.ts +5 -5
- package/examples/semantic-composition/packages/sound-styles/README.md +36 -0
- package/examples/semantic-composition/packages/sound-styles/package.json +25 -0
- package/examples/semantic-composition/packages/sound-styles/src/activation.ts +53 -0
- package/examples/semantic-composition/packages/sound-styles/src/render.ts +14 -0
- package/examples/semantic-composition/packages/sound-styles/tsconfig.json +18 -0
- package/package.json +35 -15
- package/packages/audio-track/README.md +20 -13
- package/packages/audio-track/package.json +1 -1
- package/packages/audio-track/src/component.ts +4 -4
- package/packages/audio-track/src/fragment.ts +6 -5
- package/packages/audio-track/src/index.ts +1 -1
- package/packages/audio-track/src/manifest.ts +17 -16
- package/packages/audio-track/src/program.ts +21 -25
- package/packages/audio-track/src/surface.ts +19 -18
- package/packages/audio-track-studio/README.md +23 -0
- package/packages/audio-track-studio/src/index.ts +33 -19
- package/packages/author-kit/README.md +1 -1
- package/packages/background-removal/README.md +4 -7
- package/packages/browser-capture/package.json +1 -1
- package/packages/build-result/README.md +69 -0
- package/packages/build-result/package.json +2 -1
- package/packages/build-result/src/decode.ts +12 -8
- package/packages/build-result/src/execution-log.ts +17 -0
- package/packages/build-result/src/file-reference.ts +42 -0
- package/packages/build-result/src/index.ts +4 -0
- package/packages/build-result/src/replace-file-windows.ts +58 -0
- package/packages/build-result/src/replace-file.ts +11 -0
- package/packages/build-result/src/store.ts +58 -14
- package/packages/build-result/src/types.ts +41 -8
- package/packages/build-result/src/writer.ts +12 -1
- package/packages/build-result-fs/README.md +23 -1
- package/packages/build-result-s3/README.md +5 -0
- package/packages/build-result-s3/src/repository.ts +23 -5
- package/packages/caption/README.md +61 -73
- package/packages/caption/package.json +3 -2
- package/packages/caption/src/activation.ts +2 -2
- package/packages/caption/src/component.ts +20 -5
- package/packages/caption/src/display.ts +3 -18
- package/packages/caption/src/fragment.ts +3 -7
- package/packages/caption/src/index.ts +6 -5
- package/packages/caption/src/manifest.ts +29 -46
- package/packages/caption/src/style.ts +24 -135
- package/packages/caption/src/surface.ts +12 -92
- package/packages/caption/src/temporalize.ts +18 -53
- package/packages/caption/src/types.ts +8 -35
- package/packages/caption/src/visibility.ts +23 -0
- package/packages/caption-fine/README.md +31 -11
- package/packages/caption-fine/package.json +4 -2
- package/packages/caption-fine/src/component.ts +3 -3
- package/packages/caption-fine/src/fragment.ts +7 -19
- package/packages/caption-fine/src/index.ts +2 -0
- package/packages/caption-fine/src/manifest.ts +27 -18
- package/packages/caption-fine/src/recipe.ts +7 -0
- package/packages/caption-fine/src/render.ts +62 -49
- package/packages/caption-fine/src/schedule.ts +39 -35
- package/packages/caption-fine/src/style.ts +10 -9
- package/packages/caption-fine/src/surface.ts +62 -35
- package/packages/caption-fine/src/types.ts +2 -0
- package/packages/caption-fine-studio/README.md +24 -2
- package/packages/caption-fine-studio/package.json +10 -3
- package/packages/caption-fine-studio/src/activation.ts +3 -3
- package/packages/caption-fine-studio/src/index.ts +61 -40
- package/packages/cli/README.md +81 -3
- package/packages/cli/package.json +1 -0
- package/packages/cli/src/arguments.ts +39 -15
- package/packages/cli/src/build-planning.ts +9 -3
- package/packages/cli/src/command.ts +7 -1
- package/packages/cli/src/commands/environment.ts +66 -27
- package/packages/cli/src/commands/execution.ts +81 -26
- package/packages/cli/src/commands/results.ts +7 -11
- package/packages/cli/src/index.ts +2 -2
- package/packages/cli/src/machine-view.ts +15 -5
- package/packages/cli/src/main.ts +38 -42
- package/packages/cli/src/observation.ts +7 -1
- package/packages/cli/src/output.ts +92 -34
- package/packages/cli/src/result-export.ts +22 -13
- package/packages/cli/src/run-file.ts +19 -8
- package/packages/cli/src/view.ts +64 -18
- package/packages/comment-sticker/README.md +3 -3
- package/packages/comment-sticker/package.json +1 -1
- package/packages/comment-sticker/src/component.ts +4 -4
- package/packages/comment-sticker/src/fragment.ts +5 -4
- package/packages/comment-sticker/src/manifest.ts +7 -6
- package/packages/comment-sticker/src/program.ts +9 -9
- package/packages/comment-sticker/src/surface.ts +6 -7
- package/packages/comment-sticker-studio/src/index.ts +2 -1
- package/packages/compiler-node/src/compiler.ts +1 -0
- package/packages/composition/README.md +21 -0
- package/packages/composition/src/audio-presentation.ts +44 -0
- package/packages/composition/src/index.ts +3 -0
- package/packages/composition/src/schema.ts +8 -3
- package/packages/composition/src/track.ts +15 -1
- package/packages/credential-store-env/README.md +1 -1
- package/packages/deck-track/README.md +3 -3
- package/packages/deck-track/package.json +1 -1
- package/packages/deck-track/src/component.ts +5 -5
- package/packages/deck-track/src/fragment.ts +6 -5
- package/packages/deck-track/src/lower.ts +12 -12
- package/packages/deck-track/src/manifest.ts +8 -7
- package/packages/deck-track/src/program.ts +13 -16
- package/packages/deck-track/src/surface.ts +9 -10
- package/packages/driver-node/src/driver.ts +41 -3
- package/packages/elevenlabs-speech/README.md +27 -0
- package/packages/{provider-xiaomi-mimo → elevenlabs-speech}/package.json +5 -8
- package/packages/elevenlabs-speech/src/activation.ts +26 -0
- package/packages/elevenlabs-speech/src/fragment.ts +11 -0
- package/packages/elevenlabs-speech/src/index.ts +111 -0
- package/packages/elevenlabs-speech/src/surface.ts +167 -0
- package/packages/endpoint-kit/README.md +24 -0
- package/packages/endpoint-kit/src/index.ts +7 -1
- package/packages/estimate/README.md +56 -3
- package/packages/estimate/src/program.ts +7 -8
- package/packages/film/README.md +12 -7
- package/packages/film/package.json +1 -1
- package/packages/film/src/component.ts +4 -4
- package/packages/film/src/fragment.ts +6 -5
- package/packages/film/src/manifest.ts +11 -10
- package/packages/film/src/program.ts +5 -5
- package/packages/film/src/recipe.ts +2 -1
- package/packages/film/src/surface.ts +6 -6
- package/packages/film-studio/package.json +1 -1
- package/packages/film-studio/src/index.ts +2 -2
- package/packages/fishaudio-speech/README.md +33 -0
- package/packages/fishaudio-speech/package.json +21 -0
- package/packages/fishaudio-speech/src/activation.ts +32 -0
- package/packages/fishaudio-speech/src/fragment.ts +11 -0
- package/packages/fishaudio-speech/src/index.ts +156 -0
- package/packages/fishaudio-speech/src/surface.ts +192 -0
- package/packages/fonts-open/README.md +5 -0
- package/packages/fonts-open/package.json +5 -1
- package/packages/fonts-open/src/studio.ts +21 -0
- package/packages/generation/README.md +11 -1
- package/packages/generation/src/mapping.ts +28 -30
- package/packages/gpt-image/README.md +1 -2
- package/packages/grok-imagine/README.md +1 -2
- package/packages/hyperframes/README.md +7 -3
- package/packages/hyperframes/src/browser-program.ts +11 -2
- package/packages/hyperframes/src/document.ts +15 -2
- package/packages/interview-emoji-reveal/README.md +4 -4
- package/packages/interview-emoji-reveal/package.json +1 -1
- package/packages/interview-emoji-reveal/src/component.ts +4 -4
- package/packages/interview-emoji-reveal/src/fragment.ts +6 -5
- package/packages/interview-emoji-reveal/src/manifest.ts +9 -8
- package/packages/interview-emoji-reveal/src/program.ts +14 -14
- package/packages/interview-emoji-reveal/src/surface.ts +8 -9
- package/packages/media-execution/README.md +7 -3
- package/packages/media-execution/src/audio-presentation.ts +23 -0
- package/packages/media-execution/src/execute.ts +2 -0
- package/packages/media-pipeline/README.md +7 -3
- package/packages/media-pipeline/src/audio-plan.ts +4 -1
- package/packages/media-pipeline/src/component.ts +16 -2
- package/packages/media-pipeline/src/manifest.ts +3 -1
- package/packages/media-pipeline/src/types.ts +2 -1
- package/packages/media-track/README.md +14 -47
- package/packages/media-track/package.json +1 -1
- package/packages/media-track/preview/preview.svml +5 -5
- package/packages/media-track/src/author.ts +12 -6
- package/packages/media-track/src/component.ts +10 -16
- package/packages/media-track/src/fragment.ts +8 -7
- package/packages/media-track/src/index.ts +3 -1
- package/packages/media-track/src/lower.ts +7 -7
- package/packages/media-track/src/manifest.ts +16 -38
- package/packages/media-track/src/program.ts +62 -67
- package/packages/media-track/src/sampling.ts +6 -6
- package/packages/media-track/src/sequence.ts +8 -8
- package/packages/media-track/src/surface.ts +25 -43
- package/packages/media-track-studio/README.md +9 -0
- package/packages/media-track-studio/src/index.ts +23 -13
- package/packages/mimo-speech/README.md +1 -1
- package/packages/minimax-h3/README.md +1 -1
- package/packages/nano-banana/README.md +1 -1
- package/packages/narrative/README.md +23 -1
- package/packages/narrative/src/identity.ts +11 -0
- package/packages/narrative/src/index.ts +3 -0
- package/packages/narrative/src/schema.ts +28 -27
- package/packages/narrative/src/selection.ts +52 -0
- package/packages/narrative/src/types.ts +2 -0
- package/packages/package-loader-node/README.md +30 -0
- package/packages/package-loader-node/package.json +5 -2
- package/packages/package-loader-node/src/distribution-resolution.ts +10 -3
- package/packages/package-loader-node/src/index.ts +1 -0
- package/packages/package-loader-node/src/loader.ts +12 -15
- package/packages/package-loader-node/src/location.ts +27 -1
- package/packages/package-loader-node/src/module-scope.ts +183 -0
- package/packages/package-loader-node/src/types.ts +4 -0
- package/packages/performance/README.md +83 -0
- package/packages/performance/package.json +30 -0
- package/packages/performance/src/activation.ts +11 -0
- package/packages/performance/src/component.ts +46 -0
- package/packages/performance/src/index.ts +6 -0
- package/packages/performance/src/manifest.ts +53 -0
- package/packages/{media-track/src/performance.ts → performance/src/media.ts} +9 -10
- package/packages/performance/src/program.ts +51 -0
- package/packages/performance/src/style.ts +35 -0
- package/packages/performance/src/surface.ts +99 -0
- package/packages/performance-studio/README.md +25 -0
- package/packages/performance-studio/package.json +21 -0
- package/packages/performance-studio/src/activation.ts +6 -0
- package/packages/performance-studio/src/index.ts +84 -0
- package/packages/program-space/README.md +9 -18
- package/packages/program-space/src/activation.ts +1 -5
- package/packages/program-space/src/index.ts +2 -11
- package/packages/program-space/src/surface.ts +1 -20
- package/packages/project-context-node/README.md +20 -0
- package/packages/project-context-node/package.json +10 -0
- package/packages/project-context-node/src/index.ts +3 -0
- package/packages/{cli → project-context-node}/src/runtime-selection.ts +7 -2
- package/packages/provider-hyperframes-local/README.md +43 -15
- package/packages/provider-hyperframes-local/src/activation.ts +4 -3
- package/packages/provider-hyperframes-local/src/capture-process.ts +26 -4
- package/packages/provider-hyperframes-local/src/capture.ts +96 -26
- package/packages/provider-hyperframes-local/src/concurrency.ts +86 -0
- package/packages/provider-hyperframes-local/src/opaque-capture.ts +92 -0
- package/packages/provider-hyperframes-local/src/options.ts +2 -0
- package/packages/provider-hyperframes-local/src/program.ts +6 -3
- package/packages/provider-hyperframes-local/src/progress.ts +53 -0
- package/packages/provider-hyperframes-local/src/provider.ts +18 -5
- package/packages/provider-hyperframes-local/src/render.ts +48 -7
- package/packages/provider-hypihub/README.md +48 -17
- package/packages/provider-hypihub/package.json +2 -0
- package/packages/provider-hypihub/src/mapping.ts +31 -7
- package/packages/provider-hypihub/src/oauth.ts +6 -0
- package/packages/provider-hypihub/src/provider.ts +25 -13
- package/packages/provider-hypihub/src/routes.ts +1 -2
- package/packages/provider-hypihub/src/upload.ts +2 -0
- package/packages/provider-media-local/README.md +3 -4
- package/packages/provider-whisperx-local/README.md +57 -0
- package/packages/provider-whisperx-local/src/program.ts +1 -0
- package/packages/provider-whisperx-local/src/provider.ts +3 -0
- package/packages/ranking/README.md +8 -6
- package/packages/ranking/package.json +1 -1
- package/packages/ranking/src/component.ts +6 -6
- package/packages/ranking/src/fragment.ts +11 -7
- package/packages/ranking/src/manifest.ts +21 -14
- package/packages/ranking/src/render.ts +33 -35
- package/packages/ranking/src/schedule.ts +16 -19
- package/packages/ranking/src/surface.ts +12 -13
- package/packages/ranking-studio/README.md +29 -0
- package/packages/ranking-studio/package.json +8 -3
- package/packages/ranking-studio/src/index.ts +71 -12
- package/packages/render-hyperframes/README.md +7 -7
- package/packages/render-hyperframes/package.json +1 -1
- package/packages/render-hyperframes/src/component.ts +11 -1
- package/packages/render-hyperframes/src/fragment.ts +7 -4
- package/packages/render-hyperframes/src/manifest.ts +4 -4
- package/packages/render-hyperframes/src/surface.ts +6 -6
- package/packages/runtime/README.md +8 -1
- package/packages/runtime/src/catalog.ts +2 -0
- package/packages/runtime/src/execution.ts +15 -4
- package/packages/runtime/src/index.ts +2 -1
- package/packages/runtime/src/log.ts +51 -0
- package/packages/runtime/src/types.ts +5 -8
- package/packages/runtime-host-node/README.md +30 -0
- package/packages/runtime-host-node/package.json +1 -0
- package/packages/runtime-host-node/src/index.ts +25 -9
- package/packages/runtime-host-node/src/packages.ts +47 -50
- package/packages/runtime-kit/README.md +5 -0
- package/packages/runtime-kit/src/index.ts +3 -1
- package/packages/runtime-local/README.md +111 -4
- package/packages/runtime-local/src/config.ts +202 -56
- package/packages/runtime-local/src/control.ts +9 -1
- package/packages/runtime-local/src/executor.ts +66 -0
- package/packages/runtime-local/src/host.ts +37 -17
- package/packages/runtime-local/src/log.ts +48 -0
- package/packages/runtime-local/src/programs.ts +41 -25
- package/packages/runtime-local/src/result-writer.ts +2 -0
- package/packages/runtime-local/src/runtime.ts +10 -6
- package/packages/runtime-local/src/supervisor.ts +142 -0
- package/packages/runtime-local/src/types.ts +9 -2
- package/packages/runtime-local/src/worker-process.ts +7 -24
- package/packages/runtime-local/src/worker.ts +55 -83
- package/packages/screen-overlay/README.md +3 -3
- package/packages/screen-overlay/package.json +1 -1
- package/packages/screen-overlay/src/component.ts +3 -3
- package/packages/screen-overlay/src/fragment.ts +5 -4
- package/packages/screen-overlay/src/manifest.ts +7 -6
- package/packages/screen-overlay/src/program.ts +9 -9
- package/packages/screen-overlay/src/surface.ts +6 -7
- package/packages/script/README.md +37 -2
- package/packages/script/src/edit.ts +123 -73
- package/packages/script/src/lexical.ts +40 -6
- package/packages/script/src/manifest.ts +2 -2
- package/packages/script/src/narrative.ts +1 -0
- package/packages/script/src/parser.ts +36 -8
- package/packages/script/src/surface.ts +4 -3
- package/packages/script/src/types.ts +5 -1
- package/packages/script-studio/package.json +9 -3
- package/packages/script-studio/src/index.ts +2 -0
- package/packages/script-studio/src/projection.ts +105 -0
- package/packages/seedance/README.md +30 -1
- package/packages/seedance/src/index.ts +18 -7
- package/packages/seedance/src/surface.ts +17 -4
- package/packages/seedance-kits/README.md +10 -2
- package/packages/seedance-kits/kits/speaker-v1.svs +5 -5
- package/packages/seedream/README.md +1 -1
- package/packages/sound/README.md +81 -0
- package/packages/sound/package.json +25 -0
- package/packages/sound/src/activation.ts +11 -0
- package/packages/sound/src/component.ts +28 -0
- package/packages/sound/src/index.ts +5 -0
- package/packages/sound/src/manifest.ts +47 -0
- package/packages/sound/src/program.ts +84 -0
- package/packages/sound/src/style.ts +34 -0
- package/packages/sound/src/surface.ts +90 -0
- package/packages/sound-studio/README.md +22 -0
- package/packages/sound-studio/package.json +20 -0
- package/packages/sound-studio/src/activation.ts +6 -0
- package/packages/sound-studio/src/index.ts +74 -0
- package/packages/speech/README.md +2 -2
- package/packages/speech-alignment/src/align.ts +45 -21
- package/packages/speech-alignment/src/local.ts +8 -0
- package/packages/speech-alignment/src/locate.ts +1 -1
- package/packages/store-sqlite/README.md +7 -0
- package/packages/store-sqlite/src/store.ts +84 -83
- package/packages/studio/INSPECTOR.md +117 -0
- package/packages/studio/README.md +149 -14
- package/packages/studio/package.json +8 -7
- package/packages/studio/src/build-library.ts +99 -84
- package/packages/studio/src/companion-assembly.ts +1 -0
- package/packages/studio/src/domain.ts +1 -1
- package/packages/studio/src/fallback-companions.ts +3 -3
- package/packages/studio/src/feedback-server.ts +51 -0
- package/packages/studio/src/feedback-store.ts +66 -0
- package/packages/studio/src/feedback.ts +60 -0
- package/packages/studio/src/library-media.ts +19 -0
- package/packages/studio/src/parameter-values.ts +83 -1
- package/packages/studio/src/parameters.ts +132 -43
- package/packages/studio/src/preview/render.ts +5 -1
- package/packages/studio/src/preview/runtime-shim.ts +49 -3
- package/packages/studio/src/programme.ts +14 -30
- package/packages/studio/src/server.ts +66 -34
- package/packages/studio/src/shared.ts +24 -8
- package/packages/studio/src/snapshot.ts +21 -132
- package/packages/studio/src/studio-preflight.ts +3 -3
- package/packages/studio/src/studio-registry.ts +72 -6
- package/packages/studio/src/style.css +342 -190
- package/packages/studio/src/temporal-edit.ts +131 -0
- package/packages/studio/src/ui/artifact-name.ts +80 -0
- package/packages/studio/src/ui/artifact-preview.ts +99 -0
- package/packages/studio/src/ui/comments.ts +233 -0
- package/packages/studio/src/ui/icons.ts +10 -1
- package/packages/studio/src/ui/library.ts +373 -192
- package/packages/studio/src/ui/main.ts +291 -110
- package/packages/studio/src/ui/material-preview.ts +1 -1
- package/packages/studio/src/ui/overlay.ts +31 -26
- package/packages/studio/src/ui/scrub-preview.ts +108 -0
- package/packages/studio/src/ui/sidebar-panel.ts +31 -0
- package/packages/studio/src/ui/stage.ts +188 -9
- package/packages/studio/src/ui/timeline.ts +187 -281
- package/packages/studio/start.ts +19 -5
- package/packages/studio-adapter/README.md +151 -11
- package/packages/studio-adapter/src/index.ts +126 -14
- package/packages/temporal/README.md +6 -6
- package/packages/temporal/package.json +1 -1
- package/packages/temporal/src/component.ts +5 -6
- package/packages/temporal/src/index.ts +8 -6
- package/packages/temporal/src/location.ts +11 -11
- package/packages/temporal/src/projection.ts +19 -19
- package/packages/temporal/src/rational.ts +4 -4
- package/packages/temporal-markup/EDITING.md +183 -0
- package/packages/temporal-markup/README.md +31 -11
- package/packages/temporal-markup/package.json +1 -1
- package/packages/temporal-markup/src/index.ts +20 -25
- package/packages/temporal-markup/src/space.ts +10 -41
- package/packages/timeline/README.md +31 -0
- package/packages/{semantic-track → timeline}/package.json +1 -1
- package/packages/timeline/src/activation.ts +8 -0
- package/packages/timeline/src/component.ts +24 -0
- package/packages/timeline/src/identity.ts +60 -0
- package/packages/timeline/src/index.ts +6 -0
- package/packages/{semantic-track → timeline}/src/location.ts +20 -20
- package/packages/timeline/src/manifest.ts +39 -0
- package/packages/{semantic-track → timeline}/src/projection.ts +14 -14
- package/packages/timeline/src/types.ts +24 -0
- package/packages/timeline-author/README.md +68 -0
- package/packages/{speech-track → timeline-author}/package.json +6 -4
- package/packages/timeline-author/src/activation.ts +22 -0
- package/packages/{speech-track → timeline-author}/src/component.ts +15 -13
- package/packages/{speech-track → timeline-author}/src/fragment.ts +14 -23
- package/packages/timeline-author/src/index.ts +7 -0
- package/packages/timeline-author/src/manifest.ts +78 -0
- package/packages/timeline-author/src/program.ts +107 -0
- package/packages/timeline-author/src/surface.ts +46 -0
- package/packages/timeline-author/src/types.ts +6 -0
- package/packages/typography-track/README.md +4 -4
- package/packages/typography-track/package.json +1 -1
- package/packages/typography-track/src/component.ts +4 -4
- package/packages/typography-track/src/fragment.ts +4 -3
- package/packages/typography-track/src/manifest.ts +11 -9
- package/packages/typography-track/src/program.ts +15 -15
- package/packages/typography-track/src/surface.ts +17 -18
- package/packages/typography-track-studio/package.json +8 -3
- package/packages/typography-track-studio/src/index.ts +5 -1
- package/packages/video-cli/README.md +16 -4
- package/packages/video-cli/package.json +2 -1
- package/packages/video-cli/src/creation.ts +25 -9
- package/packages/video-cli/src/index.ts +1 -1
- package/packages/video-cli/src/studio-distribution.ts +2 -1
- package/packages/volcengine-matting/README.md +3 -3
- package/packages/whisperx/README.md +8 -1
- package/packages/workspace/src/index.ts +2 -0
- package/packages/workspace-fs-node/README.md +4 -1
- package/packages/workspace-fs-node/src/workspace.ts +3 -1
- package/services/whisperx/README.md +14 -0
- package/services/whisperx/pyproject.toml +2 -0
- package/services/whisperx/uv.lock +20 -20
- package/packages/provider-hyperframes-aws-lambda/README.md +0 -30
- package/packages/provider-hyperframes-aws-lambda/package.json +0 -30
- package/packages/provider-hyperframes-aws-lambda/src/activation.ts +0 -97
- package/packages/provider-hyperframes-aws-lambda/src/client.ts +0 -114
- package/packages/provider-hyperframes-aws-lambda/src/index.ts +0 -21
- package/packages/provider-hyperframes-aws-lambda/src/provider.ts +0 -522
- package/packages/provider-kie/README.md +0 -134
- package/packages/provider-kie/package.json +0 -43
- package/packages/provider-kie/src/activation.ts +0 -71
- package/packages/provider-kie/src/index.ts +0 -10
- package/packages/provider-kie/src/mapping.ts +0 -182
- package/packages/provider-kie/src/provider.ts +0 -657
- package/packages/provider-kie/src/routes.ts +0 -150
- package/packages/provider-xiaomi-mimo/README.md +0 -32
- package/packages/provider-xiaomi-mimo/src/activation.ts +0 -57
- package/packages/provider-xiaomi-mimo/src/index.ts +0 -5
- package/packages/provider-xiaomi-mimo/src/provider.ts +0 -214
- package/packages/runtime/src/environment.ts +0 -6
- package/packages/semantic-track/README.md +0 -21
- package/packages/semantic-track/src/activation.ts +0 -8
- package/packages/semantic-track/src/component.ts +0 -24
- package/packages/semantic-track/src/identity.ts +0 -58
- package/packages/semantic-track/src/index.ts +0 -6
- package/packages/semantic-track/src/manifest.ts +0 -38
- package/packages/semantic-track/src/types.ts +0 -26
- package/packages/speech-track/README.md +0 -51
- package/packages/speech-track/src/activation.ts +0 -19
- package/packages/speech-track/src/index.ts +0 -7
- package/packages/speech-track/src/manifest.ts +0 -73
- package/packages/speech-track/src/program.ts +0 -64
- package/packages/speech-track/src/surface.ts +0 -35
- package/packages/speech-track/src/types.ts +0 -6
- package/packages/speech-track-studio/README.md +0 -3
- package/packages/speech-track-studio/package.json +0 -14
- package/packages/speech-track-studio/src/activation.ts +0 -7
- package/packages/speech-track-studio/src/index.ts +0 -40
- /package/packages/{cli → project-context-node}/src/project-context.ts +0 -0
- /package/packages/{speech-track → timeline-author}/preview/Track.png +0 -0
|
@@ -6,7 +6,11 @@ import type {
|
|
|
6
6
|
StudioTaskView,
|
|
7
7
|
} from "../shared.js";
|
|
8
8
|
import type { CodePane } from "./code.js";
|
|
9
|
+
import { createArtifactName } from "./artifact-name.js";
|
|
10
|
+
import { audioPreview } from "./material-preview.js";
|
|
11
|
+
import { createSidebarPanel, sidebarItem } from "./sidebar-panel.js";
|
|
9
12
|
import { icon } from "./icons.js";
|
|
13
|
+
import { mergeStudioArtifacts } from "../library-media.js";
|
|
10
14
|
|
|
11
15
|
type LibrarySection = "source" | "tasks" | "artifacts";
|
|
12
16
|
|
|
@@ -14,6 +18,7 @@ export type LibraryPane = {
|
|
|
14
18
|
readonly element: HTMLElement;
|
|
15
19
|
show(snapshot: StudioSnapshot): void;
|
|
16
20
|
refresh(): Promise<void>;
|
|
21
|
+
selectArtifact(id: string | undefined): void;
|
|
17
22
|
};
|
|
18
23
|
|
|
19
24
|
function leaf(path: string): string {
|
|
@@ -26,10 +31,6 @@ function stem(path: string): string {
|
|
|
26
31
|
return dot > 0 ? name.slice(0, dot) : name;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
function compactId(value: string): string {
|
|
30
|
-
return value.length <= 18 ? value : `${value.slice(0, 9)}…${value.slice(-6)}`;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
34
|
function formatBytes(value: number): string {
|
|
34
35
|
if (value < 1_000) return `${value} B`;
|
|
35
36
|
if (value < 1_000_000) return `${(value / 1_000).toFixed(value < 10_000 ? 1 : 0)} KB`;
|
|
@@ -55,7 +56,8 @@ function emptyState(iconName: string, title: string, detail: string): HTMLElemen
|
|
|
55
56
|
|
|
56
57
|
function taskProgress(task: StudioTaskView): string | undefined {
|
|
57
58
|
const progress = task.operations.find((operation) => operation.status === "pending" && operation.phase !== undefined);
|
|
58
|
-
if (progress === undefined) return undefined
|
|
59
|
+
if (progress === undefined) return task.requests === undefined ? undefined
|
|
60
|
+
: `${task.requests.completed}/${task.requests.total} steps complete`;
|
|
59
61
|
if (progress.completed === undefined) return progress.phase;
|
|
60
62
|
const amount = progress.total === undefined
|
|
61
63
|
? String(progress.completed)
|
|
@@ -63,33 +65,60 @@ function taskProgress(task: StudioTaskView): string | undefined {
|
|
|
63
65
|
return `${progress.phase} · ${amount}${progress.unit === undefined ? "" : ` ${progress.unit}`}`;
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
function taskCard(task: StudioTaskView): HTMLElement {
|
|
68
|
+
function taskCard(task: StudioTaskView, selected: boolean, select: () => void, showMedia: () => void): HTMLElement {
|
|
67
69
|
const node = document.createElement("article");
|
|
68
|
-
node.className = `task-card task-${task.status}`;
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
node.className = `task-card task-${task.status}${selected ? " selected" : ""}`;
|
|
71
|
+
node.tabIndex = 0;
|
|
72
|
+
node.setAttribute("aria-label", task.title ?? stem(task.run ?? task.source));
|
|
73
|
+
node.addEventListener("click", select);
|
|
74
|
+
node.addEventListener("keydown", (event) => {
|
|
75
|
+
if (event.target === node && (event.key === "Enter" || event.key === " ")) { event.preventDefault(); select(); }
|
|
76
|
+
});
|
|
77
|
+
node.dataset.taskId = task.id;
|
|
78
|
+
const source = task.run ?? task.source;
|
|
79
|
+
const title = task.title ?? stem(source);
|
|
80
|
+
const statuses: Record<StudioTaskView["status"], string> = {
|
|
81
|
+
queued: "Queued", running: "Running", waiting: "Waiting", complete: "Completed",
|
|
82
|
+
failed: "Failed", cancelled: "Cancelled", "saving-result": "Saving", attention: "Needs attention",
|
|
83
|
+
};
|
|
71
84
|
node.innerHTML = `
|
|
72
|
-
<div class="task-state"
|
|
85
|
+
<div class="task-state" aria-hidden="true">${icon(task.ongoing ? "when" : task.status === "complete" ? "check" : task.status === "failed" ? "alert" : "tasks")}</div>
|
|
73
86
|
<div class="task-copy">
|
|
74
|
-
<div class="task-title"><
|
|
75
|
-
<
|
|
76
|
-
<div class="task-facts"><span data-time></span><span data-records></span><span data-command></span></div>
|
|
87
|
+
<div class="task-title"><button type="button" class="task-name"></button></div>
|
|
88
|
+
<div class="task-facts"><span class="task-status"></span><time></time></div>
|
|
77
89
|
<div class="task-progress" data-progress></div>
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
node.querySelector<HTMLElement>("
|
|
85
|
-
node.querySelector
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
<div class="task-detail" data-detail></div>
|
|
91
|
+
</div>
|
|
92
|
+
<button type="button" class="task-open" aria-label="View task media" title="View media">${icon("arrowRight")}</button>`;
|
|
93
|
+
const name = node.querySelector<HTMLButtonElement>(".task-name")!;
|
|
94
|
+
name.textContent = title;
|
|
95
|
+
name.addEventListener("click", (event) => { event.stopPropagation(); select(); });
|
|
96
|
+
node.querySelector<HTMLElement>(".task-status")!.textContent = statuses[task.status];
|
|
97
|
+
const time = node.querySelector("time")!;
|
|
98
|
+
time.dateTime = new Date(task.createdAt).toISOString();
|
|
99
|
+
time.textContent = date.format(task.createdAt);
|
|
100
|
+
const progress = task.ongoing ? taskProgress(task) : undefined;
|
|
89
101
|
const progressNode = node.querySelector<HTMLElement>("[data-progress]")!;
|
|
90
102
|
if (progress === undefined) progressNode.remove();
|
|
91
|
-
else progressNode.textContent = progress;
|
|
92
|
-
|
|
103
|
+
else { progressNode.textContent = progress; progressNode.title = progress; }
|
|
104
|
+
const detailNode = node.querySelector<HTMLElement>("[data-detail]")!;
|
|
105
|
+
if (task.detail === undefined) detailNode.remove();
|
|
106
|
+
else {
|
|
107
|
+
const message = document.createElement("div");
|
|
108
|
+
message.className = "task-error-message";
|
|
109
|
+
message.textContent = task.detail;
|
|
110
|
+
detailNode.append(message);
|
|
111
|
+
const copy = document.createElement("button");
|
|
112
|
+
copy.type = "button"; copy.className = "task-copy-error"; copy.textContent = "Copy error";
|
|
113
|
+
copy.addEventListener("click", (event) => {
|
|
114
|
+
event.stopPropagation();
|
|
115
|
+
void navigator.clipboard.writeText(task.detail!).then(() => { copy.textContent = "Copied"; }, () => { copy.textContent = "Select the text to copy"; });
|
|
116
|
+
});
|
|
117
|
+
detailNode.append(copy);
|
|
118
|
+
detailNode.addEventListener("click", (event) => { event.stopPropagation(); if (!node.classList.contains("selected")) select(); });
|
|
119
|
+
}
|
|
120
|
+
node.querySelector<HTMLButtonElement>(".task-open")!.addEventListener("click", (event) => { event.stopPropagation(); showMedia(); });
|
|
121
|
+
name.title = [title, source, task.id, task.note].filter((item) => item !== undefined).join("\n");
|
|
93
122
|
return node;
|
|
94
123
|
}
|
|
95
124
|
|
|
@@ -100,63 +129,115 @@ function artifactKind(mediaType: string): { readonly label: string; readonly ico
|
|
|
100
129
|
return { label: "Data", icon: "code" };
|
|
101
130
|
}
|
|
102
131
|
|
|
103
|
-
function
|
|
132
|
+
function sizeThumbnail(media: HTMLElement, width: number, height: number): void {
|
|
133
|
+
if (width <= 0 || height <= 0) return;
|
|
134
|
+
const longest = Math.max(width, height);
|
|
135
|
+
media.style.width = `${100 * width / longest}%`;
|
|
136
|
+
media.style.height = `${100 * height / longest}%`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function artifactCard(artifact: StudioArtifactView, open: (artifact: StudioArtifactView) => void, renamed: (artifact: StudioArtifactView) => void): HTMLElement {
|
|
104
140
|
const kind = artifactKind(artifact.mediaType);
|
|
105
|
-
const link = document.createElement("
|
|
141
|
+
const link = document.createElement("div");
|
|
142
|
+
link.tabIndex = 0;
|
|
106
143
|
link.className = `artifact-card artifact-${kind.label.toLowerCase()}${artifact.highlighted ? " artifact-highlighted" : ""}`;
|
|
107
144
|
const query = new URLSearchParams({
|
|
108
145
|
build: artifact.build,
|
|
109
146
|
output: artifact.output,
|
|
110
|
-
path: artifact.valuePath,
|
|
111
147
|
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
link.
|
|
115
|
-
|
|
148
|
+
const href = `/__studio/artifact?${query.toString()}`;
|
|
149
|
+
|
|
150
|
+
link.dataset.artifactId = artifact.id;
|
|
151
|
+
link.dataset.build = artifact.build;
|
|
152
|
+
link.dataset.output = artifact.output;
|
|
153
|
+
link.dataset.displayName = artifact.displayName ?? "";
|
|
154
|
+
link.dataset.nameEditable = String(artifact.nameEditable === true);
|
|
155
|
+
const title = artifact.displayName ?? artifact.output;
|
|
116
156
|
link.innerHTML = `
|
|
117
157
|
<div class="artifact-preview">
|
|
118
158
|
<span class="artifact-glyph">${icon(kind.icon)}</span>
|
|
119
159
|
<span class="artifact-type"></span>
|
|
120
|
-
${artifact.highlighted ? '<span class="artifact-highlight">Highlighted</span>' : ""}
|
|
121
|
-
</div>
|
|
122
|
-
<div class="artifact-copy">
|
|
123
|
-
<strong></strong>
|
|
124
|
-
<span class="artifact-meta"></span>
|
|
125
160
|
</div>`;
|
|
126
161
|
link.querySelector<HTMLElement>(".artifact-type")!.textContent = kind.label;
|
|
127
|
-
link.querySelector("
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
162
|
+
const preview = link.querySelector<HTMLElement>(".artifact-preview")!;
|
|
163
|
+
preview.setAttribute("role", "button");
|
|
164
|
+
preview.setAttribute("aria-label", `Preview ${title}`);
|
|
165
|
+
preview.addEventListener("click", () => open(artifact));
|
|
166
|
+
const name = createArtifactName({
|
|
167
|
+
name: title,
|
|
168
|
+
editable: artifact.nameEditable === true,
|
|
169
|
+
select: () => { if (!link.classList.contains("selected")) open(artifact); },
|
|
170
|
+
async save(displayName) {
|
|
171
|
+
const response = await fetch("/__studio/artifact-name", {
|
|
172
|
+
method: "PUT", headers: { "Content-Type": "application/json" },
|
|
173
|
+
body: JSON.stringify({ build: artifact.build, output: artifact.output, displayName }),
|
|
174
|
+
});
|
|
175
|
+
const result = await response.json() as { displayName?: string; error?: string };
|
|
176
|
+
if (!response.ok || typeof result.displayName !== "string") throw new Error(result.error ?? "Could not save the name");
|
|
177
|
+
artifact = { ...artifact, displayName: result.displayName };
|
|
178
|
+
link.dataset.displayName = result.displayName;
|
|
179
|
+
renamed(artifact);
|
|
180
|
+
preview.setAttribute("aria-label", `Preview ${result.displayName}`);
|
|
181
|
+
preview.title = [result.displayName, ...preview.title.split("\n").slice(1)].join("\n");
|
|
182
|
+
return result.displayName;
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
link.append(name.element);
|
|
186
|
+
link.addEventListener("keydown", (event) => {
|
|
187
|
+
if (event.target instanceof HTMLTextAreaElement) return;
|
|
188
|
+
if (event.key === "F2") { event.preventDefault(); name.edit(); }
|
|
189
|
+
else if (event.key === "Enter" && event.target === link) { event.preventDefault(); open(artifact); }
|
|
190
|
+
});
|
|
133
191
|
if (artifact.mediaType.startsWith("image/")) {
|
|
134
192
|
const image = document.createElement("img");
|
|
135
|
-
image.
|
|
193
|
+
image.addEventListener("load", () => sizeThumbnail(image, image.naturalWidth, image.naturalHeight));
|
|
194
|
+
image.addEventListener("error", () => { link.classList.add("preview-unavailable"); link.querySelector<HTMLElement>(".artifact-type")!.textContent = "Preview unavailable"; });
|
|
195
|
+
image.src = href;
|
|
136
196
|
image.alt = "";
|
|
137
197
|
image.loading = "lazy";
|
|
138
198
|
link.querySelector<HTMLElement>(".artifact-preview")!.prepend(image);
|
|
199
|
+
} else if (artifact.mediaType.startsWith("video/")) {
|
|
200
|
+
const video = document.createElement("video");
|
|
201
|
+
video.preload = "none";
|
|
202
|
+
video.muted = true;
|
|
203
|
+
video.playsInline = true;
|
|
204
|
+
video.dataset.previewSource = href;
|
|
205
|
+
video.setAttribute("aria-hidden", "true");
|
|
206
|
+
const label = link.querySelector<HTMLElement>(".artifact-type")!;
|
|
207
|
+
label.textContent = "Video · Loading preview";
|
|
208
|
+
const ready = () => {
|
|
209
|
+
if (video.readyState < 2 || video.seeking) return;
|
|
210
|
+
video.classList.add("is-ready");
|
|
211
|
+
label.textContent = "Video";
|
|
212
|
+
};
|
|
213
|
+
video.addEventListener("loadedmetadata", () => {
|
|
214
|
+
sizeThumbnail(video, video.videoWidth, video.videoHeight);
|
|
215
|
+
video.currentTime = Number.isFinite(video.duration) ? Math.min(0.1, video.duration / 2) : 0.1;
|
|
216
|
+
}, { once: true });
|
|
217
|
+
video.addEventListener("loadeddata", ready);
|
|
218
|
+
video.addEventListener("seeked", ready);
|
|
219
|
+
video.addEventListener("error", () => { label.textContent = "Preview unavailable"; link.classList.add("preview-unavailable"); });
|
|
220
|
+
link.querySelector<HTMLElement>(".artifact-preview")!.prepend(video);
|
|
221
|
+
} else if (artifact.mediaType.startsWith("audio/")) {
|
|
222
|
+
const waveform = document.createElement("img");
|
|
223
|
+
waveform.className = "artifact-waveform";
|
|
224
|
+
waveform.alt = "";
|
|
225
|
+
waveform.dataset.audioSource = href;
|
|
226
|
+
link.querySelector<HTMLElement>(".artifact-preview")!.prepend(waveform);
|
|
139
227
|
}
|
|
140
|
-
|
|
228
|
+
preview.title = [
|
|
141
229
|
title,
|
|
142
230
|
artifact.mediaType,
|
|
143
|
-
|
|
144
|
-
|
|
231
|
+
formatBytes(artifact.size),
|
|
232
|
+
date.format(artifact.createdAt),
|
|
233
|
+
artifact.ownerBuild === undefined ? artifact.filePath : `${artifact.ownerBuild}/${artifact.filePath}`,
|
|
234
|
+
...artifact.origins.map((origin) => `${origin.run ?? origin.source} · ${origin.build} · ${origin.output}`),
|
|
145
235
|
artifact.buildNote,
|
|
146
236
|
].filter((item) => item !== undefined).join("\n");
|
|
147
237
|
return link;
|
|
148
238
|
}
|
|
149
239
|
|
|
150
|
-
function
|
|
151
|
-
const button = document.createElement("button");
|
|
152
|
-
button.type = "button";
|
|
153
|
-
button.className = "library-older";
|
|
154
|
-
button.textContent = "Load older";
|
|
155
|
-
button.addEventListener("click", load);
|
|
156
|
-
return button;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function createLibraryPane(code: CodePane): LibraryPane {
|
|
240
|
+
export function createLibraryPane(code: CodePane, openArtifact: (artifact: StudioArtifactView) => void, renamedArtifact: (artifact: StudioArtifactView) => void): LibraryPane {
|
|
160
241
|
const element = document.createElement("section");
|
|
161
242
|
element.className = "library";
|
|
162
243
|
element.innerHTML = `
|
|
@@ -172,46 +253,83 @@ export function createLibraryPane(code: CodePane): LibraryPane {
|
|
|
172
253
|
</button>
|
|
173
254
|
</div>
|
|
174
255
|
<section class="library-view active" data-library-view="source">
|
|
175
|
-
<div class="source-workspace" data-source-workspace>
|
|
176
|
-
<div class="source-sidebar-heading">
|
|
177
|
-
<span class="source-sidebar-mark" aria-hidden="true">${icon("sidebarCollapse")}</span>
|
|
178
|
-
</div>
|
|
179
|
-
<div class="source-code-heading" data-source-toolbar></div>
|
|
180
|
-
<nav class="source-files" aria-label="Referenced source files" data-source-files></nav>
|
|
181
|
-
<div class="source-code" data-source-code></div>
|
|
182
|
-
</div>
|
|
183
|
-
</section>
|
|
184
|
-
<section class="library-view" data-library-view="tasks">
|
|
185
|
-
<div class="library-toolbar">
|
|
186
|
-
<div><strong>Build Results</strong><small data-task-count></small></div>
|
|
187
|
-
<button type="button" class="library-refresh" data-library-refresh aria-label="Refresh tasks" title="Refresh">${icon("refresh")}</button>
|
|
188
|
-
</div>
|
|
189
|
-
<div class="library-context-row" data-runtime-context></div>
|
|
190
|
-
<div class="task-list" data-task-list></div>
|
|
191
256
|
</section>
|
|
257
|
+
<section class="library-view" data-library-view="tasks"></section>
|
|
192
258
|
<section class="library-view" data-library-view="artifacts">
|
|
193
|
-
<div class="library-toolbar">
|
|
194
|
-
<div><strong>Accepted artifacts</strong><small data-artifact-count></small></div>
|
|
195
|
-
<button type="button" class="library-refresh" data-library-refresh aria-label="Refresh artifacts" title="Refresh">${icon("refresh")}</button>
|
|
196
|
-
</div>
|
|
197
|
-
<div class="artifact-filters" role="tablist" aria-label="Artifact kinds" data-artifact-filters></div>
|
|
198
|
-
<div class="artifact-grid" data-artifact-grid></div>
|
|
199
259
|
</section>`;
|
|
200
260
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
261
|
+
const sourcePanel = createSidebarPanel("panel", "Referenced source files");
|
|
262
|
+
sourcePanel.toolbar.append(code.toolbar);
|
|
263
|
+
sourcePanel.content.classList.add("source-code");
|
|
264
|
+
sourcePanel.content.append(code.element);
|
|
265
|
+
element.querySelector('[data-library-view="source"]')!.append(sourcePanel.element);
|
|
266
|
+
const taskPanel = createSidebarPanel("panel", "Task categories");
|
|
267
|
+
taskPanel.toolbar.innerHTML = `<span class="code-location" data-task-heading>All tasks</span><div class="task-context" data-task-context hidden></div>
|
|
268
|
+
<button type="button" class="library-refresh" data-library-refresh aria-label="Refresh tasks" title="Refresh">${icon("refresh")}</button>`;
|
|
269
|
+
taskPanel.content.innerHTML = `<div class="media-status" data-library-status="tasks" role="status" hidden></div><div class="task-list" data-task-list></div>`;
|
|
270
|
+
element.querySelector('[data-library-view="tasks"]')!.append(taskPanel.element);
|
|
271
|
+
const mediaPanel = createSidebarPanel("panel", "Media categories");
|
|
272
|
+
mediaPanel.toolbar.innerHTML = `<span class="code-location" data-media-heading>All media</span><div class="task-context" data-task-context hidden></div>
|
|
273
|
+
<button type="button" class="library-refresh" data-library-refresh aria-label="Refresh media" title="Refresh">${icon("refresh")}</button>`;
|
|
274
|
+
mediaPanel.content.innerHTML = `<div class="media-status" data-library-status="artifacts" role="status" hidden></div><div class="artifact-grid" data-artifact-grid></div>`;
|
|
275
|
+
element.querySelector('[data-library-view="artifacts"]')!.append(mediaPanel.element);
|
|
276
|
+
const sourceList = sourcePanel.navigation;
|
|
204
277
|
const taskList = element.querySelector<HTMLElement>("[data-task-list]")!;
|
|
205
278
|
const artifactGrid = element.querySelector<HTMLElement>("[data-artifact-grid]")!;
|
|
206
|
-
const artifactFilters =
|
|
207
|
-
const runtimeContext = element.querySelector<HTMLElement>("[data-runtime-context]")!;
|
|
279
|
+
const artifactFilters = mediaPanel.navigation;
|
|
208
280
|
let snapshot: StudioSnapshot | undefined;
|
|
209
281
|
let selectedSource = "";
|
|
210
282
|
let active: LibrarySection = "source";
|
|
211
|
-
|
|
283
|
+
const libraries: Partial<Record<"tasks" | "artifacts", StudioLibraryView>> = {};
|
|
284
|
+
let taskFilter: "all" | "ongoing" | "finished" = "all";
|
|
212
285
|
let artifactFilter = "all";
|
|
213
|
-
let
|
|
214
|
-
let
|
|
286
|
+
let selectedArtifact: string | undefined;
|
|
287
|
+
let selectedTask: StudioTaskView | undefined;
|
|
288
|
+
let request: AbortController | undefined;
|
|
289
|
+
const morePages = new IntersectionObserver((entries) => {
|
|
290
|
+
for (const entry of entries) {
|
|
291
|
+
const node = entry.target as HTMLElement;
|
|
292
|
+
const section = node.dataset.moreSection as "tasks" | "artifacts";
|
|
293
|
+
if (!entry.isIntersecting || request !== undefined || active !== section) continue;
|
|
294
|
+
morePages.unobserve(node);
|
|
295
|
+
void refresh(section, node.dataset.before);
|
|
296
|
+
}
|
|
297
|
+
}, { rootMargin: "0px 0px 120px 0px" });
|
|
298
|
+
const continuation = (section: "tasks" | "artifacts", cursor: string): HTMLElement => {
|
|
299
|
+
const node = document.createElement("div");
|
|
300
|
+
node.className = "library-continuation";
|
|
301
|
+
node.dataset.moreSection = section;
|
|
302
|
+
node.dataset.before = cursor;
|
|
303
|
+
node.textContent = "Loading more…";
|
|
304
|
+
return node;
|
|
305
|
+
};
|
|
306
|
+
const selectArtifact = (id: string | undefined): void => {
|
|
307
|
+
selectedArtifact = id;
|
|
308
|
+
for (const card of Array.from(artifactGrid.querySelectorAll<HTMLElement>("[data-artifact-id]"))) {
|
|
309
|
+
const selected = card.dataset.artifactId === id;
|
|
310
|
+
card.classList.toggle("selected", selected);
|
|
311
|
+
if (selected) card.setAttribute("aria-current", "true");
|
|
312
|
+
else card.removeAttribute("aria-current");
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
const videoPreviews = new IntersectionObserver((entries) => {
|
|
316
|
+
for (const entry of entries) {
|
|
317
|
+
if (!entry.isIntersecting) continue;
|
|
318
|
+
videoPreviews.unobserve(entry.target);
|
|
319
|
+
if (entry.target instanceof HTMLImageElement) {
|
|
320
|
+
const image = entry.target;
|
|
321
|
+
void audioPreview(image.dataset.audioSource!).then((url) => {
|
|
322
|
+
if (url === undefined || !image.isConnected) return;
|
|
323
|
+
image.src = url;
|
|
324
|
+
image.classList.add("is-ready");
|
|
325
|
+
});
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
const video = entry.target as HTMLVideoElement;
|
|
329
|
+
video.preload = "metadata";
|
|
330
|
+
video.src = video.dataset.previewSource!;
|
|
331
|
+
}
|
|
332
|
+
}, { root: artifactGrid });
|
|
215
333
|
|
|
216
334
|
const renderSources = (): void => {
|
|
217
335
|
if (snapshot === undefined) return;
|
|
@@ -224,75 +342,140 @@ export function createLibraryPane(code: CodePane): LibraryPane {
|
|
|
224
342
|
selectedSource = code.activePath() ?? snapshot.source.path;
|
|
225
343
|
}
|
|
226
344
|
sourceList.replaceChildren(...files.map((file) => {
|
|
227
|
-
const button =
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
button.title = `${file.role} · ${file.path}${file.imports.length === 0 ? "" : `\nimports ${file.imports.join(", ")}`}`;
|
|
233
|
-
button.addEventListener("click", () => {
|
|
234
|
-
selectedSource = file.path;
|
|
235
|
-
renderSources();
|
|
345
|
+
const button = sidebarItem({
|
|
346
|
+
label: `${stem(file.path)} ${file.language.toUpperCase()}`,
|
|
347
|
+
icon: file.language === "svrun" ? "run" : file.language === "svs" ? "tune" : "code",
|
|
348
|
+
selected: file.path === selectedSource,
|
|
349
|
+
select: () => { selectedSource = file.path; renderSources(); },
|
|
236
350
|
});
|
|
351
|
+
button.title = `${file.role} · ${file.path}${file.imports.length === 0 ? "" : `\nimports ${file.imports.join(", ")}`}`;
|
|
237
352
|
return button;
|
|
238
353
|
}));
|
|
239
354
|
};
|
|
240
355
|
|
|
356
|
+
const renderTaskContext = (): void => {
|
|
357
|
+
for (const node of Array.from(element.querySelectorAll<HTMLElement>("[data-task-context]"))) {
|
|
358
|
+
const title = selectedTask === undefined ? undefined : selectedTask.title ?? stem(selectedTask.run ?? selectedTask.source);
|
|
359
|
+
if (selectedTask !== undefined && node.dataset.taskId === selectedTask.id
|
|
360
|
+
&& node.querySelector(".task-context-name span")?.textContent === title) continue;
|
|
361
|
+
node.replaceChildren();
|
|
362
|
+
node.hidden = selectedTask === undefined;
|
|
363
|
+
node.dataset.taskId = selectedTask?.id ?? "";
|
|
364
|
+
if (selectedTask === undefined) continue;
|
|
365
|
+
const task = selectedTask;
|
|
366
|
+
const back = document.createElement("button");
|
|
367
|
+
back.type = "button"; back.className = "task-context-name";
|
|
368
|
+
back.innerHTML = "<span></span>";
|
|
369
|
+
back.querySelector("span")!.textContent = task.title ?? stem(task.run ?? task.source);
|
|
370
|
+
back.title = `${task.title ?? stem(task.run ?? task.source)} · Return to task`;
|
|
371
|
+
back.addEventListener("click", () => {
|
|
372
|
+
taskFilter = "all";
|
|
373
|
+
switchTo("tasks", false);
|
|
374
|
+
renderTasks();
|
|
375
|
+
taskList.querySelector<HTMLElement>(`[data-task-id="${CSS.escape(task.id)}"]`)?.scrollIntoView({ block: "nearest" });
|
|
376
|
+
});
|
|
377
|
+
const clear = document.createElement("button");
|
|
378
|
+
clear.type = "button"; clear.className = "task-context-clear";
|
|
379
|
+
clear.innerHTML = icon("close"); clear.title = "Clear task filter"; clear.setAttribute("aria-label", clear.title);
|
|
380
|
+
clear.addEventListener("click", () => {
|
|
381
|
+
selectedTask = undefined; delete libraries.artifacts; renderTaskContext(); renderTasks();
|
|
382
|
+
if (active === "artifacts") { renderArtifacts(); void refresh("artifacts"); }
|
|
383
|
+
});
|
|
384
|
+
node.append(back, clear);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
241
388
|
const renderTasks = (): void => {
|
|
389
|
+
for (const node of Array.from(taskList.querySelectorAll("[data-more-section]"))) morePages.unobserve(node);
|
|
390
|
+
const library = libraries.tasks;
|
|
242
391
|
const tasks = library?.tasks ?? [];
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
392
|
+
const filters = [["all", "All tasks", "component"], ["ongoing", "In progress", "when"], ["finished", "Finished", "check"]] as const;
|
|
393
|
+
const heading = taskPanel.toolbar.querySelector<HTMLElement>("[data-task-heading]")!;
|
|
394
|
+
heading.textContent = filters.find(([id]) => id === taskFilter)![1];
|
|
395
|
+
heading.title = library?.runtime === undefined ? "Saved project Results · no Runtime selected" : library.runtime;
|
|
396
|
+
taskPanel.navigation.replaceChildren(...filters.map(([id, label, mark]) => sidebarItem({
|
|
397
|
+
label, icon: mark, selected: id === taskFilter,
|
|
398
|
+
select: () => { taskFilter = id; taskList.scrollTop = 0; renderTasks(); },
|
|
399
|
+
})));
|
|
400
|
+
const tasksToShow = tasks.filter((task) => taskFilter === "all" || task.ongoing === (taskFilter === "ongoing"))
|
|
401
|
+
.sort((left, right) => Number(right.ongoing) - Number(left.ongoing) || right.createdAt - left.createdAt);
|
|
402
|
+
if (selectedTask !== undefined) selectedTask = tasks.find((task) => task.id === selectedTask!.id) ?? selectedTask;
|
|
403
|
+
const selectTask = (task: StudioTaskView): void => {
|
|
404
|
+
const changed = selectedTask?.id !== task.id;
|
|
405
|
+
selectedTask = task;
|
|
406
|
+
if (changed) delete libraries.artifacts;
|
|
407
|
+
renderTaskContext();
|
|
408
|
+
for (const card of Array.from(taskList.querySelectorAll<HTMLElement>("[data-task-id]"))) {
|
|
409
|
+
card.classList.toggle("selected", card.dataset.taskId === task.id);
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
const entries = tasksToShow.map((task) => taskCard(task, selectedTask?.id === task.id,
|
|
413
|
+
() => selectTask(task), () => { selectTask(task); switchTo("artifacts"); }));
|
|
414
|
+
renderTaskContext();
|
|
415
|
+
if (tasksToShow.length === 0) entries.push(emptyState("tasks",
|
|
416
|
+
library === undefined && request !== undefined ? "Loading tasks…" : taskFilter === "ongoing" ? "No tasks in progress" : "No tasks here",
|
|
417
|
+
taskFilter === "ongoing" && library?.runtime === undefined
|
|
418
|
+
? "No Runtime is selected. Saved tasks are available under Finished."
|
|
419
|
+
: "Refresh to read the latest task status."));
|
|
420
|
+
// Runtime activity is returned in full on the first page. Older pages contain Results only.
|
|
421
|
+
if (taskFilter !== "ongoing" && library?.next !== undefined) entries.push(continuation("tasks", library.next));
|
|
262
422
|
taskList.replaceChildren(...entries);
|
|
423
|
+
for (const node of Array.from(taskList.querySelectorAll("[data-more-section]"))) morePages.observe(node);
|
|
263
424
|
};
|
|
264
425
|
|
|
265
426
|
const renderArtifacts = (): void => {
|
|
427
|
+
videoPreviews.disconnect();
|
|
428
|
+
for (const node of Array.from(artifactGrid.querySelectorAll("[data-more-section]"))) morePages.unobserve(node);
|
|
429
|
+
const cards = new Map(Array.from(artifactGrid.querySelectorAll<HTMLElement>("[data-artifact-id]"), (card) => [card.dataset.artifactId!, card]));
|
|
430
|
+
const library = libraries.artifacts;
|
|
266
431
|
const artifacts = library?.artifacts ?? [];
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}));
|
|
282
|
-
const shown = artifactFilter === "all"
|
|
283
|
-
? artifacts
|
|
432
|
+
const filters = [["all", "All media", "component"], ["video", "Videos", "video"], ["image", "Images", "image"], ["audio", "Audio", "waveform"]] as const;
|
|
433
|
+
const heading = mediaPanel.toolbar.querySelector<HTMLElement>("[data-media-heading]")!;
|
|
434
|
+
heading.textContent = filters.find(([id]) => id === artifactFilter)?.[1] ?? "All media";
|
|
435
|
+
heading.title = "Media category";
|
|
436
|
+
renderTaskContext();
|
|
437
|
+
artifactFilters.replaceChildren(...filters.map(([id, label, mark]) => sidebarItem({
|
|
438
|
+
label, icon: mark, selected: id === artifactFilter,
|
|
439
|
+
select: () => {
|
|
440
|
+
artifactFilter = id;
|
|
441
|
+
delete libraries.artifacts;
|
|
442
|
+
artifactGrid.scrollTop = 0;
|
|
443
|
+
void refresh("artifacts");
|
|
444
|
+
renderArtifacts();
|
|
445
|
+
},
|
|
446
|
+
})));
|
|
447
|
+
const shown = artifactFilter === "all" ? artifacts
|
|
284
448
|
: artifacts.filter((artifact) => artifact.mediaType.startsWith(`${artifactFilter}/`));
|
|
285
|
-
const entries: HTMLElement[] = shown.map(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
449
|
+
const entries: HTMLElement[] = shown.map((artifact) => {
|
|
450
|
+
const held = cards.get(artifact.id);
|
|
451
|
+
cards.delete(artifact.id);
|
|
452
|
+
if (held !== undefined && held.dataset.build === artifact.build && held.dataset.output === artifact.output
|
|
453
|
+
&& held.dataset.displayName === (artifact.displayName ?? "") && held.dataset.nameEditable === String(artifact.nameEditable === true)) return held;
|
|
454
|
+
const previousVideo = held?.querySelector("video");
|
|
455
|
+
if (previousVideo != null) { previousVideo.removeAttribute("src"); previousVideo.load(); }
|
|
456
|
+
return artifactCard(artifact, openArtifact, (updated) => {
|
|
457
|
+
const current = libraries.artifacts;
|
|
458
|
+
if (current !== undefined) libraries.artifacts = { ...current,
|
|
459
|
+
artifacts: current.artifacts.map((item) => item.id === updated.id ? { ...item, displayName: updated.displayName! } : item),
|
|
460
|
+
};
|
|
461
|
+
renamedArtifact(updated);
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
for (const card of cards.values()) {
|
|
465
|
+
const video = card.querySelector("video");
|
|
466
|
+
if (video !== null) { video.removeAttribute("src"); video.load(); }
|
|
290
467
|
}
|
|
291
|
-
if (
|
|
468
|
+
if (shown.length === 0) entries.push(emptyState("results",
|
|
469
|
+
library === undefined && request !== undefined ? "Loading media…" : artifactFilter === "all" ? "No media" : `No ${artifactFilter} files`,
|
|
470
|
+
"Images, videos and audio published as file Outputs appear here, including those from ongoing Builds."));
|
|
471
|
+
if (library?.next !== undefined) entries.push(continuation("artifacts", library.next));
|
|
292
472
|
artifactGrid.replaceChildren(...entries);
|
|
473
|
+
selectArtifact(selectedArtifact);
|
|
474
|
+
for (const preview of Array.from(artifactGrid.querySelectorAll("video:not([src]), [data-audio-source]:not(.is-ready)"))) videoPreviews.observe(preview);
|
|
475
|
+
for (const node of Array.from(artifactGrid.querySelectorAll("[data-more-section]"))) morePages.observe(node);
|
|
293
476
|
};
|
|
294
477
|
|
|
295
|
-
const switchTo = (next: LibrarySection): void => {
|
|
478
|
+
const switchTo = (next: LibrarySection, reload = true): void => {
|
|
296
479
|
active = next;
|
|
297
480
|
for (const tab of Array.from(element.querySelectorAll<HTMLButtonElement>("[data-library-tab]"))) {
|
|
298
481
|
const selected = tab.dataset.libraryTab === next;
|
|
@@ -302,77 +485,75 @@ export function createLibraryPane(code: CodePane): LibraryPane {
|
|
|
302
485
|
for (const view of Array.from(element.querySelectorAll<HTMLElement>("[data-library-view]"))) {
|
|
303
486
|
view.classList.toggle("active", view.dataset.libraryView === next);
|
|
304
487
|
}
|
|
305
|
-
if (next
|
|
488
|
+
if (next === "artifacts") renderArtifacts();
|
|
489
|
+
if (next === "tasks") renderTasks();
|
|
490
|
+
if (next !== "source" && reload) void refresh(next);
|
|
491
|
+
else request?.abort();
|
|
306
492
|
};
|
|
307
493
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
const tasks = new Map(library.tasks.map((task) => [task.id, task]));
|
|
318
|
-
const artifacts = new Map(library.artifacts.map((artifact) => [artifact.id, artifact]));
|
|
319
|
-
for (const task of value.tasks) tasks.set(task.id, task);
|
|
320
|
-
for (const artifact of value.artifacts) artifacts.set(artifact.id, artifact);
|
|
321
|
-
library = {
|
|
322
|
-
environment: value.environment,
|
|
323
|
-
...(value.runtime === undefined ? {} : { runtime: value.runtime }),
|
|
324
|
-
...((append || !expanded ? value.next : library.next) === undefined
|
|
325
|
-
? {}
|
|
326
|
-
: { next: append || !expanded ? value.next : library.next }),
|
|
327
|
-
tasks: [...tasks.values()].sort((left, right) => right.createdAt - left.createdAt || left.id.localeCompare(right.id)),
|
|
328
|
-
artifacts: [...artifacts.values()].sort((left, right) =>
|
|
329
|
-
Number(right.highlighted) - Number(left.highlighted)
|
|
330
|
-
|| right.createdAt - left.createdAt
|
|
331
|
-
|| left.output.localeCompare(right.output)
|
|
332
|
-
|| left.valuePath.localeCompare(right.valuePath)),
|
|
333
|
-
};
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
const refresh = async (before?: string): Promise<void> => {
|
|
337
|
-
if (refreshing) return;
|
|
338
|
-
refreshing = true;
|
|
494
|
+
const refresh = async (section: "tasks" | "artifacts", before?: string): Promise<void> => {
|
|
495
|
+
if (before !== undefined && request !== undefined) return;
|
|
496
|
+
request?.abort();
|
|
497
|
+
const controller = new AbortController();
|
|
498
|
+
request = controller;
|
|
499
|
+
const status = element.querySelector<HTMLElement>(`[data-library-status="${section}"]`)!;
|
|
500
|
+
status.textContent = "Refreshing…";
|
|
501
|
+
status.hidden = true;
|
|
339
502
|
element.classList.add("is-refreshing");
|
|
340
503
|
try {
|
|
341
|
-
const query =
|
|
342
|
-
|
|
504
|
+
const query = new URLSearchParams({ section });
|
|
505
|
+
if (before !== undefined) query.set("before", before);
|
|
506
|
+
if (section === "artifacts" && artifactFilter !== "all") query.set("media", artifactFilter);
|
|
507
|
+
if (section === "artifacts" && selectedTask !== undefined) query.set("build", selectedTask.id);
|
|
508
|
+
const response = await fetch(`/__studio/library?${query.toString()}`, { signal: controller.signal });
|
|
343
509
|
const value = await response.json() as StudioLibraryView | { readonly error: string };
|
|
344
510
|
if (!response.ok || "error" in value) throw new Error("error" in value ? value.error : "Library unavailable");
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
511
|
+
if (controller.signal.aborted) return;
|
|
512
|
+
const previous = libraries[section];
|
|
513
|
+
if (before === undefined || previous === undefined) libraries[section] = value;
|
|
514
|
+
else {
|
|
515
|
+
const tasks = new Map(previous.tasks.map((task) => [task.id, task]));
|
|
516
|
+
for (const task of value.tasks) tasks.set(task.id, task);
|
|
517
|
+
libraries[section] = {
|
|
518
|
+
...value,
|
|
519
|
+
tasks: [...tasks.values()].sort((left, right) => right.createdAt - left.createdAt || left.id.localeCompare(right.id)),
|
|
520
|
+
artifacts: mergeStudioArtifacts([...previous.artifacts, ...value.artifacts]),
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
if (section === "tasks") renderTasks();
|
|
524
|
+
else renderArtifacts();
|
|
525
|
+
status.textContent = `Updated ${new Date().toLocaleTimeString()}`;
|
|
349
526
|
} catch (error) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
527
|
+
if (!controller.signal.aborted) {
|
|
528
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
529
|
+
status.hidden = false;
|
|
530
|
+
status.textContent = `Refresh failed: ${detail}${libraries[section] === undefined ? "" : " · Previous view retained"}`;
|
|
531
|
+
}
|
|
353
532
|
} finally {
|
|
354
|
-
|
|
355
|
-
|
|
533
|
+
if (request === controller) {
|
|
534
|
+
request = undefined;
|
|
535
|
+
element.classList.remove("is-refreshing");
|
|
536
|
+
if (controller.signal.aborted) status.textContent = "Refresh interrupted";
|
|
537
|
+
}
|
|
356
538
|
}
|
|
357
539
|
};
|
|
358
540
|
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
541
|
+
for (const tab of Array.from(element.querySelectorAll<HTMLButtonElement>("[data-library-tab]"))) {
|
|
542
|
+
tab.addEventListener("click", () => {
|
|
543
|
+
switchTo(tab.dataset.libraryTab as LibrarySection, tab.dataset.libraryTab !== "tasks" || libraries.tasks === undefined);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
363
546
|
for (const button of Array.from(element.querySelectorAll<HTMLButtonElement>("[data-library-refresh]"))) {
|
|
364
|
-
button.addEventListener("click", () => void refresh());
|
|
547
|
+
button.addEventListener("click", () => { if (active !== "source") void refresh(active); });
|
|
365
548
|
}
|
|
366
|
-
window.setInterval(() => {
|
|
367
|
-
if (document.visibilityState === "visible" && active !== "source") void refresh();
|
|
368
|
-
}, 3_000);
|
|
369
549
|
|
|
370
550
|
return {
|
|
371
551
|
element,
|
|
552
|
+
selectArtifact,
|
|
372
553
|
show(value) {
|
|
373
554
|
snapshot = value;
|
|
374
555
|
renderSources();
|
|
375
556
|
},
|
|
376
|
-
refresh,
|
|
557
|
+
refresh: async () => { if (active !== "source") await refresh(active); },
|
|
377
558
|
};
|
|
378
559
|
}
|