Finalize the Effect View rename and refresh docs, examples, and tooling (#59)
## 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:
@@ -47,8 +47,8 @@ const refreshIdentifier = "__effectViewRefresh"
|
||||
const acceptIdentifier = "__effectViewAccept"
|
||||
|
||||
const isSupportedPackage = (source: string): boolean =>
|
||||
source === "effect-fc-next"
|
||||
|| source === "effect-fc-next/Component"
|
||||
source === "effect-view"
|
||||
|| source === "effect-view/Component"
|
||||
|
||||
const collectImports = (
|
||||
sourceFile: ts.SourceFile,
|
||||
@@ -342,7 +342,7 @@ const scriptKind = (id: string): ts.ScriptKind => id.endsWith(".tsx")
|
||||
*
|
||||
* Place this plugin before `@vitejs/plugin-react`.
|
||||
*/
|
||||
export function effectViewPlugin(
|
||||
export function effectView(
|
||||
options: EffectViewRefreshOptions = {},
|
||||
): Plugin {
|
||||
const include = options.include ?? defaultInclude
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from "node:path"
|
||||
import type { Plugin } from "vite"
|
||||
import { describe, expect, it } from "vitest"
|
||||
import { effectViewPlugin } from "./index.js"
|
||||
import { effectView } from "./index.js"
|
||||
|
||||
|
||||
type TransformHook = Extract<
|
||||
@@ -31,12 +31,12 @@ const runTransform = async (
|
||||
const transform = (
|
||||
code: string,
|
||||
id = path.join(process.cwd(), "src/View.tsx"),
|
||||
): Promise<string | undefined> => runTransform(effectViewPlugin(), code, id)
|
||||
): Promise<string | undefined> => runTransform(effectView(), code, id)
|
||||
|
||||
describe("effectViewPlugin", () => {
|
||||
describe("effectView", () => {
|
||||
it("wraps a const Effect View descriptor", async () => {
|
||||
const result = await transform(`
|
||||
import { Component } from "effect-fc-next"
|
||||
import { Component } from "effect-view"
|
||||
import * as React from "react"
|
||||
|
||||
export const CounterView = Component.make("CounterView")(function*() {
|
||||
@@ -53,7 +53,7 @@ export const CounterView = Component.make("CounterView")(function*() {
|
||||
|
||||
it("registers a pipeline before withContext", async () => {
|
||||
const result = await transform(`
|
||||
import { Component } from "effect-fc-next"
|
||||
import { Component } from "effect-view"
|
||||
|
||||
const Page = Component.make("Page")(function*() {
|
||||
return <main />
|
||||
@@ -69,7 +69,7 @@ const Page = Component.make("Page")(function*() {
|
||||
|
||||
it("wraps a class's complete trait pipeline", async () => {
|
||||
const result = await transform(`
|
||||
import { Async, Component, Memoized } from "effect-fc-next"
|
||||
import { Async, Component, Memoized } from "effect-view"
|
||||
|
||||
class PostView extends Component.make("PostView")(function*() {
|
||||
const value = yield* Component.useOnMount(load)
|
||||
@@ -88,7 +88,7 @@ class PostView extends Component.make("PostView")(function*() {
|
||||
it("supports aliased Component imports and refresh reset", async () => {
|
||||
const result = await transform(`
|
||||
// @refresh reset
|
||||
import { Component as View } from "effect-fc-next"
|
||||
import { Component as View } from "effect-view"
|
||||
|
||||
const Probe = View.makeUntraced(function*() {
|
||||
return null
|
||||
@@ -109,11 +109,11 @@ export function View() {
|
||||
})
|
||||
|
||||
it("keeps instrumenting a module when all Effect Views are removed", async () => {
|
||||
const plugin = effectViewPlugin() as Plugin
|
||||
const plugin = effectView() as Plugin
|
||||
const id = path.join(process.cwd(), "src/Removed.tsx")
|
||||
|
||||
await runTransform(plugin, `
|
||||
import { Component } from "effect-fc-next"
|
||||
import { Component } from "effect-view"
|
||||
export const Probe = Component.makeUntraced(function*() {
|
||||
return null
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type * as Component from "effect-fc-next/Component"
|
||||
import * as Refreshable from "effect-fc-next/Refreshable"
|
||||
import type * as Component from "effect-view/Component"
|
||||
import * as Refreshable from "effect-view/Refreshable"
|
||||
import { describe, expect, it, vi } from "vitest"
|
||||
import { accept, register } from "./runtime.js"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type * as Component from "effect-fc-next/Component"
|
||||
import * as Refreshable from "effect-fc-next/Refreshable"
|
||||
import type * as Component from "effect-view/Component"
|
||||
import * as Refreshable from "effect-view/Refreshable"
|
||||
|
||||
export interface HotContext {
|
||||
readonly data: Record<string, unknown>
|
||||
|
||||
Reference in New Issue
Block a user