diff --git a/packages/effect-fc/src/types/Subscribable.ts b/packages/effect-fc/src/types/Subscribable.ts
new file mode 100644
index 0000000..d622ec8
--- /dev/null
+++ b/packages/effect-fc/src/types/Subscribable.ts
@@ -0,0 +1,24 @@
+import { Effect, Effectable, Readable, Stream, Subscribable } from "effect"
+
+
+class SubscribableImpl
+extends Effectable.Class implements Subscribable.Subscribable {
+ readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId
+ readonly [Subscribable.TypeId]: Subscribable.TypeId = Subscribable.TypeId
+
+ constructor(
+ readonly get: Effect.Effect,
+ readonly changes: Stream.Stream,
+ ) {
+ super()
+ }
+
+ commit() {
+ return this.get
+ }
+}
+
+export const make = (values: {
+ readonly get: Effect.Effect
+ readonly changes: Stream.Stream
+}): Subscribable.Subscribable => new SubscribableImpl(values.get, values.changes)
diff --git a/packages/effect-fc/src/types/index.ts b/packages/effect-fc/src/types/index.ts
index e8b2633..6273110 100644
--- a/packages/effect-fc/src/types/index.ts
+++ b/packages/effect-fc/src/types/index.ts
@@ -1,3 +1,4 @@
export * as PropertyPath from "./PropertyPath.js"
export * as SetStateAction from "./SetStateAction.js"
+export * as Subscribable from "./Subscribable.js"
export * as SubscriptionSubRef from "./SubscriptionSubRef.js"
diff --git a/packages/example/src/todo/Todo.tsx b/packages/example/src/todo/Todo.tsx
index f364ed1..40f3293 100644
--- a/packages/example/src/todo/Todo.tsx
+++ b/packages/example/src/todo/Todo.tsx
@@ -54,7 +54,7 @@ export class Todo extends Component.makeUntraced(function* Todo(props: TodoProps
// eslint-disable-next-line react-hooks/exhaustive-deps
), [props._tag, props._tag === "edit" ? props.id : undefined])
- const [index, size] = yield* useSubscribe(indexRef, state.sizeRef)
+ const [index, size] = yield* useSubscribe(indexRef, state.sizeSubscribable)
const StringTextAreaInputFC = yield* StringTextAreaInput
const OptionalDateTimeInputFC = yield* OptionalDateTimeInput
diff --git a/packages/example/src/todo/TodosState.service.ts b/packages/example/src/todo/TodosState.service.ts
index 5b01c99..7fed39e 100644
--- a/packages/example/src/todo/TodosState.service.ts
+++ b/packages/example/src/todo/TodosState.service.ts
@@ -2,7 +2,7 @@ import { Todo } from "@/domain"
import { KeyValueStore } from "@effect/platform"
import { BrowserKeyValueStore } from "@effect/platform-browser"
import { Chunk, Console, Effect, Option, Schema, Stream, SubscriptionRef } from "effect"
-import { SubscriptionSubRef } from "effect-fc/types"
+import { Subscribable } from "effect-fc/types"
export class TodosState extends Effect.Service()("TodosState", {
@@ -32,7 +32,11 @@ export class TodosState extends Effect.Service()("TodosState", {
)
const ref = yield* SubscriptionRef.make(yield* readFromLocalStorage)
- const sizeRef = SubscriptionSubRef.makeFromPath(ref, ["length"])
+
+ const sizeSubscribable = Subscribable.make({
+ get: Effect.andThen(ref, Chunk.size),
+ get changes() { return Stream.map(ref.changes, Chunk.size) },
+ })
yield* Effect.forkScoped(ref.changes.pipe(
Stream.debounce("500 millis"),
@@ -43,7 +47,7 @@ export class TodosState extends Effect.Service()("TodosState", {
Effect.ignore,
))
- return { ref, sizeRef } as const
+ return { ref, sizeSubscribable } as const
}),
dependencies: [BrowserKeyValueStore.layerLocalStorage],