diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md
index 7a9b67b..e941385 100644
--- a/packages/docs/docs/getting-started.md
+++ b/packages/docs/docs/getting-started.md
@@ -370,7 +370,7 @@ that behavior, pass their tags with `Component.withOptions({ nonReactiveTags:
## Provide Services To A Subtree
-Use `Component.useContextFromLayer` when an Effect View component should provide
+Use `Component.useLayer` when an Effect View component should provide
extra services to another Effect View component. It turns a `Layer` into a runtime
context that can be provided to `.use`.
@@ -381,19 +381,19 @@ import { GreetingView } from "./Greeting"
import { GreetingLive } from "./services"
export const GreetingPageView = Component.make("GreetingPage")(function* () {
- const context = yield* Component.useContextFromLayer(GreetingLive)
+ const context = yield* Component.useLayer(GreetingLive)
const Greeting = yield* GreetingView.use.pipe(Effect.provide(context))
return
})
```
-The layer passed to `useContextFromLayer` should be stable. If a new layer value
+The layer passed to `useLayer` should be stable. If a new layer value
is created on every render, Effect View has to build a new context, which can
cause unnecessary re-renders and scoped lifecycle restarts. Define static layers
outside the component, or memoize layers that depend on React props or state.
-Layers built with `useContextFromLayer` are scoped to the component that builds
+Layers built with `useLayer` are scoped to the component that builds
them. That means service construction can register scoped logic, acquire
resources, fork scoped fibers, and add finalizers that are tied to that
component's lifecycle.
diff --git a/packages/effect-fc-next/README.md b/packages/effect-fc-next/README.md
index 2ce8f10..1c613a0 100644
--- a/packages/effect-fc-next/README.md
+++ b/packages/effect-fc-next/README.md
@@ -42,7 +42,7 @@ export class TodosView extends Component.make("TodosView")(function*() {
}) {}
const Index = Component.make("IndexView")(function*() {
- const context = yield* Component.useContextFromLayer(TodosState.Default)
+ const context = yield* Component.useLayer(TodosState.Default)
const Todos = yield* Effect.provide(TodosView.use, context)
return
diff --git a/packages/effect-fc-next/src/Component.ts b/packages/effect-fc-next/src/Component.ts
index 8aaa622..c9a45be 100644
--- a/packages/effect-fc-next/src/Component.ts
+++ b/packages/effect-fc-next/src/Component.ts
@@ -1099,7 +1099,7 @@ export declare namespace useContext {
* ```tsx
* const MyLayer = Layer.succeed(MyService, new MyServiceImpl())
* const MyComponent = Component.make(function*() {
- * const context = yield* Component.useContextFromLayer(MyLayer)
+ * const context = yield* Component.useLayer(MyLayer)
* const Sub = yield* SubComponent.use.pipe(
* Effect.provide(context)
* )
@@ -1111,7 +1111,7 @@ export declare namespace useContext {
* @example With memoized layer
* ```tsx
* const MyComponent = Component.make(function*(props: { id: string })) {
- * const context = yield* Component.useContextFromLayer(
+ * const context = yield* Component.useLayer(
* React.useMemo(() => Layer.succeed(MyService, new MyServiceImpl(props.id)), [props.id])
* )
* const Sub = yield* SubComponent.use.pipe(
@@ -1126,17 +1126,15 @@ export declare namespace useContext {
* ```tsx
* const MyAsyncLayer = Layer.effect(MyService, someAsyncEffect)
* const MyComponent = Component.make(function*() {
- * const context = yield* Component.useContextFromLayer(MyAsyncLayer)
- * const Sub = yield* SubComponent.use.pipe(
- * Effect.provide(context)
- * )
+ * const context = yield* Component.useLayer(MyAsyncLayer)
+ * const Sub = yield* Effect.provide(SubComponent, context)
*
* return
* }).pipe(
* Async.async // Required to handle async layer effects
* )
*/
-export const useContextFromLayer = (
+export const useLayer = (
layer: Layer.Layer,
options?: useContext.Options,
): Effect.Effect, E, RIn | Scope.Scope> => useOnChange(() => Effect.flatMap(
diff --git a/packages/effect-fc-next/test/Component.test.tsx b/packages/effect-fc-next/test/Component.test.tsx
index 0abd55e..34393f0 100644
--- a/packages/effect-fc-next/test/Component.test.tsx
+++ b/packages/effect-fc-next/test/Component.test.tsx
@@ -317,7 +317,7 @@ describe("Component", () => {
() => Layer.succeed(ValueService, { value: props.value }),
[props.value],
)
- const context = yield* Component.useContextFromLayer(serviceLayer, {
+ const context = yield* Component.useLayer(serviceLayer, {
finalizerExecutionDebounce: 0,
})
const Child = yield* Effect.provide(SubComponent.use, context)
diff --git a/packages/effect-fc/README.md b/packages/effect-fc/README.md
index d35c93d..4a9e717 100644
--- a/packages/effect-fc/README.md
+++ b/packages/effect-fc/README.md
@@ -42,7 +42,7 @@ export class TodosView extends Component.make("TodosView")(function*() {
}) {}
const Index = Component.make("IndexView")(function*() {
- const context = yield* Component.useContextFromLayer(TodosState.Default)
+ const context = yield* Component.useLayer(TodosState.Default)
const Todos = yield* Effect.provide(TodosView.use, context)
return
diff --git a/packages/effect-fc/src/Component.ts b/packages/effect-fc/src/Component.ts
index ef54a5b..91df15e 100644
--- a/packages/effect-fc/src/Component.ts
+++ b/packages/effect-fc/src/Component.ts
@@ -1075,10 +1075,8 @@ export declare namespace useContext {
* ```tsx
* const MyLayer = Layer.succeed(MyService, new MyServiceImpl())
* const MyComponent = Component.make(function*() {
- * const context = yield* Component.useContextFromLayer(MyLayer)
- * const Sub = yield* SubComponent.use.pipe(
- * Effect.provide(context)
- * )
+ * const context = yield* Component.useLayer(MyLayer)
+ * const Sub = yield* Effect.provide(SubComponent.use, context)
*
* return
* })
@@ -1087,12 +1085,10 @@ export declare namespace useContext {
* @example With memoized layer
* ```tsx
* const MyComponent = Component.make(function*(props: { id: string })) {
- * const context = yield* Component.useContextFromLayer(
+ * const context = yield* Component.useLayer(
* React.useMemo(() => Layer.succeed(MyService, new MyServiceImpl(props.id)), [props.id])
* )
- * const Sub = yield* SubComponent.use.pipe(
- * Effect.provide(context)
- * )
+ * const Sub = yield* Effect.provide(SubComponent.use, context)
*
* return
* })
@@ -1102,17 +1098,15 @@ export declare namespace useContext {
* ```tsx
* const MyAsyncLayer = Layer.effect(MyService, someAsyncEffect)
* const MyComponent = Component.make(function*() {
- * const context = yield* Component.useContextFromLayer(MyAsyncLayer)
- * const Sub = yield* SubComponent.use.pipe(
- * Effect.provide(context)
- * )
+ * const context = yield* Component.useLayer(MyAsyncLayer)
+ * const Sub = yield* Effect.provide(SubComponent.use, context)
*
* return
* }).pipe(
* Async.async // Required to handle async layer effects
* )
*/
-export const useContextFromLayer = (
+export const useLayer = (
layer: Layer.Layer,
options?: useContext.Options,
): Effect.Effect, E, RIn | Scope.Scope> => useOnChange(() => Effect.context().pipe(
diff --git a/packages/effect-fc/test/Component.test.tsx b/packages/effect-fc/test/Component.test.tsx
index eb846d9..f870806 100644
--- a/packages/effect-fc/test/Component.test.tsx
+++ b/packages/effect-fc/test/Component.test.tsx
@@ -317,7 +317,7 @@ describe("Component", () => {
() => Layer.succeed(ValueService, { value: props.value }),
[props.value],
)
- const context = yield* Component.useContextFromLayer(serviceLayer, {
+ const context = yield* Component.useLayer(serviceLayer, {
finalizerExecutionDebounce: 0,
})
const Child = yield* Effect.provide(SubComponent.use, context)
diff --git a/packages/example-next/src/routes/lensform.tsx b/packages/example-next/src/routes/lensform.tsx
index aa1cae0..8b5b037 100644
--- a/packages/example-next/src/routes/lensform.tsx
+++ b/packages/example-next/src/routes/lensform.tsx
@@ -47,7 +47,7 @@ const LensFormPageView = Component.make("LensFormPageView")(function*() {
yield* Console.log("LensForm route mounted")
}))
- const context = yield* Component.useContextFromLayer(AppState.layer)
+ const context = yield* Component.useLayer(AppState.layer)
const UserProfileEditor = yield* Effect.provide(UserProfileEditorView.use, context)
return
diff --git a/packages/example/package.json b/packages/example/package.json
index e2b05c7..141145e 100644
--- a/packages/example/package.json
+++ b/packages/example/package.json
@@ -5,7 +5,7 @@
"private": true,
"scripts": {
"dev": "vite",
- "lint:tsc": "tsc --noEmit",
+ "lint:tsc": "tsc -b --noEmit",
"lint:biome": "biome lint",
"preview": "vite preview",
"clean:cache": "rm -rf .turbo node_modules/.tmp node_modules/.vite* .tanstack",
diff --git a/packages/example/src/routes/dev/context.tsx b/packages/example/src/routes/dev/context.tsx
index 26048a9..7e5e600 100644
--- a/packages/example/src/routes/dev/context.tsx
+++ b/packages/example/src/routes/dev/context.tsx
@@ -23,7 +23,7 @@ const SubComponent = Component.makeUntraced("SubComponent")(function*() {
const ContextView = Component.makeUntraced("ContextView")(function*() {
const [serviceValue, setServiceValue] = React.useState("test")
const SubServiceLayer = React.useMemo(() => SubService.Default(serviceValue), [serviceValue])
- const SubComponentFC = yield* Effect.provide(SubComponent.use, yield* Component.useContextFromLayer(SubServiceLayer))
+ const SubComponentFC = yield* Effect.provide(SubComponent.use, yield* Component.useLayer(SubServiceLayer))
return (
diff --git a/packages/example/src/routes/form.tsx b/packages/example/src/routes/form.tsx
index 9ce3fae..cde4eda 100644
--- a/packages/example/src/routes/form.tsx
+++ b/packages/example/src/routes/form.tsx
@@ -129,7 +129,7 @@ class RegisterFormView extends Component.make("RegisterFormView")(function*() {
const RegisterPage = Component.make("RegisterPageView")(function*() {
const RegisterForm = yield* Effect.provide(
RegisterFormView.use,
- yield* Component.useContextFromLayer(RegisterFormService.Default),
+ yield* Component.useLayer(RegisterFormService.Default),
)
return
diff --git a/packages/example/src/routes/index.tsx b/packages/example/src/routes/index.tsx
index d747b39..b4582f3 100644
--- a/packages/example/src/routes/index.tsx
+++ b/packages/example/src/routes/index.tsx
@@ -11,7 +11,7 @@ const TodosStateLive = TodosState.Default("todos")
const Index = Component.make("IndexView")(function*() {
const Todos = yield* Effect.provide(
TodosView.use,
- yield* Component.useContextFromLayer(TodosStateLive),
+ yield* Component.useLayer(TodosStateLive),
)
return
diff --git a/packages/example/tsconfig.app.json b/packages/example/tsconfig.app.json
index 835427f..b823bd2 100644
--- a/packages/example/tsconfig.app.json
+++ b/packages/example/tsconfig.app.json
@@ -22,7 +22,6 @@
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
- "baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},