Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Binary file not shown.
66 changes: 53 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,64 @@
## [1.0.0] - 2026-02-01
## [1.1.0] - 2026-02-26

🏛️ The Birth of SINT (Initial Stable Release)
SINT 1.0.0 is a hard fork and Clean Architecture evolution of GetX (v5.0.0-rc). This version marks the transition from a "do-everything" framework to a "do the right things" infrastructure, focused exclusively on four pillars: State, Injection, Navigation, and Translation.
The Four Pillars Evolve — Workers, Pattern Matching, Async DI & Web-Safe Navigation.

175 lines of new code. Zero new dependencies. All four pillars upgraded.

### Pillar S (State Management)

- **Reactive Workers**: Added `ever()`, `once()`, `debounce()`, and `interval()` to `SintController`. Built on top of the existing `Rx.listen()` engine with automatic lifecycle management — all subscriptions auto-cancel on `onClose()`.
- **SintStatus Pattern Matching**: Added `.when()` and `.maybeWhen()` exhaustive pattern matching to `SintStatus<T>`, plus convenience getters (`.isLoading`, `.isSuccess`, `.isError`, `.isEmpty`, `.dataOrNull`, `.errorOrNull`). Inspired by Riverpod's `AsyncValue`.
- **SintListener Widget**: New widget that listens to `Rx` changes and executes a callback without rebuilding the widget tree. Equivalent to BLoC's `BlocListener` — ideal for side effects like snackbars, navigation triggers, and logging.

### Pillar I (Injection)

- **`putAsync<S>()`**: Async dependency registration for services that require `Future`-based initialization (SharedPreferences, databases, HTTP clients). Equivalent to GetIt's `registerSingletonAsync`.
- **`InjectionExtension.registeredKeys`**: Exposed registered dependency keys for internal selective cleanup operations.

🛠️ Key Architectural Changes
### Pillar N (Navigation)

Massive Code Pruning: Removed 7,766 lines of code (~37.7%) by stripping away non-core features like the HTTP client, animations, and unused string validators.
- **`SintSnackBarStyle`**: Global snackbar styling via `SintMaterialApp(snackBarStyle: ...)`. Defines default visual properties (colors, margins, durations, position, etc.) that apply to every `Sint.snackbar()` call. Three-level cascade: call-site parameters > global style > hardcoded defaults.
- **Web-Safe `back()`**: Integrated web-aware logic directly into `Sint.back()`. On web, if there's no internal navigation history to pop, it gracefully does nothing instead of crashing — the browser's back/forward arrows handle it.
- **`toInitial()` Hard Reset**: Performs a full app reset — deletes all non-permanent controllers (`onClose()` called on each), then reloads `initialRoute` from scratch. Supports selective preservation via `keep` parameter: `Sint.toInitial(keep: {AuthController})`.
- **`Sint.isWeb`**: Platform detection shortcut.
- **`Sint.showBackButton`**: Returns `false` on web (browser has native arrows), `true` on mobile.
- **Web Fade Transition**: Default `Transition.fade` on web for GPU-light performance (vs heavy Cupertino/Zoom).
- **Web Scroll Behavior**: Enabled drag scrolling for touch, mouse, and trackpad on web by default.
- **Deprecated `webBack()`**: Logic merged into `back()`. Use `Sint.back()` directly.
- **Deprecated `home` property**: In `SintMaterialApp`, `ConfigData`, and `SintRoot`. Use `initialRoute` + `sintPages` instead.

Clean Architecture Restructuring: Reorganized the entire codebase into a modular domain/engine/ui structure for every pilar, replacing the legacy flat-file layout.
### Pillar T (Translation)

Pillar Consolidation: Unified the framework into 5 core modules (core, injection, navigation, state_manager, translation) instead of the original 9+ scattered directories.
- **`loadTranslations()`**: Async lazy-loading of translations per module/feature. Merges with existing translations without replacing them — built on top of the existing `appendTranslations()` engine.

### Performance (v1.1.0 Benchmarks)

| Pillar | Operation | Avg Time |
|--------|-----------|----------|
| S | Reactive `.obs` update | 0.09 us/op |
| S | Simple `update()` | 0.11 us/op |
| I | `find()` with 10 tags | 1.34 us/find |
| T | `trParams()` interpolation | 2.65 us/op |

---

## [1.0.0] - 2026-02-01

The Birth of SINT (Initial Stable Release).
SINT 1.0.0 is a hard fork and Clean Architecture evolution of GetX (v5.0.0-rc). This version marks the transition from a "do-everything" framework to a "do the right things" infrastructure, focused exclusively on four pillars: State, Injection, Navigation, and Translation.

Reactive Sovereignty: Consolidated all reactive types (Rx) into the core/ module and moved platform detection into the navigation/ module where it is actually consumed.
### Key Architectural Changes

🔄 Compatibility & Migration
- Massive Code Pruning: Removed 7,766 lines of code (~37.7%) by stripping away non-core features like the HTTP client, animations, and unused string validators.
- Clean Architecture Restructuring: Reorganized the entire codebase into a modular domain/engine/ui structure for every pillar, replacing the legacy flat-file layout.
- Pillar Consolidation: Unified the framework into 5 core modules (core, injection, navigation, state_manager, translation) instead of the original 9+ scattered directories.
- Reactive Sovereignty: Consolidated all reactive types (Rx) into the core/ module and moved platform detection into the navigation/ module where it is actually consumed.

Legacy Bridge: Included a deprecated Get alias to allow a seamless migration for the existing apps.
### Compatibility & Migration

Single Entry Point: All pillars are now accessible through a single, clean import: package:sint/sint.dart.
- Legacy Bridge: Included a deprecated Get alias to allow a seamless migration for existing apps.
- Single Entry Point: All pillars are now accessible through a single, clean import: `package:sint/sint.dart`.

🌍 Documentation & Global Ready
### Documentation & Global Ready

Standardized Documentation: Shipped with complete guides for each of the four pillars in 12 languages, ensuring global adoption across the Open Neom ecosystem.
- Standardized Documentation: Shipped with complete guides for each of the four pillars in 12 languages, ensuring global adoption across the Open Neom ecosystem.
167 changes: 146 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
---

- [About SINT](#about-sint)
- [What's New in 1.1.0](#whats-new-in-110)
- [Installing](#installing)
- [The Four Pillars](#the-four-pillars)
- [State Management (S)](#state-management-s)
Expand All @@ -44,10 +45,10 @@ SINT is an architectural evolution of GetX (v5.0.0-rc), built as a focused frame

| Pillar | Responsibility |
|---|---|
| **S** — State Management | `SintController`, `SintBuilder`, `Obx`, `.obs`, Rx types, Workers |
| **I** — Injection | `Sint.put`, `Sint.find`, `Sint.lazyPut`, Bindings, SmartManagement |
| **N** — Navigation | `SintPage`, `Sint.toNamed`, middleware, `SintMaterialApp`, transitions |
| **T** — Translation | `.tr` extension, `Translations` class, locale management |
| **S** — State Management | `SintController`, `SintBuilder`, `Obx`, `.obs`, Rx types, Workers, `SintStatus`, `SintListener` |
| **I** — Injection | `Sint.put`, `Sint.find`, `Sint.lazyPut`, `Sint.putAsync`, Bindings, SmartManagement |
| **N** — Navigation | `SintPage`, `Sint.toNamed`, `Sint.toInitial`, middleware, `SintMaterialApp`, web-safe `back()` |
| **T** — Translation | `.tr` extension, `Translations` class, locale management, `loadTranslations` |

Everything outside these four pillars has been removed: no HTTP client, no animations, no string validators, no generic utilities. The result is **37.7% less code** than GetX — 12,849 LOC vs 20,615 LOC.

Expand All @@ -59,13 +60,93 @@ Everything outside these four pillars has been removed: no HTTP client, no anima

---

## What's New in 1.1.0

### Reactive Workers

Auto-cancelling reactive listeners on `SintController`:

```dart
class SearchController extends SintController {
final query = ''.obs;

@override
void onInit() {
super.onInit();
debounce(query, (q) => fetchResults(q)); // Wait 400ms after typing stops
once(query, (_) => analytics.track('search')); // Fire once, then auto-cancel
ever(query, (q) => print('Query: $q')); // Every change
interval(query, (q) => save(q)); // Max once per second
}
}
// All subscriptions auto-cancel on onClose(). Zero cleanup code.
```

### SintStatus Pattern Matching

Exhaustive `.when()` and `.maybeWhen()` on `SintStatus<T>`:

```dart
final status = SintStatus<User>.loading().obs;

Obx(() => status.value.when(
loading: () => CircularProgressIndicator(),
success: (user) => Text(user.name),
error: (err) => Text('$err'),
empty: () => Text('No data'),
));

// Convenience: status.value.isLoading, .dataOrNull, .errorOrNull
```

### SintListener

React to state without rebuilding (like BLoC's `BlocListener`):

```dart
SintListener<String>(
rx: controller.errorMsg,
listener: (msg) => Sint.snackbar(msg),
child: MyPage(),
)
```

### Async DI

```dart
await Sint.putAsync<SharedPreferences>(
() => SharedPreferences.getInstance(),
);
final prefs = Sint.find<SharedPreferences>();
```

### Hard Reset Navigation

```dart
Sint.toInitial(); // Full reset
Sint.toInitial(keep: {AuthController}); // Keep auth alive
```

### Lazy Translation Loading

```dart
await Sint.loadTranslations(() async {
final json = await rootBundle.loadString('assets/i18n/shop_es.json');
return {'es': Map<String, String>.from(jsonDecode(json))};
});
```

See [CHANGELOG.md](CHANGELOG.md) for the full list of changes.

---

## Installing

Add SINT to your `pubspec.yaml`:

```yaml
dependencies:
sint: ^1.0.0
sint: ^1.1.0
```

Import it:
Expand All @@ -75,21 +156,27 @@ import 'package:sint/sint.dart';
```

---

## High-Fidelity Performance (Benchmarks)
SINT is built for speed. Every pillar is audited against the Open Neom Standard to ensure minimal latency in high-load scenarios.

Current Performance Audit (v1.0.0)
Pillar Metric Result Context
S (State) Reactive Core Speed 5.0151 µs/op 30,000 updates stress test
T (Translation) Dynamic Interpolation 2.1614 µs/op 10,000 trParams lookups
I (Injection) Registry Lookup 1.1688 µs/find Depth 10 dependency resolution
N (Navigation) Middleware Latency 1,504 µs 5-layer middleware chain execution
Core Sync Latency 803 µs Stream-to-Rx event synchronization
SINT is built for speed. Every pillar is audited against the Open Neom Standard.

Why SINT is Faster:
• Pillar S: SINT avoids Stream overhead by using microtasks for high-fidelity notifications.
• Pillar I: Dependency resolution uses O(1) hash lookups in the global registry.
• Pillar N: Navigation is context-less, removing the need for heavy widget tree lookups during routing.
| Pillar | Metric | Result | Context |
|--------|--------|--------|---------|
| S (State) | Reactive `.obs` update | **0.09 us/op** | 50,000 updates |
| S (State) | Simple `update()` | **0.11 us/op** | 50,000 updates |
| S (State) | Rx with listener | **6.23 us/op** | 30,000 updates stress test |
| I (Injection) | Registry Lookup | **1.34 us/find** | Depth 10 dependency resolution |
| N (Navigation) | Middleware Latency | **23 ms** | 5-layer middleware chain |
| T (Translation) | Dynamic Interpolation | **2.65 us/op** | 10,000 trParams lookups |

**Why SINT is faster:**

- **Pillar S:** Avoids Stream overhead by using direct `ListNotifier` propagation. 15-30x faster than BLoC.
- **Pillar I:** O(1) hash lookups in the global registry with lifecycle management.
- **Pillar N:** Context-less navigation removes heavy widget tree lookups during routing.

---

## The Four Pillars

Expand All @@ -108,6 +195,26 @@ SintBuilder<Controller>(
)
```

**Workers** for reactive side effects:

```dart
ever(rx, callback); // Every change
once(rx, callback); // First change only
debounce(rx, callback); // After pause (400ms default)
interval(rx, callback); // Max once per duration (1s default)
```

**SintStatus** for async state:

```dart
status.value.when(
loading: () => spinner,
success: (data) => content(data),
error: (err) => errorView(err),
empty: () => emptyView,
);
```

[Full documentation](documentation/en_US/state_management.md)

### Injection (I)
Expand All @@ -116,6 +223,9 @@ Dependency injection without context:

```dart
Sint.put(AuthController());
Sint.lazyPut(() => ApiService());
await Sint.putAsync(() => SharedPreferences.getInstance());

final controller = Sint.find<AuthController>();
```

Expand All @@ -127,14 +237,17 @@ Route management without context:

```dart
SintMaterialApp(
getPages: [
initialRoute: '/',
sintPages: [
SintPage(name: '/', page: () => Home()),
SintPage(name: '/details', page: () => Details()),
],
)

Sint.toNamed('/details');
Sint.back();
Sint.back(); // Web-safe
Sint.toInitial(); // Hard reset to home
Sint.toInitial(keep: {AuthController}); // Keep specific controllers
Sint.snackbar('Title', 'Message');
```

Expand All @@ -148,6 +261,12 @@ Internationalization with `.tr`:
Text('hello'.tr);
Text('welcome'.trParams({'name': 'Serzen'}));
Sint.updateLocale(Locale('es', 'ES'));

// Lazy loading per module
await Sint.loadTranslations(() async {
final json = await rootBundle.loadString('assets/i18n/shop.json');
return {'es': Map<String, String>.from(jsonDecode(json))};
});
```

[Full documentation](documentation/en_US/translation_management.md)
Expand All @@ -157,7 +276,13 @@ Sint.updateLocale(Locale('es', 'ES'));
## Counter App with SINT

```dart
void main() => runApp(SintMaterialApp(home: Home()));
void main() => runApp(SintMaterialApp(
initialRoute: '/',
sintPages: [
SintPage(name: '/', page: () => Home()),
SintPage(name: '/other', page: () => Other()),
],
));

class Controller extends SintController {
var count = 0.obs;
Expand All @@ -173,7 +298,7 @@ class Home extends StatelessWidget {
body: Center(
child: ElevatedButton(
child: Text("Go to Other"),
onPressed: () => Sint.to(Other()),
onPressed: () => Sint.toNamed('/other'),
),
),
floatingActionButton: FloatingActionButton(
Expand Down
Loading
Loading