generated from fluture-js/fluture-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
178 lines (161 loc) · 5.1 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//. # Fluture Observe
//.
//. Consume a [Fluture][] Future, observing changes to its state as the
//. consumption is happening.
//.
//. ## Usage
//.
//. ### Node
//.
//. ```console
//. $ npm install --save fluture-observe
//. ```
//.
//. On Node 12 and up, this module can be loaded directly with `import` or
//. `require`. On Node versions below 12, `require` or the [esm][]-loader can
//. be used.
//.
//. ### Deno and Modern Browsers
//.
//. You can load the EcmaScript module from various content delivery networks:
//.
//. - [Skypack](https://cdn.skypack.dev/[email protected])
//. - [JSPM](https://jspm.dev/[email protected])
//. - [jsDelivr](https://cdn.jsdelivr.net/npm/[email protected]/+esm)
//.
//. ### Old Browsers and Code Pens
//.
//. There's a [UMD][] file included in the NPM package, also available via
//. jsDelivr: https://cdn.jsdelivr.net/npm/[email protected]/dist/umd.js
//.
//. This file adds `flutureObserve` to the global scope, or use CommonJS/AMD
//. when available.
//.
//. ### Usage Example
//.
//. ```js
//. import {observe, cata} from 'fluture-observe/index.js';
//.
//. const consume = observe (cata ({
//. Idle: () => {
//. console.log ('Computation is idle.');
//. },
//. Pending: cancel => {
//. console.log ('Computation is pending. Send SIGINT to cancel it');
//. process.once ('SIGINT', cancel);
//. },
//. Canceled: future => {
//. console.log ('Computation was canceled. Send SIGINT to restart it');
//. process.once ('SIGINT', () => consume (future));
//. },
//. Crashed: error => {
//. console.error ('I am sorry to inform you:', error);
//. process.exit (1);
//. },
//. Rejected: reason => {
//. console.log ('The computation rejected with reason', reason);
//. },
//. Resolved: value => {
//. console.log ('The computation resolved with value', value);
//. }
//. }));
//. ```
//.
//. ## API
import daggy from 'daggy';
import {forkCatch, isFuture} from 'fluture/index.js';
//# Computation :: Type
//.
//. A [Daggy][] tagged union type representing the state of the consumption of
//. a Future. The `Cancel` and `Future` types below are imported
//. [types from Fluture][].
//.
//. ```hs
//. data Computation a b = Idle
//. | Pending Cancel
//. | Cancelled (Future a b)
//. | Crashed Error
//. | Rejected a
//. | Resolved b
//. ```
//.
//. Constructor details are documented below.
export var Computation = daggy.taggedSum ('Computation', {
Idle: [],
Pending: ['cancel'],
Canceled: ['future'],
Crashed: ['exception'],
Rejected: ['reason'],
Resolved: ['value']
});
//# Idle :: Computation a b
//.
//. Represents a not running computation.
export const Idle = Computation.Idle;
//# Pending :: Cancel -> Computation a b
//.
//. Represents a running computation which can be cancelled.
export const Pending = Computation.Pending;
//# Canceled :: Future a b -> Computation a b
//.
//. Represents a computation that was cancelled and can be restarted.
export const Canceled = Computation.Canceled;
//# Crashed :: Error -> Computation a b
//.
//. Represents a computation which encountered an exception while running.
export const Crashed = Computation.Crashed;
//# Rejected :: a -> Computation a b
//.
//. Represents a computation which rejected with a reason.
export const Rejected = Computation.Rejected;
//# Resolved :: b -> Computation a b
//.
//. Represents a computation which resolved with a value.
export const Resolved = Computation.Resolved;
//# cata :: { Idle :: () -> c, Pending :: Cancel -> c, Canceled :: Future a b -> c, Crashed :: Error -> c, Rejected :: a -> c, Resolved :: b -> c } -> Computation a b -> c
//.
//. [Daggy][]'s catamorphism as a curried function.
export function cata(cases) {
return function(t) {
return t.cata (cases);
};
}
//# observe :: (Computation a b -> Any) -> Future a b -> Undefined
//.
//. Consume a Future, observing changes to its state. See [usage](#usage).
export function observe(f) {
if (typeof f !== 'function') {
throw new TypeError (
'observe() expects its first argument to be a Function.'
);
}
return function observe(m) {
if (!isFuture (m)) {
throw new TypeError (
'observe() expects its second argument to be a valid Future.'
);
}
var settled = false;
f (Computation.Idle);
var unsubscribe = m.pipe (forkCatch (function observe$recover(exception) {
settled = true;
f (Computation.Crashed (exception));
}) (function observe$reason(reason) {
settled = true;
f (Computation.Rejected (reason));
}) (function observe$value(value) {
settled = true;
f (Computation.Resolved (value));
}));
if (settled) return;
f (Computation.Pending (function observe$cancel() {
unsubscribe ();
f (Computation.Canceled (m));
}));
};
}
//. [Fluture]: https://github.com/fluture-js/Fluture
//. [Daggy]: https://github.com/fantasyland/daggy
//. [types from Fluture]: https://github.com/fluture-js/Fluture#types
//. [esm]: https://github.com/standard-things/esm
//. [UMD]: https://github.com/umdjs/umd