Skip to content

Commit

Permalink
reorganize state mixins
Browse files Browse the repository at this point in the history
  • Loading branch information
Kilian Schulte committed Jan 10, 2024
1 parent a53c6d9 commit 8454473
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 63 deletions.
54 changes: 54 additions & 0 deletions packages/jaspr/lib/src/foundation/sync.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'dart:convert';
import 'package:binary_codec/binary_codec.dart';
import 'package:meta/meta.dart';

import '../framework/framework.dart';

mixin SyncBinding {
/// Returns the accumulated data from all active [State]s that use the [SyncStateMixin]
@protected
Expand Down Expand Up @@ -102,6 +104,58 @@ abstract class SyncState<U> {
bool wantsSync();
}

/// Mixin on [State] that syncs state data from the server with the client
///
/// Requires a [GlobalKey] on the component.
mixin SyncStateMixin<T extends StatefulComponent, U> on State<T> implements SyncState<U> {
/// Codec used to serialize the state data on the server and deserialize on the client
/// Should convert the state to any dynamic type: Null, bool, double, int, Uint8List, String, Map, List
@override
Codec<U, dynamic>? get syncCodec => null;

/// Globally unique id used to identify the state data between server and client
/// Returns null if state should not be synced
@override
String get syncId;

/// Called on the client when a new state value is available, either when the state is first initialized, or when the
/// state becomes available through lazy loading a route.
///
/// On initialization, this will be called as part of the `super.initState()` call. It is recommended to start with the
/// inherited method call in you custom `initState()` implementation, however when you want to do some work before the
/// initial `updateState()` call, you can invoke the `super.initState()` later in your implementation.
///
/// ```dart
/// @override
/// void initState() {
/// // do some pre-initialization
/// super.initState(); // this will also call your updateState() implementation
/// // do some post-initialization
/// }
/// ```
///
/// The framework won't call setState() for you, so you have to call it yourself if you want to rebuild the component.
/// That allows for custom update logic and reduces unnecessary builds.
@override
void updateState(U? value);

/// Can be overridden to signal that the state should not be synced
@override
bool wantsSync() => true;

@override
void initState() {
super.initState();
context.binding.registerSyncState(this, initialUpdate: context.binding.isClient);
}

@override
void dispose() {
context.binding.unregisterSyncState(this);
super.dispose();
}
}

extension _SyncEncoding<U> on SyncState<U> {
_update(dynamic data) {
if (data == null || syncCodec == null) {
Expand Down
3 changes: 0 additions & 3 deletions packages/jaspr/lib/src/framework/framework.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ library framework;

import 'dart:async';
import 'dart:collection';
import 'dart:convert';

import 'package:meta/meta.dart';

import '../foundation/basic_types.dart';
import '../foundation/binding.dart';
import '../foundation/sync.dart';
import '../ui/styles/styles.dart';

part 'build_context.dart';
Expand All @@ -27,7 +25,6 @@ part 'observer_component.dart';
part 'render_element.dart';
part 'render_scope.dart';
part 'single_child_element.dart';
part 'state_mixins.dart';
part 'stateful_component.dart';
part 'stateless_component.dart';

Expand Down
60 changes: 0 additions & 60 deletions packages/jaspr/lib/src/framework/state_mixins.dart

This file was deleted.

7 changes: 7 additions & 0 deletions packages/jaspr/lib/src/framework/stateful_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,13 @@ abstract class State<T extends StatefulComponent> {
void didChangeDependencies() {}
}

/// Mixin on [State] that preloads state on the server
mixin PreloadStateMixin<T extends StatefulComponent> on State<T> {
/// Called on the server before initState() to preload asynchronous data
@protected
Future<void> preloadState();
}

/// An [Element] that uses a [StatefulComponent] as its configuration.
class StatefulElement extends MultiChildElement {
/// Creates an element that uses the given component as its configuration.
Expand Down

0 comments on commit 8454473

Please sign in to comment.