@f8team/reel-core 1.0.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,103 @@
1
+ # @f8team/reel-core
2
+
3
+ ## 1.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b8ac150: # 2026-05-12 senior review fixes
8
+
9
+ Round of corrections from a senior review of the Reel monorepo. Mostly
10
+ production-robustness fixes, plus a small set of additive public-API changes
11
+ and a couple of breaking visual defaults to make the package cleanly
12
+ publishable as OSS.
13
+
14
+ ## Public API additions (minor)
15
+ - **`@f8team/reel-core`** — `Player.retry(): boolean` re-attempts the last
16
+ source. Returns `false` when there is nothing to retry. Useful for
17
+ "Try again" buttons on error overlays.
18
+ - **`@f8team/reel-core`** — `SourceLoader.abort?()` (optional) lets the
19
+ orchestrator cancel in-flight network work on rapid `setSource` swaps
20
+ without tearing down the underlying media element. Both built-in HLS and
21
+ YouTube loaders implement it.
22
+ - **`@f8team/reel-react`** — `<Player.Root labels>` prop + `defaultLabels` /
23
+ `vietnameseLabels` presets + `useLabels()` hook for ARIA / time-formatter
24
+ i18n.
25
+ - **`@f8team/reel-plugin-resume-position`** — `keyFn(source) => string | null`
26
+ (signed-URL-friendly), `saveIntervalMs` (default 10s, periodic save while
27
+ playing).
28
+ - **`@f8team/reel-plugin-auth-aware`** — `allowlist` now accepts
29
+ `string | RegExp | (url: string) => boolean` per entry; new
30
+ `AuthAwareAllowlistEntry` exported type.
31
+ - **`@f8team/reel-themes`** — `f8-brand.css` opt-in layer for F8 orange
32
+ branding on top of any base theme.
33
+
34
+ ## Production robustness (patch + minor)
35
+ - **HLS** — listener-leak fix on per-segment XHRs; manifest-load timeout
36
+ (default 30s) so a stalled manifest doesn't pin the player in `loading`;
37
+ non-fatal HTTP 4xx/5xx now surface as load errors; native fallback path
38
+ cleans up listeners on early `detach()`.
39
+ - **YouTube** — bridges polled `getCurrentTime` / `getDuration` into the
40
+ core store and event bus (seek bars and time-aware plugins now tick on
41
+ YouTube sources); marks the underlying `<video>` via the
42
+ `data-reel-yt-hidden` attribute instead of mutating inline styles
43
+ (host CSS no longer fights the loader); warns once when the player's
44
+ parent is `position: static`.
45
+ - **createPlayer** — autoplay / startTime no longer leak listeners across
46
+ re-attach cycles, and re-attach to an already-`ready` player now applies
47
+ them synchronously instead of waiting for a transition that already fired.
48
+ - **plugin-keyboard** — fixes container-scope fallback; skips `contenteditable`
49
+ regions, `role="textbox"`, and IME composition (no more accidental Space
50
+ toggles while typing in a rich-text editor).
51
+ - **plugin-resume-position** — SSR-safe (no-op when `window` is undefined);
52
+ also saves on `pagehide` / `visibilitychange→hidden` for iOS Safari, plus
53
+ periodic save while playing.
54
+ - **plugin-auth-aware** — emits a one-time console warning when a string
55
+ allowlist entry ends with `.`, to surface a class of consumer mistakes
56
+ (`"https://api-gateway."` literal vs `/^https:\/\/api-gateway\./` regex).
57
+
58
+ ## Breaking changes (visual / OSS posture)
59
+ - **`@f8team/reel-react` default ARIA labels are English.** F8 apps that need
60
+ Vietnamese must pass `labels={vietnameseLabels}` to `<Player.Root>`. Time
61
+ labels are now functions of the formatted string so locales can frame the
62
+ output (`"Current time 1:23"` vs `"Vị trí hiện tại: 1:23"`). The
63
+ `vietnameseLabels` preset matches the previous hardcoded strings byte for
64
+ byte, so adopting it produces the exact same screenshots.
65
+ - **`@f8team/reel-themes` default accent is neutral blue (`#3b82f6`).** F8
66
+ brand orange now lives in the opt-in `f8-brand.css` layer:
67
+
68
+ ```ts
69
+ import "@f8team/reel-themes/classroom.css";
70
+ import "@f8team/reel-themes/f8-brand.css"; // F8 only
71
+ ```
72
+
73
+ - **`@f8team/reel-themes` selectors are scoped exclusively under
74
+ `[data-reel][data-theme="X"]`.** The `.reel-X` fallback class
75
+ was removed to prevent style leakage onto host pages with the same
76
+ generic class names. Use the data-attribute selector or the
77
+ `<Player.Root>` adapter (which sets it for you).
78
+ - **SeekBar wrapper changed.** The component now renders
79
+ `<div data-reel-seek-wrapper>` containing a `<div data-reel-seek-buffered>`
80
+ overlay and the range input. Custom CSS that targeted the bare
81
+ `<input type="range">` directly may need to add `data-reel-seek-wrapper`
82
+ to its selectors to keep alignment.
83
+
84
+ ## UX details
85
+ - Mobile breakpoint (`@media (pointer: coarse), (max-width: 48rem)`) bumps
86
+ every theme's button to ≥ 4.4rem (44px) and enlarges the seek bar thumb
87
+ for tap accuracy.
88
+ - `:focus-visible` ring restored on every theme's range thumb (previously
89
+ `outline: none` with no replacement).
90
+ - Every theme respects `prefers-reduced-motion: reduce`.
91
+ - Documented z-index contract via `--reel-z-buffered`, `--reel-z-controls`,
92
+ `--reel-z-watermark`, `--reel-z-overlay`. Host modals should pick z-index
93
+ ≥ 30 to safely overlay the player.
94
+
95
+ ## Migration notes for F8 consumers
96
+ - **f8-ui:** delete `src/shims/reactPlayerHls.ts` + the
97
+ `declare module "react-player"` block in `vendor-modules.d.ts` (already
98
+ done). Pass `vietnameseLabels` to `<Player.Root>` if you want Vietnamese
99
+ ARIA. Import `@f8team/reel-themes/f8-brand.css` after a base theme to
100
+ re-apply the F8 orange.
101
+ - **f8-dash-ui:** drop the invalid `enableVolumeScroll` argument from
102
+ `createKeyboardPlugin` (already done). Use the `RegExp` form for
103
+ `auth-aware` allowlist (already done).
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 F8 (Son Dang)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # `@f8team/reel-core`
2
+
3
+ > Headless, framework-agnostic, plugin-driven video player engine. The foundation for every `@f8team/reel-*` adapter and plugin.
4
+
5
+ ```bash
6
+ pnpm add @f8team/reel-core
7
+ ```
8
+
9
+ ## Why headless?
10
+
11
+ - **Framework-agnostic.** Works with React, Lit, Vue, Svelte, or vanilla DOM.
12
+ - **Plugin-driven.** Pay only for the features you import — `subtitles`, `markers`, `hls-quality`, `keyboard`, `pip`, … each ships separately.
13
+ - **Tree-shakeable.** Side-effect free; bundlers drop everything you don't use.
14
+ - **Tiny.** Hard size budget enforced in CI: <12 KB gzip core (15 KB hard fail).
15
+
16
+ ## Quick start
17
+
18
+ ```ts
19
+ import { createPlayer } from "@f8team/reel-core";
20
+
21
+ const player = createPlayer({
22
+ source: { src: "https://cdn.example.com/master.m3u8" },
23
+ autoplay: "muted",
24
+ });
25
+
26
+ await player.attach(document.querySelector("video")!);
27
+ await player.play();
28
+ ```
29
+
30
+ ## Architecture
31
+
32
+ See [docs/spec/architecture.md](../../docs/spec/architecture.md) for the state
33
+ machine, module layout, lazy loading strategy, and bundle budgets.
34
+
35
+ ## Public API
36
+
37
+ The contract is frozen in [docs/spec/api-contract.md](../../docs/spec/api-contract.md).
38
+ Any change to a public type is a **breaking change** unless explicitly marked
39
+ `@internal` or covered by a feature flag.
40
+
41
+ ## License
42
+
43
+ MIT © F8.