From 514532c1efedb96ec902f624f2f056bc014b1e84 Mon Sep 17 00:00:00 2001 From: Karn Date: Sun, 28 Jun 2026 15:59:50 +0530 Subject: [PATCH 01/21] docs: Vimeo provider design spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Event-driven provider over the Vimeo Player SDK — quality, captions, PiP, and rate. Mirrors youtube/ shape (async iframe SDK, destroyed flag) but syncs on SDK events instead of a ticker, renders cues in kino's own overlay (enableTextTrack showing:false + cuechange), and derives plan-gated capabilities at runtime. Supports unlisted videos via hash parsing. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../specs/2026-06-28-vimeo-provider-design.md | 338 ++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-28-vimeo-provider-design.md diff --git a/docs/superpowers/specs/2026-06-28-vimeo-provider-design.md b/docs/superpowers/specs/2026-06-28-vimeo-provider-design.md new file mode 100644 index 0000000..0e3ecb0 --- /dev/null +++ b/docs/superpowers/specs/2026-06-28-vimeo-provider-design.md @@ -0,0 +1,338 @@ +# Vimeo provider — design + +## Goal + +Add a Vimeo provider to kino so the same glass chrome plays Vimeo videos, +mirroring the existing `mux/`, `native/`, and `youtube/` providers. Vimeo's +Player SDK is the richest of the iframe-backed engines — quality selection, +text tracks with cue text, picture-in-picture, and playback rate — so this +provider reports the widest capability set **and** is the first iframe provider +to render styled captions in kino's own overlay. Then update the README, demo +site, and overview copy so the docs advertise **four** shipped providers (Mux, +Native, YouTube, Vimeo). + +## Architecture + +kino's contract is `Provider` (`src/core/types.ts`): `mount(container)`, +`getState()`, `subscribe(listener)`, `actions`, `destroy()`, optional +`swapSource(opts)`. A thin React wrapper creates the provider once (`useRef`) +and routes reactive prop changes through `swapSource`. UI controls gate +themselves on the `capabilities` set the provider reports. + +The Vimeo provider follows the `youtube/` shape (async-loaded iframe SDK, host +div, `destroyed` flag), but its state sync is **event-driven** like `native/` +rather than polled — the Vimeo SDK emits `timeupdate`. + +### New files + +- `src/vimeo/provider.ts` — `createVimeoProvider(opts): Provider` + + `VimeoProviderOptions` type + `parseVimeoSource(input): { id; hash? }` helper. +- `src/vimeo/vimeo-player.tsx` — `` (props = `VimeoProviderOptions` + + `accentColor/theme/className/placeholder/children`). +- `src/vimeo/provider.test.ts` — vitest, mirroring `youtube/provider.test.ts` + (fake `window.Vimeo.Player`). +- `src/vimeo.ts` — entry re-exporting the provider, component, types, helper. + +### Wiring + +- `package.json` → add `exports["./vimeo"]` (`./dist/vimeo.{d.ts,js}`); add + `"vimeo"` to `keywords` (mirrors the `youtube` entry). +- `tsdown.config.ts` → add `vimeo: "src/vimeo.ts"` entry. +- `src/styles/kino.css` → **no change**. The existing + `.kino .kino-video-host iframe` rules (sizing + `pointer-events: none`, added + for YouTube) already cover the Vimeo iframe, which lands inside + `.kino-video-host`. +- No runtime dependency and no `@types/*` package — the SDK script is loaded at + runtime and its surface is hand-rolled as a narrow local structural type + (matching `MuxVideoEl` / the YouTube `YTPlayer` alias style). + +## Engine integration + +Vimeo Player SDK (`player.js`). A module-level singleton promise lazy-loads +`https://player.vimeo.com/api/player.js` and resolves when `window.Vimeo.Player` +is ready. An already-present `window.Vimeo` short-circuits. Unlike YouTube there +is **no global ready callback** — the injected `