Add Effect v4 support, Fast Refresh tooling, and revamped docs #56
@@ -130,11 +130,11 @@ A complete implementation should provide the same safety contract developers exp
|
||||
|
||||
### 1. Add an Effect View refresh transform
|
||||
|
||||
Ship a Vite plugin, for example `@effect-view/vite`, placed before `react()`:
|
||||
Ship a Vite plugin, `@effect-view/vite-plugin`, placed before `react()`:
|
||||
|
||||
```ts
|
||||
plugins: [
|
||||
effectViewRefresh(),
|
||||
effectViewPlugin(),
|
||||
react(),
|
||||
]
|
||||
```
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
"react-icons": "^5.6.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@effect-view/vite": "workspace:*",
|
||||
"@effect-view/vite-plugin": "workspace:*",
|
||||
"@tanstack/react-router": "^1.170.10",
|
||||
"@tanstack/react-router-devtools": "^1.167.0",
|
||||
"@tanstack/router-plugin": "^1.168.13",
|
||||
@@ -124,8 +124,8 @@
|
||||
"vite": "^8.0.16",
|
||||
},
|
||||
},
|
||||
"packages/vite": {
|
||||
"name": "@effect-view/vite",
|
||||
"packages/vite-plugin": {
|
||||
"name": "@effect-view/vite-plugin",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"typescript": "^6.0.3",
|
||||
@@ -574,7 +574,7 @@
|
||||
|
||||
"@effect-fc/example-next": ["@effect-fc/example-next@workspace:packages/example-next"],
|
||||
|
||||
"@effect-view/vite": ["@effect-view/vite@workspace:packages/vite"],
|
||||
"@effect-view/vite-plugin": ["@effect-view/vite-plugin@workspace:packages/vite-plugin"],
|
||||
|
||||
"@effect/language-service": ["@effect/language-service@0.86.6", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-uwXbp+lWzt60bZnm6lG6S5DWy0m6TthUzV2hcQoiS6NzieEDm07tuBakscxOXoO+AU9+yTH+0TSIa9mEDt9dFA=="],
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import type * as Component from "./Component.js"
|
||||
* development refresh cell.
|
||||
*
|
||||
* This low-level API is intended for development-server integrations such as
|
||||
* `@effect-view/vite`.
|
||||
* `@effect-view/vite-plugin`.
|
||||
*/
|
||||
export const RefreshableTypeId: unique symbol = Symbol.for("@effect-view/Refreshable/Refreshable")
|
||||
export type RefreshableTypeId = typeof RefreshableTypeId
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"clean:modules": "rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@effect-view/vite": "workspace:*",
|
||||
"@effect-view/vite-plugin": "workspace:*",
|
||||
"@tanstack/react-router": "^1.170.10",
|
||||
"@tanstack/react-router-devtools": "^1.167.0",
|
||||
"@tanstack/router-plugin": "^1.168.13",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { tanstackRouter } from "@tanstack/router-plugin/vite"
|
||||
import react from "@vitejs/plugin-react"
|
||||
import effectViewRefresh from "@effect-view/vite"
|
||||
import { effectViewPlugin } from "@effect-view/vite-plugin"
|
||||
import path from "node:path"
|
||||
import { defineConfig } from "vite"
|
||||
|
||||
@@ -8,7 +8,7 @@ import { defineConfig } from "vite"
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
effectViewRefresh(),
|
||||
effectViewPlugin(),
|
||||
tanstackRouter({
|
||||
target: "react",
|
||||
autoCodeSplitting: true,
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# `@effect-view/vite`
|
||||
# `@effect-view/vite-plugin`
|
||||
|
||||
Experimental Vite Fast Refresh support for Effect View components.
|
||||
|
||||
```ts
|
||||
import effectViewRefresh from "@effect-view/vite"
|
||||
import { effectViewPlugin } from "@effect-view/vite-plugin"
|
||||
import react from "@vitejs/plugin-react"
|
||||
import { defineConfig } from "vite"
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
effectViewRefresh(),
|
||||
effectViewPlugin(),
|
||||
react(),
|
||||
],
|
||||
})
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@effect-view/vite",
|
||||
"name": "@effect-view/vite-plugin",
|
||||
"description": "Vite Fast Refresh support for Effect View components",
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
@@ -42,7 +42,7 @@ interface Definition {
|
||||
|
||||
const defaultInclude = /\.[cm]?[jt]sx?$/
|
||||
const defaultExclude = /\/node_modules\//
|
||||
const runtimeImport = "@effect-view/vite/runtime"
|
||||
const runtimeImport = "@effect-view/vite-plugin/runtime"
|
||||
const refreshIdentifier = "__effectViewRefresh"
|
||||
const acceptIdentifier = "__effectViewAccept"
|
||||
|
||||
@@ -342,7 +342,7 @@ const scriptKind = (id: string): ts.ScriptKind => id.endsWith(".tsx")
|
||||
*
|
||||
* Place this plugin before `@vitejs/plugin-react`.
|
||||
*/
|
||||
export default function effectViewRefresh(
|
||||
export function effectViewPlugin(
|
||||
options: EffectViewRefreshOptions = {},
|
||||
): Plugin {
|
||||
const include = options.include ?? defaultInclude
|
||||
@@ -30,7 +30,7 @@ const getRefreshData = (hot: HotContext): RefreshData => {
|
||||
/**
|
||||
* Registers an Effect View descriptor in a Vite HMR data cell.
|
||||
*
|
||||
* This API is injected by `@effect-view/vite`; applications should not need to
|
||||
* This API is injected by `@effect-view/vite-plugin`; applications should not need to
|
||||
* call it directly.
|
||||
*/
|
||||
export const register = <A extends Component.Component.Any>(
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from "node:path"
|
||||
import type { Plugin, TransformPluginContext } from "vite"
|
||||
import { describe, expect, it } from "vitest"
|
||||
import effectViewRefresh from "../src/index.js"
|
||||
import { effectViewPlugin } from "../src/index.js"
|
||||
|
||||
|
||||
const runTransform = async (
|
||||
@@ -25,9 +25,9 @@ const runTransform = async (
|
||||
const transform = (
|
||||
code: string,
|
||||
id = path.join(process.cwd(), "src/View.tsx"),
|
||||
): Promise<string | undefined> => runTransform(effectViewRefresh(), code, id)
|
||||
): Promise<string | undefined> => runTransform(effectViewPlugin(), code, id)
|
||||
|
||||
describe("effectViewRefresh", () => {
|
||||
describe("effectViewPlugin", () => {
|
||||
it("wraps a const Effect View descriptor", async () => {
|
||||
const result = await transform(`
|
||||
import { Component } from "effect-fc-next"
|
||||
@@ -39,7 +39,7 @@ export const CounterView = Component.make("CounterView")(function*() {
|
||||
})
|
||||
`)
|
||||
|
||||
expect(result).toContain("import { accept as __effectViewAccept, register as __effectViewRefresh } from \"@effect-view/vite/runtime\"")
|
||||
expect(result).toContain("import { accept as __effectViewAccept, register as __effectViewRefresh } from \"@effect-view/vite-plugin/runtime\"")
|
||||
expect(result).toContain("__effectViewRefresh(Component.make(\"CounterView\")")
|
||||
expect(result).toContain("\"src/View.tsx:CounterView\"")
|
||||
expect(result).toContain("__effectViewAccept(import.meta.hot, [\"src/View.tsx:CounterView\"])")
|
||||
@@ -103,7 +103,7 @@ export function View() {
|
||||
})
|
||||
|
||||
it("keeps instrumenting a module when all Effect Views are removed", async () => {
|
||||
const plugin = effectViewRefresh() as Plugin
|
||||
const plugin = effectViewPlugin() as Plugin
|
||||
const id = path.join(process.cwd(), "src/Removed.tsx")
|
||||
|
||||
await runTransform(plugin, `
|
||||
Reference in New Issue
Block a user