Finalize the Effect View rename and refresh docs, examples, and tooling (#59)
Publish / publish (push) Successful in 3m23s
Lint / lint (push) Successful in 48s

## Summary

- Rename `effect-fc-next` to `effect-view` and update package metadata, internal symbols, imports, and repository references.
- Promote the Effect 4 example to `packages/example` and move the legacy Effect 3 example to `packages/effect-fc-example`.
- Add `effect-view` to the npm publishing workflow.
- Update the Vite Fast Refresh plugin for `effect-view` and rename `effectViewPlugin()` to `effectView()`.
- Upgrade Effect, React, TypeScript, build tooling, and related dependencies.
- Refresh the documentation and homepage.

## Documentation

- Add a dedicated Async guide covering:
  - Suspense fallbacks
  - Hook ordering
  - Memoization
  - Structural prop equality
- Clarify synchronous and asynchronous component behavior.
- Document runner scope and service requirements.
- Explain stable construction of Query, Mutation, and Form instances.
- Expand focused Lens and Form examples, including curried focus helpers.
- Document the optional `@effect/platform-browser` dependency for window-focus query refresh.
- Improve the Forms guide structure and examples.
- Fix responsive homepage headline wrapping and update homepage copy.

## Notable API changes

- Package rename:

  ```diff
  - effect-fc-next
  + effect-view

---------

Co-authored-by: Julien Valverdé <julien.valverde@mailo.com>
Reviewed-on: #59
This commit was merged in pull request #59.
This commit is contained in:
2026-07-27 04:11:42 +02:00
parent ec21d49dce
commit 4b712de788
111 changed files with 1536 additions and 1278 deletions
+8 -4
View File
@@ -273,6 +273,7 @@ describe("Component", () => {
)
await screen.findByText("first")
vi.useFakeTimers()
view.rerender(
<runtime.context.Provider value={effectRuntime}>
@@ -280,16 +281,19 @@ describe("Component", () => {
</runtime.context.Provider>
)
await screen.findByText("second")
expect(screen.getByText("second")).toBeTruthy()
expect(cleanup).not.toHaveBeenCalled()
await new Promise(resolve => setTimeout(resolve, 5))
await vi.advanceTimersByTimeAsync(19)
expect(cleanup).not.toHaveBeenCalled()
await waitFor(() => expect(cleanup).toHaveBeenCalledWith("first"), { timeout: 100 })
await vi.advanceTimersByTimeAsync(1)
expect(cleanup).toHaveBeenCalledWith("first")
view.unmount()
await waitFor(() => expect(cleanup).toHaveBeenCalledWith("second"), { timeout: 100 })
await vi.advanceTimersByTimeAsync(20)
expect(cleanup).toHaveBeenCalledWith("second")
vi.useRealTimers()
await Effect.runPromise(runtime.runtime.disposeEffect)
})