Summon provides a flexible lifecycle management system designed to work across different JavaScript environments. This guide explains how to use it with browsers, Node.js, and Web Workers.
The JS lifecycle system consists of:
LifecycleOwner class that manages lifecycle states// Get the current lifecycle owner
val lifecycleOwner = currentLifecycleOwner()
// Create a lifecycle-aware component
val component = LifecycleAwareComponent(
lifecycleOwner = lifecycleOwner,
onResume = {
// Start services, open connections
println("Component is active")
},
onPause = {
// Pause operations, reduce resource usage
println("Component is paused")
},
onDestroy = {
// Cleanup resources, close connections
println("Component is destroyed")
}
)
// Don't forget to dispose when no longer needed
component.dispose()
// Add custom startup hook
JsLifecycleOwner.addStartupHook {
// Initialize your service
println("My service is starting up")
}
// Add custom shutdown hook
JsLifecycleOwner.addShutdownHook {
// Clean up your service
println("My service is shutting down")
}
// Add custom visibility change hook (useful in browser environments)
JsLifecycleOwner.addVisibilityChangeHook { isVisible ->
if (isVisible) {
// App is now visible to the user
println("Application became visible")
} else {
// App is hidden from the user
println("Application is hidden")
}
}
In browser environments, the lifecycle is connected to document visibility and page lifecycle events:
visibilitychange event: Controls transitions between RESUMED and PAUSED statesbeforeunload event: Triggers STOPPED state and shutdown hooks// Example of browser-specific code
class MyBrowserComponent {
init {
// This will work in browser environments
val lifecycleOwner = currentLifecycleOwner()
// Respond to visibility changes
JsLifecycleOwner.addVisibilityChangeHook { isVisible ->
if (isVisible) {
refreshData()
} else {
pauseBackgroundTasks()
}
}
}
private fun refreshData() {
// Refresh data when tab becomes visible
}
private fun pauseBackgroundTasks() {
// Pause tasks when tab is hidden
}
}
In Node.js environments, the lifecycle connects to process events:
exit event: Triggers DESTROYED stateSIGINT and SIGTERM signals: Trigger STOPPED state and shutdown hooks// Example of Node.js integration
class MyNodeService {
init {
// This will work in Node.js environments
val lifecycleOwner = currentLifecycleOwner()
// Use lifecycleCoroutineScope for background work
lifecycleCoroutineScope(lifecycleOwner).launch {
// This coroutine will be cancelled when the process exits
}
// Register cleanup on shutdown
JsLifecycleOwner.addShutdownHook {
closeConnections()
}
}
private fun closeConnections() {
// Close database connections, etc.
}
}
In Web Worker environments, the lifecycle can be controlled via custom messages:
// Example of Web Worker integration
class MyWorkerComponent {
init {
// This will work in Web Worker environments
val lifecycleOwner = currentLifecycleOwner()
// Web Workers can receive lifecycle events via messages
// Example message to control lifecycle:
// { type: 'lifecycle', action: 'pause' }
// { type: 'lifecycle', action: 'resume' }
// { type: 'lifecycle', action: 'terminate' }
}
}
You can add support for other JS environments by extending the JsEnvironmentIntegrations object:
// Add to JsEnvironmentIntegrations object
fun setupCustomEnvironmentIntegration() {
try {
// Check if your environment is available
if (isCustomEnvironment()) {
println("Custom environment detected")
// Add lifecycle hooks
JsLifecycleOwner.addStartupHook {
println("Custom environment started")
}
JsLifecycleOwner.addShutdownHook {
println("Custom environment shutting down")
}
// Set up custom event listeners
setupCustomEventListeners()
}
} catch (e: Throwable) {
// Error handling
}
}
private fun isCustomEnvironment(): Boolean {
return js("typeof customGlobal !== 'undefined'").unsafeCast<Boolean>()
}
private fun setupCustomEventListeners() {
js("""
// Your custom JS environment integration code
""".trimIndent()).unsafeCast<Unit>()
}
// Call your integration setup
JsEnvironmentIntegrations.setupCustomEnvironmentIntegration()
For JavaScript applications, lifecycle states have these meanings:
CREATED: The component has been created but not startedSTARTED: The component is starting but not yet fully operationalRESUMED: The component is fully operational and visible (for browser environments)PAUSED: The component is still running but not visible (e.g., tab in background)STOPPED: The component is being shut downDESTROYED: The component has been destroyed and all resources releasedWhen your application starts:
JsLifecycleOwner is initialized by the first call to currentLifecycleOwner()JsEnvironmentIntegrations.setupAll() method is calledThis allows your code to respond to lifecycle events regardless of which JavaScript environment you're using.