Line data Source code
1 : part of flutter_data;
2 :
3 : typedef FutureFn<R> = FutureOr<R> Function();
4 :
5 : class DataHelpers {
6 3 : static final uuid = Uuid();
7 :
8 1 : static String getType<T>([String? type]) {
9 1 : if (T == dynamic && type == null) {
10 0 : throw UnsupportedError('Please supply a type');
11 : }
12 1 : type ??= T.toString();
13 1 : type = type.decapitalize();
14 1 : return type.pluralize();
15 : }
16 :
17 1 : static String generateShortKey<T>() {
18 3 : return uuid.v1().substring(0, 6);
19 : }
20 :
21 1 : static String generateKey<T>([String? type]) {
22 1 : type = getType<T>(type);
23 4 : return uuid.v1().substring(0, 8).typifyWith(type);
24 : }
25 : }
26 :
27 : class OfflineException extends DataException {
28 2 : OfflineException({required Object error}) : super(error);
29 1 : @override
30 : String toString() {
31 2 : return 'OfflineException: $error';
32 : }
33 : }
34 :
35 : abstract class _Lifecycle {
36 : @protected
37 : @visibleForTesting
38 : bool get isInitialized;
39 :
40 : void dispose();
41 : }
42 :
43 : class InternalHolder<T extends DataModel<T>> {
44 : final Map<String, dynamic> finders;
45 1 : InternalHolder(this.finders);
46 : }
47 :
48 : // finders
49 :
50 : class DataFinder {
51 1 : const DataFinder();
52 : }
53 :
54 : typedef DataFinderAll<T extends DataModel<T>> = Future<List<T>?> Function({
55 : bool? remote,
56 : bool? background,
57 : Map<String, dynamic>? params,
58 : Map<String, String>? headers,
59 : bool? syncLocal,
60 : OnSuccessAll<T>? onSuccess,
61 : OnErrorAll<T>? onError,
62 : DataRequestLabel? label,
63 : });
64 :
65 : typedef DataFinderOne<T extends DataModel<T>> = Future<T?> Function(
66 : Object model, {
67 : bool? remote,
68 : bool? background,
69 : Map<String, dynamic>? params,
70 : Map<String, String>? headers,
71 : OnSuccessOne<T>? onSuccess,
72 : OnErrorOne<T>? onError,
73 : DataRequestLabel? label,
74 : });
75 :
76 : typedef DataWatcherAll<T extends DataModel<T>> = DataStateNotifier<List<T>?>
77 : Function({
78 : bool? remote,
79 : Map<String, dynamic>? params,
80 : Map<String, String>? headers,
81 : bool? syncLocal,
82 : String? finder,
83 : DataRequestLabel? label,
84 : });
85 :
86 : typedef DataWatcherOne<T extends DataModel<T>> = DataStateNotifier<T?> Function(
87 : Object model, {
88 : bool? remote,
89 : Map<String, dynamic>? params,
90 : Map<String, String>? headers,
91 : AlsoWatch<T>? alsoWatch,
92 : String? finder,
93 : DataRequestLabel? label,
94 : });
95 :
96 : // watch
97 :
98 : typedef Watcher = W Function<W>(ProviderListenable<W> provider);
99 :
100 : typedef AlsoWatch<T extends DataModel<T>> = Iterable<Relationship?> Function(T);
101 :
102 : /// This argument holder class is used internally with
103 : /// Riverpod `family`s.
104 : class WatchArgs<T extends DataModel<T>> with EquatableMixin {
105 1 : WatchArgs({
106 : this.key,
107 : this.remote,
108 : this.params,
109 : this.headers,
110 : this.syncLocal,
111 : this.alsoWatch,
112 : this.finder,
113 : this.label,
114 : });
115 :
116 : final String? key;
117 : final bool? remote;
118 : final Map<String, dynamic>? params;
119 : final Map<String, String>? headers;
120 : final bool? syncLocal;
121 : final AlsoWatch<T>? alsoWatch;
122 : final String? finder;
123 : final DataRequestLabel? label;
124 :
125 1 : @override
126 : List<Object?> get props =>
127 8 : [key, remote, params, headers, syncLocal, finder, label];
128 : }
129 :
130 : // ignore: constant_identifier_names
131 2 : enum DataRequestMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE }
132 :
133 : extension _ToStringX on DataRequestMethod {
134 4 : String toShortString() => toString().split('.').last;
135 : }
136 :
137 : typedef _OnSuccessGeneric<R> = FutureOr<R?> Function(
138 : Object? data, DataRequestLabel? label);
139 : typedef OnSuccessOne<T extends DataModel<T>> = FutureOr<T?> Function(
140 : Object? data, DataRequestLabel? label, RemoteAdapter<T> adapter);
141 : typedef OnSuccessAll<T extends DataModel<T>> = FutureOr<List<T>?> Function(
142 : Object? data, DataRequestLabel? label, RemoteAdapter<T> adapter);
143 :
144 : typedef _OnErrorGeneric<R> = FutureOr<R?> Function(
145 : DataException e, DataRequestLabel? label);
146 : typedef OnErrorOne<T extends DataModel<T>> = FutureOr<T?> Function(
147 : DataException e, DataRequestLabel? label, RemoteAdapter<T> adapter);
148 : typedef OnErrorAll<T extends DataModel<T>> = FutureOr<List<T>?> Function(
149 : DataException e, DataRequestLabel? label, RemoteAdapter<T> adapter);
150 :
151 : /// Data request information holder.
152 : ///
153 : /// Format examples:
154 : /// - findAll/reports@b5d14c
155 : /// - findOne/inspections#3@c4a1bb
156 : /// - findAll/reports@b5d14c<c4a1bb
157 : class DataRequestLabel with EquatableMixin {
158 : final String kind;
159 : late final String type;
160 : final String? id;
161 : DataModel? model;
162 : final _requestIds = <String>[];
163 :
164 3 : String get requestId => _requestIds.first;
165 4 : int get indentation => _requestIds.length - 1;
166 :
167 1 : DataRequestLabel(
168 : String kind, {
169 : required String type,
170 : this.id,
171 : String? requestId,
172 : this.model,
173 : DataRequestLabel? withParent,
174 1 : }) : kind = kind.trim() {
175 : assert(!type.contains('#'));
176 1 : if (id != null) {
177 : assert(!id!.contains('#'));
178 : }
179 : if (requestId != null) {
180 : assert(!requestId.contains('@'));
181 : }
182 2 : this.type = DataHelpers.getType(type);
183 3 : _requestIds.add(requestId ?? DataHelpers.generateShortKey());
184 :
185 : if (withParent != null) {
186 3 : _requestIds.addAll(withParent._requestIds);
187 : }
188 : }
189 :
190 1 : factory DataRequestLabel.parse(String text) {
191 1 : final parts = text.split('/');
192 2 : final parts2 = parts.last.split('@');
193 2 : final parts3 = parts2[0].split('#');
194 2 : final kind = (parts..removeLast()).join('/');
195 1 : final requestId = parts2[1];
196 1 : final type = parts3[0];
197 3 : final id = parts3.length > 1 ? parts3[1] : null;
198 :
199 1 : return DataRequestLabel(kind, type: type, id: id, requestId: requestId);
200 : }
201 :
202 1 : @override
203 : String toString() {
204 7 : return '$kind/${(id ?? '').typifyWith(type)}@${_requestIds.join('<')}';
205 : }
206 :
207 1 : @override
208 5 : List<Object?> get props => [kind, type, id, _requestIds];
209 : }
210 :
211 : /// ONLY FOR FLUTTER DATA INTERNAL USE
212 3 : final internalRepositories = <String, Repository>{};
|