@hypit/hypit 0.1.4 → 0.1.6
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 +4 -2
- 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 +77 -15
- 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 +8 -1
- package/examples/semantic-composition/chat.svml +6 -5
- package/examples/semantic-composition/hypit.runtime.json +1 -1
- 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 +28 -17
- 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 +11 -0
- package/packages/build-result/src/decode.ts +2 -0
- package/packages/build-result/src/execution-log.ts +17 -0
- package/packages/build-result/src/index.ts +1 -0
- package/packages/build-result/src/store.ts +14 -1
- package/packages/build-result/src/types.ts +3 -0
- package/packages/build-result-s3/src/repository.ts +4 -0
- 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 +21 -9
- 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 +26 -17
- package/packages/caption-fine/src/recipe.ts +7 -0
- package/packages/caption-fine/src/render.ts +14 -13
- 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 +3 -1
- package/packages/caption-fine-studio/src/activation.ts +3 -3
- package/packages/caption-fine-studio/src/index.ts +54 -42
- package/packages/cli/README.md +57 -4
- package/packages/cli/package.json +1 -0
- package/packages/cli/src/arguments.ts +25 -6
- package/packages/cli/src/build-planning.ts +3 -2
- package/packages/cli/src/command.ts +6 -0
- package/packages/cli/src/commands/environment.ts +28 -18
- 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 +3 -2
- package/packages/cli/src/main.ts +34 -42
- package/packages/cli/src/observation.ts +7 -1
- package/packages/cli/src/output.ts +65 -23
- package/packages/cli/src/view.ts +66 -19
- 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/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/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 +10 -7
- 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/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 +16 -11
- 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/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 +22 -26
- package/packages/ranking/src/schedule.ts +16 -19
- package/packages/ranking/src/surface.ts +12 -13
- package/packages/ranking-studio/README.md +18 -0
- package/packages/ranking-studio/src/index.ts +61 -9
- 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/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 +24 -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 +109 -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 +2 -1
- package/packages/runtime-local/src/result-writer.ts +2 -0
- package/packages/runtime-local/src/runtime.ts +8 -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 +30 -5
- package/packages/script/src/manifest.ts +4 -3
- package/packages/script/src/narrative.ts +1 -0
- package/packages/script/src/parser.ts +45 -6
- package/packages/script/src/surface.ts +4 -3
- package/packages/script/src/types.ts +1 -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 +7 -1
- 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/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 +15 -2
- package/packages/studio/LOCALIZATION.md +98 -0
- package/packages/studio/README.md +101 -14
- package/packages/studio/locales/en.json +197 -0
- package/packages/studio/locales/zh-CN.json +191 -0
- package/packages/studio/package.json +8 -7
- 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/localization-node.ts +46 -0
- package/packages/studio/src/localization.ts +85 -0
- package/packages/studio/src/parameter-values.ts +43 -1
- package/packages/studio/src/parameters.ts +114 -24
- 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 +10 -6
- package/packages/studio/src/shared.ts +4 -2
- package/packages/studio/src/snapshot.ts +21 -132
- package/packages/studio/src/studio-preflight.ts +3 -3
- package/packages/studio/src/studio-registry.ts +50 -6
- package/packages/studio/src/style.css +223 -50
- package/packages/studio/src/ui/artifact-name.ts +8 -6
- package/packages/studio/src/ui/artifact-preview.ts +5 -4
- package/packages/studio/src/ui/code.ts +17 -16
- package/packages/studio/src/ui/comments.ts +234 -0
- package/packages/studio/src/ui/dropdown.ts +68 -0
- package/packages/studio/src/ui/i18n.ts +109 -0
- package/packages/studio/src/ui/icons.ts +6 -0
- package/packages/studio/src/ui/library.ts +76 -65
- package/packages/studio/src/ui/main.ts +223 -211
- package/packages/studio/src/ui/overlay.ts +12 -8
- package/packages/studio/src/ui/scrub-preview.ts +110 -0
- package/packages/studio/src/ui/stage.ts +93 -29
- package/packages/studio/src/ui/timeline.ts +190 -118
- package/packages/studio/start.ts +41 -22
- package/packages/studio-adapter/README.md +130 -11
- package/packages/studio-adapter/src/index.ts +100 -13
- 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 +2 -2
- package/packages/temporal-markup/README.md +27 -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/video-cli/README.md +4 -1
- package/packages/video-cli/package.json +2 -1
- package/packages/video-cli/src/creation.ts +14 -4
- 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 +1 -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
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { isAbsolute, resolve } from "node:path";
|
|
4
|
+
import type { Plugin } from "vite";
|
|
5
|
+
import { builtinLanguages, languageCoverage, readLanguagePack } from "./localization.js";
|
|
6
|
+
import type { LanguagePack } from "./localization.js";
|
|
7
|
+
|
|
8
|
+
export async function loadLanguagePack(specifier: string, cwd: string, packageRoot: string): Promise<LanguagePack> {
|
|
9
|
+
const path = isAbsolute(specifier) || specifier.startsWith(".")
|
|
10
|
+
? resolve(cwd, specifier)
|
|
11
|
+
: createRequire(resolve(packageRoot, "package.json")).resolve(specifier);
|
|
12
|
+
try { return readLanguagePack(JSON.parse(await readFile(path, "utf8"))); }
|
|
13
|
+
catch (error) { throw new Error(`Language pack ${specifier}: ${error instanceof Error ? error.message : String(error)}`); }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function describeLanguagePack(pack: LanguagePack): string {
|
|
17
|
+
const { missing, unknown } = languageCoverage(pack);
|
|
18
|
+
return [`${pack.name} (${pack.locale})`,
|
|
19
|
+
`Missing translations (${missing.length}; English is used): ${missing.join(", ") || "none"}`,
|
|
20
|
+
`Unknown message IDs (${unknown.length}): ${unknown.join(", ") || "none"}`,
|
|
21
|
+
].join("\n");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function studioLanguages(specifiers: readonly string[], cwd: string, packageRoot: string): Promise<readonly LanguagePack[]> {
|
|
25
|
+
const packs = new Map(builtinLanguages.map(pack => [pack.locale, pack]));
|
|
26
|
+
for (const specifier of specifiers) {
|
|
27
|
+
const pack = await loadLanguagePack(specifier, cwd, packageRoot);
|
|
28
|
+
packs.set(pack.locale, pack);
|
|
29
|
+
}
|
|
30
|
+
return [...packs.values()];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function studioLocalizationPlugin(packs: readonly LanguagePack[]): Plugin {
|
|
34
|
+
return {
|
|
35
|
+
name: "hypit-studio-localization",
|
|
36
|
+
configureServer(server) {
|
|
37
|
+
server.middlewares.use((request, response, next) => {
|
|
38
|
+
if (new URL(request.url ?? "/", "http://localhost").pathname !== "/__studio/locales") return next();
|
|
39
|
+
if (request.method !== "GET") { response.statusCode = 405; response.end(); return; }
|
|
40
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
41
|
+
response.setHeader("cache-control", "no-store");
|
|
42
|
+
response.end(JSON.stringify(packs));
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import english from "../locales/en.json" with { type: "json" };
|
|
2
|
+
import chinese from "../locales/zh-CN.json" with { type: "json" };
|
|
3
|
+
|
|
4
|
+
export type Message = keyof typeof english.messages;
|
|
5
|
+
export type MessageValue = string | ({ readonly other: string } & Partial<Record<Intl.LDMLPluralRule, string>>);
|
|
6
|
+
export type LanguagePack = {
|
|
7
|
+
readonly locale: string;
|
|
8
|
+
/** Native language name, displayed without translation. */
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly direction: "ltr" | "rtl";
|
|
11
|
+
readonly messages: Readonly<Record<string, MessageValue>>;
|
|
12
|
+
};
|
|
13
|
+
export const defaultLanguage: LanguagePack = english as LanguagePack;
|
|
14
|
+
export const builtinLanguages: readonly LanguagePack[] = [defaultLanguage, chinese as LanguagePack];
|
|
15
|
+
export type MessageValues = Readonly<Record<string, string | number>>;
|
|
16
|
+
const plurals = new Set(["zero", "one", "two", "few", "many", "other"]);
|
|
17
|
+
const record = (value: unknown): value is Record<string, unknown> => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18
|
+
const variants = (message: MessageValue): readonly string[] => typeof message === "string" ? [message] : Object.values(message);
|
|
19
|
+
const variables = (text: string): string[] => [...new Set([...text.matchAll(/\{(\w+)\}/gu)].map(match => match[1]!))].sort();
|
|
20
|
+
|
|
21
|
+
/** Read data, never executable translation code. Partial translations remain useful. */
|
|
22
|
+
export function readLanguagePack(value: unknown): LanguagePack {
|
|
23
|
+
if (!record(value) || typeof value.locale !== "string" || typeof value.name !== "string" || !value.name.trim()
|
|
24
|
+
|| (value.direction !== "ltr" && value.direction !== "rtl") || !record(value.messages)) {
|
|
25
|
+
throw new Error("A Studio language pack needs locale, name, direction (ltr/rtl) and messages.");
|
|
26
|
+
}
|
|
27
|
+
const locale = Intl.getCanonicalLocales(value.locale)[0];
|
|
28
|
+
if (!locale) throw new Error("A Studio language pack needs a BCP 47 locale.");
|
|
29
|
+
const messages: Record<string, MessageValue> = {};
|
|
30
|
+
for (const [id, message] of Object.entries(value.messages)) {
|
|
31
|
+
if (typeof message !== "string" && (!record(message) || typeof message.other !== "string"
|
|
32
|
+
|| Object.entries(message).some(([form, text]) => !plurals.has(form) || typeof text !== "string"))) {
|
|
33
|
+
throw new Error(`${id}: expected text or plural forms with an 'other' form.`);
|
|
34
|
+
}
|
|
35
|
+
const translated = message as MessageValue;
|
|
36
|
+
const original = Object.hasOwn(defaultLanguage.messages, id) ? defaultLanguage.messages[id] : undefined;
|
|
37
|
+
if (original !== undefined) {
|
|
38
|
+
const expected = variables(variants(original)[0]!).join(",");
|
|
39
|
+
for (const text of variants(translated)) {
|
|
40
|
+
if (variables(text).join(",") !== expected) throw new Error(`${id}: preserve the named variables {${expected.split(",").join("}, {")}}.`);
|
|
41
|
+
}
|
|
42
|
+
if (typeof translated !== "string" && !variables(variants(original)[0]!).includes("count")) {
|
|
43
|
+
throw new Error(`${id}: plural forms require a count variable.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
messages[id] = translated;
|
|
47
|
+
}
|
|
48
|
+
return { locale, name: value.name, direction: value.direction, messages };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function languageCoverage(pack: LanguagePack): { missing: string[]; unknown: string[] } {
|
|
52
|
+
return {
|
|
53
|
+
missing: Object.keys(defaultLanguage.messages).filter(id => !Object.hasOwn(pack.messages, id)),
|
|
54
|
+
unknown: Object.keys(pack.messages).filter(id => !Object.hasOwn(defaultLanguage.messages, id)),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function chooseLanguage(packs: readonly LanguagePack[], preferences: readonly string[]): LanguagePack {
|
|
59
|
+
for (const preference of preferences) {
|
|
60
|
+
let locale: string;
|
|
61
|
+
try { locale = Intl.getCanonicalLocales(preference)[0]!; } catch { continue; }
|
|
62
|
+
const exact = packs.find(pack => pack.locale === locale);
|
|
63
|
+
if (exact) return exact;
|
|
64
|
+
// Match regional/script variants without a list of special language cases.
|
|
65
|
+
const requested = new Intl.Locale(locale).maximize();
|
|
66
|
+
const related = packs.find(pack => {
|
|
67
|
+
const candidate = new Intl.Locale(pack.locale).maximize();
|
|
68
|
+
return candidate.language === requested.language && candidate.script === requested.script;
|
|
69
|
+
});
|
|
70
|
+
if (related) return related;
|
|
71
|
+
}
|
|
72
|
+
return packs.find(pack => pack.locale === defaultLanguage.locale) ?? defaultLanguage;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function formatMessage(pack: LanguagePack, id: Message, values: MessageValues = {}): string {
|
|
76
|
+
const translated = pack.messages[id];
|
|
77
|
+
const message = translated ?? defaultLanguage.messages[id]!;
|
|
78
|
+
const locale = translated === undefined ? defaultLanguage.locale : pack.locale;
|
|
79
|
+
const template = typeof message === "string" ? message
|
|
80
|
+
: message[new Intl.PluralRules(locale).select(Number(values.count))] ?? message.other;
|
|
81
|
+
return template.replace(/\{(\w+)\}/gu, (match, key: string) => {
|
|
82
|
+
const value = values[key];
|
|
83
|
+
return typeof value === "number" ? new Intl.NumberFormat(pack.locale).format(value) : value ?? match;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CanonicalValue, ValueSchema } from "@hypit/protocol";
|
|
2
2
|
import { formatSvsValue } from "@hypit/svs";
|
|
3
|
-
import type { StudioInspectorField, StudioParameterOption, StudioNumberPresentation } from "@hypit/studio-adapter";
|
|
3
|
+
import type { StudioInspectorField, StudioParameterControl, StudioParameterOption, StudioNumberPresentation } from "@hypit/studio-adapter";
|
|
4
4
|
|
|
5
5
|
export const parameterOption = (option: StudioParameterOption): Exclude<StudioParameterOption, string> =>
|
|
6
6
|
typeof option === "string" ? { value: option, label: option } : option;
|
|
@@ -119,3 +119,45 @@ export function serializeParameterValue(value: CanonicalValue, language: "svml"
|
|
|
119
119
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
120
120
|
throw new Error(`${language.toUpperCase()} parameter bindings currently accept scalar values only.`);
|
|
121
121
|
}
|
|
122
|
+
|
|
123
|
+
/** Record alternatives are selected by an explicitly literal-valued field. */
|
|
124
|
+
export function parameterRecordVariants(schema: ValueSchema): readonly {
|
|
125
|
+
key: string; value: CanonicalValue; schema: Extract<ValueSchema, { kind: "object" }>;
|
|
126
|
+
}[] {
|
|
127
|
+
if (schema.kind !== "oneOf" || !schema.variants.every(variant => variant.kind === "object")) return [];
|
|
128
|
+
const records = schema.variants as readonly Extract<ValueSchema, { kind: "object" }>[];
|
|
129
|
+
const key = Object.keys(records[0]?.fields ?? {}).find(name => records.every(record => record.fields[name]?.schema.kind === "literal")
|
|
130
|
+
&& new Set(records.map(record => JSON.stringify((record.fields[name]!.schema as { value: CanonicalValue }).value))).size === records.length);
|
|
131
|
+
return key === undefined ? [] : records.map(record => ({ key, value: (record.fields[key]!.schema as { value: CanonicalValue }).value, schema: record }));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function parameterRecordSchema(schema: ValueSchema, value: CanonicalValue): Extract<ValueSchema, { kind: "object" }> | undefined {
|
|
135
|
+
if (schema.kind === "object") return schema;
|
|
136
|
+
if (value === null || Array.isArray(value) || typeof value !== "object") return undefined;
|
|
137
|
+
return parameterRecordVariants(schema).find(variant => (value as Readonly<Record<string, CanonicalValue>>)[variant.key] === variant.value)?.schema;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Replace only a Companion-declared group; unrelated attributes and child content survive. */
|
|
141
|
+
export function serializeAttributeGroup(field: StudioInspectorField, value: CanonicalValue): string {
|
|
142
|
+
const group = field.edit?.attributes;
|
|
143
|
+
if (!group || value === null || Array.isArray(value) || typeof value !== "object") throw new Error("Expected an attribute record.");
|
|
144
|
+
const entries = Object.entries(value);
|
|
145
|
+
if (entries.some(([name]) => !Object.hasOwn(group.ranges, name))) throw new Error("Attribute is outside this group.");
|
|
146
|
+
let text = field.edit!.source.preimage;
|
|
147
|
+
const ranges = Object.values(group.ranges).filter((range): range is NonNullable<typeof range> => range !== null);
|
|
148
|
+
for (const range of ranges.sort((a, b) => b.start - a.start)) text = text.slice(0, range.start) + text.slice(range.end);
|
|
149
|
+
const attributes = entries.map(([name, held]) => ` ${name}="${serializeParameterValue(held, field.edit!.language)}"`).join("");
|
|
150
|
+
return text.slice(0, group.insertionOffset) + attributes + text.slice(group.insertionOffset);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function parameterControlForSchema(schema: ValueSchema | undefined): StudioParameterControl | undefined {
|
|
154
|
+
if (schema === undefined) return undefined;
|
|
155
|
+
if (schema.kind === "boolean") return "boolean";
|
|
156
|
+
if (schema.kind === "number") return "number";
|
|
157
|
+
if (schema.kind === "string") return schema.enum === undefined
|
|
158
|
+
? schema.format === "color" ? "color" : "text"
|
|
159
|
+
: "select";
|
|
160
|
+
if (schema.kind === "array") return "list";
|
|
161
|
+
if (schema.kind === "object" || parameterRecordVariants(schema).length > 0) return "record";
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
@@ -5,7 +5,6 @@ import type {
|
|
|
5
5
|
StudioInspectorFieldDeclaration,
|
|
6
6
|
StudioSourceBinding,
|
|
7
7
|
StudioSourceBindingDeclaration,
|
|
8
|
-
StudioParameterControl,
|
|
9
8
|
StudioRecipeReferenceBindingDeclaration,
|
|
10
9
|
StudioEntityDraft,
|
|
11
10
|
StudioEditSource,
|
|
@@ -17,6 +16,11 @@ import type {
|
|
|
17
16
|
StudioTimelineGesture,
|
|
18
17
|
} from "@hypit/studio-adapter";
|
|
19
18
|
import { parseSvs } from "@hypit/svs";
|
|
19
|
+
import { parseOpeningTag } from "@hypit/markup";
|
|
20
|
+
import { parameterControlForSchema, parameterRecordSchema } from "./parameter-values.js";
|
|
21
|
+
import type { CanonicalValue } from "@hypit/protocol";
|
|
22
|
+
|
|
23
|
+
import type { StudioCompanionRegistry } from "./studio-registry.js";
|
|
20
24
|
|
|
21
25
|
import type { Range } from "./shared.js";
|
|
22
26
|
import type { Placement } from "./observe.js";
|
|
@@ -30,6 +34,7 @@ export type StudioSourceFile = {
|
|
|
30
34
|
};
|
|
31
35
|
|
|
32
36
|
type AuthorElement = {
|
|
37
|
+
readonly range: Range;
|
|
33
38
|
readonly authorElement?: string;
|
|
34
39
|
readonly authorEndpoints: Readonly<Record<string, string>>;
|
|
35
40
|
readonly id?: string;
|
|
@@ -48,6 +53,7 @@ function authoredElements(placements: readonly Placement[]): readonly AuthorElem
|
|
|
48
53
|
...(placement.authorElement === undefined ? {} : { authorElement: placement.authorElement }),
|
|
49
54
|
authorEndpoints: placement.authorEndpoints ?? {},
|
|
50
55
|
...(placement.id === undefined ? {} : { id: placement.id }),
|
|
56
|
+
range: placement.range,
|
|
51
57
|
sourcePath: placement.sourcePath,
|
|
52
58
|
attributes: placement.attributes,
|
|
53
59
|
references: placement.referenceAttributes,
|
|
@@ -60,6 +66,7 @@ function authoredElements(placements: readonly Placement[]): readonly AuthorElem
|
|
|
60
66
|
...(child.authorElement === undefined ? {} : { authorElement: child.authorElement }),
|
|
61
67
|
authorEndpoints: child.authorEndpoints ?? {},
|
|
62
68
|
...(child.id === undefined ? {} : { id: child.id }),
|
|
69
|
+
range: child.range,
|
|
63
70
|
sourcePath: child.sourcePath,
|
|
64
71
|
attributes: child.attributes,
|
|
65
72
|
references: child.referenceAttributes,
|
|
@@ -175,7 +182,8 @@ function recipeParameters(input: {
|
|
|
175
182
|
return input.recipe.bindings.flatMap((declaration): readonly StudioSourceBinding[] => {
|
|
176
183
|
const property = recipe.properties.find((candidate) => candidate.name === declaration.name);
|
|
177
184
|
if (property === undefined) {
|
|
178
|
-
|
|
185
|
+
const fallback = typeof declaration.fallback === "function" ? declaration.fallback(recipe.value.properties) : declaration.fallback;
|
|
186
|
+
if (fallback === undefined) return [];
|
|
179
187
|
const close = recipe.range.end - 1;
|
|
180
188
|
const lineStart = Math.max(source.text.lastIndexOf("\n", close - 1), source.text.lastIndexOf("\r", close - 1)) + 1;
|
|
181
189
|
const closeIndent = source.text.slice(lineStart, close);
|
|
@@ -189,7 +197,7 @@ function recipeParameters(input: {
|
|
|
189
197
|
id: `${input.draft.id}:${input.referenceName}:${declaration.name}`,
|
|
190
198
|
binding: `${input.referenceName}.${declaration.name}`,
|
|
191
199
|
name: declaration.name,
|
|
192
|
-
value:
|
|
200
|
+
value: fallback,
|
|
193
201
|
...(declaration.schema === undefined ? {} : { schema: declaration.schema }),
|
|
194
202
|
language: "svs" as const,
|
|
195
203
|
writable: declaration.writable ?? true,
|
|
@@ -220,6 +228,57 @@ function recipeParameters(input: {
|
|
|
220
228
|
});
|
|
221
229
|
}
|
|
222
230
|
|
|
231
|
+
function attributeGroup(file: StudioSourceFile, target: AuthorElement, draft: StudioEntityDraft,
|
|
232
|
+
declaration: StudioSourceBindingDeclaration, binding: string, root: string): readonly StudioSourceBinding[] {
|
|
233
|
+
if (declaration.schema === undefined) throw new Error(`Attribute group ${binding} needs a schema.`);
|
|
234
|
+
const tag = parseOpeningTag({ name: file.path, text: file.text }, target.range.start);
|
|
235
|
+
const sourceRange = { start: target.range.start, end: tag.end };
|
|
236
|
+
const preimage = file.text.slice(sourceRange.start, sourceRange.end);
|
|
237
|
+
const opening = /^<[\w:.-]+/u.exec(preimage);
|
|
238
|
+
if (!opening) throw new Error(`Cannot locate opening tag for ${binding}.`);
|
|
239
|
+
const fallback = typeof declaration.fallback === "function" ? declaration.fallback(target.attributes) : declaration.fallback;
|
|
240
|
+
const value: Record<string, CanonicalValue> = fallback !== null && typeof fallback === "object" && !Array.isArray(fallback) ? { ...(fallback as Readonly<Record<string, CanonicalValue>>) } : {};
|
|
241
|
+
const ranges: Record<string, Range | null> = {};
|
|
242
|
+
let writable = declaration.writable === true;
|
|
243
|
+
for (const name of declaration.attributes!) {
|
|
244
|
+
const range = target.attributeValueRanges[name];
|
|
245
|
+
ranges[name] = null;
|
|
246
|
+
if (range === undefined) continue;
|
|
247
|
+
if (target.references[name] !== undefined) { writable = false; value[name] = target.references[name]!; continue; }
|
|
248
|
+
value[name] = target.attributes[name] ?? target.references[name] ?? "";
|
|
249
|
+
const before = file.text.slice(target.range.start, range.start);
|
|
250
|
+
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
251
|
+
const prefix = new RegExp(`\\s+${escaped}\\s*=\\s*["']$`, "u").exec(before);
|
|
252
|
+
if (!prefix) throw new Error(`Cannot locate scalar attribute ${name}.`);
|
|
253
|
+
ranges[name] = { start: prefix.index, end: range.end - target.range.start + 1 };
|
|
254
|
+
}
|
|
255
|
+
const schema = parameterRecordSchema(declaration.schema, value);
|
|
256
|
+
for (const [name, held] of Object.entries(value)) {
|
|
257
|
+
if (target.references[name] !== undefined || typeof held !== "string") continue;
|
|
258
|
+
const kind = schema?.fields[name]?.schema.kind;
|
|
259
|
+
if (kind === "number" && held.trim() !== "") value[name] = Number(held);
|
|
260
|
+
if (kind === "boolean" && (held === "true" || held === "false")) value[name] = held === "true";
|
|
261
|
+
}
|
|
262
|
+
return [{ id: `${draft.id}:${binding}`, binding, name: declaration.name, value, schema: declaration.schema,
|
|
263
|
+
language: file.language, writable, source: { path: relative(root, sourceAbsolute(root, target.sourcePath)),
|
|
264
|
+
range: sourceRange, preimage }, attributes: { insertionOffset: opening[0].length, ranges } }];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function omittedAttribute(file: StudioSourceFile, target: AuthorElement, draft: StudioEntityDraft,
|
|
268
|
+
declaration: StudioSourceBindingDeclaration, binding: string, root: string): readonly StudioSourceBinding[] {
|
|
269
|
+
const value = typeof declaration.fallback === "function" ? declaration.fallback(target.attributes) : declaration.fallback;
|
|
270
|
+
if (value === undefined) return [];
|
|
271
|
+
const tag = /^<[\w:.-]+/u.exec(file.text.slice(target.range.start));
|
|
272
|
+
if (tag === null) throw new Error(`Cannot locate opening tag for ${binding}.`);
|
|
273
|
+
const at = target.range.start + tag[0].length;
|
|
274
|
+
return [{ id: `${draft.id}:${binding}`, binding, name: declaration.name, value,
|
|
275
|
+
...(declaration.schema === undefined ? {} : { schema: declaration.schema }),
|
|
276
|
+
language: file.language, writable: declaration.writable === true,
|
|
277
|
+
source: { path: relative(root, sourceAbsolute(root, target.sourcePath)),
|
|
278
|
+
range: { start: at, end: at }, preimage: "", prefix: ` ${declaration.name}="`, suffix: '"' },
|
|
279
|
+
}];
|
|
280
|
+
}
|
|
281
|
+
|
|
223
282
|
function referencedParameters(input: {
|
|
224
283
|
readonly root: string;
|
|
225
284
|
readonly files: readonly StudioSourceFile[];
|
|
@@ -238,16 +297,25 @@ function referencedParameters(input: {
|
|
|
238
297
|
const file = sourceFor(input.root, target.sourcePath, input.files);
|
|
239
298
|
if (file === undefined) return [];
|
|
240
299
|
return input.declarations.flatMap((declaration) => {
|
|
300
|
+
if (declaration.attributes) return attributeGroup(file, target, input.draft, declaration, `${input.referenceName}.${declaration.name}`, input.root);
|
|
241
301
|
const nestedPath = target.references[declaration.name];
|
|
242
|
-
const
|
|
302
|
+
const referenced = nestedPath === undefined || declaration.referenced === undefined ? [] : referencedParameters({
|
|
243
303
|
root: input.root, files: input.files, draft: input.draft, placements: input.placements,
|
|
244
304
|
referenceName: `${input.referenceName}.${declaration.name}`,
|
|
245
305
|
referencePath: nestedPath,
|
|
246
306
|
...(target.resolvedReferences[declaration.name] === undefined ? {} : { referenceRef: target.resolvedReferences[declaration.name] }),
|
|
247
307
|
declarations: declaration.referenced,
|
|
248
308
|
});
|
|
309
|
+
const recipe = nestedPath === undefined || declaration.recipe === undefined ? [] : recipeParameters({
|
|
310
|
+
root: input.root, files: input.files, draft: input.draft, placements: input.placements,
|
|
311
|
+
current: file, referenceName: `${input.referenceName}.${declaration.name}`,
|
|
312
|
+
referencePath: nestedPath,
|
|
313
|
+
...(target.resolvedReferences[declaration.name] === undefined ? {} : { referenceRef: target.resolvedReferences[declaration.name] }), recipe: declaration.recipe,
|
|
314
|
+
through: declaration.recipe.through ?? [],
|
|
315
|
+
});
|
|
316
|
+
const nested = [...referenced, ...recipe];
|
|
249
317
|
const range = target.attributeValueRanges[declaration.name];
|
|
250
|
-
if (range === undefined) return nested;
|
|
318
|
+
if (range === undefined) return [...omittedAttribute(file, target, input.draft, declaration, `${input.referenceName}.${declaration.name}`, input.root), ...nested];
|
|
251
319
|
const preimage = file.text.slice(range.start, range.end);
|
|
252
320
|
const reference = target.references[declaration.name];
|
|
253
321
|
const value = reference === undefined ? (target.attributes[declaration.name] ?? preimage) : reference;
|
|
@@ -288,6 +356,37 @@ function parameterReference(
|
|
|
288
356
|
return ref === undefined ? { path } : { path, ref };
|
|
289
357
|
}
|
|
290
358
|
|
|
359
|
+
/** Resolve only references opted into by the consuming Companion. */
|
|
360
|
+
export function composeParameterDeclarations(input: {
|
|
361
|
+
readonly placement: StudioPlacement | undefined;
|
|
362
|
+
readonly draft: StudioEntityDraft;
|
|
363
|
+
readonly placements: readonly Placement[];
|
|
364
|
+
readonly registry: StudioCompanionRegistry;
|
|
365
|
+
readonly bindings: readonly StudioSourceBindingDeclaration[];
|
|
366
|
+
readonly inspector: readonly StudioInspectorFieldDeclaration[];
|
|
367
|
+
}): { bindings: readonly StudioSourceBindingDeclaration[]; inspector: readonly StudioInspectorFieldDeclaration[] } {
|
|
368
|
+
const inspector = [...input.inspector];
|
|
369
|
+
const element = input.placement === undefined ? undefined : elementFor(input.placement, input.draft);
|
|
370
|
+
const expand = (declarations: readonly StudioSourceBindingDeclaration[], owner: AuthorElement | undefined,
|
|
371
|
+
prefix: string, seen: ReadonlySet<string>): readonly StudioSourceBindingDeclaration[] => declarations.map(declaration => {
|
|
372
|
+
const path = prefix ? `${prefix}.${declaration.name}` : declaration.name;
|
|
373
|
+
const reference = prefix ? owner?.references[declaration.name] : input.draft.parameterReferences?.[declaration.name] ?? owner?.references[declaration.name];
|
|
374
|
+
const resolved = !prefix && input.draft.parameterReferences?.[declaration.name] !== undefined ? undefined : owner?.resolvedReferences[declaration.name];
|
|
375
|
+
const target = input.placements.find(candidate => resolved !== undefined
|
|
376
|
+
? candidate.records.includes(resolved) || candidate.outputs.includes(resolved)
|
|
377
|
+
: candidate.id === reference && candidate.sourcePath === owner?.sourcePath);
|
|
378
|
+
const companion = declaration.companion && target !== undefined
|
|
379
|
+
? input.registry.parameterCompanionFor(target.module, target.surface) : undefined;
|
|
380
|
+
const key = target?.authorElement ?? `${target?.sourcePath}:${target?.range.start}`;
|
|
381
|
+
if (companion !== undefined && seen.has(key)) throw new Error(`Circular Studio parameter reference at ${path}.`);
|
|
382
|
+
if (companion !== undefined) inspector.push(...companion.inspector.map(field => ({ ...field, binding: `${path}.${field.binding}` })));
|
|
383
|
+
const next = target === undefined ? undefined : elementFor(target, { ...input.draft, authoredId: target.id ?? "", elementRange: target.range });
|
|
384
|
+
const nested = [...(declaration.referenced ?? []), ...(companion?.bindings ?? [])];
|
|
385
|
+
return { ...declaration, referenced: expand(nested, next, path, new Set([...seen, key])) };
|
|
386
|
+
});
|
|
387
|
+
return { bindings: expand(input.bindings, element, "", new Set()), inspector };
|
|
388
|
+
}
|
|
389
|
+
|
|
291
390
|
/**
|
|
292
391
|
* Expose only attributes a package explicitly registered. The source range is
|
|
293
392
|
* still discovered by the generic markup frontend, while the meaning and
|
|
@@ -310,8 +409,9 @@ export function sourceBindingsForDraft(input: {
|
|
|
310
409
|
|
|
311
410
|
const direct = input.declarations.flatMap((declaration) => {
|
|
312
411
|
const name = declaration.name;
|
|
412
|
+
if (declaration.attributes) return attributeGroup(file, element, input.draft, declaration, name, input.root);
|
|
313
413
|
const range = element.attributeValueRanges[name];
|
|
314
|
-
if (range === undefined) return
|
|
414
|
+
if (range === undefined) return omittedAttribute(file, element, input.draft, declaration, name, input.root);
|
|
315
415
|
const preimage = file.text.slice(range.start, range.end);
|
|
316
416
|
const reference = element.references[name];
|
|
317
417
|
const value = reference === undefined
|
|
@@ -372,29 +472,17 @@ export function sourceBindingsForDraft(input: {
|
|
|
372
472
|
return [...direct, ...recipes];
|
|
373
473
|
}
|
|
374
474
|
|
|
375
|
-
|
|
376
|
-
if (schema === undefined) return undefined;
|
|
377
|
-
if (schema.kind === "boolean") return "boolean";
|
|
378
|
-
if (schema.kind === "number") return "number";
|
|
379
|
-
if (schema.kind === "string") return schema.enum === undefined
|
|
380
|
-
? schema.format === "color" ? "color" : "text"
|
|
381
|
-
: "select";
|
|
382
|
-
if (schema.kind === "array") return "list";
|
|
383
|
-
if (schema.kind === "object") return "record";
|
|
384
|
-
return undefined;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/** Resolve the Companion's visible field table against real writable bindings. */
|
|
475
|
+
/** Resolve the Companion's visible field table against real bindings and entity facts. */
|
|
388
476
|
export function inspectorFieldsForBindings(
|
|
389
477
|
draft: StudioEntityDraft,
|
|
390
478
|
bindings: readonly StudioSourceBinding[],
|
|
391
479
|
declarations: readonly StudioInspectorFieldDeclaration[],
|
|
392
480
|
): readonly StudioInspectorField[] {
|
|
393
481
|
const byBinding = new Map(bindings.map((binding) => [binding.binding, binding] as const));
|
|
394
|
-
|
|
482
|
+
const fields = declarations.flatMap((declaration): readonly StudioInspectorField[] => {
|
|
395
483
|
const binding = byBinding.get(declaration.binding);
|
|
396
|
-
if (binding === undefined
|
|
397
|
-
const control = declaration.control ??
|
|
484
|
+
if (binding === undefined) return [];
|
|
485
|
+
const control = declaration.control ?? (binding.attributes ? "record" : parameterControlForSchema(binding.schema));
|
|
398
486
|
if (control === undefined) {
|
|
399
487
|
throw new Error(`Studio Inspector binding ${declaration.binding} has neither a control nor a supported public schema.`);
|
|
400
488
|
}
|
|
@@ -408,10 +496,12 @@ export function inspectorFieldsForBindings(
|
|
|
408
496
|
...(declaration.options !== undefined || schemaOptions === undefined
|
|
409
497
|
? {}
|
|
410
498
|
: { options: schemaOptions }),
|
|
411
|
-
language: binding.language,
|
|
412
|
-
source: binding.source,
|
|
499
|
+
...(binding.writable ? { edit: { language: binding.language, source: binding.source, ...(binding.attributes ? { attributes: binding.attributes } : {}) } } : {}),
|
|
413
500
|
}];
|
|
414
501
|
});
|
|
502
|
+
return [...fields, ...(draft.inspector ?? []).map((fact): StudioInspectorField => ({
|
|
503
|
+
...fact, id: `${draft.id}:inspector:fact:${fact.id}`, control: "text",
|
|
504
|
+
}))];
|
|
415
505
|
}
|
|
416
506
|
|
|
417
507
|
/** Runtime authority, rather than a Companion allowlist, makes timing fields writable. */
|
|
@@ -45,7 +45,11 @@ export function renderPreview(input: RenderInput): string {
|
|
|
45
45
|
data-loop="${clip.source.loop}"
|
|
46
46
|
data-phase="${clip.source.phaseSample / 48_000}"
|
|
47
47
|
data-playback-rate="${clip.playbackRate}"
|
|
48
|
-
data-gain="${clip.gain}"
|
|
48
|
+
data-gain="${clip.gain}"
|
|
49
|
+
data-presentation="${encodeURIComponent(JSON.stringify({
|
|
50
|
+
gainEnvelope: clip.gainEnvelope, audibility: clip.audibility,
|
|
51
|
+
fadeInSamples: clip.fadeInSamples, fadeOutSamples: clip.fadeOutSamples,
|
|
52
|
+
}))}"></audio>`;
|
|
49
53
|
}).join("");
|
|
50
54
|
return injectRuntimeShim(html, audio);
|
|
51
55
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { audioEnvelopeGainAt } from "@hypit/composition";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Studio's frame driver for a compiled HyperFrames document.
|
|
3
5
|
*
|
|
@@ -48,6 +50,7 @@ function shim(): string {
|
|
|
48
50
|
rate: parseFloat(element.getAttribute('data-playback-rate') || '1') || 1
|
|
49
51
|
});
|
|
50
52
|
}
|
|
53
|
+
var audioContext;
|
|
51
54
|
var programmeAudio = [];
|
|
52
55
|
for (var element of document.querySelectorAll('.hypit-studio-audio')) {
|
|
53
56
|
programmeAudio.push({
|
|
@@ -59,10 +62,51 @@ function shim(): string {
|
|
|
59
62
|
loop: element.getAttribute('data-loop') === 'true',
|
|
60
63
|
phase: parseFloat(element.getAttribute('data-phase') || '0') || 0,
|
|
61
64
|
rate: parseFloat(element.getAttribute('data-playback-rate') || '1') || 1,
|
|
62
|
-
gain:
|
|
65
|
+
gain: Number(element.getAttribute('data-gain') ?? '1'),
|
|
66
|
+
presentation: JSON.parse(decodeURIComponent(element.getAttribute('data-presentation') || '%7B%7D'))
|
|
63
67
|
});
|
|
64
68
|
}
|
|
65
69
|
|
|
70
|
+
function scheduleEnvelope(param, points, sample, now) {
|
|
71
|
+
param.cancelScheduledValues(now);
|
|
72
|
+
param.setValueAtTime(audioEnvelopeGainAt(points, sample), now);
|
|
73
|
+
for (var point of points || []) {
|
|
74
|
+
if (point.sample > sample) param.linearRampToValueAtTime(point.gain, now + (point.sample - sample) / 48000);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Each factor has its own GainNode so intersecting ramps multiply exactly.
|
|
79
|
+
// These are the same absolute-sample envelopes consumed by the render mixer.
|
|
80
|
+
function placeAudioGain(record, seconds) {
|
|
81
|
+
if (!record.nodes) {
|
|
82
|
+
var source = audioContext.createMediaElementSource(record.element);
|
|
83
|
+
record.nodes = Array.from({ length: 5 }, function () { return audioContext.createGain(); });
|
|
84
|
+
var previous = source;
|
|
85
|
+
for (var node of record.nodes) { previous.connect(node); previous = node; }
|
|
86
|
+
previous.connect(audioContext.destination);
|
|
87
|
+
record.element.volume = 1;
|
|
88
|
+
}
|
|
89
|
+
var sample = seconds * 48000;
|
|
90
|
+
var now = audioContext.currentTime;
|
|
91
|
+
var p = record.presentation;
|
|
92
|
+
var start = record.start * 48000, end = (record.start + record.duration) * 48000;
|
|
93
|
+
record.nodes[0].gain.setValueAtTime(record.gain, now);
|
|
94
|
+
scheduleEnvelope(record.nodes[1].gain, p.gainEnvelope, sample, now);
|
|
95
|
+
scheduleEnvelope(record.nodes[2].gain, p.fadeInSamples > 0
|
|
96
|
+
? [{ sample: start, gain: 0 }, { sample: start + p.fadeInSamples, gain: 1 }] : undefined, sample, now);
|
|
97
|
+
scheduleEnvelope(record.nodes[3].gain, p.fadeOutSamples > 0
|
|
98
|
+
? [{ sample: end - p.fadeOutSamples, gain: 1 }, { sample: end, gain: 0 }] : undefined, sample, now);
|
|
99
|
+
var gate = record.nodes[4].gain;
|
|
100
|
+
gate.cancelScheduledValues(now);
|
|
101
|
+
gate.setValueAtTime(p.audibility === undefined || p.audibility.some(function (span) {
|
|
102
|
+
return sample >= span.startSample && sample < span.endSampleExclusive;
|
|
103
|
+
}) ? 1 : 0, now);
|
|
104
|
+
for (var span of p.audibility || []) {
|
|
105
|
+
if (span.startSample > sample) gate.setValueAtTime(1, now + (span.startSample - sample) / 48000);
|
|
106
|
+
if (span.endSampleExclusive > sample) gate.setValueAtTime(0, now + (span.endSampleExclusive - sample) / 48000);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
66
110
|
function seekDecoded(element, target) {
|
|
67
111
|
if (Math.abs(element.currentTime - target) < 0.0005 && element.readyState >= 2) return Promise.resolve();
|
|
68
112
|
return new Promise(function (resolve) {
|
|
@@ -148,7 +192,7 @@ function shim(): string {
|
|
|
148
192
|
} else {
|
|
149
193
|
if (Math.abs(element.currentTime - target) > 0.08) element.currentTime = target;
|
|
150
194
|
element.playbackRate = record.rate;
|
|
151
|
-
|
|
195
|
+
placeAudioGain(record, currentSeconds + frameSeconds / 2);
|
|
152
196
|
if (element.paused) {
|
|
153
197
|
var started = element.play();
|
|
154
198
|
if (started) started.catch(function () {});
|
|
@@ -169,6 +213,8 @@ function shim(): string {
|
|
|
169
213
|
};
|
|
170
214
|
window.__hypitPlayFrame = function (frame) {
|
|
171
215
|
playing = true;
|
|
216
|
+
if (programmeAudio.length && !audioContext) audioContext = new AudioContext();
|
|
217
|
+
if (audioContext && audioContext.state === 'suspended') audioContext.resume();
|
|
172
218
|
return apply(frame / fps, false);
|
|
173
219
|
};
|
|
174
220
|
window.__hypitFrameReady = apply(0, true);
|
|
@@ -178,7 +224,7 @@ function shim(): string {
|
|
|
178
224
|
}
|
|
179
225
|
|
|
180
226
|
export function injectRuntimeShim(html: string, audio = ""): string {
|
|
181
|
-
const script = audio + shim();
|
|
227
|
+
const script = audio + shim().replace("(function () {", `(function () {\n${audioEnvelopeGainAt.toString()}`);
|
|
182
228
|
const at = html.lastIndexOf("</body>");
|
|
183
229
|
return at < 0 ? html + script : html.slice(0, at) + script + html.slice(at);
|
|
184
230
|
}
|
|
@@ -4,13 +4,13 @@ import { sameType } from "@hypit/protocol";
|
|
|
4
4
|
import type { Composition } from "@hypit/composition";
|
|
5
5
|
import { compositionTypes } from "@hypit/composition";
|
|
6
6
|
import {
|
|
7
|
-
|
|
7
|
+
projectTimelineSpace,
|
|
8
8
|
semanticAnchorFrames,
|
|
9
|
-
|
|
10
|
-
} from "@hypit/
|
|
11
|
-
import type {
|
|
12
|
-
import {
|
|
13
|
-
import { assertProgramSpaceIdentity
|
|
9
|
+
timelineSpans,
|
|
10
|
+
} from "@hypit/timeline";
|
|
11
|
+
import type { Timeline } from "@hypit/timeline";
|
|
12
|
+
import { timelineTypes } from "@hypit/timeline";
|
|
13
|
+
import { assertProgramSpaceIdentity } from "@hypit/program-space";
|
|
14
14
|
import type { ProgramSpace } from "@hypit/program-space";
|
|
15
15
|
import type { StudioResolvedTrack, StudioTemporalBinding } from "@hypit/studio-adapter";
|
|
16
16
|
import type { RuntimeHostTransientExecution } from "@hypit/runtime-host-node";
|
|
@@ -36,7 +36,6 @@ export type Preview = {
|
|
|
36
36
|
readonly values: ReadonlyMap<string, unknown>;
|
|
37
37
|
readonly temporalBindings: ReadonlyMap<string, readonly StudioTemporalBinding[]>;
|
|
38
38
|
readonly composition: Composition;
|
|
39
|
-
readonly timing: "measured" | "authored";
|
|
40
39
|
readonly narrativeId?: string;
|
|
41
40
|
readonly timingOutput?: { readonly name: string; readonly ref: string };
|
|
42
41
|
readonly timingCandidateId?: string;
|
|
@@ -173,11 +172,11 @@ export async function preview(input: {
|
|
|
173
172
|
const timingType = timingOutput?.typeRef ?? timingRecord?.type;
|
|
174
173
|
const timingValue = selectedValue(executed.state, input.timeRef);
|
|
175
174
|
if (timingValue?.kind !== "inline" || timingType === undefined) throw new Error("Studio requires a resolved film time source.");
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const spans =
|
|
179
|
-
const anchors =
|
|
180
|
-
const space =
|
|
175
|
+
if (!sameType(timingType, timelineTypes.track)) throw new Error("Studio requires the declared Timeline.");
|
|
176
|
+
const semantic = timingValue.value as unknown as Timeline;
|
|
177
|
+
const spans = timelineSpans(semantic);
|
|
178
|
+
const anchors = semanticAnchorFrames(semantic);
|
|
179
|
+
const space = projectTimelineSpace(semantic);
|
|
181
180
|
assertProgramSpaceIdentity(space);
|
|
182
181
|
const rate = space.frameRate;
|
|
183
182
|
const compositionValue = selectedValue(executed.state, input.compositionRef);
|
|
@@ -227,22 +226,8 @@ export async function preview(input: {
|
|
|
227
226
|
const stored = selectedValue(executed.state, target.ref);
|
|
228
227
|
if (stored?.kind === "inline") values.set(target.ref, stored.value);
|
|
229
228
|
}
|
|
230
|
-
// Author
|
|
231
|
-
//
|
|
232
|
-
// (for example Caption cue text); exposing them here avoids recomputing the
|
|
233
|
-
// domain value or turning a Record into a fake graph target.
|
|
234
|
-
for (const placement of input.source.observations.placements) {
|
|
235
|
-
for (const value of placement.values) {
|
|
236
|
-
const suffixes = [`::record::${value.id}`, `::output::${value.id}`];
|
|
237
|
-
for (const reference of input.projections.flatMap((projection) => projection.trace.references)) {
|
|
238
|
-
if (suffixes.some((suffix) => reference.ref.endsWith(suffix))) values.set(reference.ref, value.value);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
// Script is a raw Surface, so its inline Records are not among the structured
|
|
243
|
-
// element observations above. They are still ordinary Author values from
|
|
244
|
-
// the same compilation and are needed to turn Caption atom ids back into the
|
|
245
|
-
// text the author actually sees.
|
|
229
|
+
// Author records from this compilation already carry exact qualified references.
|
|
230
|
+
// Expose referenced inline values to Companions without guessing their owner by suffix.
|
|
246
231
|
for (const record of input.source.compiled.program.records) {
|
|
247
232
|
if (record.value.kind !== "inline") continue;
|
|
248
233
|
if (input.projections.some((projection) => projection.trace.references
|
|
@@ -257,8 +242,7 @@ export async function preview(input: {
|
|
|
257
242
|
values,
|
|
258
243
|
temporalBindings,
|
|
259
244
|
composition,
|
|
260
|
-
|
|
261
|
-
...(semantic === undefined ? {} : { narrativeId: semantic.narrativeId }),
|
|
245
|
+
...(semantic.narrativeId === undefined ? {} : { narrativeId: semantic.narrativeId }),
|
|
262
246
|
timingOutput: { name: timingOutput?.name ?? space.id, ref: input.timeRef },
|
|
263
247
|
...(timingCandidateId === undefined ? {} : { timingCandidateId }),
|
|
264
248
|
timingCandidateOrigin: timingCandidateId === undefined ? "source" : "run",
|