Skip to content

Commit d5a0a80

Browse files
committed
feat(dispatch): propagateError option
allow for dispatch cycle to fail and thus not to issue next state if a middleware throws. This feature is opt-in. #7
1 parent 5578200 commit d5a0a80

File tree

14 files changed

+266
-41
lines changed

14 files changed

+266
-41
lines changed

dist/amd/store.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ import { Observable } from "rxjs/Observable";
22
import { Middleware, MiddlewarePlacement } from "./middleware";
33
import { HistoryOptions } from "./aurelia-store";
44
export declare type Reducer<T> = (state: T, ...params: any[]) => T | Promise<T>;
5+
export declare enum PerformanceMeasurement {
6+
StartEnd = "startEnd",
7+
All = "all",
8+
}
59
export interface StoreOptions {
610
history: Partial<HistoryOptions>;
711
logDispatchedActions?: boolean;
12+
measurePerformance?: PerformanceMeasurement;
13+
propagateError?: boolean;
814
}
915
export declare class Store<T> {
1016
private initialState;

dist/amd/store.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
4242
define(["require", "exports", "rxjs/BehaviorSubject", "aurelia-framework", "./history", "./middleware", "./aurelia-store"], function (require, exports, BehaviorSubject_1, aurelia_framework_1, history_1, middleware_1, aurelia_store_1) {
4343
"use strict";
4444
Object.defineProperty(exports, "__esModule", { value: true });
45+
var PerformanceMeasurement;
46+
(function (PerformanceMeasurement) {
47+
PerformanceMeasurement["StartEnd"] = "startEnd";
48+
PerformanceMeasurement["All"] = "all";
49+
})(PerformanceMeasurement = exports.PerformanceMeasurement || (exports.PerformanceMeasurement = {}));
4550
var Store = /** @class */ (function () {
4651
function Store(initialState, options) {
4752
this.initialState = initialState;
@@ -130,6 +135,7 @@ define(["require", "exports", "rxjs/BehaviorSubject", "aurelia-framework", "./hi
130135
if (!this.actions.has(reducer)) {
131136
throw new Error("Tried to dispatch an unregistered action " + reducer.name);
132137
}
138+
performance.mark("dispatch-start");
133139
if (this.options && this.options.logDispatchedActions) {
134140
this.logger.info("Dispatching: " + reducer.name);
135141
}
@@ -138,11 +144,12 @@ define(["require", "exports", "rxjs/BehaviorSubject", "aurelia-framework", "./hi
138144
case 1:
139145
beforeMiddleswaresResult = _c.sent();
140146
result = (_b = action).reducer.apply(_b, [beforeMiddleswaresResult].concat(params));
147+
performance.mark("dispatch-after-reducer-" + reducer.name);
141148
if (!result && typeof result !== "object") {
142149
throw new Error("The reducer has to return a new state");
143150
}
144151
apply = function (newState) { return __awaiter(_this, void 0, void 0, function () {
145-
var resultingState;
152+
var resultingState, measures, marks, totalDuration;
146153
return __generator(this, function (_a) {
147154
switch (_a.label) {
148155
case 0: return [4 /*yield*/, this.executeMiddlewares(newState, middleware_1.MiddlewarePlacement.After)];
@@ -155,6 +162,21 @@ define(["require", "exports", "rxjs/BehaviorSubject", "aurelia-framework", "./hi
155162
resultingState = history_1.applyLimits(resultingState, this.options.history.limit);
156163
}
157164
this._state.next(resultingState);
165+
performance.mark("dispatch-end");
166+
if (this.options) {
167+
if (this.options.measurePerformance === PerformanceMeasurement.StartEnd) {
168+
performance.measure("startEndDispatchDuration", "dispatch-start", "dispatch-end");
169+
measures = performance.getEntriesByName("startEndDispatchDuration");
170+
this.logger.info("Total duration " + measures[0].duration + " of dispatched action " + reducer.name + ":", measures);
171+
}
172+
else if (this.options.measurePerformance === PerformanceMeasurement.All) {
173+
marks = performance.getEntriesByType("mark");
174+
totalDuration = marks[marks.length - 1].startTime - marks[0].startTime;
175+
this.logger.info("Total duration " + totalDuration + " of dispatched action " + reducer.name + ":", marks);
176+
}
177+
}
178+
performance.clearMarks();
179+
performance.clearMeasures();
158180
this.updateDevToolsState(action.name, newState);
159181
return [2 /*return*/];
160182
}
@@ -181,12 +203,12 @@ define(["require", "exports", "rxjs/BehaviorSubject", "aurelia-framework", "./hi
181203
return Array.from(this.middlewares.values())
182204
.filter(function (middleware) { return middleware.placement === placement; })
183205
.map(function (middleware) { return middleware.reducer; })
184-
.reduce(function (prev, curr) { return __awaiter(_this, void 0, void 0, function () {
206+
.reduce(function (prev, curr, _, _arr) { return __awaiter(_this, void 0, void 0, function () {
185207
var result, _a, _b, e_2;
186208
return __generator(this, function (_c) {
187209
switch (_c.label) {
188210
case 0:
189-
_c.trys.push([0, 5, , 7]);
211+
_c.trys.push([0, 5, 7, 8]);
190212
_a = curr;
191213
return [4 /*yield*/, prev];
192214
case 1: return [4 /*yield*/, _a.apply(void 0, [_c.sent(), (placement === middleware_1.MiddlewarePlacement.After) ? this._state.getValue() : undefined])];
@@ -201,9 +223,16 @@ define(["require", "exports", "rxjs/BehaviorSubject", "aurelia-framework", "./hi
201223
case 4: return [2 /*return*/, _b];
202224
case 5:
203225
e_2 = _c.sent();
226+
if (this.options && this.options.propagateError) {
227+
_arr = [];
228+
throw e_2;
229+
}
204230
return [4 /*yield*/, prev];
205231
case 6: return [2 /*return*/, _c.sent()];
206-
case 7: return [2 /*return*/];
232+
case 7:
233+
performance.mark("dispatch-" + placement + "-" + curr.name);
234+
return [7 /*endfinally*/];
235+
case 8: return [2 /*return*/];
207236
}
208237
});
209238
}); }, state);

dist/commonjs/store.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ import { Observable } from "rxjs/Observable";
22
import { Middleware, MiddlewarePlacement } from "./middleware";
33
import { HistoryOptions } from "./aurelia-store";
44
export declare type Reducer<T> = (state: T, ...params: any[]) => T | Promise<T>;
5+
export declare enum PerformanceMeasurement {
6+
StartEnd = "startEnd",
7+
All = "all",
8+
}
59
export interface StoreOptions {
610
history: Partial<HistoryOptions>;
711
logDispatchedActions?: boolean;
12+
measurePerformance?: PerformanceMeasurement;
13+
propagateError?: boolean;
814
}
915
export declare class Store<T> {
1016
private initialState;

dist/commonjs/store.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ var aurelia_framework_1 = require("aurelia-framework");
4646
var history_1 = require("./history");
4747
var middleware_1 = require("./middleware");
4848
var aurelia_store_1 = require("./aurelia-store");
49+
var PerformanceMeasurement;
50+
(function (PerformanceMeasurement) {
51+
PerformanceMeasurement["StartEnd"] = "startEnd";
52+
PerformanceMeasurement["All"] = "all";
53+
})(PerformanceMeasurement = exports.PerformanceMeasurement || (exports.PerformanceMeasurement = {}));
4954
var Store = /** @class */ (function () {
5055
function Store(initialState, options) {
5156
this.initialState = initialState;
@@ -134,6 +139,7 @@ var Store = /** @class */ (function () {
134139
if (!this.actions.has(reducer)) {
135140
throw new Error("Tried to dispatch an unregistered action " + reducer.name);
136141
}
142+
performance.mark("dispatch-start");
137143
if (this.options && this.options.logDispatchedActions) {
138144
this.logger.info("Dispatching: " + reducer.name);
139145
}
@@ -142,11 +148,12 @@ var Store = /** @class */ (function () {
142148
case 1:
143149
beforeMiddleswaresResult = _c.sent();
144150
result = (_b = action).reducer.apply(_b, [beforeMiddleswaresResult].concat(params));
151+
performance.mark("dispatch-after-reducer-" + reducer.name);
145152
if (!result && typeof result !== "object") {
146153
throw new Error("The reducer has to return a new state");
147154
}
148155
apply = function (newState) { return __awaiter(_this, void 0, void 0, function () {
149-
var resultingState;
156+
var resultingState, measures, marks, totalDuration;
150157
return __generator(this, function (_a) {
151158
switch (_a.label) {
152159
case 0: return [4 /*yield*/, this.executeMiddlewares(newState, middleware_1.MiddlewarePlacement.After)];
@@ -159,6 +166,21 @@ var Store = /** @class */ (function () {
159166
resultingState = history_1.applyLimits(resultingState, this.options.history.limit);
160167
}
161168
this._state.next(resultingState);
169+
performance.mark("dispatch-end");
170+
if (this.options) {
171+
if (this.options.measurePerformance === PerformanceMeasurement.StartEnd) {
172+
performance.measure("startEndDispatchDuration", "dispatch-start", "dispatch-end");
173+
measures = performance.getEntriesByName("startEndDispatchDuration");
174+
this.logger.info("Total duration " + measures[0].duration + " of dispatched action " + reducer.name + ":", measures);
175+
}
176+
else if (this.options.measurePerformance === PerformanceMeasurement.All) {
177+
marks = performance.getEntriesByType("mark");
178+
totalDuration = marks[marks.length - 1].startTime - marks[0].startTime;
179+
this.logger.info("Total duration " + totalDuration + " of dispatched action " + reducer.name + ":", marks);
180+
}
181+
}
182+
performance.clearMarks();
183+
performance.clearMeasures();
162184
this.updateDevToolsState(action.name, newState);
163185
return [2 /*return*/];
164186
}
@@ -185,12 +207,12 @@ var Store = /** @class */ (function () {
185207
return Array.from(this.middlewares.values())
186208
.filter(function (middleware) { return middleware.placement === placement; })
187209
.map(function (middleware) { return middleware.reducer; })
188-
.reduce(function (prev, curr) { return __awaiter(_this, void 0, void 0, function () {
210+
.reduce(function (prev, curr, _, _arr) { return __awaiter(_this, void 0, void 0, function () {
189211
var result, _a, _b, e_2;
190212
return __generator(this, function (_c) {
191213
switch (_c.label) {
192214
case 0:
193-
_c.trys.push([0, 5, , 7]);
215+
_c.trys.push([0, 5, 7, 8]);
194216
_a = curr;
195217
return [4 /*yield*/, prev];
196218
case 1: return [4 /*yield*/, _a.apply(void 0, [_c.sent(), (placement === middleware_1.MiddlewarePlacement.After) ? this._state.getValue() : undefined])];
@@ -205,9 +227,16 @@ var Store = /** @class */ (function () {
205227
case 4: return [2 /*return*/, _b];
206228
case 5:
207229
e_2 = _c.sent();
230+
if (this.options && this.options.propagateError) {
231+
_arr = [];
232+
throw e_2;
233+
}
208234
return [4 /*yield*/, prev];
209235
case 6: return [2 /*return*/, _c.sent()];
210-
case 7: return [2 /*return*/];
236+
case 7:
237+
performance.mark("dispatch-" + placement + "-" + curr.name);
238+
return [7 /*endfinally*/];
239+
case 8: return [2 /*return*/];
211240
}
212241
});
213242
}); }, state);

dist/es2015/store.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ import { Observable } from "rxjs/Observable";
22
import { Middleware, MiddlewarePlacement } from "./middleware";
33
import { HistoryOptions } from "./aurelia-store";
44
export declare type Reducer<T> = (state: T, ...params: any[]) => T | Promise<T>;
5+
export declare enum PerformanceMeasurement {
6+
StartEnd = "startEnd",
7+
All = "all",
8+
}
59
export interface StoreOptions {
610
history: Partial<HistoryOptions>;
711
logDispatchedActions?: boolean;
12+
measurePerformance?: PerformanceMeasurement;
13+
propagateError?: boolean;
814
}
915
export declare class Store<T> {
1016
private initialState;

dist/es2015/store.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ import { autoinject, Container, LogManager } from "aurelia-framework";
4444
import { jump, applyLimits } from "./history";
4545
import { MiddlewarePlacement } from "./middleware";
4646
import { isStateHistory } from "./aurelia-store";
47+
export var PerformanceMeasurement;
48+
(function (PerformanceMeasurement) {
49+
PerformanceMeasurement["StartEnd"] = "startEnd";
50+
PerformanceMeasurement["All"] = "all";
51+
})(PerformanceMeasurement || (PerformanceMeasurement = {}));
4752
var Store = /** @class */ (function () {
4853
function Store(initialState, options) {
4954
this.initialState = initialState;
@@ -132,6 +137,7 @@ var Store = /** @class */ (function () {
132137
if (!this.actions.has(reducer)) {
133138
throw new Error("Tried to dispatch an unregistered action " + reducer.name);
134139
}
140+
performance.mark("dispatch-start");
135141
if (this.options && this.options.logDispatchedActions) {
136142
this.logger.info("Dispatching: " + reducer.name);
137143
}
@@ -140,11 +146,12 @@ var Store = /** @class */ (function () {
140146
case 1:
141147
beforeMiddleswaresResult = _c.sent();
142148
result = (_b = action).reducer.apply(_b, [beforeMiddleswaresResult].concat(params));
149+
performance.mark("dispatch-after-reducer-" + reducer.name);
143150
if (!result && typeof result !== "object") {
144151
throw new Error("The reducer has to return a new state");
145152
}
146153
apply = function (newState) { return __awaiter(_this, void 0, void 0, function () {
147-
var resultingState;
154+
var resultingState, measures, marks, totalDuration;
148155
return __generator(this, function (_a) {
149156
switch (_a.label) {
150157
case 0: return [4 /*yield*/, this.executeMiddlewares(newState, MiddlewarePlacement.After)];
@@ -157,6 +164,21 @@ var Store = /** @class */ (function () {
157164
resultingState = applyLimits(resultingState, this.options.history.limit);
158165
}
159166
this._state.next(resultingState);
167+
performance.mark("dispatch-end");
168+
if (this.options) {
169+
if (this.options.measurePerformance === PerformanceMeasurement.StartEnd) {
170+
performance.measure("startEndDispatchDuration", "dispatch-start", "dispatch-end");
171+
measures = performance.getEntriesByName("startEndDispatchDuration");
172+
this.logger.info("Total duration " + measures[0].duration + " of dispatched action " + reducer.name + ":", measures);
173+
}
174+
else if (this.options.measurePerformance === PerformanceMeasurement.All) {
175+
marks = performance.getEntriesByType("mark");
176+
totalDuration = marks[marks.length - 1].startTime - marks[0].startTime;
177+
this.logger.info("Total duration " + totalDuration + " of dispatched action " + reducer.name + ":", marks);
178+
}
179+
}
180+
performance.clearMarks();
181+
performance.clearMeasures();
160182
this.updateDevToolsState(action.name, newState);
161183
return [2 /*return*/];
162184
}
@@ -183,12 +205,12 @@ var Store = /** @class */ (function () {
183205
return Array.from(this.middlewares.values())
184206
.filter(function (middleware) { return middleware.placement === placement; })
185207
.map(function (middleware) { return middleware.reducer; })
186-
.reduce(function (prev, curr) { return __awaiter(_this, void 0, void 0, function () {
208+
.reduce(function (prev, curr, _, _arr) { return __awaiter(_this, void 0, void 0, function () {
187209
var result, _a, _b, e_2;
188210
return __generator(this, function (_c) {
189211
switch (_c.label) {
190212
case 0:
191-
_c.trys.push([0, 5, , 7]);
213+
_c.trys.push([0, 5, 7, 8]);
192214
_a = curr;
193215
return [4 /*yield*/, prev];
194216
case 1: return [4 /*yield*/, _a.apply(void 0, [_c.sent(), (placement === MiddlewarePlacement.After) ? this._state.getValue() : undefined])];
@@ -203,9 +225,16 @@ var Store = /** @class */ (function () {
203225
case 4: return [2 /*return*/, _b];
204226
case 5:
205227
e_2 = _c.sent();
228+
if (this.options && this.options.propagateError) {
229+
_arr = [];
230+
throw e_2;
231+
}
206232
return [4 /*yield*/, prev];
207233
case 6: return [2 /*return*/, _c.sent()];
208-
case 7: return [2 /*return*/];
234+
case 7:
235+
performance.mark("dispatch-" + placement + "-" + curr.name);
236+
return [7 /*endfinally*/];
237+
case 8: return [2 /*return*/];
209238
}
210239
});
211240
}); }, state);

0 commit comments

Comments
 (0)