vexana_jaspr
vexana_jaspr brings the full power of Vexana to the Jaspr web framework.
It allows you to share identical INetworkModel classes between your Flutter apps and Jaspr web apps while providing web-native storage caching and reactive offline UI components.
Features
- Built on
vexana_core: Share the exact sameINetworkModelclasses across Flutter mobile apps, Jaspr web apps, and backend services. - Web LocalStorage Cache: Built-in
JasprLocalStorageFileManagerbacked bywindow.localStoragewith duration-based cache expiration (falls back gracefully to in-memory storage during SSR or VM tests). - Jaspr No-Network Handler:
JasprNoNetworkimplementsINoNetworkHandlerto intercept requests made without an active internet connection. - Reactive Offline Component: Drop-in
JasprNoNetworkComponentcomponent rendering an interactive banner with a "Retry" button when connectivity drops. - Navigator Connectivity Check:
JasprNetworkCheckchecks connection state viawindow.navigator.onLine.
Installation
Add vexana_jaspr to your Jaspr project's pubspec.yaml:
dependencies:
jaspr: ^0.23.5
vexana_jaspr: ^0.1.0
Quick Start
1. Define a Shared Model
import 'package:vexana_jaspr/vexana_jaspr.dart';
final class Post extends INetworkModel<Post> {
Post({this.id, this.title, this.body});
final int? id;
final String? title;
final String? body;
@override
Post fromJson(Map<String, dynamic> json) => Post(
id: json['id'] as int?,
title: json['title'] as String?,
body: json['body'] as String?,
);
@override
Map<String, dynamic>? toJson() => {'id': id, 'title': title, 'body': body};
}
2. Configure NetworkManager with Web Cache & NoNetwork
import 'package:vexana_jaspr/vexana_jaspr.dart';
final networkManager = NetworkManager<EmptyModel>(
isEnableLogger: true,
options: BaseOptions(
baseUrl: 'https://jsonplaceholder.typicode.com',
connectTimeout: const Duration(seconds: 10),
),
// Caches responses in browser window.localStorage
fileManager: JasprLocalStorageFileManager(),
);
3. Display Offline Banner in your Jaspr Component Tree
JasprNoNetwork only acts when the browser is offline (navigator.onLine)
and the request was sent with isErrorDialog: true. onNetworkLoss receives
retry and dismiss; the failed request waits until one of them is called.
Retries are capped by maxRetryCount.
import 'package:jaspr/dom.dart';
import 'package:jaspr/jaspr.dart';
import 'package:vexana_jaspr/vexana_jaspr.dart';
class App extends StatefulComponent {
const App({super.key});
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
late final NetworkManager<EmptyModel> _manager;
JasprRetryCallback? _pendingRetry;
@override
void initState() {
super.initState();
_manager = NetworkManager<EmptyModel>(
options: BaseOptions(baseUrl: 'https://jsonplaceholder.typicode.com'),
noNetwork: JasprNoNetwork(
onNetworkLoss: (retry, dismiss) {
setState(() => _pendingRetry = retry);
},
),
);
}
void _retry() {
final retry = _pendingRetry;
setState(() => _pendingRetry = null);
retry?.call();
}
@override
Component build(BuildContext context) {
return div([
if (_pendingRetry != null) JasprNoNetworkComponent(onRetry: _retry),
h1([Component.text('Welcome to My Jaspr App')]),
]);
}
}
Requests opt in per call:
await _manager.send<Post, List<Post>>(
'/posts',
parseModel: Post(),
method: RequestType.GET,
isErrorDialog: true,
);
Complete Example
Check out the full working Jaspr web application in the example directory:
cd packages/vexana_jaspr/example
jaspr serve
Related Packages
vexana_core: Pure Dart core engine (zero Flutter SDK dependencies).vexana: Flutter package with mobile disk cache and Flutter widgets.
License
This package is licensed under the MIT License - see the LICENSE file.
Libraries
- vexana_jaspr
- Jaspr web networking package for Vexana.