Przejdź do treści
Biblioteka skilli
Programowanie · Przegląd i audyt

streaming

/streaming

Pilnuje niezmienników strumieniowania między klientem, serwerem i pakietem wspólnym, przy zmianach w elementach streamingu.

Repozytorium
kolu ↗
Licencja
AGPL-3.0
Ostatnia zmiana repozytorium
23.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 23.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

AGPL-3.0, copyleft: przeróbki udostępniane innym muszą mieć tę samą licencję.

Co robi i kiedy

Pilnuje niezmienników strumieniowania między klientem, serwerem i pakietem wspólnym, przy zmianach w elementach streamingu.

Oryginalny opis (EN)

Cross-file invariants for surface streaming members — the retry fence, server snapshot-then-deltas, and the captured-input hazard. Use when touching any streaming member in the client, server, or common packages.

Jak działa

  1. Streaming members
Sekcje z nagłówków SKILL.md, w oryginale · 37 linii, 761 słów
Podgląd SKILL.md
---
name: streaming
description: >-
  Cross-file invariants for surface streaming members — the retry fence, server snapshot-then-deltas, and the captured-input hazard. Use when touching any streaming member in the client, server, or common packages.
---

## Streaming members

Three invariants an agent editing any single file would otherwise miss. They are independent rules (different layers, different enforcement mechanisms) that share a trigger: **touching any streaming member**.

### 1. Apply the retry fence — via `client.rawStream` or `unenrolledStreamCall`, never a bare `client.*` call

A streaming member hands back a **lazy Effect `Stream`**. Every one the client consumes must be wrapped in the framework's **per-subscription retry fence** (`fenceStream` + `STREAM_RETRY`, `@kolu/surface/src/client.ts`) so a dropped socket transparently re-subscribes. The fence is per SUBSCRIPTION and not per link, deliberately: Effect RPC's own `retryTransientErrors` reconnects the socket but **re-issues nothing** — an established-socket close fails every in-flight call and no layer below re-opens them. Two paths bake the fence in:

- **`client.rawStream(name, proc, input, { onItem, onRetry, isExpectedStop })`** — a SURFACE-scoped raw stream that ENROLS into `client.health()` (throws outside a reactive owner, so a raw stream can't silently escape the health fact). This is the default for a surface stream member.
- **`unenrolledStreamCall(proc, input, { onRetry })`** (from `@kolu/surface/client`) — the bare, un-enrolled call: the fence applied, but DELIBERATELY carved out of any surface `health()`. Reach for it only when the stream's health is a per-consumer concern that must not flicker the global gate.

`onRetry` fires once per RETRYABLE failure, INSIDE the fence and before the delay, so "fired ⇒ a re-subscribe follows" holds and a consumer that clears its buffer is never left with a cleared view and no new stream. The terminal **attach** stream (`padiSurface.streams.terminalAttach`, in `terminal/Terminal.tsx`) uses `unenrolledStreamCall` for exactly this reason (Leak-A carve-out): a single terminal's re-attach — overflow re-attach #1591, PTY exit — must never light padi's connection-health indicator. Its `onRetry` resets xterm + the scroll lock and re-arms the snapshot boundary, because imperative consumers must clear their buffer before the retried stream delivers its fresh snapshot — otherwise scrollback double-paints.

What the fence retries is a **positive** test (`shouldRetryStreamError`): an Effect RPC `RpcClientError` transport failure, plus the one named retryable relay end (`SurfaceRelayTransportLost`). Everything else fails the stream on its first occurrence — a **declared** (PLAN D4) tagged procedure error is an application-level answer, and the two permanently-dead transport tags (`SurfaceTransportRetired`, `SurfaceStdioTransportClosed`) are corpses a retry loop would storm against.

**When adding a new streaming member**, pick `client.rawStream` (enrolled) unless the stream is a deliberate health carve-out (`unenrolledStreamCall`). Consuming a member's `Stream` directly — without either wrapper — silently loses reconnect handling.

**There is no `signal`.** Cancellation is fiber interruption (PLAN D10/#18): interrupting the subscription's scoped fiber runs the stream's own finalizers, which IS the unsubscribe. A one-shot read of the opening frame is `@kolu/surface/first-frame`'s `firstFrameOrThrow` / `firstFrameOrUndefined`, which take the `Stream` itself.

### 2. Server handlers yield snapshot-then-deltas

Every server-side streaming handler (`packages/server/src/router.ts`, and every `implementSurface` `streams.<key>` slot) MUST yield a full state snapshot as its first item, then stream deltas. This is the invariant that makes the fence's transparent re-subscribe work: `Stream.retry` re-runs the WHOLE stream, so the next frame the consumer sees is a fresh snapshot that replaces stale client state.

Two acceptable shapes:

- **Implicit**: each yield is already a full replacement (e.g. `onMetadataChange` yields a current `TerminalMetadata`; `preferences.get` yields a current `Preferences`; `activity.get` yields a current `ActivityFeed`; `session.get` yields the current `SavedSession | null`; `terminal.list` yields a current `TerminalInfo[]`). Client reducers can just use the latest value.
- **Explicit discriminated union**: when clients accumulate deltas into a derived structure, yield `{ kind: "snapshot", ... } | { kind: "delta", ... }`. Client reducers replace on snapshot, append on delta. Without the discriminator, reconnect replays the history into an already-populated accumulator and duplicates state.

If a new handler yields deltas only (no initial snapshot), reconnects will silently lose state with no error.

### 3. A member's input is CAPTURED — never a live fact

The fence re-subscribes by REPLAYING the input it read once, at the first call. So a stream whose input carries a LIVE fact (a size, a cursor, a viewport) re-sends a STALE one after any transport drop — and if the server acts on that input (kolu's terminal attach resizes the PTY to it), the replay actively moves shared state backwards.

Either keep the input a **stable key**, or have the consumer REFUSE an answer computed for the stale fact and reopen the stream. The terminal attach is the worked example: it remembers the grid it asked at, drops a snapshot answering any other grid, and re-reads the live grid on every open (`client/src/terminal/Terminal.tsx`). Painting the stale answer and correcting afterwards does NOT work — the damage (scrollback wrapped at the wrong width) is already done.

Wersje

RepozytoriumWynikLicencja
Ta strona · juspay/kolu100AGPL-3.0
redpanda-data/skills100Apache-2.0
chrishuffman5/domain-expert90MIT

Migawka bazy z 28.10.2026 · wersja paczki 930d3957cdaf (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100server-components
    Doradza przy architekturze React Server Components w Next.js: Server i Client Components, dyrektywa use client, wybór między serwerem a klientem, kompozycja komponentów i pobieranie danych.
  • 100react-server-components
    Wyjaśnia React Server Components: model renderowania, dyrektywy „use client” i „use server”, streaming, Server Actions oraz cache.
  • 100react-server-components-framework
    Pomaga budować aplikacje Next.js 16+ z React Server Components: App Router, Cache Components, streaming SSR, Server Actions i wzorce React 19.
  • 100video-streaming-expert
    Doradza w technologiach streamingu wideo: HLS, DASH, adaptacyjny bitrate, dostarczanie przez CDN, ochrona DRM oraz kodowanie i transkodowanie, w tym serwer streamingowy w Node.js.
  • 100react-server-components
    Opisuje React Server Components: komponenty serwerowe i klienckie, pobieranie danych, Server Actions, streaming, cache i integracja z Next.js App Router.
  • 100sse
    Pomaga wdrożyć Server-Sent Events: format text/event-stream, automatyczne ponowne połączenia i strumieniowanie odpowiedzi LLM.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.