Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .claude/plans/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Implementation Plans

Working notes and implementation details for AI agents and developers.

## Purpose

This directory contains:

- Step-by-step implementation plans
- Working notes during development
- AI-agent context for executing RFCs
- Completed work logs with key decisions

## What Belongs Here

- Implementation details and code snippets
- Debugging notes and discoveries
- Task breakdowns for complex features
- Post-implementation summaries

## What Doesn't Belong Here

Design proposals and architectural decisions belong in `/rfcs`. This directory is for **how** to implement, not **what** or **why**.

## Compaction Rule

Before merging a PR, compact completed plans:

1. Remove verbose implementation details
2. Point to PR and commits for specifics
3. Keep key decisions and important notes
4. Update status to COMPLETED

Example compacted plan:

```markdown
# Feature Name

**Status:** COMPLETED
**PR:** [#123](https://github.com/videojs/v10/pull/123)

## Summary

Brief description of what was implemented.

## Key Decisions

- Decision 1: Rationale
- Decision 2: Rationale

## Notes

Any gotchas or important context for future reference.
```

## Relationship to RFCs

Plans may link to their parent RFC:

```markdown
# Implementing Feature X

**RFC:** [/rfcs/feature-x.md](/rfcs/feature-x.md)

## Tasks

...
```
41 changes: 16 additions & 25 deletions .claude/plans/store/bindings.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,29 @@
# Store React/DOM Bindings

> **STATUS: COMPLETED** Superseded by `proxies.md` for API changes.
**Status:** COMPLETED (Superseded by reactive.md)

## Summary

Implemented React and Lit bindings for `@videojs/store`:
Implemented React and Lit bindings for `@videojs/store`: `createStore()` factory returning Provider + hooks/controllers.

- `createStore()` factory returning Provider + hooks/controllers
- Skins define store configs, export Provider + Skin + extendConfig
- Base hooks/controllers for testing and advanced use
## Key PRs

## Completed Work

| Phase | PR | Description |
| ----- | ----------------------------------------------- | ------------------------------------------------------------- |
| 0 | [#283](https://github.com/videojs/v10/pull/283) | `uniqBy`, `composeCallbacks`, `extendConfig` utilities |
| 0.5 | [#287](https://github.com/videojs/v10/pull/287) | Queue task refactor (unified tasks map, status discriminator) |
| 1 | [#288](https://github.com/videojs/v10/pull/288) | React bindings (createStore, Provider, hooks) |
| 2 | [#289](https://github.com/videojs/v10/pull/289) | Lit bindings (controllers, mixins, context) |
| 3 | [#292](https://github.com/videojs/v10/pull/292) | DOM media slices (playback, time, buffer, volume, source) |
| 4 | [#290](https://github.com/videojs/v10/pull/290) | Mutation hooks/controllers |
| 5 | [#291](https://github.com/videojs/v10/pull/291) | Optimistic hooks/controllers |
| 6 | [#298](https://github.com/videojs/v10/pull/298) | Frosted skin (React + HTML) |
| Phase | PR | Description |
| ----- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------ |
| 0 | [#283](https://github.com/videojs/v10/pull/283) | `uniqBy`, `composeCallbacks`, `extendConfig` utilities |
| 0.5 | [#287](https://github.com/videojs/v10/pull/287) | Queue task refactor |
| 1 | [#288](https://github.com/videojs/v10/pull/288) | React bindings |
| 2 | [#289](https://github.com/videojs/v10/pull/289) | Lit bindings |
| 3 | [#292](https://github.com/videojs/v10/pull/292) | DOM media slices |
| 4-5 | [#290](https://github.com/videojs/v10/pull/290), [#291](https://github.com/videojs/v10/pull/291) | Mutation/Optimistic hooks |
| 6 | [#298](https://github.com/videojs/v10/pull/298) | Frosted skin |

## Key Decisions

- Hook naming: `useStore`, `useSelector`, `useRequest`, `useTasks`, `useMutation`, `useOptimistic`
- Controller naming: `SelectorController`, `RequestController`, `TasksController`, etc.
- Mutation/Optimistic: Discriminated union types with `status` field
- Lit mixins: `StoreMixin` (combined), `StoreProviderMixin`, `StoreAttachMixin`
- Provider resolution: Isolated by default; `inherit` prop for parent context
- Package structure: `store/react` and `store/lit`
- Provider resolution: Isolated by default; `inherit` prop for parent context
- Lit mixins: `StoreMixin` (combined), `StoreProviderMixin`, `StoreAttachMixin`

## Superseded By
## Notes

The selector-based APIs (`useSelector`, `SelectorController`, `store.subscribe()`) are being
replaced by proxy-based reactivity. See **`proxies.md`** for the migration plan.
Selector-based APIs were later replaced by proxy-based reactivity. See `reactive.md`.
30 changes: 7 additions & 23 deletions .claude/plans/store/queue-simplification.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,26 @@
# Queue Simplification

> **STATUS: COMPLETED**
**Status:** COMPLETED

## Summary

Simplified Queue from ~524 LOC to ~405 LOC. Removed convenience features only used in tests/docs, kept what's essential for async media operations.
Simplified Queue from ~524 LOC to ~405 LOC. Removed convenience features only used in tests/docs, kept essentials for async media operations.

## Why Queue Exists

All writes are async requests — this is the architecture. Queue handles:
All writes are async requests. Queue handles:

- Supersession (rapid clicks → only last executes)
- AbortController propagation
- Task lifecycle tracking (pending/success/error)
- Error surfacing for UI

## Features Removed
## Removed

- `cancel()` method (use `abort()`)
- `flush()` method (no configurable scheduling)
- `queued` getter (internal detail)
- `TaskScheduler` type, `QueueConfig` interface
- `delay()`, `microtask` exports
- `schedule` param on `QueueTask`
- `cancel()`, `flush()`, `queued` getter
- `TaskScheduler`, `QueueConfig`, `schedule` param
- `delay()`, `microtask`, DOM schedulers (`raf()`, `idle()`)
- `onDispatch`, `onSettled` hooks
- DOM schedulers (`raf()`, `idle()`)

## Files Changed

| File | Change |
| ------------------------- | ------------------------------------ |
| `core/queue.ts` | Main simplification |
| `core/task.ts` | NEW: Extracted task types and guards |
| `core/index.ts` | Added task.ts export |
| `core/request.ts` | Removed schedule field |
| `core/store.ts` | Removed schedule from enqueue |
| `dom/` | DELETED entire directory |
| Various controllers/hooks | Updated imports |

## Final API

Expand Down
63 changes: 14 additions & 49 deletions .claude/plans/store/reactive.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,28 @@
# Reactive State

**Status:** COMPLETE
**Status:** COMPLETED
**PR:** [#311](https://github.com/videojs/v10/pull/311)

Replaced class-based `State` with proxy-based reactive primitives. Inspired by [Valtio](https://github.com/pmndrs/valtio).
## Summary

Replaced class-based `State` with proxy-based reactive primitives inspired by Valtio.

## Key Decisions

| Decision | Rationale |
| ----------------------------- | ---------------------------------------------------- |
| Auto-batch to microtask | Coalesce rapid mutations, export `flush()` for tests |
| React: `useSyncExternalStore` | Version counter for change detection |
| Lit: `SnapshotController` | `host.requestUpdate()` + optional callback |

## API

```ts
import { batch, flush, reactive, snapshot, subscribe, subscribeKeys, track } from '@videojs/store';
```

| Export | Purpose |
| -------------------------------- | ---------------------------------------------- |
| `reactive(initial)` | Create reactive state with parent bubbling |
| `isReactive(value)` | Check if value is reactive |
| `subscribe(state, fn)` | Subscribe to all changes |
| `subscribeKeys(state, keys, fn)` | Subscribe to specific key changes |
| `batch(fn)` | Group mutations, flush after |
| `flush()` | Force pending notifications (for tests) |
| `snapshot(state)` | Return frozen shallow copy |
| `track(state)` | Track property access for fine-grained updates |

## Key Behaviors

- **Auto-batching** — Notifications deferred to microtask
- **Nested tracking** — Auto-wraps nested objects, changes bubble to parents
- **Synchronous reads** — Mutations apply immediately, only notifications are deferred

## Decisions

| Question | Decision |
| ------------- | -------------------------------------------------------------------- |
| Batching | Auto-batch to microtask. Export `flush()` for tests. |
| React pattern | `useSyncExternalStore` with version counter for change detection |
| Lit pattern | `SnapshotController` with `host.requestUpdate()` + optional callback |

## Breaking Changes

**Removed:**
Removed: `useMutation`, `useOptimistic`, `useSelector`, `MutationController`, `OptimisticController`, `SelectorController`

- React: `useMutation`, `useOptimistic`, `useSelector`
- Lit: `MutationController`, `OptimisticController`, `SelectorController`

**Migration:**

| Before | After |
| ----------------------------------- | ------------------------------------- |
| `useSelector(store, s => s.volume)` | `useSnapshot(store.state).volume` |
| `useMutation(store, 'play')` | `useSnapshot(store.queue.tasks).play` |
| `SelectorController` | `SnapshotController` |
| `store.subscribe(fn)` | `subscribe(store.state, fn)` |

## Testing

Use `flush()` for synchronous assertions:

```ts
state.volume = 0.5;
flush();
expect(listener).toHaveBeenCalledOnce();
```
Migration: Use `useSnapshot(store.state)` and `subscribe(store.state, fn)` instead.
4 changes: 3 additions & 1 deletion .claude/skills/git/references/pr.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ type(scope): lowercase description

| Prefix | Use for |
| ------------ | ------------------------------------ |
| `RFC:` | Request for comments / proposals |
| `[RFC]` | Request for comments / proposals |
| `Discovery:` | Exploration / research / prototyping |

**Note:** RFC PRs use `[RFC] Title` format while open. When merged, the squash commit uses `docs(rfc): title`.

## PR Body Template

```markdown
Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/git/references/scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ Infer commit scope from changed file paths.
| `packages/react/` | `react` |
| `packages/react-native/` | `react-native` |
| `packages/icons/` | `icons` |
| `packages/skins/` | `skins` |
| `site/` | `site` |
| `rfcs/` | `rfc` |
| `.claude/` | `claude` |
| `.github/workflows/` | `ci` |
| `.github/` | `cd` |
Expand All @@ -34,7 +34,7 @@ From `commitlint.config.js`:

```
cd, ci, claude, core, docs, html, icons, packages,
plan, react-native, react, root, site, skins, store,
plan, react-native, react, rfc, root, site, store,
test, utils
```

Expand Down
13 changes: 13 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,19 @@ get size(): number { ... }
add(cleanup: CleanupFn): void { ... }
```

## Design Documents

| Location | Purpose |
| ---------------- | ----------------------------------------------------------------- |
| `rfcs/` | Design proposals, API decisions, architecture — public discussion |
| `.claude/plans/` | Implementation notes, AI-agent context, working drafts |

**RFCs** focus on **what** and **why**. Write an RFC for major API changes, architectural decisions, or patterns used across packages.

**Implementation plans** focus on **how**. Use `.claude/plans/` for step-by-step implementation details, debugging notes, and AI-agent context.

Before merging, compact completed plans: keep key decisions and important notes, point to PRs/commits for details. See `.claude/plans/README.md`.

## Rule Placement

CLAUDE.md contains repo-wide conventions. Domain-specific patterns live in skills:
Expand Down
17 changes: 13 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ pnpm dev
This will run the entire workspace in developer mode, meaning all applications (examples and website) will also be started on their respective ports.

```sh
# Run a specific app
pnpm dev:html
pnpm dev:react
pnpm dev:next
# Run the documentation site
pnpm dev:site
```

Expand Down Expand Up @@ -175,6 +172,18 @@ When your changes introduce new patterns:
- **Code conventions** → Update `CLAUDE.md` Code Rules section
- **Domain patterns** → Update relevant skill in `.claude/skills/`

## RFCs (Design Documents)

For significant architectural decisions and API designs, we use RFCs (Request for Comments). See [`rfcs/README.md`](./rfcs/README.md) for the full process.

**When to write an RFC:**

- Introducing a new public API surface
- Making architectural changes affecting multiple packages
- Proposing patterns used throughout the codebase

**Skip the RFC for:** Bug fixes, small contained features, implementation details.

## Creating a Pull Request

By submitting a pull request, you agree that your contribution is provided under the
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Modern, modular, and composable media player framework for Web and React.
Thanks for checking out the project! It's in its early stages and currently a mix of prototyping
and early structure pointing in the direction we want to go with Video.js v10 (so be kind 🙏).

- Read our [early architecture goals][architecture].
- Read our [design documents][rfcs].
- Read the [v10 discussion topic][v10-discussion].
- Watch [Heff's recent presentation][heff-presentation].

Expand Down Expand Up @@ -58,7 +58,7 @@ Please see our [contributing guide](./CONTRIBUTING.md) for getting setup locally
Please note that this project is released with a [Contributor Code of Conduct][coc]. By
participating in this project you agree to abide by its terms.

[architecture]: ./docs/ARCHITECTURE.md
[rfcs]: ./rfcs
[v10-discussion]: https://github.com/videojs/video.js/discussions/9035
[heff-presentation]: https://players.brightcove.net/3737230800001/eyILA5XG7K_default/index.html?videoId=6379311036112
[coc]: https://github.com/videojs/video.js/blob/main/CODE_OF_CONDUCT.md
Expand Down
Loading