A simple, powerful state management library for Svelte applications, inspired by GetX for Flutter.
- 🚀 Simple and intuitive API
- 🎯 Dependency injection for controllers
- 🔄 Reactive state management
- đź§© Automatic component updates
- ♻️ Optional automatic controller disposal
- 🏷️ Tag-based controller identification
# npm
npm install get-svelte
# pnpm
pnpm add get-svelte
# yarn
yarn add get-svelte
First, create a controller that extends GetxController
:
import { GetxController } from 'get-svelte';
class CounterController extends GetxController {
count = 0;
increment() {
this.count++;
this.notifyListener(); // Notify listeners about state change
}
decrement() {
this.count--;
this.notifyListener(); // Notify listeners about state change
}
// Optional: Override onInit for initialization logic
protected onInit(): void {
console.log('CounterController initialized');
}
}
Register your controller with the Get
service:
import { Get } from 'get-svelte';
import { CounterController } from './CounterController';
// Register controller without tag
const counterController = Get.put(new CounterController());
// Or register with a tag for specific identification
const taggedController = Get.put(new CounterController(), { tag: 'main-counter' });
Use the GetListener
component to automatically react to controller state changes:
<script>
import { Get, GetListener } from 'get-svelte';
import { CounterController } from './CounterController';
// Find existing controller or throw error if not found
const counterController = Get.find(CounterController);
// Or find controller by tag
const taggedController = Get.find(CounterController, { tag: 'main-counter' });
</script>
<GetListener controller={counterController}>
{#snippet builder(controller)}
<div>
<h1>Counter: {controller.count}</h1>
<button on:click={() => controller.increment()}>Increment</button>
<button on:click={() => controller.decrement()}>Decrement</button>
</div>
{/snippet}
</GetListener>
The main service class for controller management:
Registers a controller with the Get system. If a controller of the same type and tag exists, returns the existing instance.
const controller = Get.put(new MyController());
const taggedController = Get.put(new MyController(), { tag: 'unique-tag' });
Get.find<T extends GetxController>(ControllerClass: new (...args: any[]) => T, params?: { tag?: string }): T
Finds and returns a registered controller. Throws an error if not found.
const controller = Get.find(MyController);
const taggedController = Get.find(MyController, { tag: 'unique-tag' });
Get.isRegistered<T extends GetxController>(ControllerClass: new (...args: any[]) => T, params?: { tag?: string }): boolean
Checks if a controller is registered with the Get system.
const exists = Get.isRegistered(MyController, { tag: 'unique-tag' });
Base class for all controllers:
Notifies all registered listeners about state changes. Call this method whenever your controller's state changes.
Lifecycle hook called when the controller is initialized. Override this method to perform initialization tasks.
Removes the controller from the Get system.
A Svelte component that listens to controller state changes and rebuilds its UI:
<GetListener
controller={myController}
autoDestroy={true}>
{#snippet builder(controller)}
<!-- Your UI that uses controller state -->
<div>Count: {controller.count}</div>
{/snippet}
</GetListener>
controller
: The controller instance to listen toautoDestroy
(optional, default:true
): Whether to automatically dispose the controller when the component is destroyed
// CounterController.ts
import { GetxController } from 'get-svelte';
export class CounterController extends GetxController {
count = 0;
increment() {
this.count++;
this.notifyListener();
}
decrement() {
this.count--;
this.notifyListener();
}
}
<!-- Counter.svelte -->
<script>
import { Get, GetListener } from 'get-svelte';
import { CounterController } from './CounterController';
// Create and register controller if not already registered
const controller = Get.isRegistered(CounterController)
? Get.find(CounterController)
: Get.put(new CounterController());
</script>
<GetListener controller={controller}>
{#snippet builder(ctrl)}
<div>
<h2>Count: {ctrl.count}</h2>
<button on:click={() => ctrl.increment()}>+</button>
<button on:click={() => ctrl.decrement()}>-</button>
</div>
{/snippet}
</GetListener>
// Create multiple counter instances
const counter1 = Get.put(new CounterController(), { tag: 'counter1' });
const counter2 = Get.put(new CounterController(), { tag: 'counter2' });
// Later, retrieve specific counters
const counter1Instance = Get.find(CounterController, { tag: 'counter1' });
const counter2Instance = Get.find(CounterController, { tag: 'counter2' });
<script>
import { Get, GetListener } from 'get-svelte';
import { MyController } from './MyController';
const controller = Get.put(new MyController());
function cleanupController() {
controller.dispose();
}
</script>
<GetListener
controller={controller}
autoDestroy={false}>
{#snippet builder(ctrl)}
<!-- Your UI components here -->
<div>Data: {ctrl.data}</div>
{/snippet}
</GetListener>
<button on:click={cleanupController}>Dispose Controller</button>
Contributions are welcome! Please feel free to submit a Pull Request.
ISC License
Created by Abdalmonem