mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
build(spf): build26 from 45504a2b
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# SPF fundamentals
|
||||
|
||||
SPF builds long-lived systems from small behaviors connected by signals. The framework supplies composition, lifecycle, and work primitives; a domain supplies the behaviors and engine adapter.
|
||||
|
||||
Source and tests define exact types and runtime behavior. This guide explains the mental model.
|
||||
|
||||
## Behaviors and compositions
|
||||
|
||||
A behavior declares the state and context slots it participates in and installs one concern. Its setup may return cleanup or an object with `destroy()`.
|
||||
|
||||
`createComposition()`:
|
||||
|
||||
1. creates one signal for every declared slot;
|
||||
2. supplies the shared state, context, and immutable configuration to each behavior;
|
||||
3. retains every cleanup handle;
|
||||
4. destroys all behaviors and clears the signal maps as one lifecycle.
|
||||
|
||||
Type inference intersects the requirements of the behavior tuple. Incompatible slot or configuration types fail at the composition call.
|
||||
|
||||
Use `defineBehavior()` for ordinary source behaviors. It verifies that runtime key declarations match the typed setup slices.
|
||||
|
||||
## State, context, and configuration
|
||||
|
||||
- **State** contains reactive engine facts and consumer intent.
|
||||
- **Context** contains owned resources, platform objects, and actor references.
|
||||
- **Configuration** contains immutable tuning and replaceable strategies supplied by the engine variant.
|
||||
|
||||
Each behavior expresses slot access with `Signal<T>` for values it writes and `ReadonlySignal<T>` for values it only consumes. This is a local ownership contract over shared signal identities.
|
||||
|
||||
Initial state or context materializes values that no behavior naturally seeds. External input slots can be materialized by `makeShareSignals()` and handed to an adapter through `onSignalsReady`.
|
||||
|
||||
## Signals
|
||||
|
||||
Use signals for state over time:
|
||||
|
||||
- `signal()` owns a writable value;
|
||||
- `computed()` derives a value from tracked reads;
|
||||
- `effect()` connects reactive state to work and returns cleanup;
|
||||
- `untrack()` or `peek()` reads context without adding a dependency;
|
||||
- `update()` replaces structured state through an updater.
|
||||
|
||||
Effects are appropriate for direct synchronization. When tracked inputs derive meaningful lifecycle states with different setup or cleanup, use a reactor.
|
||||
|
||||
## Tasks and runners
|
||||
|
||||
A task is one cancellable asynchronous operation with inspectable status, value, and error. It starts only when run or scheduled.
|
||||
|
||||
Runners own scheduling:
|
||||
|
||||
- `SerialRunner` executes tasks in submission order when work cannot overlap.
|
||||
- `ConcurrentRunner` runs independent tasks and deduplicates by task ID.
|
||||
|
||||
Tasks are internal work units. A behavior or actor owns their runner and destroys it with the surrounding lifecycle.
|
||||
|
||||
## Actors
|
||||
|
||||
Actors receive discrete messages and own resources or queues.
|
||||
|
||||
- A callback actor is the lightest fire-and-forget shape.
|
||||
- A transition actor reduces messages into observable context.
|
||||
- A machine actor uses explicit states, per-state handlers, optional runners, settling transitions, and destruction.
|
||||
|
||||
Use actor snapshots for observation, not as another mutation channel. The creator owns actor destruction.
|
||||
|
||||
## Reactors
|
||||
|
||||
Reactors observe signals and derive finite lifecycle state. Their monitor chooses the active state; each state may provide:
|
||||
|
||||
- `entry` work that runs once and is automatically untracked;
|
||||
- reactive `effects` that rerun with dependencies;
|
||||
- cleanup that runs before rerun, on state exit, and on destruction.
|
||||
|
||||
Reactors do not own a message channel. They commonly translate shared engine state into messages for an actor that owns the resource.
|
||||
|
||||
## External adapters
|
||||
|
||||
An engine adapter should not depend on internal behavior instances. `makeShareSignals()` exposes selected signal references at setup so an HTML, React, or other platform adapter can drive input and observe output.
|
||||
|
||||
The adapter owns platform semantics such as attachment, play activation, and property synchronization. The engine owns streaming behavior and cleanup.
|
||||
|
||||
## Design constraints
|
||||
|
||||
- Prefer one writer per resolved state slot; represent external intent separately from automatic policy.
|
||||
- Put browser APIs behind explicit DOM boundaries.
|
||||
- Abort source-bound work and release owned resources on source replacement.
|
||||
- Use the smallest primitive matching the work.
|
||||
- Treat source, tests, and public entry points as the contract.
|
||||
|
||||
## Current sources
|
||||
|
||||
- Public primitives: `packages/spf/src/index.ts`
|
||||
- Composition: `packages/spf/src/core/composition/`
|
||||
- Signals, tasks, actors, and reactors: corresponding directories under `packages/spf/src/core/`
|
||||
- Tests: colocated `tests/` directories
|
||||
- Internal rationale and conventions: `internal/design/spf/`
|
||||
@@ -0,0 +1,63 @@
|
||||
# HLS engine composition
|
||||
|
||||
`createSimpleHlsEngine()` composes SPF behaviors into HLS playback over MediaSource. This guide describes ownership and stage relationships, not the exact behavior array or configuration interface; those live in source.
|
||||
|
||||
## Inputs and adapter boundary
|
||||
|
||||
The adapter supplies a media element and an unresolved presentation URL through shared signals. It may also write preload, current-time triggers, or user track-selection intent.
|
||||
|
||||
The engine returns a composition with one asynchronous destruction boundary. Assigning another presentation reuses that composition while per-source behaviors clean up and set up again.
|
||||
|
||||
## Resolution and selection
|
||||
|
||||
The first stage:
|
||||
|
||||
1. synchronizes preload and activation;
|
||||
2. fetches and parses the multivariant playlist;
|
||||
3. derives CDN priority and failover eligibility;
|
||||
4. resolves video, audio, and text selection intent;
|
||||
5. fetches the selected media playlists;
|
||||
6. derives presentation duration.
|
||||
|
||||
Track switching uses ordered constraints and terminal selection rules. User selection narrows candidates without disabling automatic policy through a separate mode flag. Video ABR consumes bandwidth estimates; audio and text apply their language/default policies.
|
||||
|
||||
## MediaSource and buffering
|
||||
|
||||
After the presentation resolves, browser-bound behaviors:
|
||||
|
||||
- attach a standard or managed MediaSource;
|
||||
- propagate duration;
|
||||
- create independent video and audio buffer/loader actor clusters;
|
||||
- track current time and load activation;
|
||||
- plan bounded forward loading and back-buffer eviction;
|
||||
- serialize SourceBuffer operations;
|
||||
- coordinate end-of-stream after active types finish.
|
||||
|
||||
Video buffer setup is registered before audio to preserve the Firefox audio-detection ordering invariant. The exact setup and cleanup behavior is tested in the DOM behavior and engine suites.
|
||||
|
||||
## Text tracks
|
||||
|
||||
Text selection is resolved through the same constraint model as other tracks. DOM synchronization converts user mode changes into selection intent and mirrors the resolved result back without creating an echo loop.
|
||||
|
||||
Owned actors load WebVTT segments and cues. They are destroyed on source replacement with the other per-source resources.
|
||||
|
||||
## Multi-CDN behavior
|
||||
|
||||
The engine derives comparable CDN identifiers from track URLs. Track selection prefers one active CDN across media types, while failed-CDN state temporarily removes candidates and later expires through the failover monitor.
|
||||
|
||||
Single-CDN sources pass through the same composition without additional behavior.
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration supplies engine policy and replaceable operations, including parsers, capability probing, text resolution, duration policy, buffer targets, bandwidth/quality tuning, language preference, and failover behavior.
|
||||
|
||||
Defaults are resolved at the engine boundary and passed to the behaviors that consume them. See `SimpleHlsEngineConfig` for the current surface.
|
||||
|
||||
## Current sources
|
||||
|
||||
- Composition, state, context, and configuration: `packages/spf/src/playback/engines/hls/engine.ts`
|
||||
- Adapter behavior: `packages/spf/src/playback/engines/hls/adapter.ts`
|
||||
- Behaviors and tests: `packages/spf/src/playback/behaviors/`
|
||||
- Actors and tests: `packages/spf/src/playback/actors/`
|
||||
- Media and network algorithms: `packages/spf/src/media/` and `packages/spf/src/network/`
|
||||
- Feature status and rationale: `internal/design/spf/features/`
|
||||
Reference in New Issue
Block a user