ctrl-fx 0.1.0 → 0.1.2

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.
Files changed (152) hide show
  1. package/README.md +13 -0
  2. package/dist/chunk-BDTTV33M.js +4050 -0
  3. package/dist/chunk-EKBLRHWK.js +916 -0
  4. package/dist/chunk-OSIRHKDB.js +1812 -0
  5. package/dist/chunk-PKBMQBKP.js +7 -0
  6. package/dist/chunk-XICUXW4T.js +252 -0
  7. package/dist/db/index.d.ts +218 -16
  8. package/dist/db/index.js +53 -19
  9. package/dist/dom/index.d.ts +2 -248
  10. package/dist/dom/index.js +30 -266
  11. package/dist/effects.d.ts +2 -580
  12. package/dist/effects.js +111 -1556
  13. package/dist/index-DeEjNrg-.d.ts +1399 -0
  14. package/dist/index.d.ts +2 -41
  15. package/dist/index.js +18 -78
  16. package/dist/router.d.ts +11 -12
  17. package/dist/router.js +57 -68
  18. package/dist/testing.d.ts +67 -60
  19. package/dist/testing.js +46 -158
  20. package/dist/webcomponent.d.ts +7 -4
  21. package/dist/webcomponent.js +48 -40
  22. package/package.json +4 -3
  23. package/dist/clipboard.d.ts +0 -7
  24. package/dist/clipboard.d.ts.map +0 -1
  25. package/dist/clipboard.js +0 -3
  26. package/dist/db/effects.d.ts +0 -78
  27. package/dist/db/effects.d.ts.map +0 -1
  28. package/dist/db/effects.js +0 -98
  29. package/dist/db/errors.d.ts +0 -21
  30. package/dist/db/errors.d.ts.map +0 -1
  31. package/dist/db/errors.js +0 -13
  32. package/dist/db/index.d.ts.map +0 -1
  33. package/dist/db/keypath.d.ts +0 -40
  34. package/dist/db/keypath.d.ts.map +0 -1
  35. package/dist/db/keypath.js +0 -20
  36. package/dist/db/setup.d.ts +0 -83
  37. package/dist/db/setup.d.ts.map +0 -1
  38. package/dist/db/setup.js +0 -100
  39. package/dist/db/testdb.d.ts +0 -19
  40. package/dist/db/testdb.d.ts.map +0 -1
  41. package/dist/db/testdb.js +0 -34
  42. package/dist/dom/attrs.d.ts +0 -67
  43. package/dist/dom/attrs.d.ts.map +0 -1
  44. package/dist/dom/attrs.js +0 -154
  45. package/dist/dom/components.d.ts +0 -43
  46. package/dist/dom/components.d.ts.map +0 -1
  47. package/dist/dom/components.js +0 -86
  48. package/dist/dom/elems.d.ts +0 -121
  49. package/dist/dom/elems.d.ts.map +0 -1
  50. package/dist/dom/elems.js +0 -52
  51. package/dist/dom/events.d.ts +0 -232
  52. package/dist/dom/events.d.ts.map +0 -1
  53. package/dist/dom/events.js +0 -289
  54. package/dist/dom/index.d.ts.map +0 -1
  55. package/dist/dom/nodeid.d.ts +0 -9
  56. package/dist/dom/nodeid.d.ts.map +0 -1
  57. package/dist/dom/nodeid.js +0 -27
  58. package/dist/dom/svg.d.ts +0 -23
  59. package/dist/dom/svg.d.ts.map +0 -1
  60. package/dist/dom/svg.js +0 -1
  61. package/dist/dom/views.d.ts +0 -60
  62. package/dist/dom/views.d.ts.map +0 -1
  63. package/dist/dom/views.js +0 -154
  64. package/dist/effects.d.ts.map +0 -1
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/internal/clipboard.d.ts +0 -5
  67. package/dist/internal/clipboard.d.ts.map +0 -1
  68. package/dist/internal/clipboard.js +0 -33
  69. package/dist/internal/cmpmgr.d.ts +0 -46
  70. package/dist/internal/cmpmgr.d.ts.map +0 -1
  71. package/dist/internal/cmpmgr.js +0 -561
  72. package/dist/internal/dbmgr.d.ts +0 -11
  73. package/dist/internal/dbmgr.d.ts.map +0 -1
  74. package/dist/internal/dbmgr.js +0 -200
  75. package/dist/internal/dominterpreter.d.ts +0 -5
  76. package/dist/internal/dominterpreter.d.ts.map +0 -1
  77. package/dist/internal/dominterpreter.js +0 -337
  78. package/dist/internal/eventmgr.d.ts +0 -41
  79. package/dist/internal/eventmgr.d.ts.map +0 -1
  80. package/dist/internal/eventmgr.js +0 -696
  81. package/dist/internal/index.d.ts +0 -19
  82. package/dist/internal/index.d.ts.map +0 -1
  83. package/dist/internal/index.js +0 -38
  84. package/dist/internal/interpreter.d.ts +0 -10
  85. package/dist/internal/interpreter.d.ts.map +0 -1
  86. package/dist/internal/interpreter.js +0 -1
  87. package/dist/internal/locutils.d.ts +0 -4
  88. package/dist/internal/locutils.d.ts.map +0 -1
  89. package/dist/internal/locutils.js +0 -22
  90. package/dist/internal/net.d.ts +0 -4
  91. package/dist/internal/net.d.ts.map +0 -1
  92. package/dist/internal/net.js +0 -64
  93. package/dist/internal/realdom.d.ts +0 -249
  94. package/dist/internal/realdom.d.ts.map +0 -1
  95. package/dist/internal/realdom.js +0 -1
  96. package/dist/internal/styleregistry.d.ts +0 -6
  97. package/dist/internal/styleregistry.d.ts.map +0 -1
  98. package/dist/internal/styleregistry.js +0 -18
  99. package/dist/internal/taskreg.d.ts +0 -9
  100. package/dist/internal/taskreg.d.ts.map +0 -1
  101. package/dist/internal/taskreg.js +0 -28
  102. package/dist/internal/testing.d.ts +0 -12
  103. package/dist/internal/testing.d.ts.map +0 -1
  104. package/dist/internal/testing.js +0 -974
  105. package/dist/internal/testinginterpreter.d.ts +0 -10
  106. package/dist/internal/testinginterpreter.d.ts.map +0 -1
  107. package/dist/internal/testinginterpreter.js +0 -646
  108. package/dist/internal/vdom.d.ts +0 -93
  109. package/dist/internal/vdom.d.ts.map +0 -1
  110. package/dist/internal/vdom.js +0 -470
  111. package/dist/json/index.d.ts +0 -5
  112. package/dist/json/index.d.ts.map +0 -1
  113. package/dist/json/index.js +0 -2
  114. package/dist/json/validation.d.ts +0 -28
  115. package/dist/json/validation.d.ts.map +0 -1
  116. package/dist/json/validation.js +0 -8
  117. package/dist/net/fragment.d.ts +0 -10
  118. package/dist/net/fragment.d.ts.map +0 -1
  119. package/dist/net/fragment.js +0 -27
  120. package/dist/net/index.d.ts +0 -42
  121. package/dist/net/index.d.ts.map +0 -1
  122. package/dist/net/index.js +0 -60
  123. package/dist/net/location.d.ts +0 -21
  124. package/dist/net/location.d.ts.map +0 -1
  125. package/dist/net/location.js +0 -41
  126. package/dist/net/path.d.ts +0 -12
  127. package/dist/net/path.d.ts.map +0 -1
  128. package/dist/net/path.js +0 -29
  129. package/dist/net/queryparam.d.ts +0 -10
  130. package/dist/net/queryparam.d.ts.map +0 -1
  131. package/dist/net/queryparam.js +0 -34
  132. package/dist/router.d.ts.map +0 -1
  133. package/dist/scroll.d.ts +0 -7
  134. package/dist/scroll.d.ts.map +0 -1
  135. package/dist/scroll.js +0 -3
  136. package/dist/testing.d.ts.map +0 -1
  137. package/dist/utils/apply.d.ts +0 -9
  138. package/dist/utils/apply.d.ts.map +0 -1
  139. package/dist/utils/apply.js +0 -10
  140. package/dist/utils/index.d.ts +0 -22
  141. package/dist/utils/index.d.ts.map +0 -1
  142. package/dist/utils/index.js +0 -138
  143. package/dist/utils/lens.d.ts +0 -18
  144. package/dist/utils/lens.d.ts.map +0 -1
  145. package/dist/utils/lens.js +0 -27
  146. package/dist/utils/match.d.ts +0 -17
  147. package/dist/utils/match.d.ts.map +0 -1
  148. package/dist/utils/match.js +0 -28
  149. package/dist/utils/result.d.ts +0 -47
  150. package/dist/utils/result.d.ts.map +0 -1
  151. package/dist/utils/result.js +0 -97
  152. package/dist/webcomponent.d.ts.map +0 -1
package/dist/effects.js CHANGED
@@ -1,1556 +1,111 @@
1
- import { getJson, } from './net';
2
- import { parseInternalLocation } from './net/location';
3
- import {} from './utils/lens';
4
- import { failure, success } from './utils/result';
5
- /** Creates a typed TaskId from a plain string. */
6
- export function taskId(id) {
7
- return id;
8
- }
9
- /**
10
- * Creates a factory for effects that call an external library function.
11
- * Use this when you want to call a library whose logic would be too cumbersome
12
- * to reimplement using built-in effects. In production `f` is called directly.
13
- * In tests the `test` callback receives the arguments and a queue of scripted
14
- * return values (`data`), and must return `{ out, data }` where `data` is the
15
- * remaining queue after consuming one entry.
16
- *
17
- * @param f Production implementation. May return a Promise.
18
- * @param test Test-time implementation. Receives the scripted data queue and
19
- * returns `{ out, data }` — `out` is the value to return, `data` is the
20
- * remaining queue. Provide scripted values via `newTestData(queue)`.
21
- */
22
- export function customEffect(f, test) {
23
- return (args) => ({
24
- _type: 'Suspend',
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- operation: { _type: 'CustomEffect', input: { args, f, test } },
27
- flatMap(fn) {
28
- return flatMap(this, fn);
29
- },
30
- and(effect) {
31
- return flatMap(this, _ => effect);
32
- },
33
- map(fn) {
34
- return flatMap(this, out => pure(fn(out)));
35
- },
36
- as(b) {
37
- return flatMap(this, _ => pure(b));
38
- },
39
- void() {
40
- return this.map(_out => { });
41
- },
42
- apply(fn) {
43
- return fn(this);
44
- },
45
- });
46
- }
47
- function flatMap(effect, next) {
48
- return {
49
- _type: 'FlatMap',
50
- effect,
51
- next,
52
- flatMap(f) {
53
- return flatMap(this, f);
54
- },
55
- and(effect) {
56
- return flatMap(this, _ => effect);
57
- },
58
- map(f) {
59
- return this.flatMap(b => pure(f(b)));
60
- },
61
- as(c) {
62
- return this.flatMap(_ => pure(c));
63
- },
64
- void() {
65
- return this.map(_b => { });
66
- },
67
- apply(f) {
68
- return f(this);
69
- },
70
- };
71
- }
72
- /**
73
- * Wraps a plain value in an Effect that completes immediately without performing any operations.
74
- * Useful as a base case when building effects conditionally, or to lift a
75
- * computed value into the Effect chain.
76
- */
77
- export function pure(value) {
78
- return {
79
- _type: 'Return',
80
- value,
81
- flatMap(f) {
82
- return flatMap(this, f);
83
- },
84
- and(effect) {
85
- return flatMap(this, _ => effect);
86
- },
87
- map(f) {
88
- return flatMap(this, a => pure(f(a)));
89
- },
90
- as(b) {
91
- return flatMap(this, _ => pure(b));
92
- },
93
- void() {
94
- return this.map(_b => { });
95
- },
96
- apply(f) {
97
- return f(this);
98
- },
99
- };
100
- }
101
- /** An effect describing a browser alert dialog. */
102
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
- export function alert(message) {
104
- return {
105
- _type: 'Suspend',
106
- operation: {
107
- _type: 'Alert',
108
- input: message,
109
- },
110
- flatMap(f) {
111
- return flatMap(this, f);
112
- },
113
- and(effect) {
114
- return flatMap(this, _ => effect);
115
- },
116
- map(f) {
117
- return flatMap(this, () => pure(f()));
118
- },
119
- as(b) {
120
- return flatMap(this, () => pure(b));
121
- },
122
- void() {
123
- return this.map(_b => { });
124
- },
125
- apply(f) {
126
- return f(this);
127
- },
128
- };
129
- }
130
- /**
131
- * An effect describing a browser confirm dialog.
132
- * @returns true if confirmed
133
- */
134
- export function confirm(message) {
135
- return {
136
- _type: 'Suspend',
137
- operation: { _type: 'Confirm', input: message },
138
- flatMap(f) {
139
- return flatMap(this, f);
140
- },
141
- and(effect) {
142
- return flatMap(this, _ => effect);
143
- },
144
- map(f) {
145
- return flatMap(this, b => pure(f(b)));
146
- },
147
- as(b) {
148
- return flatMap(this, () => pure(b));
149
- },
150
- void() {
151
- return this.map(_b => { });
152
- },
153
- apply(f) {
154
- return f(this);
155
- },
156
- };
157
- }
158
- /**
159
- * An effect describing a browser prompt dialog.
160
- * @returns the entered string, or null if cancelled
161
- */
162
- export function prompt(message, defaultValue) {
163
- return {
164
- _type: 'Suspend',
165
- operation: { _type: 'Prompt', input: { message, default: defaultValue } },
166
- flatMap(f) {
167
- return flatMap(this, f);
168
- },
169
- and(effect) {
170
- return flatMap(this, _ => effect);
171
- },
172
- map(f) {
173
- return flatMap(this, s => pure(f(s)));
174
- },
175
- as(b) {
176
- return flatMap(this, () => pure(b));
177
- },
178
- void() {
179
- return this.map(_b => { });
180
- },
181
- apply(f) {
182
- return f(this);
183
- },
184
- };
185
- }
186
- /** An effect describing a clear of the app badge on the browser/OS icon. */
187
- export function clearAppBadge() {
188
- return {
189
- _type: 'Suspend',
190
- operation: { _type: 'ClearAppBadge', input: undefined },
191
- flatMap(f) {
192
- return flatMap(this, f);
193
- },
194
- and(effect) {
195
- return flatMap(this, _ => effect);
196
- },
197
- map(f) {
198
- return flatMap(this, () => pure(f()));
199
- },
200
- as(b) {
201
- return flatMap(this, () => pure(b));
202
- },
203
- void() {
204
- return this.map(_b => { });
205
- },
206
- apply(f) {
207
- return f(this);
208
- },
209
- };
210
- }
211
- /** An effect describing a clipboard text read. */
212
- export function readClipboard() {
213
- return {
214
- _type: 'Suspend',
215
- operation: { _type: 'ReadClipboard', input: undefined },
216
- flatMap(f) {
217
- return flatMap(this, f);
218
- },
219
- and(effect) {
220
- return flatMap(this, _ => effect);
221
- },
222
- map(f) {
223
- return flatMap(this, result => pure(f(result)));
224
- },
225
- as(b) {
226
- return flatMap(this, () => pure(b));
227
- },
228
- void() {
229
- return this.map(_b => { });
230
- },
231
- apply(f) {
232
- return f(this);
233
- },
234
- };
235
- }
236
- /** An effect describing a clipboard write of `text`. */
237
- export function writeClipboard(text) {
238
- return {
239
- _type: 'Suspend',
240
- operation: { _type: 'WriteClipboard', input: text },
241
- flatMap(f) {
242
- return flatMap(this, f);
243
- },
244
- and(effect) {
245
- return flatMap(this, _ => effect);
246
- },
247
- map(f) {
248
- return flatMap(this, result => pure(f(result)));
249
- },
250
- as(b) {
251
- return flatMap(this, () => pure(b));
252
- },
253
- void() {
254
- return this.map(_b => { });
255
- },
256
- apply(f) {
257
- return f(this);
258
- },
259
- };
260
- }
261
- /** An effect describing a `document.title` update. */
262
- export function setDocumentTitle(title) {
263
- return {
264
- _type: 'Suspend',
265
- operation: { _type: 'SetDocumentTitle', input: title },
266
- flatMap(f) {
267
- return flatMap(this, f);
268
- },
269
- and(effect) {
270
- return flatMap(this, _ => effect);
271
- },
272
- map(f) {
273
- return flatMap(this, () => pure(f()));
274
- },
275
- as(b) {
276
- return flatMap(this, () => pure(b));
277
- },
278
- void() {
279
- return this.map(_b => { });
280
- },
281
- apply(f) {
282
- return f(this);
283
- },
284
- };
285
- }
286
- /** An effect describing an app badge count update on the browser/OS icon. */
287
- export function setAppBadge(count) {
288
- return {
289
- _type: 'Suspend',
290
- operation: { _type: 'SetAppBadge', input: count },
291
- flatMap(f) {
292
- return flatMap(this, f);
293
- },
294
- and(effect) {
295
- return flatMap(this, _ => effect);
296
- },
297
- map(f) {
298
- return flatMap(this, () => pure(f()));
299
- },
300
- as(b) {
301
- return flatMap(this, () => pure(b));
302
- },
303
- void() {
304
- return this.map(_b => { });
305
- },
306
- apply(f) {
307
- return f(this);
308
- },
309
- };
310
- }
311
- /**
312
- * An effect describing fire-and-forget async dispatch of `effect`.
313
- * The chain continues without waiting for `effect` to complete.
314
- * Use `scheduleTask` instead if you need cancellation or debounce/repeat behaviour.
315
- */
316
- export function async(effect, delayInMillis = 0) {
317
- return {
318
- _type: 'Suspend',
319
- operation: {
320
- _type: 'Async',
321
- input: { effect, delayInMillis },
322
- },
323
- flatMap(f) {
324
- return flatMap(this, f);
325
- },
326
- and(effect) {
327
- return flatMap(this, _ => effect);
328
- },
329
- map(f) {
330
- return flatMap(this, _ => pure(f()));
331
- },
332
- as(b) {
333
- return flatMap(this, _ => pure(b));
334
- },
335
- void() {
336
- return this.map(_b => { });
337
- },
338
- apply(f) {
339
- return f(this);
340
- },
341
- };
342
- }
343
- /** An effect describing the cancellation of a previously scheduled task. */
344
- export function cancelTask(taskId) {
345
- return {
346
- _type: 'Suspend',
347
- operation: {
348
- _type: 'CancelTask',
349
- input: taskId,
350
- },
351
- flatMap(f) {
352
- return flatMap(this, f);
353
- },
354
- and(effect) {
355
- return flatMap(this, _ => effect);
356
- },
357
- map(f) {
358
- return flatMap(this, () => pure(f()));
359
- },
360
- as(b) {
361
- return flatMap(this, () => pure(b));
362
- },
363
- void() {
364
- return this.map(_b => { });
365
- },
366
- apply(f) {
367
- return f(this);
368
- },
369
- };
370
- }
371
- /**
372
- * An effect describing a typed component event to be delivered to any `onEvent` listener
373
- * registered by the parent that mounted this component. Has no effect when
374
- * used in a top-level application (which has no parent).
375
- */
376
- export function fireEvent(event) {
377
- return {
378
- _type: 'Suspend',
379
- operation: {
380
- _type: 'FireEvent',
381
- input: event,
382
- },
383
- flatMap(f) {
384
- return flatMap(this, f);
385
- },
386
- and(effect) {
387
- return flatMap(this, _ => effect);
388
- },
389
- map(f) {
390
- return flatMap(this, () => pure(f()));
391
- },
392
- as(b) {
393
- return flatMap(this, () => pure(b));
394
- },
395
- void() {
396
- return this.map(_b => { });
397
- },
398
- apply(f) {
399
- return f(this);
400
- },
401
- };
402
- }
403
- /** An effect describing a UUID v4 generation. */
404
- export function generateUuid() {
405
- return {
406
- _type: 'Suspend',
407
- operation: {
408
- _type: 'GenerateUuid',
409
- input: undefined,
410
- },
411
- flatMap(f) {
412
- return flatMap(this, f);
413
- },
414
- and(effect) {
415
- return flatMap(this, _ => effect);
416
- },
417
- map(f) {
418
- return flatMap(this, (uuid) => pure(f(uuid)));
419
- },
420
- as(b) {
421
- return flatMap(this, () => pure(b));
422
- },
423
- void() {
424
- return this.map(_b => { });
425
- },
426
- apply(f) {
427
- return f(this);
428
- },
429
- };
430
- }
431
- /** An effect describing a read of the current time. */
432
- export function getTime() {
433
- return {
434
- _type: 'Suspend',
435
- operation: {
436
- _type: 'GetTime',
437
- input: undefined,
438
- },
439
- flatMap(f) {
440
- return flatMap(this, f);
441
- },
442
- and(effect) {
443
- return flatMap(this, _ => effect);
444
- },
445
- map(f) {
446
- return flatMap(this, (date) => pure(f(date)));
447
- },
448
- as(b) {
449
- return flatMap(this, () => pure(b));
450
- },
451
- void() {
452
- return this.map(_b => { });
453
- },
454
- apply(f) {
455
- return f(this);
456
- },
457
- };
458
- }
459
- /** An effect describing a random number in [0, 1), equivalent to Math.random(). */
460
- export function getRandom() {
461
- return {
462
- _type: 'Suspend',
463
- operation: {
464
- _type: 'GetRandom',
465
- input: undefined,
466
- },
467
- flatMap(f) {
468
- return flatMap(this, f);
469
- },
470
- and(effect) {
471
- return flatMap(this, _ => effect);
472
- },
473
- map(f) {
474
- return flatMap(this, n => pure(f(n)));
475
- },
476
- as(b) {
477
- return flatMap(this, () => pure(b));
478
- },
479
- void() {
480
- return this.map(_b => { });
481
- },
482
- apply(f) {
483
- return f(this);
484
- },
485
- };
486
- }
487
- /** An effect describing a console log of `message`. */
488
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
489
- export function log(message) {
490
- return {
491
- _type: 'Suspend',
492
- operation: {
493
- _type: 'Log',
494
- input: message,
495
- },
496
- flatMap(f) {
497
- return flatMap(this, f);
498
- },
499
- and(effect) {
500
- return flatMap(this, _ => effect);
501
- },
502
- map(f) {
503
- return flatMap(this, () => pure(f()));
504
- },
505
- as(b) {
506
- return flatMap(this, () => pure(b));
507
- },
508
- void() {
509
- return this.map(_b => { });
510
- },
511
- apply(f) {
512
- return f(this);
513
- },
514
- };
515
- }
516
- /** An effect describing an HTTP request. */
517
- export function makeHttpRequest(request) {
518
- return {
519
- _type: 'Suspend',
520
- operation: {
521
- _type: 'MakeHttpRequest',
522
- input: request,
523
- },
524
- flatMap(f) {
525
- return flatMap(this, f);
526
- },
527
- and(effect) {
528
- return flatMap(this, _ => effect);
529
- },
530
- map(f) {
531
- return flatMap(this, result => pure(f(result)));
532
- },
533
- as(b) {
534
- return flatMap(this, () => pure(b));
535
- },
536
- void() {
537
- return this.map(_b => { });
538
- },
539
- apply(f) {
540
- return f(this);
541
- },
542
- };
543
- }
544
- /** An effect describing a read of the current browser location. */
545
- export function getLocation() {
546
- return {
547
- _type: 'Suspend',
548
- operation: { _type: 'GetLocation', input: undefined },
549
- flatMap(f) {
550
- return flatMap(this, f);
551
- },
552
- and(effect) {
553
- return flatMap(this, _ => effect);
554
- },
555
- map(f) {
556
- return flatMap(this, loc => pure(f(loc)));
557
- },
558
- as(b) {
559
- return flatMap(this, () => pure(b));
560
- },
561
- void() {
562
- return this.map(_b => { });
563
- },
564
- apply(f) {
565
- return f(this);
566
- },
567
- };
568
- }
569
- /** An effect describing a read of the current notification permission state. */
570
- export function getNotificationPermission() {
571
- return {
572
- _type: 'Suspend',
573
- operation: { _type: 'GetNotificationPermission', input: undefined },
574
- flatMap(f) {
575
- return flatMap(this, f);
576
- },
577
- and(effect) {
578
- return flatMap(this, _ => effect);
579
- },
580
- map(f) {
581
- return flatMap(this, p => pure(f(p)));
582
- },
583
- as(b) {
584
- return flatMap(this, () => pure(b));
585
- },
586
- void() {
587
- return this.map(_b => { });
588
- },
589
- apply(f) {
590
- return f(this);
591
- },
592
- };
593
- }
594
- /** An effect describing a notification permission request. */
595
- export function requestNotificationPermission() {
596
- return {
597
- _type: 'Suspend',
598
- operation: { _type: 'RequestNotificationPermission', input: undefined },
599
- flatMap(f) {
600
- return flatMap(this, f);
601
- },
602
- and(effect) {
603
- return flatMap(this, _ => effect);
604
- },
605
- map(f) {
606
- return flatMap(this, p => pure(f(p)));
607
- },
608
- as(b) {
609
- return flatMap(this, () => pure(b));
610
- },
611
- void() {
612
- return this.map(_b => { });
613
- },
614
- apply(f) {
615
- return f(this);
616
- },
617
- };
618
- }
619
- /**
620
- * An effect describing a read of the current application state. Because state updates are
621
- * themselves effects sequenced in order, the value produced reflects all
622
- * `updateState` effects that appear earlier in the same effect chain.
623
- */
624
- export function getState() {
625
- return {
626
- _type: 'Suspend',
627
- operation: {
628
- _type: 'GetState',
629
- input: undefined,
630
- },
631
- flatMap(f) {
632
- return flatMap(this, f);
633
- },
634
- and(effect) {
635
- return flatMap(this, _ => effect);
636
- },
637
- map(f) {
638
- return flatMap(this, (state) => pure(f(state)));
639
- },
640
- as(b) {
641
- return flatMap(this, () => pure(b));
642
- },
643
- void() {
644
- return this.map(_b => { });
645
- },
646
- apply(f) {
647
- return f(this);
648
- },
649
- };
650
- }
651
- /**
652
- * An effect describing two concurrent sub-effects, returning both results as a tuple `[A, B]`.
653
- * Both effects share the same initial state snapshot; neither sees state
654
- * changes made by the other. Use `flatMap` instead when the second effect
655
- * must observe state updates from the first.
656
- */
657
- export function product(effectA, effectB) {
658
- return {
659
- _type: 'Suspend',
660
- operation: {
661
- _type: 'Product',
662
- input: [effectA, effectB],
663
- },
664
- flatMap(f) {
665
- return flatMap(this, f);
666
- },
667
- and(effect) {
668
- return flatMap(this, _ => effect);
669
- },
670
- map(f) {
671
- return flatMap(this, aAndB => pure(f(aAndB)));
672
- },
673
- as(c) {
674
- return flatMap(this, _ => pure(c));
675
- },
676
- void() {
677
- return this.map(_b => { });
678
- },
679
- apply(f) {
680
- return f(this);
681
- },
682
- };
683
- }
684
- /**
685
- * An effect describing the scheduling of `task` to run after `initialDelayInMillis` milliseconds.
686
- *
687
- * If `taskId` is provided and a task with that id is already pending, the
688
- * pending task is cancelled and replaced. This makes `scheduleTask` the
689
- * idiomatic way to implement debouncing: use the same `taskId` on
690
- * every keystroke and only the final one will fire.
691
- *
692
- * @param repeatIntervalInMillis If provided, the task repeats on this interval
693
- * indefinitely after the initial delay. Cancel with `cancelTask`.
694
- * @param taskId Stable identifier used to cancel-and-reschedule. Create one
695
- * with `taskId('name')` and store it as a module-level constant.
696
- * @returns The TaskId of the newly scheduled task.
697
- */
698
- export function scheduleTask(task, initialDelayInMillis, repeatIntervalInMillis, taskId) {
699
- return {
700
- _type: 'Suspend',
701
- operation: {
702
- _type: 'ScheduleTask',
703
- input: {
704
- task,
705
- initialDelayInMillis,
706
- repeatIntervalInMillis,
707
- taskId,
708
- },
709
- },
710
- flatMap(f) {
711
- return flatMap(this, f);
712
- },
713
- and(effect) {
714
- return flatMap(this, _ => effect);
715
- },
716
- map(f) {
717
- return flatMap(this, (taskId) => pure(f(taskId)));
718
- },
719
- as(b) {
720
- return flatMap(this, () => pure(b));
721
- },
722
- void() {
723
- return this.map(_b => { });
724
- },
725
- apply(f) {
726
- return f(this);
727
- },
728
- };
729
- }
730
- /** An effect describing a delay of `delayInMilliseconds` ms before continuing the chain. */
731
- export function setTimeout(delayInMilliseconds) {
732
- return {
733
- _type: 'Suspend',
734
- operation: {
735
- _type: 'SetTimeout',
736
- input: delayInMilliseconds,
737
- },
738
- flatMap(f) {
739
- return flatMap(this, f);
740
- },
741
- and(effect) {
742
- return flatMap(this, _ => effect);
743
- },
744
- map(f) {
745
- return flatMap(this, () => pure(f()));
746
- },
747
- as(b) {
748
- return flatMap(this, () => pure(b));
749
- },
750
- void() {
751
- return this.map(_b => { });
752
- },
753
- apply(f) {
754
- return f(this);
755
- },
756
- };
757
- }
758
- /** An effect describing a state update via `f`. */
759
- export function updateState(f) {
760
- return {
761
- _type: 'Suspend',
762
- operation: {
763
- _type: 'UpdateState',
764
- input: f,
765
- },
766
- flatMap(f) {
767
- return flatMap(this, f);
768
- },
769
- and(effect) {
770
- return flatMap(this, _ => effect);
771
- },
772
- map(f) {
773
- return flatMap(this, () => pure(f()));
774
- },
775
- as(b) {
776
- return flatMap(this, () => pure(b));
777
- },
778
- void() {
779
- return this.map(_b => { });
780
- },
781
- apply(f) {
782
- return f(this);
783
- },
784
- };
785
- }
786
- /** An effect describing an IndexedDB database open (or create), with `setup` applied for schema migrations. */
787
- export function openDatabase(db, version, setup) {
788
- return {
789
- _type: 'Suspend',
790
- operation: { _type: 'OpenDatabase', input: { db, version, setup } },
791
- flatMap(f) {
792
- return flatMap(this, f);
793
- },
794
- and(effect) {
795
- return flatMap(this, _ => effect);
796
- },
797
- map(f) {
798
- return flatMap(this, result => pure(f(result)));
799
- },
800
- as(b) {
801
- return flatMap(this, _ => pure(b));
802
- },
803
- void() {
804
- return this.map(_b => { });
805
- },
806
- apply(f) {
807
- return f(this);
808
- },
809
- };
810
- }
811
- /** An effect describing an IndexedDB transaction containing `effect`. */
812
- export function runDbTransaction(db, objectStores, mode, effect) {
813
- return {
814
- _type: 'Suspend',
815
- operation: {
816
- _type: 'RunDbTransaction',
817
- input: { db, objectStores, mode, effect },
818
- },
819
- flatMap(f) {
820
- return flatMap(this, f);
821
- },
822
- and(effect) {
823
- return flatMap(this, _ => effect);
824
- },
825
- map(f) {
826
- return flatMap(this, result => pure(f(result)));
827
- },
828
- as(b) {
829
- return flatMap(this, _ => pure(b));
830
- },
831
- void() {
832
- return this.map(_b => { });
833
- },
834
- apply(f) {
835
- return f(this);
836
- },
837
- };
838
- }
839
- function storageEffect(storage, key, value, tag) {
840
- const input = tag === 'SetStorageItem'
841
- ? { storage, key, value: value }
842
- : tag === 'ClearStorage'
843
- ? { storage }
844
- : { storage, key };
845
- return {
846
- _type: 'Suspend',
847
- operation: { _type: tag, input },
848
- flatMap(f) {
849
- return flatMap(this, f);
850
- },
851
- and(e) {
852
- return flatMap(this, _ => e);
853
- },
854
- map(f) {
855
- return flatMap(this, a => pure(f(a)));
856
- },
857
- as(b) {
858
- return flatMap(this, _ => pure(b));
859
- },
860
- void() {
861
- return this.map(_b => { });
862
- },
863
- apply(f) {
864
- return f(this);
865
- },
866
- };
867
- }
868
- /** An effect describing a browser history navigation of `delta` steps. */
869
- export function go(delta) {
870
- return {
871
- _type: 'Suspend',
872
- operation: { _type: 'Go', input: delta },
873
- flatMap(f) {
874
- return flatMap(this, f);
875
- },
876
- and(effect) {
877
- return flatMap(this, _ => effect);
878
- },
879
- map(f) {
880
- return flatMap(this, () => pure(f()));
881
- },
882
- as(b) {
883
- return flatMap(this, () => pure(b));
884
- },
885
- void() {
886
- return this.map(_b => { });
887
- },
888
- apply(f) {
889
- return f(this);
890
- },
891
- };
892
- }
893
- /** An effect describing a `history.pushState` to `location`. */
894
- export function pushState(location) {
895
- const loc = typeof location === 'string' ? parseInternalLocation(location) : location;
896
- return {
897
- _type: 'Suspend',
898
- operation: { _type: 'PushState', input: loc },
899
- flatMap(f) {
900
- return flatMap(this, f);
901
- },
902
- and(effect) {
903
- return flatMap(this, _ => effect);
904
- },
905
- map(f) {
906
- return flatMap(this, () => pure(f()));
907
- },
908
- as(b) {
909
- return flatMap(this, () => pure(b));
910
- },
911
- void() {
912
- return this.map(_b => { });
913
- },
914
- apply(f) {
915
- return f(this);
916
- },
917
- };
918
- }
919
- /** An effect describing a `history.replaceState` with `location`. */
920
- export function replaceState(location) {
921
- const loc = typeof location === 'string' ? parseInternalLocation(location) : location;
922
- return {
923
- _type: 'Suspend',
924
- operation: { _type: 'ReplaceState', input: loc },
925
- flatMap(f) {
926
- return flatMap(this, f);
927
- },
928
- and(effect) {
929
- return flatMap(this, _ => effect);
930
- },
931
- map(f) {
932
- return flatMap(this, () => pure(f()));
933
- },
934
- as(b) {
935
- return flatMap(this, () => pure(b));
936
- },
937
- void() {
938
- return this.map(_b => { });
939
- },
940
- apply(f) {
941
- return f(this);
942
- },
943
- };
944
- }
945
- /** An effect describing a localStorage read for `key`. */
946
- export function getLocalStorageItem(key) {
947
- return storageEffect('local', key, undefined, 'GetStorageItem');
948
- }
949
- /** An effect describing a localStorage write of `value` for `key`. */
950
- export function setLocalStorageItem(key, value) {
951
- return storageEffect('local', key, value, 'SetStorageItem');
952
- }
953
- /** An effect describing the removal of `key` from localStorage. */
954
- export function removeLocalStorageItem(key) {
955
- return storageEffect('local', key, undefined, 'RemoveStorageItem');
956
- }
957
- /** An effect describing a localStorage clear. */
958
- export function clearLocalStorage() {
959
- return storageEffect('local', '', undefined, 'ClearStorage');
960
- }
961
- /** An effect describing a sessionStorage read for `key`. */
962
- export function getSessionStorageItem(key) {
963
- return storageEffect('session', key, undefined, 'GetStorageItem');
964
- }
965
- /** An effect describing a sessionStorage write of `value` for `key`. */
966
- export function setSessionStorageItem(key, value) {
967
- return storageEffect('session', key, value, 'SetStorageItem');
968
- }
969
- /** An effect describing the removal of `key` from sessionStorage. */
970
- export function removeSessionStorageItem(key) {
971
- return storageEffect('session', key, undefined, 'RemoveStorageItem');
972
- }
973
- /** An effect describing a sessionStorage clear. */
974
- export function clearSessionStorage() {
975
- return storageEffect('session', '', undefined, 'ClearStorage');
976
- }
977
- /**
978
- * Transforms the `Event` type of an effect by mapping each fired event through `f`.
979
- * Used when composing components: a child component fires `EventA`, and the
980
- * parent needs to convert those into its own `EventB` before wiring them up.
981
- * You rarely need to call this directly — `ComponentElement.onEvent` handles it.
982
- */
983
- export function mapEvent(effect, f) {
984
- switch (effect._type) {
985
- case 'Return': {
986
- return pure(effect.value);
987
- }
988
- case 'FlatMap': {
989
- return flatMap(mapEvent(effect.effect, f), x => {
990
- return mapEvent(effect.next(x), f);
991
- });
992
- }
993
- case 'Suspend': {
994
- switch (effect.operation._type) {
995
- case 'Alert':
996
- case 'CancelTask':
997
- case 'ClearAppBadge':
998
- case 'ClearStorage':
999
- case 'Confirm':
1000
- case 'CustomEffect':
1001
- case 'Download':
1002
- case 'GenerateUuid':
1003
- case 'GetLocation':
1004
- case 'GetNotificationPermission':
1005
- case 'RequestNotificationPermission':
1006
- case 'GetState':
1007
- case 'GetStorageItem':
1008
- case 'GetTime':
1009
- case 'GetRandom':
1010
- case 'Log':
1011
- case 'PostBroadcastMessage':
1012
- case 'Prompt':
1013
- case 'MakeHttpRequest':
1014
- case 'Go':
1015
- case 'OpenDatabase':
1016
- case 'PushState':
1017
- case 'ReplaceState':
1018
- case 'RemoveStorageItem':
1019
- case 'ReadClipboard':
1020
- case 'RunDbTransaction':
1021
- case 'ScrollElement':
1022
- case 'ScrollWindow':
1023
- case 'SetAppBadge':
1024
- case 'SetDocumentTitle':
1025
- case 'SetStorageItem':
1026
- case 'SetTimeout':
1027
- case 'UpdateState':
1028
- case 'WriteClipboard': {
1029
- return effect;
1030
- }
1031
- case 'SubscribeToBroadcastChannel': {
1032
- return subscribeToBroadcastChannel(effect.operation.input.channel, msg => mapEvent(effect.operation.input.handler(msg), f), effect.operation.input.taskId);
1033
- }
1034
- case 'ScheduleTask': {
1035
- return scheduleTask(mapEvent(effect.operation.input.task, f), effect.operation.input.initialDelayInMillis, effect.operation.input.repeatIntervalInMillis, effect.operation.input.taskId);
1036
- }
1037
- case 'Async': {
1038
- return async(mapEvent(effect.operation.input.effect, f), effect.operation.input.delayInMillis);
1039
- }
1040
- case 'Product': {
1041
- return product(mapEvent(effect.operation.input[0], f), mapEvent(effect.operation.input[1], f));
1042
- }
1043
- case 'FireEvent':
1044
- return fireEvent(f(effect.operation.input));
1045
- }
1046
- }
1047
- }
1048
- }
1049
- /**
1050
- * Adapts an effect written against a sub-state `StateA` so it can run in a
1051
- * parent context with state `StateB`. The lens provides the `get`/`set`
1052
- * functions that translate between the two state shapes.
1053
- * Used when composing components whose effects operate on a slice of a larger state.
1054
- */
1055
- export function mapState(effect, lens) {
1056
- switch (effect._type) {
1057
- case 'Return': {
1058
- return pure(effect.value);
1059
- }
1060
- case 'FlatMap': {
1061
- return flatMap(mapState(effect.effect, lens), x => {
1062
- return mapState(effect.next(x), lens);
1063
- });
1064
- }
1065
- case 'Suspend': {
1066
- switch (effect.operation._type) {
1067
- case 'Alert':
1068
- case 'CancelTask':
1069
- case 'ClearAppBadge':
1070
- case 'ClearStorage':
1071
- case 'Confirm':
1072
- case 'CustomEffect':
1073
- case 'Download':
1074
- case 'FireEvent':
1075
- case 'GenerateUuid':
1076
- case 'GetLocation':
1077
- case 'GetNotificationPermission':
1078
- case 'RequestNotificationPermission':
1079
- case 'PostBroadcastMessage':
1080
- case 'Prompt':
1081
- case 'GetStorageItem':
1082
- case 'GetTime':
1083
- case 'GetRandom':
1084
- case 'Log':
1085
- case 'MakeHttpRequest':
1086
- case 'Go':
1087
- case 'OpenDatabase':
1088
- case 'PushState':
1089
- case 'ReplaceState':
1090
- case 'RemoveStorageItem':
1091
- case 'ReadClipboard':
1092
- case 'RunDbTransaction':
1093
- case 'ScrollElement':
1094
- case 'ScrollWindow':
1095
- case 'SetAppBadge':
1096
- case 'SetDocumentTitle':
1097
- case 'SetStorageItem':
1098
- case 'SetTimeout':
1099
- case 'WriteClipboard': {
1100
- return effect;
1101
- }
1102
- case 'SubscribeToBroadcastChannel': {
1103
- return subscribeToBroadcastChannel(effect.operation.input.channel, msg => mapState(effect.operation.input.handler(msg), lens), effect.operation.input.taskId);
1104
- }
1105
- case 'Async': {
1106
- return async(mapState(effect.operation.input.effect, lens), effect.operation.input.delayInMillis);
1107
- }
1108
- case 'ScheduleTask': {
1109
- return scheduleTask(mapState(effect.operation.input.task, lens), effect.operation.input.initialDelayInMillis, effect.operation.input.repeatIntervalInMillis, effect.operation.input.taskId);
1110
- }
1111
- case 'Product': {
1112
- return product(mapState(effect.operation.input[0], lens), mapState(effect.operation.input[1], lens));
1113
- }
1114
- case 'UpdateState': {
1115
- return updateState((stateB) => {
1116
- const stateAUpdate = effect.operation.input;
1117
- const stateA = lens.get(stateB);
1118
- const updatedStateA = stateAUpdate(stateA);
1119
- return lens.set(stateB, updatedStateA);
1120
- });
1121
- }
1122
- case 'GetState':
1123
- return getState().map(b => {
1124
- return lens.get(b);
1125
- });
1126
- }
1127
- }
1128
- }
1129
- }
1130
- /** Returns true if `value` is an Effect. */
1131
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1132
- export function isEffect(value) {
1133
- if (value === null || value === undefined) {
1134
- return false;
1135
- }
1136
- if (typeof value !== 'object') {
1137
- return false;
1138
- }
1139
- if (value['_type'] === 'Return') {
1140
- return Object.prototype.hasOwnProperty.call(value, 'value');
1141
- }
1142
- else if (value['_type'] === 'Suspend') {
1143
- return Object.prototype.hasOwnProperty.call(value, 'operation');
1144
- }
1145
- else if (value['_type'] === 'FlatMap') {
1146
- return Object.prototype.hasOwnProperty.call(value, 'effect');
1147
- }
1148
- else {
1149
- return false;
1150
- }
1151
- }
1152
- /*
1153
- function interpreter<State, Event, A>(
1154
- state: State,
1155
- effect: Effect<State, Event, A>
1156
- ): [State, A] {
1157
- switch (effect._type) {
1158
- case 'Return':
1159
- return [state, effect.value]
1160
- case 'FlatMap':
1161
- const [state2, result] = interpreter(state, effect.effect)
1162
- return interpreter(state2, effect.next(result))
1163
- case 'Suspend':
1164
- switch (effect.operation._type) {
1165
- case 'Alert':
1166
- console.log("ALERT: " + effect.operation.input)
1167
- return [state, undefined as A]
1168
- case 'Async': {
1169
- return todo()
1170
- }
1171
- case 'ClearAppBadge': {
1172
- return todo()
1173
- }
1174
- case 'GetState':
1175
- return [state, state as unknown as A]
1176
- case 'GetTime':
1177
- return [state, new Date() as A]
1178
- case 'FireEvent':
1179
- console.log("FIRING EVENT " + effect.operation.input)
1180
- return [state, undefined as A]
1181
- case 'Log':
1182
- console.log(effect.operation.input)
1183
- return [state, undefined as A]
1184
- case 'MakeHttpRequest': {
1185
- return todo()
1186
- }
1187
- case 'UpdateState':
1188
- const state2 = effect.operation.input(state)
1189
- return [state2, undefined as A]
1190
- }
1191
- }
1192
- }
1193
-
1194
- export function run<State, Event, A>(
1195
- state: State,
1196
- effect: Effect<State, Event, A>
1197
- ): A {
1198
- const [_, a] = interpreter(state, effect)
1199
- return a
1200
- }
1201
-
1202
- type AppState = {
1203
- count: number
1204
- }
1205
-
1206
- export const prog1 =
1207
- getState<AppState, unknown>()
1208
- .flatMap(state => {
1209
- const msg = "The count is " + state.count
1210
- return log(msg)
1211
- })
1212
- .and(updateState(s => ({ count: s.count + 1 })))
1213
- .and(getState())
1214
- .flatMap(state => {
1215
- const msg = "The count is now " + state.count
1216
- return log(msg)
1217
- })
1218
-
1219
- export const prog2 =
1220
- getState<AppState, unknown>()
1221
- .flatMap(state => {
1222
- const msg = "The count is " + state.count
1223
- return log(msg)
1224
- })
1225
-
1226
-
1227
- type OuterState = {
1228
- newField: boolean
1229
- appState: AppState
1230
- }
1231
-
1232
- const lens = lensFromProp<OuterState>()('appState')
1233
-
1234
- const changedProg = mapState(prog1, lens)
1235
-
1236
-
1237
- run({ newField: true, appState: { count: 2 } }, changedProg)
1238
- */
1239
- /** An effect describing a window scroll. */
1240
- export function scrollWindow(options) {
1241
- return {
1242
- _type: 'Suspend',
1243
- operation: { _type: 'ScrollWindow', input: options },
1244
- flatMap(f) {
1245
- return flatMap(this, f);
1246
- },
1247
- and(effect) {
1248
- return flatMap(this, _ => effect);
1249
- },
1250
- map(f) {
1251
- return flatMap(this, () => pure(f()));
1252
- },
1253
- as(b) {
1254
- return flatMap(this, () => pure(b));
1255
- },
1256
- void() {
1257
- return this.map(_b => { });
1258
- },
1259
- apply(f) {
1260
- return f(this);
1261
- },
1262
- };
1263
- }
1264
- /** An effect describing a scroll of the element matching `selector`. */
1265
- export function scrollElement(selector, options) {
1266
- return {
1267
- _type: 'Suspend',
1268
- operation: { _type: 'ScrollElement', input: { selector, options } },
1269
- flatMap(f) {
1270
- return flatMap(this, f);
1271
- },
1272
- and(effect) {
1273
- return flatMap(this, _ => effect);
1274
- },
1275
- map(f) {
1276
- return flatMap(this, result => pure(f(result)));
1277
- },
1278
- as(b) {
1279
- return flatMap(this, () => pure(b));
1280
- },
1281
- void() {
1282
- return this.map(_b => { });
1283
- },
1284
- apply(f) {
1285
- return f(this);
1286
- },
1287
- };
1288
- }
1289
- /** An effect describing a file download. */
1290
- export function download(filename, content, contentType = 'text/plain') {
1291
- return {
1292
- _type: 'Suspend',
1293
- operation: { _type: 'Download', input: { filename, content, contentType } },
1294
- flatMap(f) {
1295
- return flatMap(this, f);
1296
- },
1297
- and(effect) {
1298
- return flatMap(this, _ => effect);
1299
- },
1300
- map(f) {
1301
- return flatMap(this, () => pure(f()));
1302
- },
1303
- as(b) {
1304
- return flatMap(this, () => pure(b));
1305
- },
1306
- void() {
1307
- return this.map(_b => { });
1308
- },
1309
- apply(f) {
1310
- return f(this);
1311
- },
1312
- };
1313
- }
1314
- /** An effect describing a BroadcastChannel message post. */
1315
- export function postBroadcastMessage(channel, message) {
1316
- return {
1317
- _type: 'Suspend',
1318
- operation: { _type: 'PostBroadcastMessage', input: { channel, message } },
1319
- flatMap(f) {
1320
- return flatMap(this, f);
1321
- },
1322
- and(effect) {
1323
- return flatMap(this, _ => effect);
1324
- },
1325
- map(f) {
1326
- return flatMap(this, () => pure(f()));
1327
- },
1328
- as(b) {
1329
- return flatMap(this, () => pure(b));
1330
- },
1331
- void() {
1332
- return this.map(_b => { });
1333
- },
1334
- apply(f) {
1335
- return f(this);
1336
- },
1337
- };
1338
- }
1339
- /**
1340
- * An effect describing a BroadcastChannel subscription, with `handler` called for each message received.
1341
- * @returns a TaskId that can be used to cancel the subscription
1342
- */
1343
- export function subscribeToBroadcastChannel(channel, handler, taskId = undefined) {
1344
- return {
1345
- _type: 'Suspend',
1346
- operation: {
1347
- _type: 'SubscribeToBroadcastChannel',
1348
- input: { channel, handler, taskId },
1349
- },
1350
- flatMap(f) {
1351
- return flatMap(this, f);
1352
- },
1353
- and(effect) {
1354
- return flatMap(this, _ => effect);
1355
- },
1356
- map(f) {
1357
- return flatMap(this, id => pure(f(id)));
1358
- },
1359
- as(b) {
1360
- return flatMap(this, () => pure(b));
1361
- },
1362
- void() {
1363
- return this.map(_id => { });
1364
- },
1365
- apply(f) {
1366
- return f(this);
1367
- },
1368
- };
1369
- }
1370
- /** An Effect that does nothing. */
1371
- export function noop() {
1372
- return pure(undefined);
1373
- }
1374
- /**
1375
- * Returns all built-in effect constructors with `State` and `Event` pre-applied.
1376
- * Call this once per module, passing your application's state and event types,
1377
- * and destructure the effects you need. This removes the need to repeat the
1378
- * type parameters at every call site.
1379
- *
1380
- * ```ts
1381
- * const { updateState, getTime, scheduleTask } = makeEffects<MyState, MyEvent>()
1382
- * ```
1383
- */
1384
- export function makeEffects() {
1385
- return {
1386
- alert: (alert),
1387
- confirm: (confirm),
1388
- prompt: (prompt),
1389
- cancelTask: (cancelTask),
1390
- getLocation: (getLocation),
1391
- getNotificationPermission: (getNotificationPermission),
1392
- requestNotificationPermission: (requestNotificationPermission),
1393
- clearAppBadge: (clearAppBadge),
1394
- readClipboard: (readClipboard),
1395
- setAppBadge: (setAppBadge),
1396
- setDocumentTitle: (setDocumentTitle),
1397
- writeClipboard: (writeClipboard),
1398
- fireEvent: (fireEvent),
1399
- getState: (getState),
1400
- getTime: (getTime),
1401
- getRandom: (getRandom),
1402
- log: (log),
1403
- makeHttpRequest: (makeHttpRequest),
1404
- scheduleTask: (scheduleTask),
1405
- setTimeout: (setTimeout),
1406
- updateState: (updateState),
1407
- pure(a) {
1408
- return pure(a);
1409
- },
1410
- noop: (noop),
1411
- generateUuid: (generateUuid),
1412
- getJson: (getJson),
1413
- go: (go),
1414
- scrollWindow: (scrollWindow),
1415
- scrollElement: (scrollElement),
1416
- download: (download),
1417
- postBroadcastMessage: (postBroadcastMessage),
1418
- subscribeToBroadcastChannel: (subscribeToBroadcastChannel),
1419
- pushState: (pushState),
1420
- replaceState: (replaceState),
1421
- getLocalStorageItem: (getLocalStorageItem),
1422
- setLocalStorageItem: (setLocalStorageItem),
1423
- removeLocalStorageItem: (removeLocalStorageItem),
1424
- clearLocalStorage: (clearLocalStorage),
1425
- getSessionStorageItem: (getSessionStorageItem),
1426
- setSessionStorageItem: (setSessionStorageItem),
1427
- removeSessionStorageItem: (removeSessionStorageItem),
1428
- clearSessionStorage: (clearSessionStorage),
1429
- resultT(effect) {
1430
- return resultT(effect);
1431
- },
1432
- };
1433
- }
1434
- /**
1435
- * Maps each element of `as` to an effect and runs them in sequence, collecting
1436
- * all results into an array. Each effect runs after the previous one completes,
1437
- * so state changes from earlier effects are visible to later ones.
1438
- */
1439
- export function traverse(as, f) {
1440
- const effects = as.map(f);
1441
- if (effects.length === 0) {
1442
- return pure([]);
1443
- }
1444
- return effects.reduce((acc, effect) => {
1445
- return product(acc, effect).map(bsAndB => {
1446
- return [...bsAndB[0], bsAndB[1]];
1447
- });
1448
- }, pure([]));
1449
- }
1450
- /**
1451
- * Wraps an `Effect<State, Event, Result<A, E>>` to allow chaining on the
1452
- * success and error branches without manually unwrapping the `Result` at each
1453
- * step. Methods like `flatMap` and `errorFlatMap` short-circuit on the other
1454
- * branch. Call `.value` to get the underlying effect back.
1455
- */
1456
- export class ResultTransformer {
1457
- constructor(value) {
1458
- /** The underlying wrapped effect. */
1459
- Object.defineProperty(this, "value", {
1460
- enumerable: true,
1461
- configurable: true,
1462
- writable: true,
1463
- value: void 0
1464
- });
1465
- this.value = value;
1466
- }
1467
- /** Transforms the success value. */
1468
- map(f) {
1469
- return new ResultTransformer(this.value.map(res => {
1470
- return res.map(f);
1471
- }));
1472
- }
1473
- /** Replaces the success value with `b`. */
1474
- as(b) {
1475
- return new ResultTransformer(this.value.map(res => {
1476
- return res.map(_ => b);
1477
- }));
1478
- }
1479
- /** Discards the success value. */
1480
- void() {
1481
- return new ResultTransformer(this.value.map(res => {
1482
- return res.map(_ => { });
1483
- }));
1484
- }
1485
- /** Discards the error value. */
1486
- errorVoid() {
1487
- return this.errorMap(_ => { });
1488
- }
1489
- /** Chains on success, short-circuits on failure. */
1490
- flatMap(f) {
1491
- return new ResultTransformer(this.value.flatMap(res => {
1492
- switch (res._tag) {
1493
- case 'failure':
1494
- return pure(failure(res.error));
1495
- case 'success':
1496
- return f(res.value);
1497
- }
1498
- }));
1499
- }
1500
- /** Like `flatMap` but `f` returns an unwrapped Effect rather than an Effect of Result. */
1501
- semiFlatMap(f) {
1502
- return new ResultTransformer(this.value.flatMap(res => {
1503
- switch (res._tag) {
1504
- case 'failure':
1505
- return pure(failure(res.error));
1506
- case 'success':
1507
- return f(res.value).map(b => success(b));
1508
- }
1509
- }));
1510
- }
1511
- /** Sequences on success, short-circuits on failure. */
1512
- and(effect) {
1513
- return new ResultTransformer(this.value.flatMap(res => {
1514
- switch (res._tag) {
1515
- case 'failure':
1516
- return pure(failure(res.error));
1517
- case 'success':
1518
- return effect;
1519
- }
1520
- }));
1521
- }
1522
- /** Unwraps the Result, returning either the success value or the error. */
1523
- merge() {
1524
- return this.value.map(res => res.merge());
1525
- }
1526
- /** Logs the error to the console without changing the Result. */
1527
- logError() {
1528
- return this.errorFlatMap(e => log(e).map(_ => e));
1529
- }
1530
- /** Logs the error and converts it to void. */
1531
- logAndDropError() {
1532
- return this.logError().errorVoid();
1533
- }
1534
- /** Transforms the error value. */
1535
- errorMap(f) {
1536
- return new ResultTransformer(this.value.map(res => res.errorMap(f)));
1537
- }
1538
- /** Chains on failure, short-circuits on success. */
1539
- errorFlatMap(f) {
1540
- return new ResultTransformer(this.value.flatMap(res => {
1541
- switch (res._tag) {
1542
- case 'failure':
1543
- return f(res.error).map(e => failure(e));
1544
- case 'success':
1545
- return pure(success(res.value));
1546
- }
1547
- }));
1548
- }
1549
- }
1550
- /**
1551
- * Lifts an `Effect<State, Event, Result<A, E>>` into a `ResultTransformer` for
1552
- * chaining. Equivalent to `new ResultTransformer(effect)`.
1553
- */
1554
- export function resultT(effect) {
1555
- return new ResultTransformer(effect);
1556
- }
1
+ import {
2
+ ResultTransformer,
3
+ alert,
4
+ async,
5
+ cancelTask,
6
+ clearAppBadge,
7
+ clearLocalStorage,
8
+ clearSessionStorage,
9
+ confirm,
10
+ customEffect,
11
+ download,
12
+ fireEvent,
13
+ generateUuid,
14
+ getLocalStorageItem,
15
+ getLocation,
16
+ getNotificationPermission,
17
+ getRandom,
18
+ getSessionStorageItem,
19
+ getState,
20
+ getTime,
21
+ go,
22
+ isEffect,
23
+ log,
24
+ makeEffects,
25
+ makeHttpRequest,
26
+ mapEvent,
27
+ mapState,
28
+ noop,
29
+ openDatabase,
30
+ postBroadcastMessage,
31
+ product,
32
+ prompt,
33
+ pure,
34
+ pushState,
35
+ readClipboard,
36
+ removeLocalStorageItem,
37
+ removeSessionStorageItem,
38
+ replaceState,
39
+ requestNotificationPermission,
40
+ resultT,
41
+ runDbTransaction,
42
+ scheduleTask,
43
+ scrollElement,
44
+ scrollWindow,
45
+ setAppBadge,
46
+ setDocumentTitle,
47
+ setLocalStorageItem,
48
+ setSessionStorageItem,
49
+ setTimeout,
50
+ subscribeToBroadcastChannel,
51
+ taskId,
52
+ traverse,
53
+ updateState,
54
+ writeClipboard
55
+ } from "./chunk-OSIRHKDB.js";
56
+ import "./chunk-PKBMQBKP.js";
57
+ export {
58
+ ResultTransformer,
59
+ alert,
60
+ async,
61
+ cancelTask,
62
+ clearAppBadge,
63
+ clearLocalStorage,
64
+ clearSessionStorage,
65
+ confirm,
66
+ customEffect,
67
+ download,
68
+ fireEvent,
69
+ generateUuid,
70
+ getLocalStorageItem,
71
+ getLocation,
72
+ getNotificationPermission,
73
+ getRandom,
74
+ getSessionStorageItem,
75
+ getState,
76
+ getTime,
77
+ go,
78
+ isEffect,
79
+ log,
80
+ makeEffects,
81
+ makeHttpRequest,
82
+ mapEvent,
83
+ mapState,
84
+ noop,
85
+ openDatabase,
86
+ postBroadcastMessage,
87
+ product,
88
+ prompt,
89
+ pure,
90
+ pushState,
91
+ readClipboard,
92
+ removeLocalStorageItem,
93
+ removeSessionStorageItem,
94
+ replaceState,
95
+ requestNotificationPermission,
96
+ resultT,
97
+ runDbTransaction,
98
+ scheduleTask,
99
+ scrollElement,
100
+ scrollWindow,
101
+ setAppBadge,
102
+ setDocumentTitle,
103
+ setLocalStorageItem,
104
+ setSessionStorageItem,
105
+ setTimeout,
106
+ subscribeToBroadcastChannel,
107
+ taskId,
108
+ traverse,
109
+ updateState,
110
+ writeClipboard
111
+ };