From f3481cc2270057357abfc0b4791ecec3b673e129 Mon Sep 17 00:00:00 2001 From: Tobe O Date: Tue, 11 Sep 2018 16:34:29 -0400 Subject: [PATCH] Add generics to hooked service listeners --- .idea/workspace.xml | 249 ++++++++++++++++--------------- CHANGELOG.md | 2 + lib/src/core/core.dart | 1 - lib/src/core/hooked_service.dart | 157 ++++++++++--------- lib/src/core/typed_service.dart | 1 - 5 files changed, 211 insertions(+), 199 deletions(-) delete mode 100644 lib/src/core/typed_service.dart diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 1ce67e48..86763688 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,12 +2,11 @@ + - + - - - + @@ -30,46 +29,13 @@ - - - - - - - - - - - - - - + + - - - - - - - - - - - + + - - - - - - - - - - - - - + @@ -79,14 +45,47 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -99,7 +98,6 @@ - sopw stopw release handleRe @@ -129,6 +127,7 @@ /meta complet parseI + read( FutureOr @@ -192,10 +191,8 @@ @@ -662,14 +661,7 @@ - - - - 1534732365272 - 1534732527424 @@ -1007,7 +999,14 @@ - @@ -1043,7 +1042,7 @@ - @@ -1063,7 +1062,7 @@ - + @@ -1106,7 +1105,6 @@ @@ -1139,28 +1138,6 @@ - - - - - - - - - - - - - - - - - - - - - - @@ -1309,16 +1286,6 @@ - - - - - - - - - - @@ -1389,13 +1356,6 @@ - - - - - - - @@ -1445,16 +1405,6 @@ - - - - - - - - - - @@ -1462,6 +1412,19 @@ + + + + + + + + + + + + + @@ -1472,29 +1435,69 @@ - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - + + + + + + + + + - + @@ -1502,8 +1505,8 @@ - - + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aaf5ad9..98484132 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # 2.0.0-alpha.3 * Added `` type parameters to `Service`. * `HookedService` now follows suit, and takes a third parameter, pointing to the inner service. +* `Routable.use` now uses the generic parameters added to `Service`. +* Added generic usage to `HookedServiceListener`, etc. # 2.0.0-alpha.2 * Added `ResponseContext.detach`. diff --git a/lib/src/core/core.dart b/lib/src/core/core.dart index ebda0587..91b03380 100644 --- a/lib/src/core/core.dart +++ b/lib/src/core/core.dart @@ -7,4 +7,3 @@ export 'response_context.dart'; export 'routable.dart'; export 'server.dart'; export 'service.dart'; -export 'typed_service.dart'; diff --git a/lib/src/core/hooked_service.dart b/lib/src/core/hooked_service.dart index 87d3e42d..fe499fb2 100644 --- a/lib/src/core/hooked_service.dart +++ b/lib/src/core/hooked_service.dart @@ -1,11 +1,12 @@ library angel_framework.core.hooked_service; import 'dart:async'; + import '../util.dart'; +import 'metadata.dart'; import 'request_context.dart'; import 'response_context.dart'; import 'routable.dart'; -import 'metadata.dart'; import 'server.dart'; import 'service.dart'; @@ -17,30 +18,30 @@ class HookedService> /// Tbe service that is proxied by this hooked one. final T inner; - final HookedServiceEventDispatcher beforeIndexed = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher beforeRead = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher beforeCreated = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher beforeModified = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher beforeUpdated = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher beforeRemoved = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher afterIndexed = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher afterRead = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher afterCreated = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher afterModified = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher afterUpdated = - new HookedServiceEventDispatcher(); - final HookedServiceEventDispatcher afterRemoved = - new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher beforeIndexed = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher beforeRead = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher beforeCreated = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher beforeModified = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher beforeUpdated = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher beforeRemoved = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher afterIndexed = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher afterRead = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher afterCreated = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher afterModified = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher afterUpdated = + new HookedServiceEventDispatcher(); + final HookedServiceEventDispatcher afterRemoved = + new HookedServiceEventDispatcher(); HookedService(this.inner) { // Clone app instance @@ -90,17 +91,18 @@ class HookedService> /// Adds hooks to this instance. void addHooks(Angel app) { Hooks hooks = getAnnotation(inner, Hooks, app.container.reflector); - List before = [], after = []; + List> before = [], after = []; if (hooks != null) { before.addAll(hooks.before); after.addAll(hooks.after); } - void applyListeners(Function fn, HookedServiceEventDispatcher dispatcher, + void applyListeners( + Function fn, HookedServiceEventDispatcher dispatcher, [bool isAfter]) { Hooks hooks = getAnnotation(fn, Hooks, app.container.reflector); - final listeners = [] + final listeners = >[] ..addAll(isAfter == true ? after : before); if (hooks != null) @@ -137,8 +139,8 @@ class HookedService> } /// Runs the [listener] before every service method specified. - void before( - Iterable eventNames, HookedServiceEventListener listener) { + void before(Iterable eventNames, + HookedServiceEventListener listener) { eventNames.map((name) { switch (name) { case HookedServiceEvent.indexed: @@ -156,12 +158,13 @@ class HookedService> default: throw new ArgumentError('Invalid service method: ${name}'); } - }).forEach((HookedServiceEventDispatcher dispatcher) => + }).forEach((HookedServiceEventDispatcher dispatcher) => dispatcher.listen(listener)); } /// Runs the [listener] after every service method specified. - void after(Iterable eventNames, HookedServiceEventListener listener) { + void after(Iterable eventNames, + HookedServiceEventListener listener) { eventNames.map((name) { switch (name) { case HookedServiceEvent.indexed: @@ -179,12 +182,12 @@ class HookedService> default: throw new ArgumentError('Invalid service method: ${name}'); } - }).forEach((HookedServiceEventDispatcher dispatcher) => + }).forEach((HookedServiceEventDispatcher dispatcher) => dispatcher.listen(listener)); } /// Runs the [listener] before every service method. - void beforeAll(HookedServiceEventListener listener) { + void beforeAll(HookedServiceEventListener listener) { beforeIndexed.listen(listener); beforeRead.listen(listener); beforeCreated.listen(listener); @@ -194,7 +197,7 @@ class HookedService> } /// Runs the [listener] after every service method. - void afterAll(HookedServiceEventListener listener) { + void afterAll(HookedServiceEventListener listener) { afterIndexed.listen(listener); afterRead.listen(listener); afterCreated.listen(listener); @@ -208,8 +211,8 @@ class HookedService> /// *NOTE*: Only use this if you do not plan to modify events. There is no guarantee /// that events coming out of this [Stream] will see changes you make within the [Stream] /// callback. - Stream beforeAllStream() { - var ctrl = new StreamController(); + Stream> beforeAllStream() { + var ctrl = new StreamController>(); _ctrl.add(ctrl); before(HookedServiceEvent.all, ctrl.add); return ctrl.stream; @@ -220,8 +223,8 @@ class HookedService> /// *NOTE*: Only use this if you do not plan to modify events. There is no guarantee /// that events coming out of this [Stream] will see changes you make within the [Stream] /// callback. - Stream afterAllStream() { - var ctrl = new StreamController(); + Stream> afterAllStream() { + var ctrl = new StreamController>(); _ctrl.add(ctrl); before(HookedServiceEvent.all, ctrl.add); return ctrl.stream; @@ -232,8 +235,9 @@ class HookedService> /// *NOTE*: Only use this if you do not plan to modify events. There is no guarantee /// that events coming out of this [Stream] will see changes you make within the [Stream] /// callback. - Stream beforeStream(Iterable eventNames) { - var ctrl = new StreamController(); + Stream> beforeStream( + Iterable eventNames) { + var ctrl = new StreamController>(); _ctrl.add(ctrl); before(eventNames, ctrl.add); return ctrl.stream; @@ -244,15 +248,16 @@ class HookedService> /// *NOTE*: Only use this if you do not plan to modify events. There is no guarantee /// that events coming out of this [Stream] will see changes you make within the [Stream] /// callback. - Stream afterStream(Iterable eventNames) { - var ctrl = new StreamController(); + Stream> afterStream( + Iterable eventNames) { + var ctrl = new StreamController>(); _ctrl.add(ctrl); after(eventNames, ctrl.add); return ctrl.stream; } /// Runs the [listener] before [create], [modify] and [update]. - void beforeModify(HookedServiceEventListener listener) { + void beforeModify(HookedServiceEventListener listener) { beforeCreated.listen(listener); beforeModified.listen(listener); beforeUpdated.listen(listener); @@ -285,7 +290,7 @@ class HookedService> } @override - Future read(id, [Map _params]) { + Future read(Id id, [Map _params]) { var params = _stripReq(_params); return beforeRead ._emit(new HookedServiceEvent(false, _getRequest(_params), @@ -311,7 +316,7 @@ class HookedService> } @override - Future create(data, [Map _params]) { + Future create(Data data, [Map _params]) { var params = _stripReq(_params); return beforeCreated ._emit(new HookedServiceEvent(false, _getRequest(_params), @@ -337,7 +342,7 @@ class HookedService> } @override - Future modify(id, data, [Map _params]) { + Future modify(Id id, Data data, [Map _params]) { var params = _stripReq(_params); return beforeModified ._emit(new HookedServiceEvent(false, _getRequest(_params), @@ -363,7 +368,7 @@ class HookedService> } @override - Future update(id, data, [Map _params]) { + Future update(Id id, Data data, [Map _params]) { var params = _stripReq(_params); return beforeUpdated ._emit(new HookedServiceEvent(false, _getRequest(_params), @@ -389,7 +394,7 @@ class HookedService> } @override - Future remove(id, [Map _params]) { + Future remove(Id id, [Map _params]) { var params = _stripReq(_params); return beforeRemoved ._emit(new HookedServiceEvent(false, _getRequest(_params), @@ -416,9 +421,9 @@ class HookedService> /// Fires an `after` event. This will not be propagated to clients, /// but will be broadcasted to WebSockets, etc. - Future fire(String eventName, result, - [HookedServiceEventListener callback]) { - HookedServiceEventDispatcher dispatcher; + Future> fire(String eventName, result, + [HookedServiceEventListener callback]) { + HookedServiceEventDispatcher dispatcher; switch (eventName) { case HookedServiceEvent.indexed: @@ -443,14 +448,16 @@ class HookedService> throw new ArgumentError("Invalid service event name: '$eventName'"); } - var ev = new HookedServiceEvent(true, null, null, this, eventName); + var ev = + new HookedServiceEvent(true, null, null, inner, eventName); return fireEvent(dispatcher, ev, callback); } /// Sends an arbitrary event down the hook chain. - Future fireEvent( - HookedServiceEventDispatcher dispatcher, HookedServiceEvent event, - [HookedServiceEventListener callback]) { + Future> fireEvent( + HookedServiceEventDispatcher dispatcher, + HookedServiceEvent event, + [HookedServiceEventListener callback]) { Future f; if (callback != null && event?._canceled != true) f = new Future.sync(() => callback(event)); @@ -460,7 +467,7 @@ class HookedService> } /// Fired when a hooked service is invoked. -class HookedServiceEvent { +class HookedServiceEvent> { static const String indexed = 'indexed'; static const String read = 'read'; static const String created = 'created'; @@ -490,17 +497,17 @@ class HookedServiceEvent { bool _canceled = false; String _eventName; - var _id; + Id _id; bool _isAfter; - var data; - Map _params; + Data data; + Map _params; RequestContext _request; ResponseContext _response; var result; String get eventName => _eventName; - get id => _id; + Id get id => _id; bool get isAfter => _isAfter == true; @@ -513,23 +520,24 @@ class HookedServiceEvent { ResponseContext get response => _response; /// The inner service whose method was hooked. - Service service; + T service; - HookedServiceEvent(this._isAfter, this._request, this._response, - Service this.service, String this._eventName, - {id, this.data, Map params, this.result}) { + HookedServiceEvent(this._isAfter, this._request, this._response, this.service, + String this._eventName, + {Id id, this.data, Map params, this.result}) { _id = id; _params = params ?? {}; } } /// Triggered on a hooked service event. -typedef HookedServiceEventListener(HookedServiceEvent event); +typedef FutureOr HookedServiceEventListener>(HookedServiceEvent event); /// Can be listened to, but events may be canceled. -class HookedServiceEventDispatcher { - final List> _ctrl = []; - final List listeners = []; +class HookedServiceEventDispatcher> { + final List>> _ctrl = []; + final List> listeners = []; void _close() { _ctrl.forEach((c) => c.close()); @@ -537,11 +545,12 @@ class HookedServiceEventDispatcher { } /// Fires an event, and returns it once it is either canceled, or all listeners have run. - Future _emit(HookedServiceEvent event) { + Future> _emit( + HookedServiceEvent event) { if (event?._canceled == true || event == null || listeners.isEmpty) return new Future.value(event); - var f = new Future.value(event); + var f = new Future>.value(event); for (var listener in listeners) { f = f.then((event) { @@ -557,16 +566,16 @@ class HookedServiceEventDispatcher { /// /// *NOTE*: Callbacks on the returned [Stream] cannot be guaranteed to run before other [listeners]. /// Use this only if you need a read-only stream of events. - Stream asStream() { + Stream> asStream() { // TODO: Close StreamController - var ctrl = new StreamController(); + var ctrl = new StreamController>(); _ctrl.add(ctrl); listen(ctrl.add); return ctrl.stream; } /// Registers the listener to be called whenever an event is triggered. - void listen(HookedServiceEventListener listener) { + void listen(HookedServiceEventListener listener) { listeners.add(listener); } } diff --git a/lib/src/core/typed_service.dart b/lib/src/core/typed_service.dart deleted file mode 100644 index 8b137891..00000000 --- a/lib/src/core/typed_service.dart +++ /dev/null @@ -1 +0,0 @@ -