ReactComponent
Some checks failed
Lint / lint (push) Failing after 7s

This commit is contained in:
Julien Valverdé
2025-06-25 13:17:27 +02:00
parent 8c5613aa62
commit 1769c4074d
5 changed files with 107 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
# Reffuse
[Effect-TS](https://effect.website/) integration for React 19+ with the aim of integrating the Effect context system within React's component hierarchy, while avoiding touching React's internals.
This library is in early development. While it is (almost) feature complete and mostly usable, expect bugs and quirks. Things are still being ironed out, so ideas and criticisms are more than welcome.
Documentation is currently being written. In the meantime, you can take a look at the `packages/example` directory.
## Peer dependencies
- `effect` 3.13+
- `react` & `@types/react` 19+

View File

@@ -0,0 +1,37 @@
{
"name": "effect-components",
"version": "0.1.0",
"type": "module",
"files": [
"./README.md",
"./dist"
],
"license": "MIT",
"repository": {
"url": "git+https://github.com/Thiladev/reffuse.git"
},
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./*": {
"types": "./dist/*.d.ts",
"default": "./dist/*.js"
}
},
"scripts": {
"build": "tsc",
"lint:tsc": "tsc --noEmit",
"pack": "npm pack",
"clean:cache": "rm -f tsconfig.tsbuildinfo",
"clean:dist": "rm -rf dist",
"clean:node": "rm -rf node_modules"
},
"peerDependencies": {
"@types/react": "^19.0.0",
"effect": "^3.15.0",
"react": "^19.0.0"
}
}

View File

@@ -0,0 +1,25 @@
import { Effect, Runtime, type Scope } from "effect"
import type * as React from "react"
export interface ReactComponent<P, E, R> {
readonly fn: (props: P) => Effect.Effect<React.ReactNode, E, R | Scope.Scope>
use(callback: (Component: React.FC<P>) => React.ReactNode): Effect.Effect<React.ReactNode, never, R>
}
const ReactComponentPrototype: Omit<ReactComponent<any, any, any>, "fn"> = {
use(this: ReactComponent<any, any, any>, callback) {
return Effect.map(
Effect.runtime(),
runtime => callback(props => Runtime.runSync(runtime)(this.fn(props))),
)
}
}
export const make = <P, E, R>(
fn: (props: P) => Effect.Effect<React.ReactNode, E, R | Scope.Scope>
): ReactComponent<P, E, R> => Object.setPrototypeOf(
{ fn },
ReactComponentPrototype,
)

View File

@@ -0,0 +1 @@
export * as ReactComponent from "./ReactComponent.js"

View File

@@ -0,0 +1,33 @@
{
"compilerOptions": {
// Enable latest features
"lib": ["ESNext", "DOM"],
"target": "ESNext",
"module": "NodeNext",
"moduleDetection": "force",
"jsx": "react-jsx",
// "allowJs": true,
// Bundler mode
"moduleResolution": "NodeNext",
// "allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
// "noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false,
// Build
"outDir": "./dist",
"declaration": true
},
"include": ["./src"]
}