tsplus & effect in React
Here's how I do it in my app. I set up a "global effect runtime" that contains all of my services and I provide that via react context. Components can then execute effects with access to all the app services via that provided runtime.
/**
* Builds a "managed runtime" to be shared across the app environment. All running effects will be interrupted when the scope is closed.
* This allows for starting as many effects as needed in order to interface with other code such as react while only initializing a single
* instance of services and ensuring everything gets cleaned up.
* @returns
*/
export async function setupGlobalEffectRuntime(layer: IAppServicesLayer) {
//create a custom logger layer so output goes to console as json that can be prettified
const thConsoleLoggerLayer = L.scopedDiscard(
FiberRef.currentLoggers.locallyScopedWith(loggers => pipe(loggers, HashSet.add(thConsoleLogger)))
)
//build a runtime with the app services impl provided and our custom logger
const rt = await T.unsafeRunPromise(scopedManagedRuntime(L.provideToAndMerge(layer)(thConsoleLoggerLayer)))
setKeystoneContexts(rt)
await initAllEnv(rt)
//set observable value indicating runtime is now ready
rt.runtime.unsafeRunSync(T.serviceWith(LifecycleServiceTag, l => l.setRuntimeInitCompleted(true)))
return rt
}/**
* Builds a "managed runtime" to be shared across the app environment. All running effects will be interrupted when the scope is closed.
* This allows for starting as many effects as needed in order to interface with other code such as react while only initializing a single
* instance of services and ensuring everything gets cleaned up.
* @returns
*/
export async function setupGlobalEffectRuntime(layer: IAppServicesLayer) {
//create a custom logger layer so output goes to console as json that can be prettified
const thConsoleLoggerLayer = L.scopedDiscard(
FiberRef.currentLoggers.locallyScopedWith(loggers => pipe(loggers, HashSet.add(thConsoleLogger)))
)
//build a runtime with the app services impl provided and our custom logger
const rt = await T.unsafeRunPromise(scopedManagedRuntime(L.provideToAndMerge(layer)(thConsoleLoggerLayer)))
setKeystoneContexts(rt)
await initAllEnv(rt)
//set observable value indicating runtime is now ready
rt.runtime.unsafeRunSync(T.serviceWith(LifecycleServiceTag, l => l.setRuntimeInitCompleted(true)))
return rt
}