@thi.ng/interceptors 3.2.27 → 3.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/api.js +30 -26
- package/event-bus.js +615 -678
- package/interceptors.js +45 -216
- package/package.json +12 -10
package/interceptors.js
CHANGED
|
@@ -1,226 +1,55 @@
|
|
|
1
1
|
import { getInUnsafe } from "@thi.ng/paths/get-in";
|
|
2
2
|
import { defSetterUnsafe } from "@thi.ng/paths/setter";
|
|
3
3
|
import { defUpdaterUnsafe } from "@thi.ng/paths/updater";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* @param fxID - side effect ID
|
|
15
|
-
*/
|
|
16
|
-
export const forwardSideFx = (fxID) => (_, [__, body]) => ({ [fxID]: body !== undefined ? body : true });
|
|
17
|
-
/**
|
|
18
|
-
* Higher-order interceptor. Returns interceptor which assigns given
|
|
19
|
-
* event to `FX_DISPATCH` side effect.
|
|
20
|
-
*
|
|
21
|
-
* @param event -
|
|
22
|
-
*/
|
|
23
|
-
export const dispatch = (event) => () => ({
|
|
24
|
-
[FX_DISPATCH]: event,
|
|
4
|
+
import {
|
|
5
|
+
FX_CANCEL,
|
|
6
|
+
FX_DISPATCH,
|
|
7
|
+
FX_DISPATCH_NOW,
|
|
8
|
+
FX_STATE
|
|
9
|
+
} from "./api.js";
|
|
10
|
+
const trace = (_, e) => console.log("event:", e);
|
|
11
|
+
const forwardSideFx = (fxID) => (_, [__, body]) => ({ [fxID]: body !== void 0 ? body : true });
|
|
12
|
+
const dispatch = (event) => () => ({
|
|
13
|
+
[FX_DISPATCH]: event
|
|
25
14
|
});
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* event to `FX_DISPATCH_NOW` side effect.
|
|
29
|
-
*
|
|
30
|
-
* @param event -
|
|
31
|
-
*/
|
|
32
|
-
export const dispatchNow = (event) => () => ({
|
|
33
|
-
[FX_DISPATCH_NOW]: event,
|
|
15
|
+
const dispatchNow = (event) => () => ({
|
|
16
|
+
[FX_DISPATCH_NOW]: event
|
|
34
17
|
});
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* passed to {@link EventBus.processQueue}. The default ID for the history
|
|
41
|
-
* instance is `"history"`.
|
|
42
|
-
*
|
|
43
|
-
* Example usage:
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```ts
|
|
47
|
-
* state = new Atom({});
|
|
48
|
-
* history = new History(state);
|
|
49
|
-
* bus = new EventBus(state);
|
|
50
|
-
* // register event handler
|
|
51
|
-
* // each time the `foo` event is triggered, a snapshot of
|
|
52
|
-
* // current app state is recorded first
|
|
53
|
-
* bus.addHandlers({
|
|
54
|
-
* foo: [snapshot(), valueSetter("foo")]
|
|
55
|
-
* });
|
|
56
|
-
* ...
|
|
57
|
-
* // trigger event
|
|
58
|
-
* bus.dispatch(["foo", 23]);
|
|
59
|
-
*
|
|
60
|
-
* // pass history instance via interceptor context to handlers
|
|
61
|
-
* bus.processQueue({ history });
|
|
62
|
-
* ```
|
|
63
|
-
*
|
|
64
|
-
* @param id -
|
|
65
|
-
*/
|
|
66
|
-
export const snapshot = (id = "history") => (_, __, ___, ctx) => ctx[id].record();
|
|
67
|
-
/**
|
|
68
|
-
* Higher-order interceptor for validation purposes. Takes a predicate
|
|
69
|
-
* function and an optional interceptor function, which will only be
|
|
70
|
-
* called if the predicate fails for a given event. By default the
|
|
71
|
-
* `FX_CANCEL` side effect is triggered if the predicate failed, thus
|
|
72
|
-
* ensuring the actual event handler for the failed event will not be
|
|
73
|
-
* executed anymore. However, this can be overridden using the error
|
|
74
|
-
* interceptor's result, which is merged into the result of this
|
|
75
|
-
* interceptor.
|
|
76
|
-
*
|
|
77
|
-
* The error interceptor can return any number of other side effects and
|
|
78
|
-
* so be used to dispatch alternative events instead, for example:
|
|
79
|
-
*
|
|
80
|
-
* ```
|
|
81
|
-
* // this interceptor will cause cancellation of current event
|
|
82
|
-
* // and trigger an "error" event instead
|
|
83
|
-
* ensurePred(
|
|
84
|
-
* // a dummy predicate which always fails
|
|
85
|
-
* () => false
|
|
86
|
-
* // error interceptor fn
|
|
87
|
-
* () => ({[FX_DISPATCH_NOW]: ["error", "reason"]})
|
|
88
|
-
* )
|
|
89
|
-
* ```
|
|
90
|
-
*
|
|
91
|
-
* Note: For this interceptor to work as expected, it needs to be
|
|
92
|
-
* provided BEFORE the main handler in the interceptor list for a given
|
|
93
|
-
* event, i.e.
|
|
94
|
-
*
|
|
95
|
-
* ```
|
|
96
|
-
* [
|
|
97
|
-
* ensurePred((state, e) => false),
|
|
98
|
-
* // actual event handler
|
|
99
|
-
* (state, e) => console.log("no one never calls me")
|
|
100
|
-
* ]
|
|
101
|
-
* ```
|
|
102
|
-
*
|
|
103
|
-
* @param pred - predicate applied to given state & event
|
|
104
|
-
* @param err - interceptor triggered on predicate failure
|
|
105
|
-
*/
|
|
106
|
-
export const ensurePred = (pred, err) => (state, e, bus, ctx) => !pred(state, e, bus, ctx)
|
|
107
|
-
? {
|
|
108
|
-
[FX_CANCEL]: true,
|
|
109
|
-
...(err ? err(state, e, bus, ctx) : null),
|
|
110
|
-
}
|
|
111
|
-
: undefined;
|
|
18
|
+
const snapshot = (id = "history") => (_, __, ___, ctx) => ctx[id].record();
|
|
19
|
+
const ensurePred = (pred, err) => (state, e, bus, ctx) => !pred(state, e, bus, ctx) ? {
|
|
20
|
+
[FX_CANCEL]: true,
|
|
21
|
+
...err ? err(state, e, bus, ctx) : null
|
|
22
|
+
} : void 0;
|
|
112
23
|
const eventPathState = (state, path, e) => getInUnsafe(state, path ? path(e) : e[1]);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
* as the value path.
|
|
119
|
-
*
|
|
120
|
-
* For example, without a provided `path` function and for an event of
|
|
121
|
-
* this form: `["event-id", "foo.bar"]`, the term `"foo.bar"` would be
|
|
122
|
-
* interpreted as path.
|
|
123
|
-
*
|
|
124
|
-
* If the event has this shape: `["event-id", ["foo.bar", 23]]`, we must
|
|
125
|
-
* provide `(e) => e[1][0]` as path function to extract `"foo.bar"` from
|
|
126
|
-
* the event.
|
|
127
|
-
*
|
|
128
|
-
* @param max -
|
|
129
|
-
* @param path - path extractor
|
|
130
|
-
* @param err - error interceptor
|
|
131
|
-
*/
|
|
132
|
-
export const ensureStateLessThan = (max, path, err) => ensurePred((state, e) => eventPathState(state, path, e) < max, err);
|
|
133
|
-
/**
|
|
134
|
-
* Specialization of {@link ensurePred} to ensure a state value is greater
|
|
135
|
-
* than given min. See {@link ensureStateLessThan} for further details.
|
|
136
|
-
*
|
|
137
|
-
* @param min -
|
|
138
|
-
* @param path - path extractor
|
|
139
|
-
* @param err - error interceptor
|
|
140
|
-
*/
|
|
141
|
-
export const ensureStateGreaterThan = (min, path, err) => ensurePred((state, e) => eventPathState(state, path, e) > min, err);
|
|
142
|
-
/**
|
|
143
|
-
* Specialization of {@link ensurePred} to ensure a state value is within
|
|
144
|
-
* given `min` / `max` closed interval. See {@link ensureStateLessThan} for
|
|
145
|
-
* further details.
|
|
146
|
-
*
|
|
147
|
-
* @param min -
|
|
148
|
-
* @param max -
|
|
149
|
-
* @param path - path extractor
|
|
150
|
-
* @param err - error interceptor
|
|
151
|
-
*/
|
|
152
|
-
export const ensureStateRange = (min, max, path, err) => ensurePred((state, e) => {
|
|
153
|
-
const x = eventPathState(state, path, e);
|
|
154
|
-
return x >= min && x <= max;
|
|
24
|
+
const ensureStateLessThan = (max, path, err) => ensurePred((state, e) => eventPathState(state, path, e) < max, err);
|
|
25
|
+
const ensureStateGreaterThan = (min, path, err) => ensurePred((state, e) => eventPathState(state, path, e) > min, err);
|
|
26
|
+
const ensureStateRange = (min, max, path, err) => ensurePred((state, e) => {
|
|
27
|
+
const x = eventPathState(state, path, e);
|
|
28
|
+
return x >= min && x <= max;
|
|
155
29
|
}, err);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
* event format like: `[event-id, value]`. However if `value` is given,
|
|
160
|
-
* the provided function can be used to extract the value to be
|
|
161
|
-
* validated from any event. If the value is outside the given interval,
|
|
162
|
-
* triggers `FX_CANCEL` side effect and if `err` is given, the error
|
|
163
|
-
* interceptor can return any number of other side effects and so be
|
|
164
|
-
* used to dispatch alternative events instead.
|
|
165
|
-
*
|
|
166
|
-
* @param min -
|
|
167
|
-
* @param max -
|
|
168
|
-
* @param value - event value extractor
|
|
169
|
-
* @param err - error interceptor
|
|
170
|
-
*/
|
|
171
|
-
export const ensureParamRange = (min, max, value, err) => ensurePred((_, e) => {
|
|
172
|
-
const x = value ? value(e) : e[1];
|
|
173
|
-
return x >= min && x <= max;
|
|
30
|
+
const ensureParamRange = (min, max, value, err) => ensurePred((_, e) => {
|
|
31
|
+
const x = value ? value(e) : e[1];
|
|
32
|
+
return x >= min && x <= max;
|
|
174
33
|
}, err);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
* values more concisely, e.g. given this event definition:
|
|
179
|
-
*
|
|
180
|
-
* @example
|
|
181
|
-
* ```ts
|
|
182
|
-
* setFoo: valueSetter("foo.bar")
|
|
183
|
-
* ```
|
|
184
|
-
*
|
|
185
|
-
* ...the `setFoo` event then can be triggered like so to update the
|
|
186
|
-
* state value at `foo.bar`:
|
|
187
|
-
*
|
|
188
|
-
* @example
|
|
189
|
-
* ```ts
|
|
190
|
-
* bus.dispatch(["setFoo", 23])
|
|
191
|
-
* ```
|
|
192
|
-
*
|
|
193
|
-
* @param path -
|
|
194
|
-
* @param tx -
|
|
195
|
-
*/
|
|
196
|
-
export const valueSetter = (path, tx) => {
|
|
197
|
-
const $ = defSetterUnsafe(path);
|
|
198
|
-
return (state, [_, val]) => ({ [FX_STATE]: $(state, tx ? tx(val) : val) });
|
|
34
|
+
const valueSetter = (path, tx) => {
|
|
35
|
+
const $ = defSetterUnsafe(path);
|
|
36
|
+
return (state, [_, val]) => ({ [FX_STATE]: $(state, tx ? tx(val) : val) });
|
|
199
37
|
};
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
* bus.dispatch(["incFoo", 1]) // results in value = value + 1
|
|
218
|
-
* ```
|
|
219
|
-
*
|
|
220
|
-
* @param path -
|
|
221
|
-
* @param fn -
|
|
222
|
-
*/
|
|
223
|
-
export const valueUpdater = (path, fn) => {
|
|
224
|
-
const $ = defUpdaterUnsafe(path, fn);
|
|
225
|
-
return (state, [_, ...args]) => ({ [FX_STATE]: $(state, ...args) });
|
|
38
|
+
const valueUpdater = (path, fn) => {
|
|
39
|
+
const $ = defUpdaterUnsafe(path, fn);
|
|
40
|
+
return (state, [_, ...args]) => ({ [FX_STATE]: $(state, ...args) });
|
|
41
|
+
};
|
|
42
|
+
export {
|
|
43
|
+
dispatch,
|
|
44
|
+
dispatchNow,
|
|
45
|
+
ensureParamRange,
|
|
46
|
+
ensurePred,
|
|
47
|
+
ensureStateGreaterThan,
|
|
48
|
+
ensureStateLessThan,
|
|
49
|
+
ensureStateRange,
|
|
50
|
+
forwardSideFx,
|
|
51
|
+
snapshot,
|
|
52
|
+
trace,
|
|
53
|
+
valueSetter,
|
|
54
|
+
valueUpdater
|
|
226
55
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/interceptors",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.29",
|
|
4
4
|
"description": "Interceptor based event bus, side effect & immutable state handling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
],
|
|
28
28
|
"license": "Apache-2.0",
|
|
29
29
|
"scripts": {
|
|
30
|
-
"build": "yarn
|
|
30
|
+
"build": "yarn build:esbuild && yarn build:decl",
|
|
31
|
+
"build:decl": "tsc --declaration --emitDeclarationOnly",
|
|
32
|
+
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
|
|
31
33
|
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
|
|
32
34
|
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
|
|
33
35
|
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
|
|
@@ -36,16 +38,16 @@
|
|
|
36
38
|
"test": "bun test"
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
|
-
"@thi.ng/api": "^8.9.
|
|
40
|
-
"@thi.ng/atom": "^5.2.
|
|
41
|
-
"@thi.ng/checks": "^3.4.
|
|
42
|
-
"@thi.ng/errors": "^2.4.
|
|
43
|
-
"@thi.ng/logger": "^2.0.
|
|
44
|
-
"@thi.ng/paths": "^5.1.
|
|
41
|
+
"@thi.ng/api": "^8.9.12",
|
|
42
|
+
"@thi.ng/atom": "^5.2.18",
|
|
43
|
+
"@thi.ng/checks": "^3.4.12",
|
|
44
|
+
"@thi.ng/errors": "^2.4.6",
|
|
45
|
+
"@thi.ng/logger": "^2.0.2",
|
|
46
|
+
"@thi.ng/paths": "^5.1.53"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
47
49
|
"@microsoft/api-extractor": "^7.38.3",
|
|
48
|
-
"
|
|
50
|
+
"esbuild": "^0.19.8",
|
|
49
51
|
"rimraf": "^5.0.5",
|
|
50
52
|
"tools": "^0.0.1",
|
|
51
53
|
"typedoc": "^0.25.4",
|
|
@@ -93,5 +95,5 @@
|
|
|
93
95
|
"status": "completed",
|
|
94
96
|
"year": 2016
|
|
95
97
|
},
|
|
96
|
-
"gitHead": "
|
|
98
|
+
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
|
|
97
99
|
}
|