diff --git a/README.md b/README.md index 63f8083c..03523298 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ SSR-safe, zero-config Web Workers integration for [Nuxt](https://nuxt.com). - 🔥 SSR-safe usage of Web Workers - ✨ auto-imported, zero-configuration - 💪 fully typed +- 🕒 Automatic shutdown of workers after 1 second of inactivity ## Quick Setup @@ -58,6 +59,10 @@ const message = await hi() > [!TIP] > Even if your function is synchronous, it will always become async when it is called within a worker because communication with a worker will always be asynchronous. +### Worker Auto-Shutdown + +The module automatically shuts down workers after 1 second of inactivity to free up resources. This behavior ensures that your application remains efficient and responsive, without unnecessary resource consumption by idle workers. + ## Roadmap - [x] 📖 basic documentation @@ -65,7 +70,7 @@ const message = await hi() - [ ] 📦 webpack support - [ ] ⚠️ type-level + dev warning if non serialisable args are passed - [ ] 🤝 automatic shared workers with `.shared.ts` suffix -- [ ] 💤 worker auto-shutdown +- [x] 💤 worker auto-shutdown ## 💻 Development diff --git a/src/plugins/unplugin.ts b/src/plugins/unplugin.ts index b7b99bbe..59316de4 100644 --- a/src/plugins/unplugin.ts +++ b/src/plugins/unplugin.ts @@ -85,6 +85,7 @@ export const WorkerPlugin = (opts: WorkerPluginOptions) => createUnplugin(() => source += ` const counts = {} const map = {} +const workerTimeouts = {} function initWorker (worker, name) { map[name] = {} @@ -96,7 +97,20 @@ function initWorker (worker, name) { } else { resolve(e.data.result) } + // Reset the inactivity timer upon receiving a message + clearTimeout(workerTimeouts[name]); + workerTimeouts[name] = setTimeout(() => { + worker.terminate(); + delete workerTimeouts[name]; + console.log(\`Worker \${name} terminated due to inactivity.\`); + }, 1000); // 1 second of inactivity } + // Initialize the inactivity timer + workerTimeouts[name] = setTimeout(() => { + worker.terminate(); + delete workerTimeouts[name]; + console.log(\`Worker \${name} terminated due to inactivity.\`); + }, 1000); // 1 second of inactivity return worker }` } diff --git a/test/e2e.spec.ts b/test/e2e.spec.ts index e957e21e..0b58bb6f 100644 --- a/test/e2e.spec.ts +++ b/test/e2e.spec.ts @@ -26,4 +26,18 @@ describe('nuxt-workers', () => { expect(await page.getByText('Client-side message: Hello from worker!').textContent()).toBeDefined() await page.close() }) + + it('should automatically shut down the worker after 1 second of inactivity', async () => { + const page = await createPage() + const logs: string[] = [] + page.on('console', (l) => { + logs.push(l.text()) + }) + await page.goto(url('/')) + await page.getByText('Load client side message').click() + // wait for more than 1 second to ensure worker shutdown + await new Promise(resolve => setTimeout(resolve, 1500)) + expect(logs).toContainEqual(expect.stringContaining('Worker hi terminated due to inactivity.')) + await page.close() + }) })