uneventful 0.0.2 → 0.0.4
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/README.md +7 -7
- package/dist/mod.d.ts +922 -608
- package/dist/mod.mjs +1771 -1
- package/dist/mod.mjs.map +1 -1
- package/package.json +2 -10
- package/dist/mod.cjs +0 -2
- package/dist/mod.cjs.map +0 -1
package/dist/mod.d.ts
CHANGED
|
@@ -222,507 +222,168 @@ declare class CancelError extends Error {
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
/**
|
|
225
|
-
*
|
|
225
|
+
* A backpressure controller: returns true if downstream is ready to accept
|
|
226
|
+
* data.
|
|
226
227
|
*
|
|
227
|
-
* @
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* A suspend callback that must be `yield`-ed before the next call to the
|
|
234
|
-
* iterator's .next() method. (That is, you must `yield next` it exactly once
|
|
235
|
-
* per loop pass. See {@link each}() for more details.)
|
|
236
|
-
*/
|
|
237
|
-
next: Suspend<void>;
|
|
238
|
-
};
|
|
239
|
-
/**
|
|
240
|
-
* The iterable returned by `yield *` {@link each}()
|
|
228
|
+
* @param cb (optional) - a callback to run when the downstream consumer wishes
|
|
229
|
+
* to resume event production (i.e., when a sink calls
|
|
230
|
+
* {@link Throttle.resume}()). The callback is automatically unregistered when
|
|
231
|
+
* invoked, so the producer must re-register it after each call if it wishes to
|
|
232
|
+
* keep being called.
|
|
241
233
|
*
|
|
242
234
|
* @category Types and Interfaces
|
|
243
235
|
*/
|
|
244
|
-
type
|
|
236
|
+
type Backpressure = (cb?: () => any) => boolean;
|
|
245
237
|
/**
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* Usage:
|
|
249
|
-
*
|
|
250
|
-
* ```ts
|
|
251
|
-
* for (const {item: event, next} of yield *each(mouseMove)) {
|
|
252
|
-
* console.log(event.clientX, event.clientY);
|
|
253
|
-
* yield next; // required exactly once per iteration, even/w continue!
|
|
254
|
-
* }
|
|
255
|
-
* ```
|
|
256
|
-
*
|
|
257
|
-
* each(eventSource) yield-returns an iterator of `{item, next}` pairs. The
|
|
258
|
-
* item is the data supplied by the event source, and `next` is a
|
|
259
|
-
* {@link Suspend}\<void\> that advances the iterator to the next item. It
|
|
260
|
-
* *must* be yielded exactly once per loop iteration. If you use `continue` to
|
|
261
|
-
* shortcut the loop body, you must `yield next` *before* doing so.
|
|
262
|
-
*
|
|
263
|
-
* The for-loop will end if the source ends, errors, or is canceled. The source
|
|
264
|
-
* is paused while the loop body is running, and resumed when the `yield next`
|
|
265
|
-
* happens. If events arrive anyway (e.g. because the source doesn't support
|
|
266
|
-
* pausing), they will be ignored unless you pipe the source through the
|
|
267
|
-
* {@link slack}() operator to provide a buffer. If the for-loop is exited
|
|
268
|
-
* early for any reason (or the iterator's `.return()` is called), the source is
|
|
269
|
-
* unsubscribed and the iteration ended.
|
|
238
|
+
* Create a backpressure control function for the given connection
|
|
270
239
|
*
|
|
271
|
-
* @category Stream
|
|
240
|
+
* @category Stream Producers
|
|
272
241
|
*/
|
|
273
|
-
declare function
|
|
242
|
+
declare function backpressure(inlet?: Inlet): Backpressure;
|
|
274
243
|
/**
|
|
275
|
-
*
|
|
244
|
+
* Control backpressure for listening streams. This interface is the API
|
|
245
|
+
* internal to the implementation of {@link backpressure}(). Unless you're
|
|
246
|
+
* implementing a backpressurable stream yourself, see the {@link Throttle}
|
|
247
|
+
* interface instead.
|
|
276
248
|
*
|
|
277
249
|
* @category Types and Interfaces
|
|
278
250
|
*/
|
|
279
|
-
|
|
251
|
+
interface Inlet {
|
|
252
|
+
/** Is the main connection open? (i.e. is the creating job not closed yet?) */
|
|
253
|
+
isOpen(): boolean;
|
|
254
|
+
/** Is the conduit currently ready to receive data? */
|
|
255
|
+
isReady(): boolean;
|
|
256
|
+
/**
|
|
257
|
+
* Register a callback to produce more data when the inlet is resumed
|
|
258
|
+
* (The callback is unregistered if the supplied job ends.)
|
|
259
|
+
*/
|
|
260
|
+
onReady(cb: () => any, job: Job): this;
|
|
261
|
+
}
|
|
280
262
|
/**
|
|
281
|
-
*
|
|
282
|
-
*
|
|
263
|
+
* Control backpressure for listening streams
|
|
264
|
+
*
|
|
265
|
+
* Obtain instances via {@link throttle}(), then pass them into the appropriate
|
|
266
|
+
* stream-consuming API. (e.g. {@link connect}).
|
|
283
267
|
*
|
|
284
268
|
* @category Types and Interfaces
|
|
285
269
|
*/
|
|
286
|
-
interface
|
|
287
|
-
"
|
|
270
|
+
interface Throttle extends Inlet {
|
|
271
|
+
/** Set inlet status to "paused". */
|
|
272
|
+
pause(): void;
|
|
273
|
+
/**
|
|
274
|
+
* Un-pause, and iterate backpressure-able sources' onReady callbacks to
|
|
275
|
+
* resume sending immediately. (i.e., synchronously!)
|
|
276
|
+
*/
|
|
277
|
+
resume(): void;
|
|
288
278
|
}
|
|
289
279
|
/**
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
* @param source A {@link Waitable} data source, which can be any of:
|
|
294
|
-
* - A {@link Signal} (in which case the job will resume when the value is
|
|
295
|
-
* truthy - perhaps immediately!)
|
|
296
|
-
* - A {@link Source}
|
|
297
|
-
* - A promise, or promise-like object with a `.then()` method
|
|
298
|
-
* - An object with an `"uneventful.until"` method returning a {@link Yielding}
|
|
299
|
-
* (in which case the result will be the the result of that method)
|
|
300
|
-
*
|
|
301
|
-
* @returns a Yieldable that when processed with `yield *` in a job, will return
|
|
302
|
-
* the triggered event, promise resolution, or signal value. An error is thrown
|
|
303
|
-
* if the promise rejects or the event stream throws or closes early, or the
|
|
304
|
-
* signal throws.
|
|
280
|
+
* A Connection is a job that returns void when the connected stream ends
|
|
281
|
+
* itself. If the stream doesn't end itself (e.g. it's an event listener), the
|
|
282
|
+
* job will never return, and only end with a cancel or throw.
|
|
305
283
|
*
|
|
306
|
-
* @category
|
|
284
|
+
* @category Types and Interfaces
|
|
307
285
|
*/
|
|
308
|
-
|
|
309
|
-
|
|
286
|
+
type Connection = Job<void>;
|
|
310
287
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
288
|
+
* A Source is a function that can be called to arrange for data to be
|
|
289
|
+
* produced and sent to a {@link Sink} function for consumption, until the
|
|
290
|
+
* associated {@link Connection} is closed (either by the source or the sink,
|
|
291
|
+
* e.g. if the sink doesn't want more data or the source has no more to send).
|
|
315
292
|
*
|
|
316
|
-
*
|
|
317
|
-
|
|
318
|
-
declare class WriteConflict extends Error {
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Error indicating a rule has attempted to write a value it directly depends
|
|
322
|
-
* on, or a cached function has called itself, directly or indirectly.
|
|
293
|
+
* If the source is a backpressurable stream, it can use the (optional) supplied
|
|
294
|
+
* inlet (usually a {@link throttle}()) to rate-limit its output.
|
|
323
295
|
*
|
|
324
|
-
* @
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* A queue for rules to run during a particular kind of period, such as
|
|
330
|
-
* microtasks or animation frames. (Can only be obtained or created via
|
|
331
|
-
* {@link RuleScheduler.for}().)
|
|
296
|
+
* A producer function *must* return the special {@link IsStream} value, so
|
|
297
|
+
* TypeScript can tell what functions are usable as sources. (Otherwise any
|
|
298
|
+
* void function with no arguments would appear to be usable as a source!)
|
|
332
299
|
*
|
|
333
|
-
* @category
|
|
300
|
+
* @category Types and Interfaces
|
|
334
301
|
*/
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
|
|
338
|
-
*
|
|
339
|
-
* This is a bound method
|
|
340
|
-
*
|
|
341
|
-
* (Note: "pending" rules are ones with at least one changed ancestor
|
|
342
|
-
* dependency; this doesn't mean they will actually *do* anything,
|
|
343
|
-
* since intermediate cached() function results might end up unchanged.)
|
|
344
|
-
*/
|
|
345
|
-
flush: () => void;
|
|
346
|
-
/**
|
|
347
|
-
* Create an {@link RuleScheduler} from a callback-taking function, that
|
|
348
|
-
* you can then use to make rules that run in a specific time frame.
|
|
349
|
-
*
|
|
350
|
-
* ```ts
|
|
351
|
-
* // frame.rule will now create rules that run during animation fames
|
|
352
|
-
* const animate = RuleScheduler.for(requestAnimationFrame).rule;
|
|
353
|
-
*
|
|
354
|
-
* animate(() => {
|
|
355
|
-
* // ... do stuff in an animation frame when signals used here change
|
|
356
|
-
* })
|
|
357
|
-
* ```
|
|
358
|
-
*
|
|
359
|
-
* Returns the default scheduler if no arguments are given. If called with
|
|
360
|
-
* the same function more than once, it returns the same scheduler instance.
|
|
361
|
-
*
|
|
362
|
-
* @param scheduleFn A single-argument scheduling function (like
|
|
363
|
-
* requestAnimationFrame, setImmediate, or queueMicrotask). The scheduler
|
|
364
|
-
* will call it from time to time with a single callback. The scheduling
|
|
365
|
-
* function should then arrange for that callback to be invoked *once* at
|
|
366
|
-
* some future point, when it is the desired time for all pending rules on
|
|
367
|
-
* that scheduler to run.
|
|
368
|
-
*/
|
|
369
|
-
static for(scheduleFn?: (cb: () => unknown) => unknown): RuleScheduler;
|
|
370
|
-
protected constructor(_scheduleFn?: (cb: () => unknown) => unknown);
|
|
371
|
-
/**
|
|
372
|
-
* @inheritdoc rule tied to a specific scheduler. See {@link rule} for
|
|
373
|
-
* more details.
|
|
374
|
-
*
|
|
375
|
-
* @remarks The rule will only run during its matching
|
|
376
|
-
* {@link RuleScheduler.flush}().
|
|
377
|
-
*
|
|
378
|
-
* This is a bound method, so you can use it independently of the scheduler
|
|
379
|
-
* it came from.
|
|
380
|
-
*/
|
|
381
|
-
rule: (fn: (stop: DisposeFn) => OptionalCleanup) => DisposeFn;
|
|
302
|
+
interface Source<T> {
|
|
303
|
+
/** Subscribe sink to receive values */
|
|
304
|
+
(sink: Sink<T>, conn?: Connection, inlet?: Throttle | Inlet): typeof IsStream;
|
|
382
305
|
}
|
|
383
306
|
/**
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
* during its previous run.
|
|
390
|
-
*
|
|
391
|
-
* The created subscription is tied to the currently-active job (which may be
|
|
392
|
-
* another rule). So when that job is ended or restarted, the rule will be
|
|
393
|
-
* terminated automatically. You can also terminate it early by calling the
|
|
394
|
-
* "stop" function that is both passed to the rule function and returned by
|
|
395
|
-
* `rule()`.
|
|
396
|
-
*
|
|
397
|
-
* Note: this function will throw an error if called without an active job. If
|
|
398
|
-
* you need a standalone rule, use {@link detached}.run to wrap the
|
|
399
|
-
* call to rule.
|
|
400
|
-
*
|
|
401
|
-
* @param fn The function that will be run each time its dependencies change.
|
|
402
|
-
* The function will be run in a restarted job each time, with any resources
|
|
403
|
-
* used by the previous run being cleaned up. The function is passed a single
|
|
404
|
-
* argument: a function that can be called to terminate the rule. The function
|
|
405
|
-
* should return a cleanup function or void.
|
|
406
|
-
*
|
|
407
|
-
* @returns A function that can be called to terminate the rule.
|
|
307
|
+
* An uneventful stream is either a {@link Source} or a {@link SignalSource}.
|
|
308
|
+
* (Signals actually implement the {@link Source} interface as an overload, but
|
|
309
|
+
* TypeScript gets confused about that sometimes, so we generally declare our
|
|
310
|
+
* stream *inputs* as `Stream<T>` and our stream *outputs* as {@link Source}, so
|
|
311
|
+
* that TypeScript knows what's what.
|
|
408
312
|
*
|
|
409
|
-
* @category
|
|
313
|
+
* @category Types and Interfaces
|
|
410
314
|
*/
|
|
411
|
-
|
|
315
|
+
type Stream<T> = Source<T> | SignalSource<T>;
|
|
412
316
|
/**
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
* @remarks Equivalent to calling
|
|
416
|
-
* {@link RuleScheduler.for}(defer).{@link RuleScheduler.flush flush}().
|
|
317
|
+
* The call signatures implemented by signals. (They can be used as sources, or
|
|
318
|
+
* called with no arguments to return a value.)
|
|
417
319
|
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
* IndexedDB transaction. (You can also define rules to run in a specific
|
|
422
|
-
* timeframe by creating a {@link RuleScheduler} for them, via
|
|
423
|
-
* {@link RuleScheduler.for}.)
|
|
320
|
+
* This type is needed because TypeScript won't infer the overloads of
|
|
321
|
+
* {@link Signal} correctly otherwise. (Specifically, it won't allow it to be
|
|
322
|
+
* used as a zero-agument function.)
|
|
424
323
|
*
|
|
425
|
-
* @category
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
interface Signal<T> {
|
|
430
|
-
/**
|
|
431
|
-
* A signal object implements the {@link Producer} interface, even if it's
|
|
432
|
-
* not directly recognized as one by TypeScript.
|
|
433
|
-
*/
|
|
434
|
-
(sink: Sink<T>, conn?: Connection, inlet?: Inlet): typeof IsStream;
|
|
324
|
+
* @category Types and Interfaces
|
|
325
|
+
*/
|
|
326
|
+
type SignalSource<T> = Source<T> & {
|
|
435
327
|
/** A signal object can be called to get its current value */
|
|
436
328
|
(): T;
|
|
437
|
-
}
|
|
329
|
+
};
|
|
438
330
|
/**
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
* {@link readonly |.readonly()} on an existing signal instead.
|
|
331
|
+
* A specially-typed string used to verify that a function supports uneventful's
|
|
332
|
+
* streaming protocol. Return it from a function to implement the
|
|
333
|
+
* {@link Source} type.
|
|
443
334
|
*
|
|
444
335
|
* @category Types and Interfaces
|
|
445
336
|
*/
|
|
446
|
-
declare
|
|
447
|
-
/** The current value */
|
|
448
|
-
get value(): T;
|
|
449
|
-
/** The current value */
|
|
450
|
-
valueOf(): T;
|
|
451
|
-
/** The current value, as a string */
|
|
452
|
-
toString(): string;
|
|
453
|
-
/** The current value */
|
|
454
|
-
toJSON(): T;
|
|
455
|
-
/** Get the signal's current value, without adding the signal as a dependency */
|
|
456
|
-
peek(): T;
|
|
457
|
-
/** Get a read-only version of this signal */
|
|
458
|
-
readonly(): Signal<T>;
|
|
459
|
-
/** New writable signal with a custom setter */
|
|
460
|
-
withSet(set: (v: T) => unknown): Writable<T>;
|
|
461
|
-
"uneventful.until"(): Yielding<T>;
|
|
462
|
-
protected constructor();
|
|
463
|
-
}
|
|
464
|
-
interface Writable<T> {
|
|
465
|
-
/** Set the current value. (Note: this is a bound method so it can be used as a callback.) */
|
|
466
|
-
set(val: T): void;
|
|
467
|
-
}
|
|
337
|
+
declare const IsStream: "uneventful/is-stream";
|
|
468
338
|
/**
|
|
469
|
-
* A
|
|
470
|
-
* {@link Writable.value | .value} property.
|
|
471
|
-
*
|
|
472
|
-
* Note: this class is not directly instantiable - use {@link value}() or call
|
|
473
|
-
* {@link Signal.withSet | .withSet()} on an existing signal instead.
|
|
339
|
+
* A `Sink` is a function that receives data from a {@link Stream}.
|
|
474
340
|
*
|
|
475
341
|
* @category Types and Interfaces
|
|
476
342
|
*/
|
|
477
|
-
|
|
478
|
-
get value(): T;
|
|
479
|
-
set value(val: T);
|
|
480
|
-
readonly(): Signal<T>;
|
|
481
|
-
}
|
|
343
|
+
type Sink<T> = (val: T) => void;
|
|
482
344
|
/**
|
|
483
|
-
*
|
|
345
|
+
* A `Transformer` is a function that takes one stream and returns another,
|
|
346
|
+
* possibly one that produces data of a different type. Most operator functions
|
|
347
|
+
* return a transformer, allowing them to be combined via {@link pipe}().
|
|
484
348
|
*
|
|
485
|
-
* @category
|
|
349
|
+
* @category Types and Interfaces
|
|
486
350
|
*/
|
|
487
|
-
|
|
351
|
+
type Transformer<T, V = T> = (input: Stream<T>) => Source<V>;
|
|
488
352
|
/**
|
|
489
|
-
*
|
|
490
|
-
* {@link
|
|
491
|
-
*
|
|
492
|
-
* Note: If the supplied function has a non-zero `.length` (i.e., it explicitly
|
|
493
|
-
* takes arguments), it is assumed to be a {@link Source}, and the second
|
|
494
|
-
* calling signature below will apply, even if TypeScript doesn't see it that
|
|
495
|
-
* way!)
|
|
353
|
+
* Subscribe a sink to a stream, returning a nested job. (Shorthand for
|
|
354
|
+
* {@link getJob}().{@link Job.connect connect}(...).)
|
|
496
355
|
*
|
|
497
|
-
* @
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
/**
|
|
501
|
-
* If the supplied function has a non-zero `.length` (i.e., it explicitly takes
|
|
502
|
-
* arguments), it is assumed to be a {@link Source}, and the second argument is
|
|
503
|
-
* a default value for the created signal to use as default value until the
|
|
504
|
-
* source produces a value.
|
|
356
|
+
* @param src An event source or signal
|
|
357
|
+
* @param sink A callback that will receive the events
|
|
358
|
+
* @param inlet Optional - a {@link throttle}() to control backpressure
|
|
505
359
|
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
* the signal will update itself with the most recent value produced by the
|
|
509
|
-
* source, triggering rules or events as appropriate if the value changes. When
|
|
510
|
-
* the signal is once again unobserved, it will revert to the supplied inital
|
|
511
|
-
* value.
|
|
360
|
+
* @returns A job that can be aborted to end the subscription, and which will
|
|
361
|
+
* end naturally (with a void return or error) if the stream ends itself.
|
|
512
362
|
*
|
|
513
|
-
* @
|
|
514
|
-
* @param initVal The value to use when the signal is unobserved or waiting for the
|
|
515
|
-
* first item from the source.
|
|
363
|
+
* @category Stream Consumers
|
|
516
364
|
*/
|
|
517
|
-
declare function
|
|
518
|
-
declare function cached<T extends Signal<any>>(signal: T): T;
|
|
365
|
+
declare function connect<T>(src: Stream<T>, sink: Sink<T>, inlet?: Throttle | Inlet): Connection;
|
|
519
366
|
/**
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
* You can also pass in any arguments the function takes, and the function's
|
|
524
|
-
* return value is returned.
|
|
367
|
+
* Create a backpressure controller for a stream. Pass it to one or more
|
|
368
|
+
* sources you're connecting to, and if they support backpressure they'll
|
|
369
|
+
* respond when you call its .pause() and .resume() methods.
|
|
525
370
|
*
|
|
526
|
-
* @
|
|
371
|
+
* @param job - Optional: a job that controls readiness. (The throttle will
|
|
372
|
+
* pause indefinitely when the job ends.) Defaults to the currently-active job,
|
|
373
|
+
* but unlike most such defaults, it won't throw if no job is active.
|
|
527
374
|
*
|
|
528
|
-
* @category
|
|
375
|
+
* @category Stream Consumers
|
|
529
376
|
*/
|
|
530
|
-
declare function
|
|
377
|
+
declare function throttle(job?: Job): Throttle;
|
|
531
378
|
/**
|
|
532
|
-
*
|
|
379
|
+
* Pipe a stream (or anything else) through a series of single-argument
|
|
380
|
+
* functions/operators
|
|
533
381
|
*
|
|
534
|
-
*
|
|
535
|
-
* subscribe to changes to it, but not directly produce a signal. (Such as
|
|
536
|
-
* querying the DOM state and using a MutationObserver.)
|
|
382
|
+
* e.g. the following creates a stream that outputs 4 and then 6:
|
|
537
383
|
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
* emits a value, the signal machinery will invalidate the caching of the
|
|
542
|
-
* function or rule, forcing a recalculation and subsequent rule reruns, if
|
|
543
|
-
* applicable.
|
|
544
|
-
*
|
|
545
|
-
* Note: you should generally only call the 1-argument version of this function
|
|
546
|
-
* with "static" sources - i.e. ones that won't change on every call. Otherwise,
|
|
547
|
-
* you will end up creating new signals each time, subscribing and unsubscribing
|
|
548
|
-
* on every call to recalcWhen().
|
|
549
|
-
*
|
|
550
|
-
* If the source needs to reference some object, it's best to use the 2-argument
|
|
551
|
-
* version (i.e. `changesWhen(someObj, factory)`, where `factory` is a function
|
|
552
|
-
* that takes `someObj` and returns a suitable {@link RecalcSource}.)
|
|
553
|
-
*
|
|
554
|
-
* @remarks
|
|
555
|
-
* recalcWhen is specifically designed so that using it does not pull in any
|
|
556
|
-
* part of Uneventful's signals framework, in the event a program doesn't
|
|
557
|
-
* already use it. This means you can use it in library code to provide signal
|
|
558
|
-
* compatibility, without adding bundle bloat to code that doesn't use signals.
|
|
559
|
-
*
|
|
560
|
-
* @category Signals
|
|
561
|
-
*/
|
|
562
|
-
declare function recalcWhen(src: RecalcSource): void;
|
|
563
|
-
/**
|
|
564
|
-
* Two-argument variant of recalcWhen
|
|
565
|
-
*
|
|
566
|
-
* In certain circumstances, you may wish to use recalcWhen with a source
|
|
567
|
-
* related to some object. You could call recalcWhen with a closure, but that
|
|
568
|
-
* would create and discard signals on every call. So this 2-argument version
|
|
569
|
-
* lets you avoid that by allowing the use of an arbitrary object as a key,
|
|
570
|
-
* along with a factory function to turn the key into a {@link RecalcSource}.
|
|
571
|
-
*
|
|
572
|
-
* @param key an object to be used as a key
|
|
573
|
-
*
|
|
574
|
-
* @param factory a function that will be called with the key to obtain a
|
|
575
|
-
* {@link RecalcSource}. Note that this factory function must also be a static
|
|
576
|
-
* function, not a closure, or the same memory thrash issue will occur.
|
|
577
|
-
*/
|
|
578
|
-
declare function recalcWhen<T extends WeakKey>(key: T, factory: (key: T) => RecalcSource): void;
|
|
579
|
-
|
|
580
|
-
/**
|
|
581
|
-
* A backpressure controller: returns true if downstream is ready to accept
|
|
582
|
-
* data.
|
|
583
|
-
*
|
|
584
|
-
* @param cb (optional) - a callback to run when the downstream consumer wishes
|
|
585
|
-
* to resume event production (i.e., when a sink calls
|
|
586
|
-
* {@link Throttle.resume}()). The callback is automatically unregistered when
|
|
587
|
-
* invoked, so the producer must re-register it after each call if it wishes to
|
|
588
|
-
* keep being called.
|
|
589
|
-
*
|
|
590
|
-
* @category Types and Interfaces
|
|
591
|
-
*/
|
|
592
|
-
type Backpressure = (cb?: () => any) => boolean;
|
|
593
|
-
/**
|
|
594
|
-
* Create a backpressure control function for the given connection
|
|
595
|
-
*
|
|
596
|
-
* @category Stream Producers
|
|
597
|
-
*/
|
|
598
|
-
declare function backpressure(inlet?: Inlet): Backpressure;
|
|
599
|
-
/**
|
|
600
|
-
* Control backpressure for listening streams. This interface is the API
|
|
601
|
-
* internal to the implementation of {@link backpressure}(). Unless you're
|
|
602
|
-
* implementing a backpressurable stream yourself, see the {@link Throttle}
|
|
603
|
-
* interface instead.
|
|
604
|
-
*
|
|
605
|
-
* @category Types and Interfaces
|
|
606
|
-
*/
|
|
607
|
-
interface Inlet {
|
|
608
|
-
/** Is the main connection open? (i.e. is the creating job not closed yet?) */
|
|
609
|
-
isOpen(): boolean;
|
|
610
|
-
/** Is the conduit currently ready to receive data? */
|
|
611
|
-
isReady(): boolean;
|
|
612
|
-
/**
|
|
613
|
-
* Register a callback to produce more data when the inlet is resumed
|
|
614
|
-
* (The callback is unregistered if the supplied job ends.)
|
|
615
|
-
*/
|
|
616
|
-
onReady(cb: () => any, job: Job): this;
|
|
617
|
-
}
|
|
618
|
-
/**
|
|
619
|
-
* Control backpressure for listening streams
|
|
620
|
-
*
|
|
621
|
-
* Obtain instances via {@link throttle}(), then pass them into the appropriate
|
|
622
|
-
* stream-consuming API. (e.g. {@link connect}).
|
|
623
|
-
*
|
|
624
|
-
* @category Types and Interfaces
|
|
625
|
-
*/
|
|
626
|
-
interface Throttle extends Inlet {
|
|
627
|
-
/** Set inlet status to "paused". */
|
|
628
|
-
pause(): void;
|
|
629
|
-
/**
|
|
630
|
-
* Un-pause, and iterate backpressure-able sources' onReady callbacks to
|
|
631
|
-
* resume sending immediately. (i.e., synchronously!)
|
|
632
|
-
*/
|
|
633
|
-
resume(): void;
|
|
634
|
-
}
|
|
635
|
-
/**
|
|
636
|
-
* A Connection is a job that returns void when the connected stream ends
|
|
637
|
-
* itself. If the stream doesn't end itself (e.g. it's an event listener), the
|
|
638
|
-
* job will never return, and only end with a cancel or throw.
|
|
639
|
-
*
|
|
640
|
-
* @category Types and Interfaces
|
|
641
|
-
*/
|
|
642
|
-
type Connection = Job<void>;
|
|
643
|
-
/**
|
|
644
|
-
* A Producer is a function that can be called to arrange for data to be
|
|
645
|
-
* produced and sent to a {@link Sink} function for consumption, until the
|
|
646
|
-
* associated {@link Connection} is closed (either by the source or the sink,
|
|
647
|
-
* e.g. if the sink doesn't want more data or the source has no more to send).
|
|
648
|
-
*
|
|
649
|
-
* If the source is a backpressurable stream, it can use the (optional) supplied
|
|
650
|
-
* inlet (usually a {@link throttle}()) to rate-limit its output.
|
|
651
|
-
*
|
|
652
|
-
* A producer function *must* return the special {@link IsStream} value, so
|
|
653
|
-
* TypeScript can tell what functions are usable as sources. (Otherwise any
|
|
654
|
-
* void function with no arguments would appear to be usable as a source!)
|
|
655
|
-
*
|
|
656
|
-
* @category Types and Interfaces
|
|
657
|
-
*/
|
|
658
|
-
type Producer<T> = (sink: Sink<T>, conn?: Connection, inlet?: Throttle | Inlet) => typeof IsStream;
|
|
659
|
-
/**
|
|
660
|
-
* A Source is either a {@link Producer} or a {@link Signal}. (Signals actually
|
|
661
|
-
* implement the {@link Producer} interface as an overload, but TypeScript gets
|
|
662
|
-
* confused about that sometimes, so we generally declare our stream *inputs* as
|
|
663
|
-
* `Source<T>` and our stream *outputs* as {@link Producer}, so that TypeScript
|
|
664
|
-
* knows what's what.
|
|
665
|
-
*
|
|
666
|
-
* @category Types and Interfaces
|
|
667
|
-
*/
|
|
668
|
-
type Source<T> = Producer<T> | Signal<T> | Writable<T>;
|
|
669
|
-
/**
|
|
670
|
-
* A specially-typed string used to verify that a function supports uneventful's
|
|
671
|
-
* streaming protocol. Return it from a function to implement the
|
|
672
|
-
* {@link Source} type.
|
|
673
|
-
*
|
|
674
|
-
* @category Types and Interfaces
|
|
675
|
-
*/
|
|
676
|
-
declare const IsStream: "uneventful/is-stream";
|
|
677
|
-
/**
|
|
678
|
-
* A `Sink` is a function that receives data from a {@link Source}.
|
|
679
|
-
*
|
|
680
|
-
* @category Types and Interfaces
|
|
681
|
-
*/
|
|
682
|
-
type Sink<T> = (val: T) => void;
|
|
683
|
-
/**
|
|
684
|
-
* A `Transformer` is a function that takes one source and returns another,
|
|
685
|
-
* possibly one that produces data of a different type. Most operator functions
|
|
686
|
-
* return a transformer, allowing them to be combined via {@link pipe}().
|
|
687
|
-
*
|
|
688
|
-
* @category Types and Interfaces
|
|
689
|
-
*/
|
|
690
|
-
type Transformer<T, V = T> = (input: Source<T>) => Producer<V>;
|
|
691
|
-
/**
|
|
692
|
-
* Subscribe a sink to a source, returning a nested job. (Shorthand for
|
|
693
|
-
* {@link getJob}().{@link Job.connect connect}(...).)
|
|
694
|
-
*
|
|
695
|
-
* @param src An event source or finite data stream
|
|
696
|
-
* @param sink A callback that will receive the events
|
|
697
|
-
* @param inlet Optional - a {@link throttle}() to control backpressure
|
|
698
|
-
*
|
|
699
|
-
* @returns A job that can be aborted to end the subscription, and which will
|
|
700
|
-
* end naturally (with a void return or error) if the stream ends itself.
|
|
701
|
-
*
|
|
702
|
-
* @category Stream Consumers
|
|
703
|
-
*/
|
|
704
|
-
declare function connect<T>(src: Source<T>, sink: Sink<T>, inlet?: Throttle | Inlet): Connection;
|
|
705
|
-
/**
|
|
706
|
-
* Create a backpressure controller for a stream. Pass it to one or more
|
|
707
|
-
* sources you're connecting to, and if they support backpressure they'll
|
|
708
|
-
* respond when you call its .pause() and .resume() methods.
|
|
709
|
-
*
|
|
710
|
-
* @param job - Optional: a job that controls readiness. (The throttle will
|
|
711
|
-
* pause indefinitely when the job ends.) Defaults to the currently-active job,
|
|
712
|
-
* but unlike most such defaults, it won't throw if no job is active.
|
|
713
|
-
*
|
|
714
|
-
* @category Stream Consumers
|
|
715
|
-
*/
|
|
716
|
-
declare function throttle(job?: Job): Throttle;
|
|
717
|
-
/**
|
|
718
|
-
* Pipe a stream (or anything else) through a series of single-argument
|
|
719
|
-
* functions/operators
|
|
720
|
-
*
|
|
721
|
-
* e.g. the following creates a stream that outputs 4 and then 6:
|
|
722
|
-
*
|
|
723
|
-
* ```ts
|
|
724
|
-
* pipe(fromIterable([1,2,3,4]), skip(1), take(2), map(x => x*2))
|
|
725
|
-
* ```
|
|
384
|
+
* ```ts
|
|
385
|
+
* pipe(fromIterable([1,2,3,4]), skip(1), take(2), map(x => x*2))
|
|
386
|
+
* ```
|
|
726
387
|
*
|
|
727
388
|
* The first argument to pipe() can be any value, but all other arguments must
|
|
728
389
|
* be functions. The value is passed to the first function, and then the result
|
|
@@ -875,8 +536,8 @@ type OptionalCleanup<T = any> = CleanupFn<T> | Nothing;
|
|
|
875
536
|
*/
|
|
876
537
|
type AsyncStart<T, This = void> = (this: This, job: Job<T>) => StartObj<T>;
|
|
877
538
|
/**
|
|
878
|
-
* A synchronous start function returns void. It runs
|
|
879
|
-
* passed the newly created job as its first argument.
|
|
539
|
+
* A synchronous start function returns void or a {@link CleanupFn}. It runs
|
|
540
|
+
* immediately and gets passed the newly created job as its first argument.
|
|
880
541
|
*
|
|
881
542
|
* @template T The type the job will end up returning
|
|
882
543
|
* @template This The type of `this` the function accepts, if using two-argument
|
|
@@ -884,7 +545,7 @@ type AsyncStart<T, This = void> = (this: This, job: Job<T>) => StartObj<T>;
|
|
|
884
545
|
*
|
|
885
546
|
* @category Types and Interfaces
|
|
886
547
|
*/
|
|
887
|
-
type SyncStart<T, This = void> = (this: This, job: Job<T>) =>
|
|
548
|
+
type SyncStart<T, This = void> = (this: This, job: Job<T>) => OptionalCleanup;
|
|
888
549
|
/**
|
|
889
550
|
* A synchronous or asynchronous initializing function for use with the
|
|
890
551
|
* {@link start}() function or a job's {@link Job.start .start}() method.
|
|
@@ -969,7 +630,7 @@ interface Job<T = any> extends Yielding<T>, Promise<T> {
|
|
|
969
630
|
* In order to ensure that all such "child" jobs, resources, and activities
|
|
970
631
|
* are marked as canceled *before* any side effects (such as events,
|
|
971
632
|
* callbacks or I/O operations) can occur, Uneventful prioritizes *all*
|
|
972
|
-
* release callbacks to run before *any* other callbacks of any kind.
|
|
633
|
+
* release callbacks to run before *any* other callbacks of any kind. Since
|
|
973
634
|
* release callbacks are used for child jobs, this means that the entire job
|
|
974
635
|
* subtree is notified immediately of cancellation, before any other actions
|
|
975
636
|
* are taken. This ensures that no "stray" operations can continue, unaware
|
|
@@ -1013,15 +674,15 @@ interface Job<T = any> extends Yielding<T>, Promise<T> {
|
|
|
1013
674
|
* This is basically shorthand for `start<void>(job => void src(sink, job,
|
|
1014
675
|
* inlet))` -- i.e. a quick way to subscribe to a finite and/or pausable stream.
|
|
1015
676
|
*
|
|
1016
|
-
* @param src An event source or
|
|
1017
|
-
* @param sink A callback that will receive the events
|
|
677
|
+
* @param src An event source or signal
|
|
678
|
+
* @param sink A callback that will receive the events or values
|
|
1018
679
|
* @param inlet Optional - a {@link throttle}() to control backpressure
|
|
1019
680
|
* @returns A job that can be aborted to end the subscription, and which will
|
|
1020
681
|
* end naturally (with a void return or error) if the stream ends itself.
|
|
1021
682
|
*
|
|
1022
683
|
* @category Execution Control
|
|
1023
684
|
*/
|
|
1024
|
-
connect<T>(src:
|
|
685
|
+
connect<T>(src: Stream<T>, sink: Sink<T>, inlet?: Throttle | Inlet): Connection;
|
|
1025
686
|
/**
|
|
1026
687
|
* Invoke a function with this job as the active one, so that calling the
|
|
1027
688
|
* global {@link must} function will add cleanup callbacks to it,
|
|
@@ -1048,7 +709,7 @@ interface Job<T = any> extends Yielding<T>, Promise<T> {
|
|
|
1048
709
|
* though TypeScript will act as if they are present at compile time. This
|
|
1049
710
|
* is because the only way to copy all overloads of a function signature is
|
|
1050
711
|
* to copy the exact type (as TypeScript has no way to generically say,
|
|
1051
|
-
* "this a function with all the same overloads, but none of the
|
|
712
|
+
* "this is a function with all the same overloads, but none of the
|
|
1052
713
|
* properties").
|
|
1053
714
|
*
|
|
1054
715
|
* @category Execution Control
|
|
@@ -1214,192 +875,782 @@ interface Job<T = any> extends Yielding<T>, Promise<T> {
|
|
|
1214
875
|
/**
|
|
1215
876
|
* A pausable computation that ultimately produces a value of type T.
|
|
1216
877
|
*
|
|
1217
|
-
* An item of this type can be used to either create a job of type T, or awaited
|
|
1218
|
-
* in a job via `yield *` to obtain the value.
|
|
878
|
+
* An item of this type can be used to either create a job of type T, or awaited
|
|
879
|
+
* in a job via `yield *` to obtain the value.
|
|
880
|
+
*
|
|
881
|
+
* Any generator function that ultimately returns a value, implicitly returns a
|
|
882
|
+
* Yielding of that type, but it's best to *explicitly* declare this so that
|
|
883
|
+
* TypeScript can properly type check your yield expressions. (e.g. `function
|
|
884
|
+
* *(): Yielding<number> {}` for a generator function that ultimately returns a
|
|
885
|
+
* number.)
|
|
886
|
+
*
|
|
887
|
+
* Generator functions implementing this type should only ever `yield *` to
|
|
888
|
+
* things that are of Yielding type, such as a {@link Job}, {@link to}() or
|
|
889
|
+
* other generators declared Yielding.
|
|
890
|
+
*
|
|
891
|
+
* @yields {@link Suspend}\<any>
|
|
892
|
+
* @returns T
|
|
893
|
+
*
|
|
894
|
+
*
|
|
895
|
+
* @category Types and Interfaces
|
|
896
|
+
*/
|
|
897
|
+
type Yielding<T> = {
|
|
898
|
+
/**
|
|
899
|
+
* An iterator suitable for use with `yield *` (in a job generator) to
|
|
900
|
+
* obtain a result.
|
|
901
|
+
*
|
|
902
|
+
* @category Obtaining Results
|
|
903
|
+
*/
|
|
904
|
+
[Symbol.iterator](): JobIterator<T>;
|
|
905
|
+
};
|
|
906
|
+
/**
|
|
907
|
+
* An iterator yielding {@link Suspend} callbacks. (An implementation detail of
|
|
908
|
+
* the {@link Yielding} type.)
|
|
909
|
+
*
|
|
910
|
+
* @category Types and Interfaces
|
|
911
|
+
*/
|
|
912
|
+
type JobIterator<T> = Generator<Suspend<any>, T, any>;
|
|
913
|
+
/**
|
|
914
|
+
* An asynchronous operation that can be waited on by a {@link Job}.
|
|
915
|
+
*
|
|
916
|
+
* When a {@link JobIterator} yields a Suspend, the job invokes it with a
|
|
917
|
+
* {@link Request}. The Suspend function should arrange for the request to be
|
|
918
|
+
* settled (via {@link resolve} or {@link reject}).
|
|
919
|
+
*
|
|
920
|
+
* Note: If the request is not settled, **the job will be suspended until
|
|
921
|
+
* cancelled by outside forces**. (Such as its enclosing job ending, or
|
|
922
|
+
* explicit throw()/return() calls on the job instance.)
|
|
923
|
+
*
|
|
924
|
+
* Also note that any subjobs the Suspend function creates (or cleanup callbacks
|
|
925
|
+
* it registers) **will not be cleaned up until the *calling* job ends**. So
|
|
926
|
+
* any resources that won't be needed once the job is resumed should be
|
|
927
|
+
* explicitly disposed of -- in which case you should probably just `yield *` to
|
|
928
|
+
* a {@link start}(), instead of yielding a Suspend!
|
|
929
|
+
*
|
|
930
|
+
* @category Types and Interfaces
|
|
931
|
+
*/
|
|
932
|
+
type Suspend<T> = (request: Request<T>) => void;
|
|
933
|
+
/**
|
|
934
|
+
* A request for a value (or error) to be returned asynchronously.
|
|
935
|
+
*
|
|
936
|
+
* A request is like the inverse of a Promise: instead of waiting for it to
|
|
937
|
+
* settle, you settle it by passing it to {@link resolve}() or {@link reject}().
|
|
938
|
+
* Like a promise, it can only be settled once: resolving or rejecting it after
|
|
939
|
+
* it's already resolved or rejected has no effect.
|
|
940
|
+
*
|
|
941
|
+
* Settling a request will cause the requesting job (or other code) to resume
|
|
942
|
+
* immediately, running up to its next suspension or termination. (Unless it's
|
|
943
|
+
* settled while the requesting job is already on the call stack, in which case
|
|
944
|
+
* the job will be resumed later.)
|
|
945
|
+
*
|
|
946
|
+
* (Note: do not call a Request directly, unless you want your code to maybe
|
|
947
|
+
* break in future. Use resolve or reject (or {@link resolver}() or
|
|
948
|
+
* {@link rejecter}()), as 1) they'll shield you from future changes to this
|
|
949
|
+
* protocol and 2) they have better type checking anyway.)
|
|
950
|
+
*
|
|
951
|
+
* @category Types and Interfaces
|
|
952
|
+
*/
|
|
953
|
+
interface Request<T> {
|
|
954
|
+
(op: "next", val: T, err?: any): void;
|
|
955
|
+
(op: "throw", val: undefined | null, err: any): void;
|
|
956
|
+
(op: "next" | "throw", val?: T | undefined | null, err?: any): void;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* A subscribable function used to trigger signal recalculations
|
|
960
|
+
*
|
|
961
|
+
* It must accept a callback, and should arrange (via {@link must}()) to
|
|
962
|
+
* unsubscribe when its calling job ends. Once subscribed, it should
|
|
963
|
+
* invoke the callback to trigger recalculation of the signal(s) that
|
|
964
|
+
* were targeted via {@link recalcWhen}.
|
|
965
|
+
*
|
|
966
|
+
* @category Types and Interfaces
|
|
967
|
+
*/
|
|
968
|
+
type RecalcSource = ((cb: () => void) => unknown);
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Is the given value a function?
|
|
972
|
+
*
|
|
973
|
+
* @category Types and Interfaces
|
|
974
|
+
*/
|
|
975
|
+
declare function isFunction(f: any): f is Function;
|
|
976
|
+
/**
|
|
977
|
+
* Return the currently-active Job, or throw an error if none is active.
|
|
978
|
+
*
|
|
979
|
+
* (You can check if a job is active first using {@link isJobActive}().)
|
|
980
|
+
*
|
|
981
|
+
* @category Jobs
|
|
982
|
+
*/
|
|
983
|
+
declare function getJob<T = unknown>(): Job<T>;
|
|
984
|
+
/**
|
|
985
|
+
* Obtain a native promise for a job
|
|
986
|
+
*
|
|
987
|
+
* While jobs have the same interface as native promises, there are occasionally
|
|
988
|
+
* reasons to just use one directly. (Like when Uneventful uses this function
|
|
989
|
+
* to implement jobs' promise methods!)
|
|
990
|
+
*
|
|
991
|
+
* @param job Optional: the job to get a native promise for. If none is given,
|
|
992
|
+
* the active job is used.
|
|
993
|
+
*
|
|
994
|
+
* @returns A {@link Promise} that resolves or rejects according to whether the
|
|
995
|
+
* job returns or throws. If the job is canceled, the promise is rejected with
|
|
996
|
+
* a {@link CancelError}.
|
|
997
|
+
*
|
|
998
|
+
* @category Jobs
|
|
999
|
+
*/
|
|
1000
|
+
declare function nativePromise<T>(job?: Job<T>): Promise<T>;
|
|
1001
|
+
/**
|
|
1002
|
+
* Return a new {@link Job}. If *either* a parent parameter or stop function
|
|
1003
|
+
* are given, the new job is linked to the parent.
|
|
1004
|
+
*
|
|
1005
|
+
* @param parent The parent job to which the new job should be attached.
|
|
1006
|
+
* Defaults to the currently-active job if none given (assuming a stop
|
|
1007
|
+
* parameter is provided).
|
|
1008
|
+
*
|
|
1009
|
+
* @param stop The function to call to destroy the nested job. Defaults to the
|
|
1010
|
+
* {@link Job.end} method of the new job if none is given (assuming a parent
|
|
1011
|
+
* parameter is provided).
|
|
1012
|
+
*
|
|
1013
|
+
* @returns A new job. The job is linked/nested if any arguments are given,
|
|
1014
|
+
* or a detached (parentless) job otherwise.
|
|
1015
|
+
*
|
|
1016
|
+
* @category Jobs
|
|
1017
|
+
*/
|
|
1018
|
+
declare const makeJob: <T, R = unknown>(parent?: Job<R>, stop?: CleanupFn<R>) => Job<T>;
|
|
1019
|
+
/**
|
|
1020
|
+
* A special {@link Job} with no parents, that can be used to create standalone
|
|
1021
|
+
* jobs. detached.start() returns a new detached job, detached.run() can be
|
|
1022
|
+
* used to run code that expects to create a child job, and detached.bind() can
|
|
1023
|
+
* wrap a function to work without a parent job.
|
|
1024
|
+
*
|
|
1025
|
+
* (Note that in all cases, a child job of `detached` *must* be stopped
|
|
1026
|
+
* explicitly, or it may "run" forever, never running its cleanup callbacks.)
|
|
1027
|
+
*
|
|
1028
|
+
* The detached job has a few special features and limitations:
|
|
1029
|
+
*
|
|
1030
|
+
* - It can't be ended, thrown, return()ed, etc. -- you'll get an error
|
|
1031
|
+
*
|
|
1032
|
+
* - It can't have any cleanup functions added: no do, must, onError, etc., and
|
|
1033
|
+
* thus also can't have any native promise, abort signal, etc. used. You can
|
|
1034
|
+
* call its release() method, but nothing will actually be registered and the
|
|
1035
|
+
* returned callback is a no-op.
|
|
1036
|
+
*
|
|
1037
|
+
* - Unhandled errors from jobs without parents (and errors from *any* job's
|
|
1038
|
+
* cleanup functions) are sent to the detached job for handling. This means
|
|
1039
|
+
* whatever you set as the detached job's .{@link Job.asyncCatch asyncCatch}()
|
|
1040
|
+
* handler will receive them. (Its default is Promise.reject, causing an
|
|
1041
|
+
* unhandled promise rejection.)
|
|
1042
|
+
*
|
|
1043
|
+
* @category Jobs
|
|
1044
|
+
*/
|
|
1045
|
+
declare const detached: Job<unknown>;
|
|
1046
|
+
|
|
1047
|
+
/**
|
|
1048
|
+
* Convert a (possible) promise to something you can `yield *to()` in a job
|
|
1049
|
+
*
|
|
1050
|
+
* Much like `await valueOrPromiseLike` in an async function, using `yield
|
|
1051
|
+
* *to(valueOrPromiseLike)` in a {@link Job}'s generator function will return
|
|
1052
|
+
* the value or the result of the promise/promise-like object.
|
|
1053
|
+
*
|
|
1054
|
+
* @category Scheduling
|
|
1055
|
+
*/
|
|
1056
|
+
declare function to<T>(p: Promise<T> | PromiseLike<T> | T): Yielding<T>;
|
|
1057
|
+
/**
|
|
1058
|
+
* Pause the job for the specified time in ms, e.g. `yield *sleep(1000)` to wait
|
|
1059
|
+
* one second.
|
|
1060
|
+
*
|
|
1061
|
+
* @category Scheduling
|
|
1062
|
+
*/
|
|
1063
|
+
declare function sleep(ms: number): Yielding<void>;
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* The result type returned from calls to {@link Each}.next()
|
|
1067
|
+
*
|
|
1068
|
+
* @category Types and Interfaces
|
|
1069
|
+
*/
|
|
1070
|
+
type EachResult<T> = {
|
|
1071
|
+
/** The value provided by the source being iterated */
|
|
1072
|
+
item: T;
|
|
1073
|
+
/**
|
|
1074
|
+
* A suspend callback that must be `yield`-ed before the next call to the
|
|
1075
|
+
* iterator's .next() method. (That is, you must `yield next` it exactly once
|
|
1076
|
+
* per loop pass. See {@link each}() for more details.)
|
|
1077
|
+
*/
|
|
1078
|
+
next: Suspend<void>;
|
|
1079
|
+
};
|
|
1080
|
+
/**
|
|
1081
|
+
* The iterable returned by `yield *` {@link each}()
|
|
1082
|
+
*
|
|
1083
|
+
* @category Types and Interfaces
|
|
1084
|
+
*/
|
|
1085
|
+
type Each<T> = IterableIterator<EachResult<T>>;
|
|
1086
|
+
/**
|
|
1087
|
+
* Asynchronously iterate over an event source
|
|
1088
|
+
*
|
|
1089
|
+
* Usage:
|
|
1090
|
+
*
|
|
1091
|
+
* ```ts
|
|
1092
|
+
* for (const {item: event, next} of yield *each(mouseMove)) {
|
|
1093
|
+
* console.log(event.clientX, event.clientY);
|
|
1094
|
+
* yield next; // required exactly once per iteration, even/w continue!
|
|
1095
|
+
* }
|
|
1096
|
+
* ```
|
|
1097
|
+
*
|
|
1098
|
+
* each(eventSource) yield-returns an iterator of `{item, next}` pairs. The
|
|
1099
|
+
* item is the data supplied by the event source, and `next` is a
|
|
1100
|
+
* {@link Suspend}\<void\> that advances the iterator to the next item. It
|
|
1101
|
+
* *must* be yielded exactly once per loop iteration. If you use `continue` to
|
|
1102
|
+
* shortcut the loop body, you must `yield next` *before* doing so.
|
|
1103
|
+
*
|
|
1104
|
+
* The for-loop will end if the source ends, errors, or is canceled. The source
|
|
1105
|
+
* is paused while the loop body is running, and resumed when the `yield next`
|
|
1106
|
+
* happens. If events arrive anyway (e.g. because the source doesn't support
|
|
1107
|
+
* pausing), they will be ignored unless you pipe the source through the
|
|
1108
|
+
* {@link slack}() operator to provide a buffer. If the for-loop is exited
|
|
1109
|
+
* early for any reason (or the iterator's `.return()` is called), the source is
|
|
1110
|
+
* unsubscribed and the iteration ended.
|
|
1111
|
+
*
|
|
1112
|
+
* @category Stream Consumers
|
|
1113
|
+
*/
|
|
1114
|
+
declare function each<T>(src: Stream<T>): Yielding<Each<T>>;
|
|
1115
|
+
/**
|
|
1116
|
+
* An object that can be waited on with `yield *until()`, by calling its
|
|
1117
|
+
* "uneventful.until" method. (This mostly exists to allow Signals to optimize
|
|
1118
|
+
* their until() implementation, but is also open for extensions.)
|
|
1119
|
+
*
|
|
1120
|
+
* @category Types and Interfaces
|
|
1121
|
+
*/
|
|
1122
|
+
interface UntilMethod<T> {
|
|
1123
|
+
/** Return an async op to resume once a truthy value is available */
|
|
1124
|
+
"uneventful.until"(): Yielding<T>;
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* An object that can be waited on with `yield *next()`, by calling its
|
|
1128
|
+
* "uneventful.next" method. (This mostly exists to allow Signals to optimize
|
|
1129
|
+
* their next() implementation, but is also open for extensions.)
|
|
1130
|
+
*
|
|
1131
|
+
* @category Types and Interfaces
|
|
1132
|
+
*/
|
|
1133
|
+
interface NextMethod<T> {
|
|
1134
|
+
/** Return an async op to resume with the "next" (i.e. not current) value produced */
|
|
1135
|
+
"uneventful.next"(): Yielding<T>;
|
|
1136
|
+
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Wait for and return the next truthy value (or error) from a data source (when
|
|
1139
|
+
* processed with `yield *` within a {@link Job}).
|
|
1140
|
+
*
|
|
1141
|
+
* This differs from {@link next}() in that it waits for the next "truthy" value
|
|
1142
|
+
* (i.e., not null, false, zero, empty string, etc.), and when used with signals
|
|
1143
|
+
* or a signal-using function, it can resume *immediately* if the result is
|
|
1144
|
+
* already truthy. (It also supports zero-argument signal-using functions,
|
|
1145
|
+
* automatically wrapping them with {@link cached}(), as the common use case for
|
|
1146
|
+
* until() is to wait for an arbitrary condition to be satisfied.)
|
|
1147
|
+
*
|
|
1148
|
+
* @param source The source to wait on, which can be:
|
|
1149
|
+
* - An object with an `"uneventful.until"` method returning a {@link Yielding}
|
|
1150
|
+
* (in which case the result will be the the result of calling that method)
|
|
1151
|
+
* - A {@link Signal}, or a zero-argument function returning a value based on
|
|
1152
|
+
* signals (in which case the job resumes as soon as the result is truthy,
|
|
1153
|
+
* perhaps immediately)
|
|
1154
|
+
* - A {@link Source} (in which case the job resumes on the next truthy value
|
|
1155
|
+
* it produces
|
|
1156
|
+
*
|
|
1157
|
+
* (Note: if the supplied source is a function with a non-zero `.length`, it is
|
|
1158
|
+
* assumed to be a {@link Source}.)
|
|
1159
|
+
*
|
|
1160
|
+
* @returns a Yieldable that when processed with `yield *` in a job, will return
|
|
1161
|
+
* the triggered event, or signal value. An error is thrown if event stream
|
|
1162
|
+
* throws or closes early, or the signal throws.
|
|
1163
|
+
*
|
|
1164
|
+
* @category Signals
|
|
1165
|
+
* @category Scheduling
|
|
1166
|
+
*/
|
|
1167
|
+
declare function until<T>(source: UntilMethod<T> | Stream<T> | (() => T)): Yielding<T>;
|
|
1168
|
+
/**
|
|
1169
|
+
* Wait for and return the next value (or error) from a data source (when
|
|
1170
|
+
* processed with `yield *` within a {@link Job}).
|
|
1171
|
+
*
|
|
1172
|
+
* This differs from {@link until}() in that it waits for the *next* value
|
|
1173
|
+
* (truthy or not!), and it never resumes immediately for signals, but instead
|
|
1174
|
+
* waits for the signal to *change*. (Also, it does not support zero-argument
|
|
1175
|
+
* functions, unless you wrap them with {@link cached}() first.)
|
|
1176
|
+
*
|
|
1177
|
+
* @param source The source to wait on, which can be:
|
|
1178
|
+
* - An object with an `"uneventful.next"` method returning a {@link Yielding}
|
|
1179
|
+
* (in which case the result will be the the result of calling that method)
|
|
1180
|
+
* - A {@link Signal} or {@link Source} (in which case the job resumes on the
|
|
1181
|
+
* next value it produces)
|
|
1182
|
+
*
|
|
1183
|
+
* (Note: if the supplied source is a function with a non-zero `.length`, it is
|
|
1184
|
+
* assumed to be a {@link Source}.)
|
|
1185
|
+
*
|
|
1186
|
+
* @returns a Yieldable that when processed with `yield *` in a job, will return
|
|
1187
|
+
* the triggered event, or signal value. An error is thrown if event stream
|
|
1188
|
+
* throws or closes early, or the signal throws.
|
|
1189
|
+
*
|
|
1190
|
+
* @category Stream Consumers
|
|
1191
|
+
* @category Scheduling
|
|
1192
|
+
*/
|
|
1193
|
+
declare function next<T>(source: NextMethod<T> | Stream<T>): Yielding<T>;
|
|
1194
|
+
/**
|
|
1195
|
+
* Run a {@link restarting}() callback for each value produced by a source.
|
|
1196
|
+
*
|
|
1197
|
+
* With each event that occurs, any previous callback run is cleaned up before
|
|
1198
|
+
* the new one begins. (And the last run is cleaned up when the connection or
|
|
1199
|
+
* job ends.)
|
|
1200
|
+
*
|
|
1201
|
+
* This function is almost the exact opposite of {@link each}(), in that the
|
|
1202
|
+
* stream is never paused (unless you do so manually via a throttle or inlet),
|
|
1203
|
+
* and if the "loop body" (callback job) is still running when a new value
|
|
1204
|
+
* arrives, forEach() restarts the job instead of dropping the value.
|
|
1205
|
+
*
|
|
1206
|
+
* @param src An event source (i.e. a {@link Source} or {@link Signal})
|
|
1207
|
+
* @param sink A callback that receives values from the source
|
|
1208
|
+
* @param inlet An optional throttle or inlet that will be used to pause the
|
|
1209
|
+
* source (if it's a signal or supports backpressure)
|
|
1210
|
+
* @returns a {@link Connection} that can be used to detect the stream
|
|
1211
|
+
* end/error, or ended to close it early.
|
|
1212
|
+
*
|
|
1213
|
+
* @category Stream Consumers
|
|
1214
|
+
*/
|
|
1215
|
+
declare function forEach<T>(src: Stream<T>, sink: Sink<T>, inlet?: Inlet): Connection;
|
|
1216
|
+
/**
|
|
1217
|
+
* When called without a source, return a callback suitable for use w/{@link pipe}().
|
|
1218
|
+
* e.g.:
|
|
1219
|
+
*
|
|
1220
|
+
* ```ts
|
|
1221
|
+
* pipe(someSource, ..., forEach(v => { doSomething(v); }), optionalInlet));
|
|
1222
|
+
* ```
|
|
1223
|
+
*
|
|
1224
|
+
*/
|
|
1225
|
+
declare function forEach<T>(sink: Sink<T>, inlet?: Inlet): (src: Stream<T>) => Connection;
|
|
1226
|
+
|
|
1227
|
+
/**
|
|
1228
|
+
* A decorator function that supports both TC39 and "legacy" decorator protocols
|
|
1229
|
+
*
|
|
1230
|
+
* @template F the type of method this decorator can decorate. If the method
|
|
1231
|
+
* doesn't conform to this type, compile-time type checks will fail.
|
|
1232
|
+
*
|
|
1233
|
+
* @category Types and Interfaces
|
|
1234
|
+
*/
|
|
1235
|
+
type GenericMethodDecorator<F extends AnyFunction> = {
|
|
1236
|
+
/** TC39 Method Decorator @hidden */
|
|
1237
|
+
(fn: F, ctx?: {
|
|
1238
|
+
kind: "method";
|
|
1239
|
+
}): F;
|
|
1240
|
+
/** Legacy Method Decorator @hidden */
|
|
1241
|
+
(proto: object, name: string | symbol, desc?: {
|
|
1242
|
+
value?: F;
|
|
1243
|
+
}): void;
|
|
1244
|
+
};
|
|
1245
|
+
/**
|
|
1246
|
+
* The interface provided by {@link rule}, and other {@link rule.factory}()
|
|
1247
|
+
* functions.
|
|
1248
|
+
*
|
|
1249
|
+
* @category Types and Interfaces
|
|
1250
|
+
*/
|
|
1251
|
+
interface RuleFactory {
|
|
1252
|
+
/**
|
|
1253
|
+
* @inheritdoc rule factory tied to a specific scheduler. See {@link rule} for
|
|
1254
|
+
* more details.
|
|
1255
|
+
*/
|
|
1256
|
+
(fn: (stop: DisposeFn) => OptionalCleanup): DisposeFn;
|
|
1257
|
+
/**
|
|
1258
|
+
* Stop the currently-executing rule, or throw an error if no rule is
|
|
1259
|
+
* currently running.
|
|
1260
|
+
*/
|
|
1261
|
+
stop(): void;
|
|
1262
|
+
/**
|
|
1263
|
+
* Observe a condition and apply an action.
|
|
1264
|
+
*
|
|
1265
|
+
* This is roughly equivalent to `rule(() => { if (condition()) return
|
|
1266
|
+
* action(); })`, except that the rule is *only* rerun if the `action`'s
|
|
1267
|
+
* dependencies change, *or* the truthiness of `condition()` changes. It
|
|
1268
|
+
* will *not* be re-run if only the dependencies of `condition()` have
|
|
1269
|
+
* changed, without affecting its truthiness.
|
|
1270
|
+
*
|
|
1271
|
+
* This behavior can be important for rules that nest other rules, have
|
|
1272
|
+
* cleanups, fire off tasks, etc., as it may be wasteful to constantly tear
|
|
1273
|
+
* them down and set them back up if the enabling condition is a calculation
|
|
1274
|
+
* with frequently-changing dependencies.
|
|
1275
|
+
*/
|
|
1276
|
+
if(condition: () => any, action: () => OptionalCleanup): DisposeFn;
|
|
1277
|
+
/**
|
|
1278
|
+
* Decorate a method to behave as a rule, e.g.
|
|
1279
|
+
*
|
|
1280
|
+
* ```ts
|
|
1281
|
+
* const animate = rule.factory(requestAnimationFrame);
|
|
1282
|
+
*
|
|
1283
|
+
* class Draggable {
|
|
1284
|
+
* @animate.method
|
|
1285
|
+
* trackPosition(handleTop: number, handleLeft: number) {
|
|
1286
|
+
* const {clientX, clientY} = lastMouseEvent();
|
|
1287
|
+
* this.element.style.top = `${clientY - handleTop}px`;
|
|
1288
|
+
* this.element.style.left = `${clientX - handleLeft}px`;
|
|
1289
|
+
* }
|
|
1290
|
+
* }
|
|
1291
|
+
*
|
|
1292
|
+
* // Start running the method in an animation frame for every change to
|
|
1293
|
+
* // lastMouseEvent, until the current job ends:
|
|
1294
|
+
* someDraggable.trackPosition(top, left);
|
|
1295
|
+
* ```
|
|
1296
|
+
*
|
|
1297
|
+
* Each time it's (explicitly) called, the decorated method will start a new
|
|
1298
|
+
* rule, which will repeatedly run the method body (with the original
|
|
1299
|
+
* arguments and `this`) whenever its dependencies change, according to the
|
|
1300
|
+
* schedule defined by the rule factory. (So e.g. `@rule.method` will
|
|
1301
|
+
* update on the microtask after a change, etc.)
|
|
1302
|
+
*
|
|
1303
|
+
* The decorated method will always return a {@link DisposeFn} to let you
|
|
1304
|
+
* explicitly stop the rule before the current job end. But if the original
|
|
1305
|
+
* method body doesn't return a dispose function of its own, TypeScript will
|
|
1306
|
+
* consider the method to return void, unless you explicitly declare its
|
|
1307
|
+
* return type to be `DisposeFn | void`.
|
|
1308
|
+
*
|
|
1309
|
+
* Also note that since rule methods can accept arbitrary parameters, they
|
|
1310
|
+
* do not receive a `stop` parameter, and must therefore use {@link
|
|
1311
|
+
* RuleFactory.stop rule.stop}() if they wish to terminate themselves.
|
|
1312
|
+
*/
|
|
1313
|
+
readonly method: GenericMethodDecorator<(...args: any[]) => OptionalCleanup>;
|
|
1314
|
+
/**
|
|
1315
|
+
* Return a rule factory for the given scheduling function, that you can
|
|
1316
|
+
* then use to make rules that run in a specific time frame.
|
|
1317
|
+
*
|
|
1318
|
+
* ```ts
|
|
1319
|
+
* // `animate` will now create rules that run during animation fames
|
|
1320
|
+
* const animate = rule.factory(requestAnimationFrame);
|
|
1321
|
+
*
|
|
1322
|
+
* animate(() => {
|
|
1323
|
+
* // ... do stuff in an animation frame when signals used here change
|
|
1324
|
+
* })
|
|
1325
|
+
* ```
|
|
1326
|
+
*
|
|
1327
|
+
* (In addition to being callable, the returned function is also a
|
|
1328
|
+
* {@link RuleFactory}, and thus has a `.method` decorator, `.if()` method,
|
|
1329
|
+
* and so on.)
|
|
1330
|
+
*
|
|
1331
|
+
* @param scheduleFn A single-argument scheduling function (such as
|
|
1332
|
+
* requestAnimationFrame, setImmediate, or queueMicrotask). The rule
|
|
1333
|
+
* scheduler will call it from time to time with a single callback. The
|
|
1334
|
+
* scheduling function should then arrange for that callback to be invoked
|
|
1335
|
+
* *once* at some future point, when it is the desired time for all pending
|
|
1336
|
+
* rules on that scheduler to run.
|
|
1337
|
+
*
|
|
1338
|
+
* @returns A {@link RuleFactory}, like {@link rule}. If called with the
|
|
1339
|
+
* same scheduling function more than once, it returns the same factory.
|
|
1340
|
+
*
|
|
1341
|
+
*/
|
|
1342
|
+
factory(scheduleFn: (cb: () => unknown) => unknown): RuleFactory;
|
|
1343
|
+
}
|
|
1344
|
+
/**
|
|
1345
|
+
* Subscribe a function to run every time certain values change.
|
|
1346
|
+
*
|
|
1347
|
+
* The function is run asynchronously, first after being created, then again
|
|
1348
|
+
* after there are changes in any of the values or cached functions it read
|
|
1349
|
+
* during its previous run.
|
|
1350
|
+
*
|
|
1351
|
+
* The created subscription is tied to the currently-active job (which may be
|
|
1352
|
+
* another rule). So when that job is ended or restarted, the rule will be
|
|
1353
|
+
* terminated automatically. You can also terminate it early by calling the
|
|
1354
|
+
* "stop" function that is both passed to the rule function and returned by
|
|
1355
|
+
* `rule()`.
|
|
1356
|
+
*
|
|
1357
|
+
* Note: this function will throw an error if called without an active job. If
|
|
1358
|
+
* you need a standalone rule, use {@link detached}.run to wrap the
|
|
1359
|
+
* call to rule.
|
|
1360
|
+
*
|
|
1361
|
+
* @param fn The function that will be run each time its dependencies change.
|
|
1362
|
+
* The function will be run in a restarted job each time, with any resources
|
|
1363
|
+
* used by the previous run being cleaned up. The function is passed a single
|
|
1364
|
+
* argument: a function that can be called to terminate the rule. The function
|
|
1365
|
+
* should return a cleanup function or void.
|
|
1366
|
+
*
|
|
1367
|
+
* @returns A function that can be called to terminate the rule.
|
|
1368
|
+
*
|
|
1369
|
+
* @category Signals
|
|
1370
|
+
*/
|
|
1371
|
+
declare const rule: ((action: (stop: DisposeFn) => OptionalCleanup) => DisposeFn) & RuleFactory;
|
|
1372
|
+
/**
|
|
1373
|
+
* Synchronously run any pending rules tied to a specific schedule.
|
|
1219
1374
|
*
|
|
1220
|
-
*
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1223
|
-
* *(): Yielding<number> {}` for a generator function that ultimately returns a
|
|
1224
|
-
* number.)
|
|
1375
|
+
* (Note: "pending" rules are ones with at least one changed ancestor
|
|
1376
|
+
* dependency; this doesn't mean they will actually *do* anything, since
|
|
1377
|
+
* intermediate cached() function results might end up unchanged.)
|
|
1225
1378
|
*
|
|
1226
|
-
*
|
|
1227
|
-
*
|
|
1228
|
-
*
|
|
1379
|
+
* You should normally only need to call this when you need to *force*
|
|
1380
|
+
* side-effects to occur within a specific *synchronous* timeframe, e.g. if
|
|
1381
|
+
* rules need to be able to cancel a synchronous event or continue an IndexedDB
|
|
1382
|
+
* transaction. (Otherwise, this is really only useful for testing.)
|
|
1229
1383
|
*
|
|
1230
|
-
* @
|
|
1231
|
-
* @
|
|
1384
|
+
* @param scheduleFn The scheduler used to create the rule factory you wish to
|
|
1385
|
+
* run pending rules for. If not given, the default {@link rule}() factory is
|
|
1386
|
+
* targeted.
|
|
1232
1387
|
*
|
|
1388
|
+
* @category Signals
|
|
1389
|
+
*/
|
|
1390
|
+
declare function runRules(scheduleFn?: (cb: () => unknown) => unknown): void;
|
|
1391
|
+
|
|
1392
|
+
/**
|
|
1393
|
+
* Error indicating a rule has attempted to write a value it indirectly
|
|
1394
|
+
* depends on, or which has already been read by another rule in the current
|
|
1395
|
+
* batch. (Also thrown when a cached function attempts to write a value at all,
|
|
1396
|
+
* directly or inidirectly.)
|
|
1233
1397
|
*
|
|
1234
|
-
* @category
|
|
1398
|
+
* @category Errors
|
|
1235
1399
|
*/
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
* An iterator suitable for use with `yield *` (in a job generator) to
|
|
1239
|
-
* obtain a result.
|
|
1240
|
-
*
|
|
1241
|
-
* @category Obtaining Results
|
|
1242
|
-
*/
|
|
1243
|
-
[Symbol.iterator](): JobIterator<T>;
|
|
1244
|
-
};
|
|
1400
|
+
declare class WriteConflict extends Error {
|
|
1401
|
+
}
|
|
1245
1402
|
/**
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1403
|
+
* Error indicating a rule has attempted to write a value it directly depends
|
|
1404
|
+
* on, or a cached function has called itself, directly or indirectly.
|
|
1248
1405
|
*
|
|
1249
|
-
* @category
|
|
1406
|
+
* @category Errors
|
|
1250
1407
|
*/
|
|
1251
|
-
|
|
1408
|
+
declare class CircularDependency extends Error {
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1252
1411
|
/**
|
|
1253
|
-
* An
|
|
1412
|
+
* An observable value, as a zero-argument callable with extra methods.
|
|
1254
1413
|
*
|
|
1255
|
-
*
|
|
1256
|
-
*
|
|
1257
|
-
*
|
|
1414
|
+
* In addition to being callable, signals also offer a `.value` getter, and
|
|
1415
|
+
* implement the standard JS methods `.toString()`, `.valueOf()`, and
|
|
1416
|
+
* `.toJSON()` in such a way that they reflect the signal's contents rather than
|
|
1417
|
+
* the signal itself.
|
|
1258
1418
|
*
|
|
1259
|
-
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1419
|
+
* Signals also implement the {@link Source} interface, and can thus be
|
|
1420
|
+
* subscribed to. Subscribers receive the current value first, and then any
|
|
1421
|
+
* changes thereafter. They can be waited on by {@link until}(), in which case
|
|
1422
|
+
* the calling job resumes when the signal's value is truthy.
|
|
1262
1423
|
*
|
|
1263
|
-
*
|
|
1264
|
-
*
|
|
1265
|
-
*
|
|
1266
|
-
* disposed of -- in which case you should probably just `yield *` to a
|
|
1267
|
-
* {@link start}(), instead of yielding a Suspend!
|
|
1424
|
+
* You can also transform a signal to a {@link Writable} by calling its
|
|
1425
|
+
* .{@link Signal.withSet withSet}() method, or create a writable value using
|
|
1426
|
+
* {@link value}().
|
|
1268
1427
|
*
|
|
1269
1428
|
* @category Types and Interfaces
|
|
1270
1429
|
*/
|
|
1271
|
-
|
|
1430
|
+
interface Signal<T> extends SignalSource<T>, UntilMethod<T> {
|
|
1431
|
+
/**
|
|
1432
|
+
* The current value
|
|
1433
|
+
*
|
|
1434
|
+
* @category Reading
|
|
1435
|
+
*/
|
|
1436
|
+
readonly value: T;
|
|
1437
|
+
/** Current value @hidden */
|
|
1438
|
+
valueOf(): T;
|
|
1439
|
+
/** Current value as a string @hidden */
|
|
1440
|
+
toString(): string;
|
|
1441
|
+
/** The current value @hidden */
|
|
1442
|
+
toJSON(): T;
|
|
1443
|
+
/**
|
|
1444
|
+
* Get the signal's current value, without adding the signal as a dependency
|
|
1445
|
+
*
|
|
1446
|
+
* (This is exactly equivalent to calling {@link peek}(signal), and exists
|
|
1447
|
+
* here mainly for interop with other signal frameworks.)
|
|
1448
|
+
*
|
|
1449
|
+
* @category Reading */
|
|
1450
|
+
peek(): T;
|
|
1451
|
+
/** Get a read-only version of this signal @category Reading */
|
|
1452
|
+
asReadonly(): Signal<T>;
|
|
1453
|
+
/** New writable signal with a custom setter @category Writing */
|
|
1454
|
+
withSet(set: (v: T) => unknown): Writable<T>;
|
|
1455
|
+
/** @hidden */
|
|
1456
|
+
"uneventful.until"(): Yielding<T>;
|
|
1457
|
+
}
|
|
1272
1458
|
/**
|
|
1273
|
-
* A
|
|
1274
|
-
*
|
|
1275
|
-
* A request is like the inverse of a Promise: instead of waiting for it to
|
|
1276
|
-
* settle, you settle it by passing it to {@link resolve}() or {@link reject}().
|
|
1277
|
-
* Like a promise, it can only be settled once: resolving or rejecting it after
|
|
1278
|
-
* it's already resolved or rejected has no effect.
|
|
1279
|
-
*
|
|
1280
|
-
* Settling a request will cause the requesting job (or other code) to resume
|
|
1281
|
-
* immediately, running up to its next suspension or termination. (Unless it's
|
|
1282
|
-
* settled while the requesting job is already on the call stack, in which case
|
|
1283
|
-
* the job will be resumed later.)
|
|
1284
|
-
*
|
|
1285
|
-
* (Note: do not call a Request directly, unless you want your code to maybe
|
|
1286
|
-
* break in future. Use resolve or reject (or {@link resolver}() or
|
|
1287
|
-
* {@link rejecter}()), as 1) they'll shield you from future changes to this
|
|
1288
|
-
* protocol and 2) they have better type checking anyway.)
|
|
1459
|
+
* A {@link Signal} with a {@link Writable.set | .set()} method and writable
|
|
1460
|
+
* {@link Writable.value | .value} property.
|
|
1289
1461
|
*
|
|
1290
1462
|
* @category Types and Interfaces
|
|
1291
1463
|
*/
|
|
1292
|
-
interface
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1464
|
+
interface Writable<T> extends Signal<T> {
|
|
1465
|
+
/**
|
|
1466
|
+
* Set the current value. (Note: this is a bound method so it can be used
|
|
1467
|
+
* as a callback.)
|
|
1468
|
+
*
|
|
1469
|
+
* @category Writing
|
|
1470
|
+
*/
|
|
1471
|
+
readonly set: (val: T) => void;
|
|
1472
|
+
get value(): T;
|
|
1473
|
+
/** Set the current value */
|
|
1474
|
+
set value(val: T);
|
|
1296
1475
|
}
|
|
1297
1476
|
/**
|
|
1298
|
-
* A
|
|
1477
|
+
* A writable signal that can be set to either a value or an expression.
|
|
1299
1478
|
*
|
|
1300
|
-
*
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1303
|
-
*
|
|
1479
|
+
* Like a spreadsheet cell, a configurable signal can contain either a value or
|
|
1480
|
+
* a formula. If you .set() a value or change the .value property of the
|
|
1481
|
+
* signal, the formula is cleared. Conversely, if you set a formula with
|
|
1482
|
+
* .setf(), then the value is calculated using that formula from then on, until
|
|
1483
|
+
* another formula is set, or the value is changed directly again.
|
|
1304
1484
|
*
|
|
1305
1485
|
* @category Types and Interfaces
|
|
1306
1486
|
*/
|
|
1307
|
-
|
|
1308
|
-
|
|
1487
|
+
interface Configurable<T> extends Writable<T> {
|
|
1488
|
+
/**
|
|
1489
|
+
* Set a formula that will be used to calculate the signal's value. If it
|
|
1490
|
+
* uses the value of other signals, this signal's value will be recalculated
|
|
1491
|
+
* when they change.
|
|
1492
|
+
*
|
|
1493
|
+
* @category Writing
|
|
1494
|
+
*/
|
|
1495
|
+
setf(expr: () => T): this;
|
|
1496
|
+
}
|
|
1309
1497
|
/**
|
|
1310
|
-
*
|
|
1498
|
+
* Create a {@link Configurable} signal with the given inital value
|
|
1311
1499
|
*
|
|
1312
|
-
* @category
|
|
1500
|
+
* @category Signals
|
|
1313
1501
|
*/
|
|
1314
|
-
declare function
|
|
1502
|
+
declare function value<T>(val?: T): Configurable<T>;
|
|
1315
1503
|
/**
|
|
1316
|
-
*
|
|
1504
|
+
* Create a cached version of a function. The returned callable is also a
|
|
1505
|
+
* {@link Signal}.
|
|
1317
1506
|
*
|
|
1318
|
-
*
|
|
1507
|
+
* Note: If the supplied function has a non-zero `.length` (i.e., it explicitly
|
|
1508
|
+
* takes arguments), it is assumed to be a {@link Source}, and the second
|
|
1509
|
+
* calling signature below will apply, even if TypeScript doesn't see it that
|
|
1510
|
+
* way!)
|
|
1319
1511
|
*
|
|
1320
|
-
* @category
|
|
1512
|
+
* @category Signals
|
|
1321
1513
|
*/
|
|
1322
|
-
declare function
|
|
1514
|
+
declare function cached<T>(compute: () => T): Signal<T>;
|
|
1323
1515
|
/**
|
|
1324
|
-
*
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1327
|
-
*
|
|
1328
|
-
* to implement jobs' promise methods!)
|
|
1516
|
+
* If the supplied function has a non-zero `.length` (i.e., it explicitly takes
|
|
1517
|
+
* arguments), it is assumed to be a {@link Source}, and the second argument is
|
|
1518
|
+
* a default value for the created signal to use as default value until the
|
|
1519
|
+
* source produces a value.
|
|
1329
1520
|
*
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1521
|
+
* The source will be subscribed *only* while the signal is subscribed as a
|
|
1522
|
+
* stream, or observed (directly or indirectly) by a rule. While subscribed,
|
|
1523
|
+
* the signal will update itself with the most recent value produced by the
|
|
1524
|
+
* source, triggering rules or events as appropriate if the value changes. When
|
|
1525
|
+
* the signal is once again unobserved (or if the source ends without an error),
|
|
1526
|
+
* its value will revert to the supplied default.
|
|
1332
1527
|
*
|
|
1333
|
-
*
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1528
|
+
* If the source ends *with* an error, however, then the cached function will
|
|
1529
|
+
* throw that error whenever called, until/unless it becomes unobserved again.
|
|
1530
|
+
* (And thus reverts to the default value once more.)
|
|
1336
1531
|
*
|
|
1337
|
-
* @
|
|
1532
|
+
* @param source A {@link Source} providing data which will become this signal's
|
|
1533
|
+
* value
|
|
1534
|
+
* @param defaultVal The value to use when the signal is unobserved or waiting for
|
|
1535
|
+
* the first item from the source.
|
|
1338
1536
|
*/
|
|
1339
|
-
declare function
|
|
1537
|
+
declare function cached<T>(source: Source<T>, defaultVal?: T): Signal<T>;
|
|
1538
|
+
declare function cached<T extends Signal<any>>(signal: T): T;
|
|
1340
1539
|
/**
|
|
1341
|
-
*
|
|
1342
|
-
*
|
|
1540
|
+
* Call a function without creating a dependency on any signals it reads. (Like
|
|
1541
|
+
* {@link Signal.peek}, but for any function with any arguments.)
|
|
1343
1542
|
*
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1346
|
-
* parameter is provided).
|
|
1543
|
+
* You can also pass in any arguments the function takes, and the function's
|
|
1544
|
+
* return value is returned.
|
|
1347
1545
|
*
|
|
1348
|
-
*
|
|
1349
|
-
*
|
|
1350
|
-
*
|
|
1546
|
+
* (Note: Typed overloads are not supported: TypeScript will use the function's
|
|
1547
|
+
* *last* overload for argument-typing purposes. If you need to call a function
|
|
1548
|
+
* with a specific overload, wrap the function with {@link action}() instead, and
|
|
1549
|
+
* then TypeScript will be able to detect which overload you're using.)
|
|
1351
1550
|
*
|
|
1352
|
-
* @returns
|
|
1353
|
-
* or a detached (parentless) job otherwise.
|
|
1551
|
+
* @returns The result of calling `fn(..args)`
|
|
1354
1552
|
*
|
|
1355
|
-
* @category
|
|
1553
|
+
* @category Signals
|
|
1356
1554
|
*/
|
|
1357
|
-
declare
|
|
1555
|
+
declare function peek<F extends PlainFunction>(fn: F, ...args: Parameters<F>): ReturnType<F>;
|
|
1358
1556
|
/**
|
|
1359
|
-
*
|
|
1360
|
-
* jobs. detached.start() returns a new detached job, detached.run() can be
|
|
1361
|
-
* used to run code that expects to create a child job, and detached.bind() can
|
|
1362
|
-
* wrap a function to work without a parent job.
|
|
1557
|
+
* Arrange for the current signal or rule to recalculate on demand
|
|
1363
1558
|
*
|
|
1364
|
-
*
|
|
1365
|
-
*
|
|
1559
|
+
* This lets you interop with systems that have a way to query a value and
|
|
1560
|
+
* subscribe to changes to it, but not directly produce a signal. (Such as
|
|
1561
|
+
* querying the DOM state and using a MutationObserver.)
|
|
1366
1562
|
*
|
|
1367
|
-
*
|
|
1563
|
+
* By calling this with a {@link Source} or {@link RecalcSource}, you arrange
|
|
1564
|
+
* for it to be subscribed, if and when the call occurs in a rule or a cached
|
|
1565
|
+
* function that's in use by a rule (directly or indirectly). When the source
|
|
1566
|
+
* emits a value, the signal machinery will invalidate the caching of the
|
|
1567
|
+
* function or rule, forcing a recalculation and subsequent rule reruns, if
|
|
1568
|
+
* applicable.
|
|
1368
1569
|
*
|
|
1369
|
-
*
|
|
1570
|
+
* Note: you should generally only call the 1-argument version of this function
|
|
1571
|
+
* with "static" sources - i.e. ones that won't change on every call. Otherwise,
|
|
1572
|
+
* you will end up creating new signals each time, subscribing and unsubscribing
|
|
1573
|
+
* on every call to recalcWhen().
|
|
1370
1574
|
*
|
|
1371
|
-
*
|
|
1372
|
-
*
|
|
1373
|
-
*
|
|
1374
|
-
* returned callback is a no-op.
|
|
1575
|
+
* If the source needs to reference some object, it's best to use the 2-argument
|
|
1576
|
+
* version (i.e. `recalcWhen(someObj, factory)`, where `factory` is a function
|
|
1577
|
+
* that takes `someObj` and returns a suitable {@link RecalcSource}.)
|
|
1375
1578
|
*
|
|
1376
|
-
*
|
|
1377
|
-
*
|
|
1378
|
-
*
|
|
1379
|
-
*
|
|
1380
|
-
*
|
|
1579
|
+
* @remarks
|
|
1580
|
+
* recalcWhen is specifically designed so that using it does not pull in any
|
|
1581
|
+
* part of Uneventful's signals framework, in the event a program doesn't
|
|
1582
|
+
* already use it. This means you can use it in library code to provide signal
|
|
1583
|
+
* compatibility, without adding bundle bloat to code that doesn't use signals.
|
|
1381
1584
|
*
|
|
1382
|
-
* @category
|
|
1585
|
+
* @category Signals
|
|
1383
1586
|
*/
|
|
1384
|
-
declare
|
|
1385
|
-
|
|
1587
|
+
declare function recalcWhen(src: RecalcSource): void;
|
|
1386
1588
|
/**
|
|
1387
|
-
*
|
|
1589
|
+
* Two-argument variant of recalcWhen
|
|
1388
1590
|
*
|
|
1389
|
-
*
|
|
1390
|
-
*
|
|
1391
|
-
*
|
|
1591
|
+
* In certain circumstances, you may wish to use recalcWhen with a source
|
|
1592
|
+
* related to some object. You could call recalcWhen with a closure, but that
|
|
1593
|
+
* would create and discard signals on every call. So this 2-argument version
|
|
1594
|
+
* lets you avoid that by allowing the use of an arbitrary object as a key,
|
|
1595
|
+
* along with a factory function to turn the key into a {@link RecalcSource}.
|
|
1392
1596
|
*
|
|
1393
|
-
* @
|
|
1597
|
+
* @param key an object to be used as a key
|
|
1598
|
+
*
|
|
1599
|
+
* @param factory a function that will be called with the key to obtain a
|
|
1600
|
+
* {@link RecalcSource}. (Note that this factory function must also be a static
|
|
1601
|
+
* function, not a closure, or the same memory thrash issue will occur!)
|
|
1394
1602
|
*/
|
|
1395
|
-
declare function
|
|
1603
|
+
declare function recalcWhen<T extends WeakKey>(key: T, factory: (key: T) => RecalcSource): void;
|
|
1396
1604
|
/**
|
|
1397
|
-
*
|
|
1398
|
-
*
|
|
1605
|
+
* Wrap a function (or decorate a method) so that signals it reads are not added
|
|
1606
|
+
* as dependencies to the current rule (if any). (Basically, it's shorthand for
|
|
1607
|
+
* wrapping the function or method body in a giant call to {@link peek}().)
|
|
1399
1608
|
*
|
|
1400
|
-
*
|
|
1609
|
+
* So, instead of writing an action function like this:
|
|
1610
|
+
*
|
|
1611
|
+
* ```ts
|
|
1612
|
+
* function outer(arg1, arg2) {
|
|
1613
|
+
* return peek(() => {
|
|
1614
|
+
* // reactive values used here will not be added to the running rule
|
|
1615
|
+
* })
|
|
1616
|
+
* }
|
|
1617
|
+
* ```
|
|
1618
|
+
* you can just write this:
|
|
1619
|
+
* ```ts
|
|
1620
|
+
* const outer = action((arg1, arg2) => {
|
|
1621
|
+
* // reactive values used here will not be added to the running rule
|
|
1622
|
+
* });
|
|
1623
|
+
* ```
|
|
1624
|
+
* or this:
|
|
1625
|
+
* ```ts
|
|
1626
|
+
* class Something {
|
|
1627
|
+
* @action // auto-detects TC39 or legacy decorators
|
|
1628
|
+
* someMethod(arg1) {
|
|
1629
|
+
* // reactive values used here will not be added to the running rule
|
|
1630
|
+
* }
|
|
1631
|
+
* }
|
|
1632
|
+
* ```
|
|
1633
|
+
*
|
|
1634
|
+
* @param fn The function to wrap. It can take any arguments or return value,
|
|
1635
|
+
* and overloads are supported. However, any non-standard properties the
|
|
1636
|
+
* function may have had will *not* be present on the wrapped function, even if
|
|
1637
|
+
* TypeScript will act as if they are!
|
|
1638
|
+
*
|
|
1639
|
+
* @returns A wrapped version of the function that passes through its arguments
|
|
1640
|
+
* to the original function, while running with dependency tracking suppressed
|
|
1641
|
+
* (as with {@link peek}()).
|
|
1642
|
+
*
|
|
1643
|
+
* @category Signals
|
|
1401
1644
|
*/
|
|
1402
|
-
declare function
|
|
1645
|
+
declare function action<F extends AnyFunction>(fn: F): F;
|
|
1646
|
+
/** @hidden TC39 Decorator protocol */
|
|
1647
|
+
declare function action<F extends AnyFunction>(fn: F, ctx: {
|
|
1648
|
+
kind: "method";
|
|
1649
|
+
}): F;
|
|
1650
|
+
/** @hidden Legacy Decorator protocol */
|
|
1651
|
+
declare function action<F extends AnyFunction, D extends {
|
|
1652
|
+
value?: F;
|
|
1653
|
+
}>(clsOrProto: any, name: string | symbol, desc: D): D;
|
|
1403
1654
|
|
|
1404
1655
|
/**
|
|
1405
1656
|
* A function that emits events, with a .source they're emitted from
|
|
@@ -1412,7 +1663,7 @@ interface Emitter<T> {
|
|
|
1412
1663
|
/** Call the emitter to emit events on its .source */
|
|
1413
1664
|
(val: T): void;
|
|
1414
1665
|
/** An event source that receives the events */
|
|
1415
|
-
source:
|
|
1666
|
+
source: Source<T>;
|
|
1416
1667
|
/** Close all current subscribers' connections */
|
|
1417
1668
|
end: () => void;
|
|
1418
1669
|
/** Close all current subscribers' connections with an error */
|
|
@@ -1435,7 +1686,7 @@ declare function emitter<T>(): Emitter<T>;
|
|
|
1435
1686
|
*
|
|
1436
1687
|
* @category Stream Producers
|
|
1437
1688
|
*/
|
|
1438
|
-
declare function empty():
|
|
1689
|
+
declare function empty(): Source<never>;
|
|
1439
1690
|
/**
|
|
1440
1691
|
* Convert an async iterable to an event source
|
|
1441
1692
|
*
|
|
@@ -1445,7 +1696,7 @@ declare function empty(): Producer<never>;
|
|
|
1445
1696
|
*
|
|
1446
1697
|
* @category Stream Producers
|
|
1447
1698
|
*/
|
|
1448
|
-
declare function fromAsyncIterable<T>(iterable: AsyncIterable<T>):
|
|
1699
|
+
declare function fromAsyncIterable<T>(iterable: AsyncIterable<T>): Source<T>;
|
|
1449
1700
|
/**
|
|
1450
1701
|
* Create an event source from an element, window, or other event target
|
|
1451
1702
|
*
|
|
@@ -1461,10 +1712,10 @@ declare function fromAsyncIterable<T>(iterable: AsyncIterable<T>): Producer<T>;
|
|
|
1461
1712
|
*
|
|
1462
1713
|
* @category Stream Producers
|
|
1463
1714
|
*/
|
|
1464
|
-
declare function fromDomEvent<T extends HTMLElement, K extends keyof HTMLElementEventMap>(target: T, type: K, options?: boolean | AddEventListenerOptions):
|
|
1465
|
-
declare function fromDomEvent<T extends Window, K extends keyof WindowEventMap>(target: T, type: K, options?: boolean | AddEventListenerOptions):
|
|
1466
|
-
declare function fromDomEvent<T extends Document, K extends keyof DocumentEventMap>(target: T, type: K, options?: boolean | AddEventListenerOptions):
|
|
1467
|
-
declare function fromDomEvent<T extends Event>(target: EventTarget, type: string, options?: boolean | AddEventListenerOptions):
|
|
1715
|
+
declare function fromDomEvent<T extends HTMLElement, K extends keyof HTMLElementEventMap>(target: T, type: K, options?: boolean | AddEventListenerOptions): Source<HTMLElementEventMap[K]>;
|
|
1716
|
+
declare function fromDomEvent<T extends Window, K extends keyof WindowEventMap>(target: T, type: K, options?: boolean | AddEventListenerOptions): Source<WindowEventMap[K]>;
|
|
1717
|
+
declare function fromDomEvent<T extends Document, K extends keyof DocumentEventMap>(target: T, type: K, options?: boolean | AddEventListenerOptions): Source<DocumentEventMap[K]>;
|
|
1718
|
+
declare function fromDomEvent<T extends Event>(target: EventTarget, type: string, options?: boolean | AddEventListenerOptions): Source<T>;
|
|
1468
1719
|
/**
|
|
1469
1720
|
* Convert an iterable to a synchronous event source
|
|
1470
1721
|
*
|
|
@@ -1474,7 +1725,7 @@ declare function fromDomEvent<T extends Event>(target: EventTarget, type: string
|
|
|
1474
1725
|
*
|
|
1475
1726
|
* @category Stream Producers
|
|
1476
1727
|
*/
|
|
1477
|
-
declare function fromIterable<T>(iterable: Iterable<T>):
|
|
1728
|
+
declare function fromIterable<T>(iterable: Iterable<T>): Source<T>;
|
|
1478
1729
|
/**
|
|
1479
1730
|
* Convert a Promise to an event source
|
|
1480
1731
|
*
|
|
@@ -1486,7 +1737,7 @@ declare function fromIterable<T>(iterable: Iterable<T>): Producer<T>;
|
|
|
1486
1737
|
*
|
|
1487
1738
|
* @category Stream Producers
|
|
1488
1739
|
*/
|
|
1489
|
-
declare function fromPromise<T>(promise: Promise<T> | PromiseLike<T> | T):
|
|
1740
|
+
declare function fromPromise<T>(promise: Promise<T> | PromiseLike<T> | T): Source<T>;
|
|
1490
1741
|
/**
|
|
1491
1742
|
* Create an event source from an arbitrary subscribe/unsubscribe function
|
|
1492
1743
|
*
|
|
@@ -1500,20 +1751,20 @@ declare function fromPromise<T>(promise: Promise<T> | PromiseLike<T> | T): Produ
|
|
|
1500
1751
|
*
|
|
1501
1752
|
* @category Stream Producers
|
|
1502
1753
|
*/
|
|
1503
|
-
declare function fromSubscribe<T>(subscribe: (cb: (val: T) => void) => DisposeFn):
|
|
1754
|
+
declare function fromSubscribe<T>(subscribe: (cb: (val: T) => void) => DisposeFn): Source<T>;
|
|
1504
1755
|
/**
|
|
1505
1756
|
* Create a source that emits a single given value
|
|
1506
1757
|
*
|
|
1507
1758
|
* @category Stream Producers
|
|
1508
1759
|
*/
|
|
1509
|
-
declare function fromValue<T>(val: T):
|
|
1760
|
+
declare function fromValue<T>(val: T): Source<T>;
|
|
1510
1761
|
/**
|
|
1511
1762
|
* Create an event source that issues a number every `ms` milliseconds (starting
|
|
1512
1763
|
* with 0 after the first interval passes).
|
|
1513
1764
|
*
|
|
1514
1765
|
* @category Stream Producers
|
|
1515
1766
|
*/
|
|
1516
|
-
declare function interval(ms: number):
|
|
1767
|
+
declare function interval(ms: number): Source<number>;
|
|
1517
1768
|
/**
|
|
1518
1769
|
* Create a dynamic source that is created each time it's subscribed
|
|
1519
1770
|
*
|
|
@@ -1524,7 +1775,7 @@ declare function interval(ms: number): Producer<number>;
|
|
|
1524
1775
|
*
|
|
1525
1776
|
* @category Stream Producers
|
|
1526
1777
|
*/
|
|
1527
|
-
declare function lazy<T>(factory: () =>
|
|
1778
|
+
declare function lazy<T>(factory: () => Stream<T>): Source<T>;
|
|
1528
1779
|
/**
|
|
1529
1780
|
* An {@link Emitter} with a ready() method, that only supports a single active
|
|
1530
1781
|
* subscriber. (Useful for testing stream operators and sinks.)
|
|
@@ -1549,7 +1800,7 @@ declare function mockSource<T>(): MockSource<T>;
|
|
|
1549
1800
|
*
|
|
1550
1801
|
* @category Stream Producers
|
|
1551
1802
|
*/
|
|
1552
|
-
declare function never():
|
|
1803
|
+
declare function never(): Source<never>;
|
|
1553
1804
|
/**
|
|
1554
1805
|
* Wrap a source to allow multiple subscribers to the same underlying stream
|
|
1555
1806
|
*
|
|
@@ -1571,7 +1822,7 @@ declare function never(): Producer<never>;
|
|
|
1571
1822
|
*
|
|
1572
1823
|
* @category Stream Operators
|
|
1573
1824
|
*/
|
|
1574
|
-
declare function share<T>(source:
|
|
1825
|
+
declare function share<T>(source: Stream<T>): Source<T>;
|
|
1575
1826
|
|
|
1576
1827
|
/**
|
|
1577
1828
|
* Output multiple streams' contents in order (from an array/iterable of stream
|
|
@@ -1586,7 +1837,7 @@ declare function share<T>(source: Source<T>): Producer<T>;
|
|
|
1586
1837
|
*
|
|
1587
1838
|
* @category Stream Operators
|
|
1588
1839
|
*/
|
|
1589
|
-
declare function concat<T>(sources:
|
|
1840
|
+
declare function concat<T>(sources: Stream<T>[] | Iterable<Stream<T>>): Source<T>;
|
|
1590
1841
|
/**
|
|
1591
1842
|
* Flatten a source of sources by emitting their contents in series
|
|
1592
1843
|
*
|
|
@@ -1600,7 +1851,7 @@ declare function concat<T>(sources: Source<T>[] | Iterable<Source<T>>): Producer
|
|
|
1600
1851
|
*
|
|
1601
1852
|
* @category Stream Operators
|
|
1602
1853
|
*/
|
|
1603
|
-
declare function concatAll<T>(sources:
|
|
1854
|
+
declare function concatAll<T>(sources: Stream<Stream<T>>): Source<T>;
|
|
1604
1855
|
/**
|
|
1605
1856
|
* Map each value of a stream to a substream, then concatenate the resulting
|
|
1606
1857
|
* substreams
|
|
@@ -1612,7 +1863,7 @@ declare function concatAll<T>(sources: Source<Source<T>>): Producer<T>;
|
|
|
1612
1863
|
*
|
|
1613
1864
|
* @category Stream Operators
|
|
1614
1865
|
*/
|
|
1615
|
-
declare function concatMap<T, R>(mapper: (v: T, idx: number) =>
|
|
1866
|
+
declare function concatMap<T, R>(mapper: (v: T, idx: number) => Stream<R>): Transformer<T, R>;
|
|
1616
1867
|
/**
|
|
1617
1868
|
* Create a subset of a stream, based on a filter function (like Array.filter)
|
|
1618
1869
|
*
|
|
@@ -1645,7 +1896,7 @@ declare function map<T, R>(mapper: (v: T, idx: number) => R): Transformer<T, R>;
|
|
|
1645
1896
|
*
|
|
1646
1897
|
* @category Stream Operators
|
|
1647
1898
|
*/
|
|
1648
|
-
declare function merge<T>(sources:
|
|
1899
|
+
declare function merge<T>(sources: Stream<T>[] | Iterable<Stream<T>>): Source<T>;
|
|
1649
1900
|
/**
|
|
1650
1901
|
* Create an event source by merging sources from a stream of event sources
|
|
1651
1902
|
*
|
|
@@ -1654,7 +1905,7 @@ declare function merge<T>(sources: Source<T>[] | Iterable<Source<T>>): Producer<
|
|
|
1654
1905
|
*
|
|
1655
1906
|
* @category Stream Operators
|
|
1656
1907
|
*/
|
|
1657
|
-
declare function mergeAll<T>(sources:
|
|
1908
|
+
declare function mergeAll<T>(sources: Stream<Stream<T>>): Source<T>;
|
|
1658
1909
|
/**
|
|
1659
1910
|
* Create an event source by merging sources created by mapping events to sources
|
|
1660
1911
|
*
|
|
@@ -1665,7 +1916,7 @@ declare function mergeAll<T>(sources: Source<Source<T>>): Producer<T>;
|
|
|
1665
1916
|
*
|
|
1666
1917
|
* @category Stream Operators
|
|
1667
1918
|
*/
|
|
1668
|
-
declare function mergeMap<T, R>(mapper: (v: T, idx: number) =>
|
|
1919
|
+
declare function mergeMap<T, R>(mapper: (v: T, idx: number) => Stream<R>): Transformer<T, R>;
|
|
1669
1920
|
/**
|
|
1670
1921
|
* Skip the first N items from a source
|
|
1671
1922
|
*
|
|
@@ -1682,7 +1933,7 @@ declare function skip<T>(n: number): Transformer<T>;
|
|
|
1682
1933
|
*
|
|
1683
1934
|
* @category Stream Operators
|
|
1684
1935
|
*/
|
|
1685
|
-
declare function skipUntil<T>(notifier:
|
|
1936
|
+
declare function skipUntil<T>(notifier: Stream<any>): Transformer<T>;
|
|
1686
1937
|
/**
|
|
1687
1938
|
* Skip items from a stream until a given condition is false, then output all
|
|
1688
1939
|
* remaining items. The condition function is not called again once it returns
|
|
@@ -1724,7 +1975,7 @@ declare function slack<T>(size: number, dropped?: Sink<T>): Transformer<T>;
|
|
|
1724
1975
|
*
|
|
1725
1976
|
* @category Stream Operators
|
|
1726
1977
|
*/
|
|
1727
|
-
declare function switchAll<T>(sources:
|
|
1978
|
+
declare function switchAll<T>(sources: Stream<Stream<T>>): Source<T>;
|
|
1728
1979
|
/**
|
|
1729
1980
|
* Map each value of a stream to a substream, then output the resulting
|
|
1730
1981
|
* substreams until a new value arrives.
|
|
@@ -1736,7 +1987,7 @@ declare function switchAll<T>(sources: Source<Source<T>>): Producer<T>;
|
|
|
1736
1987
|
*
|
|
1737
1988
|
* @category Stream Operators
|
|
1738
1989
|
*/
|
|
1739
|
-
declare function switchMap<T, R>(mapper: (v: T, idx: number) =>
|
|
1990
|
+
declare function switchMap<T, R>(mapper: (v: T, idx: number) => Stream<R>): Transformer<T, R>;
|
|
1740
1991
|
/**
|
|
1741
1992
|
* Take the first N items from a source
|
|
1742
1993
|
*
|
|
@@ -1753,7 +2004,7 @@ declare function take<T>(n: number): Transformer<T>;
|
|
|
1753
2004
|
*
|
|
1754
2005
|
* @category Stream Operators
|
|
1755
2006
|
*/
|
|
1756
|
-
declare function takeUntil<T>(notifier:
|
|
2007
|
+
declare function takeUntil<T>(notifier: Stream<any>): Transformer<T>;
|
|
1757
2008
|
/**
|
|
1758
2009
|
* Take items from a stream until a given condition is false, then close the
|
|
1759
2010
|
* output. The condition function is not called again after it returns false.
|
|
@@ -1790,7 +2041,7 @@ declare function must<T>(cleanup?: OptionalCleanup<T>): Job<T>;
|
|
|
1790
2041
|
* generator or job), a promise, or void. A returned iterator or promise will
|
|
1791
2042
|
* be treated as if the method was called with that to begin with; a returned
|
|
1792
2043
|
* job will be awaited and its result transferred to the new job
|
|
1793
|
-
* asynchronously.
|
|
2044
|
+
* asynchronously. A returned function will be added to the job via `must()`.
|
|
1794
2045
|
*
|
|
1795
2046
|
* - When called with one argument that's a {@link Yielding} iterator (such as a
|
|
1796
2047
|
* generator or an existing job): it's attached to the new job and executed
|
|
@@ -1812,7 +2063,7 @@ declare function must<T>(cleanup?: OptionalCleanup<T>): Job<T>;
|
|
|
1812
2063
|
* *(this) {...}));`) in order to correctly infer types inside a generator
|
|
1813
2064
|
* function.)
|
|
1814
2065
|
*
|
|
1815
|
-
* In any of the above cases, if a supplied function throws an error
|
|
2066
|
+
* In any of the above cases, if a supplied function throws an error while
|
|
1816
2067
|
* starting, the new job will be ended, and the error synchronously re-thrown.
|
|
1817
2068
|
*
|
|
1818
2069
|
* @returns the created {@link Job}
|
|
@@ -1891,5 +2142,68 @@ declare function abortSignal(job?: Job): AbortSignal;
|
|
|
1891
2142
|
*/
|
|
1892
2143
|
declare function restarting<F extends AnyFunction>(task: F): F;
|
|
1893
2144
|
declare function restarting(): (task: () => OptionalCleanup<never>) => void;
|
|
2145
|
+
/**
|
|
2146
|
+
* Wrap an argument-taking function so it will run in (and returns) a new Job
|
|
2147
|
+
* when called.
|
|
2148
|
+
*
|
|
2149
|
+
* This lets you avoid the common pattern of needing to write your functions or
|
|
2150
|
+
* methods like this:
|
|
2151
|
+
*
|
|
2152
|
+
* ```ts
|
|
2153
|
+
* function outer(arg1, arg2) {
|
|
2154
|
+
* return start(function*() {
|
|
2155
|
+
* // ...
|
|
2156
|
+
* })
|
|
2157
|
+
* }
|
|
2158
|
+
* ```
|
|
2159
|
+
* and instead write them like this:
|
|
2160
|
+
* ```ts
|
|
2161
|
+
* const outer = task(function *(arg1, arg2) {
|
|
2162
|
+
* // ...
|
|
2163
|
+
* });
|
|
2164
|
+
* ```
|
|
2165
|
+
* or this:
|
|
2166
|
+
* ```ts
|
|
2167
|
+
* class Something {
|
|
2168
|
+
* @task // auto-detects TC39 or legacy decorators
|
|
2169
|
+
* *someMethod(arg1): Yielding<SomeResultType> {
|
|
2170
|
+
* // ...
|
|
2171
|
+
* }
|
|
2172
|
+
* }
|
|
2173
|
+
* ```
|
|
2174
|
+
*
|
|
2175
|
+
* Important: if the wrapped function or method has overloads, the resulting
|
|
2176
|
+
* function type will be based on the **last** overload, because TypeScript (at
|
|
2177
|
+
* least as of 5.x) is still not very good at dealing with higher order
|
|
2178
|
+
* generics, especially if overloads are involved.
|
|
2179
|
+
*
|
|
2180
|
+
* Also note that TypeScript doesn't allow decorators to change the calling
|
|
2181
|
+
* signature or return type of a method, so even though the above method will
|
|
2182
|
+
* return a {@link Job}, TypeScript will only see it as a {@link Yielding}.
|
|
2183
|
+
*
|
|
2184
|
+
* This is fine if all you're going to do is `yield *` it to wait for the
|
|
2185
|
+
* result, but if you need to use any job-specific methods on it, you'll have to
|
|
2186
|
+
* pass it through {@link start} to have TypeScript treat it as an actual job.
|
|
2187
|
+
* (Luckily, start() has a fast path to return the original job if it's passed a
|
|
2188
|
+
* job, so you won't actually create a new job by doing this.)
|
|
2189
|
+
*
|
|
2190
|
+
* @param fn The function to wrap. A function returning a generator or
|
|
2191
|
+
* promise-like object (i.e., a {@link StartObj}).
|
|
2192
|
+
*
|
|
2193
|
+
* @returns A wrapped version of the function that passes through its arguments
|
|
2194
|
+
* to the original function, while running it in a new job. (The wrapper also
|
|
2195
|
+
* returns the job.)
|
|
2196
|
+
*
|
|
2197
|
+
* @category Jobs
|
|
2198
|
+
*/
|
|
2199
|
+
declare function task<T, A extends any[], C>(fn: (this: C, ...args: A) => StartObj<T>): (this: C, ...args: A) => Job<T>;
|
|
2200
|
+
/** @hidden TC39 Decorator protocol */
|
|
2201
|
+
declare function task<T, A extends any[], C>(fn: (this: C, ...args: A) => StartObj<T>, ctx: {
|
|
2202
|
+
kind: "method";
|
|
2203
|
+
}): (this: C, ...args: A) => Job<T>;
|
|
2204
|
+
/** @hidden Legacy Decorator protocol */
|
|
2205
|
+
declare function task<T, A extends any[], C, D extends {
|
|
2206
|
+
value?: (this: C, ...args: A) => StartObj<T>;
|
|
2207
|
+
}>(clsOrProto: any, name: string | symbol, desc: D): D;
|
|
1894
2208
|
|
|
1895
|
-
export { type AnyFunction, type AsyncStart, type Backpressure, CancelError, CancelResult, CircularDependency, type CleanupFn, type Connection, type DisposeFn, type Each, type EachResult, type Emitter, ErrorResult, type HandledError, type Inlet, IsStream, type Job, type JobIterator, type JobResult, type MockSource, type
|
|
2209
|
+
export { type AnyFunction, type AsyncStart, type Backpressure, CancelError, CancelResult, CircularDependency, type CleanupFn, type Configurable, type Connection, type DisposeFn, type Each, type EachResult, type Emitter, ErrorResult, type GenericMethodDecorator, type HandledError, type Inlet, IsStream, type Job, type JobIterator, type JobResult, type MockSource, type NextMethod, type Nothing, type OptionalCleanup, type PlainFunction, type RecalcSource, type Request, type RuleFactory, type Signal, type SignalSource, type Sink, type Source, type StartFn, type StartObj, type Stream, type Suspend, type SyncStart, type Throttle, type Transformer, type UnhandledError, type UntilMethod, ValueResult, type Writable, WriteConflict, type Yielding, abortSignal, action, backpressure, cached, compose, concat, concatAll, concatMap, connect, defer, detached, each, emitter, empty, filter, forEach, fromAsyncIterable, fromDomEvent, fromIterable, fromPromise, fromSubscribe, fromValue, fulfillPromise, getJob, getResult, interval, into, isCancel, isError, isFunction, isHandled, isJobActive, isUnhandled, isValue, lazy, makeJob, map, markHandled, merge, mergeAll, mergeMap, mockSource, must, nativePromise, never, next, noop, peek, pipe, propagateResult, recalcWhen, reject, rejecter, resolve, resolver, restarting, rule, runRules, share, skip, skipUntil, skipWhile, slack, sleep, start, switchAll, switchMap, take, takeUntil, takeWhile, task, throttle, timeout, to, until, value };
|