uneventful 0.0.12 → 0.0.13

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.
@@ -214,6 +214,9 @@ declare function propagateResult<T>(job: Job<T>, res: JobResult<T>): void;
214
214
  declare class CancelError extends Error {
215
215
  }
216
216
 
217
+ /** An optional value @inline */
218
+ type Maybe<T> = T | undefined;
219
+
217
220
  /**
218
221
  * A backpressure controller: returns true if downstream is ready to accept
219
222
  * data.
@@ -367,40 +370,7 @@ declare function connect<T>(src: Stream<T>, sink: Sink<T>, inlet?: Throttle | In
367
370
  *
368
371
  * @category Stream Consumers
369
372
  */
370
- declare function throttle(job?: Job): Throttle;
371
- /**
372
- * Pipe a stream (or anything else) through a series of single-argument
373
- * functions/operators
374
- *
375
- * e.g. the following creates a stream that outputs 4 and then 6:
376
- *
377
- * ```ts
378
- * pipe(fromIterable([1,2,3,4]), skip(1), take(2), map(x => x*2))
379
- * ```
380
- *
381
- * The first argument to pipe() can be any value, but all other arguments must
382
- * be functions. The value is passed to the first function, and then the result
383
- * is passed to the next function in turn, until all provided functions have
384
- * been called with the result of the previous function. The return value is
385
- * the last result, or the original value if no functions were given.
386
- *
387
- * The underlying implementation of pipe() works with any number of arguments,
388
- * but due to TypeScript limitations we only have typing defined for a max of 9
389
- * functions (10 arguments total). If you need more than 9 functions, you can
390
- * stack some of them with {@link compose}(), e.g.:
391
- *
392
- * ```typescript
393
- * pipe(
394
- * aStream,
395
- * compose(op1, op2, ...),
396
- * compose(op10, op11, ...),
397
- * compose(op19, ...),
398
- * ...
399
- * )
400
- * ```
401
- *
402
- * @category Stream Operators
403
- */
373
+ declare function throttle(job?: Maybe<Job<any>>): Throttle;
404
374
  declare function pipe<A, B, C, D, E, F, G, H, I, J>(input: A, ...fns: Chain9<A, J, B, C, D, E, F, G, H, I>): J;
405
375
  declare function pipe<A, B, C, D, E, F, G, H, I>(input: A, ...fns: Chain8<A, I, B, C, D, E, F, G, H>): I;
406
376
  declare function pipe<A, B, C, D, E, F, G, H>(input: A, ...fns: Chain7<A, H, B, C, D, E, F, G>): H;
@@ -412,25 +382,6 @@ declare function pipe<A, B, C>(input: A, ...fns: Chain2<A, C, B>): C;
412
382
  declare function pipe<A, B>(input: A, ...fns: Chain1<A, B>): B;
413
383
  declare function pipe<A>(input: A): A;
414
384
  declare function pipe(input: any, ...fns: Array<(v: any) => any>): any;
415
- /**
416
- * Compose a series of single-argument functions/operators in application order.
417
- * (This is basically a deferred version of {@link pipe}().) For example:
418
- *
419
- * ```ts
420
- * const func = compose(skip(1), take(2), map(x => x*2));
421
- * const stream_4_6 = func(fromIterable([1,2,3,4])); // stream that outputs 4, 6
422
- * ```
423
- *
424
- * As with `pipe()`, the declared typings only support composing up to 9
425
- * functions at once; if you need more you'll need to nest calls to `compose()`
426
- * (i.e. passing the result of a `compose()` as an argument to another
427
- * `compose()` call.)
428
- *
429
- * @returns A function taking the same type as the first input function,
430
- * returning the same type as the last input function.
431
- *
432
- * @category Stream Operators
433
- */
434
385
  declare function compose<A, B, C, D, E, F, G, H, I, J>(...fns: Chain9<A, J, B, C, D, E, F, G, H, I>): (a: A) => J;
435
386
  declare function compose<A, B, C, D, E, F, G, H, I>(...fns: Chain8<A, I, B, C, D, E, F, G, H>): (a: A) => I;
436
387
  declare function compose<A, B, C, D, E, F, G, H>(...fns: Chain7<A, H, B, C, D, E, F, G>): (a: A) => H;
@@ -441,6 +392,7 @@ declare function compose<A, B, C, D>(...fns: Chain3<A, D, B, C>): (a: A) => D;
441
392
  declare function compose<A, B, C>(...fns: Chain2<A, C, B>): (a: A) => C;
442
393
  declare function compose<A, B>(...fns: Chain1<A, B>): (a: A) => B;
443
394
  declare function compose<A>(): (a: A) => A;
395
+ /** @inline */
444
396
  type Chain1<A, R> = [(v: A) => R];
445
397
  type Chain2<A, R, B> = [...Chain1<A, B>, ...Chain1<B, R>];
446
398
  type Chain3<A, R, B, C> = [...Chain1<A, B>, ...Chain2<B, R, C>];
@@ -577,8 +529,7 @@ type StartObj<T> = Yielding<T> | Promise<T> | PromiseLike<T>;
577
529
  * canceled (using {@link Job.end \.end()} or
578
530
  * {@link Job.restart \.restart()}).
579
531
  *
580
- * Jobs can be created using {@link start}(), {@link detached}.start(), and
581
- * {@link makeJob}().
532
+ * Jobs can be created using {@link start}() and {@link root}.start().
582
533
  *
583
534
  * @category Types and Interfaces
584
535
  */
@@ -750,7 +701,7 @@ interface Job<T = any> extends Yielding<T>, Promise<T> {
750
701
  *
751
702
  * @category Obtaining Results
752
703
  */
753
- do(action: (res?: JobResult<T>) => unknown): this;
704
+ do(action: (res: JobResult<T>) => unknown): this;
754
705
  /**
755
706
  * Invoke a callback if the job ends with an error.
756
707
  *
@@ -814,7 +765,7 @@ interface Job<T = any> extends Yielding<T>, Promise<T> {
814
765
  * will be called with the error, otherwise the job will end with the
815
766
  * supplied error. If the error then isn't handled by a listener on the
816
767
  * job, the error will cascade to an asyncThrow on the job's parent, until
817
- * the {@link detached} job and its asyncCatch handler is reached. (Which
768
+ * the {@link root} job and its asyncCatch handler is reached. (Which
818
769
  * defaults to creating an unhandled promise rejection.)
819
770
  *
820
771
  * Note: application code should not normally need to call this method
@@ -71,6 +71,36 @@ function setMap(map, key, val) {
71
71
  function isFunction(f) {
72
72
  return typeof f === "function";
73
73
  }
74
+ function isPlainFunction(f) {
75
+ const t = functionType(f, 3 /* ES6_CLASS */);
76
+ return t === 1 /* PLAIN */ || t === 2 /* BOUND */;
77
+ }
78
+ function functionType(fn, checkClass) {
79
+ var prot;
80
+ switch (true) {
81
+ case !isFunction(fn):
82
+ return 0 /* NON_FUNC */;
83
+ case Object.getPrototypeOf(fn).constructor?.name !== "Function":
84
+ return 5 /* EXOTIC */;
85
+ case !(prot = fn.prototype):
86
+ return 2 /* BOUND */;
87
+ case (checkClass && fn.toString().startsWith("class")):
88
+ return 3 /* ES6_CLASS */;
89
+ case (checkClass === 4 /* ES5_CLASS */ && (!isPlainObject(prot) || // Does it inherit from something other than Object?
90
+ Object.getOwnPropertyNames(prot).length > 1)):
91
+ return 4 /* ES5_CLASS */;
92
+ default:
93
+ return 1 /* PLAIN */;
94
+ }
95
+ }
96
+ function isClass(f) {
97
+ const t = functionType(f, 4 /* ES5_CLASS */);
98
+ return t === 3 /* ES6_CLASS */ || t === 4 /* ES5_CLASS */;
99
+ }
100
+ function isPlainObject(ob) {
101
+ var proto;
102
+ return typeof ob === "object" && ob !== null && (!(proto = Object.getPrototypeOf(ob)) || proto.constructor?.name === "Object");
103
+ }
74
104
  const CallableObject = /* @__PURE__ */ (() => {
75
105
  function CallableObject2(fn) {
76
106
  return Object.setPrototypeOf(fn, new.target.prototype);
@@ -79,8 +109,8 @@ const CallableObject = /* @__PURE__ */ (() => {
79
109
  return CallableObject2;
80
110
  })();
81
111
  const apply = Reflect.apply;
82
- function call(fn, thisArg, ...args) {
83
- return thisArg ? apply(fn, thisArg, args) : args.length ? fn(...args) : fn();
112
+ function call(fn, thisArg) {
113
+ return thisArg ? apply(fn, thisArg, [...arguments].slice(2)) : arguments.length < 3 ? fn() : fn(...[...arguments].slice(2));
84
114
  }
85
115
  const GeneratorBase = /* @__PURE__ */ (() => {
86
116
  function G() {
@@ -93,4 +123,4 @@ function isGeneratorFunction(fn) {
93
123
  return isFunction(fn) && fn.prototype instanceof GeneratorBase;
94
124
  }
95
125
 
96
- export { CallableObject as C, GeneratorBase as G, isGeneratorFunction as a, decorateMethod as b, apply as c, defer as d, batch as e, arrayEq as f, isArray as g, call as h, isFunction as i, setMap as s };
126
+ export { CallableObject as C, GeneratorBase as G, isGeneratorFunction as a, decorateMethod as b, apply as c, defer as d, isClass as e, isPlainFunction as f, arrayEq as g, batch as h, isFunction as i, isArray as j, isPlainObject as k, call as l, setMap as s };
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as AnyFunction } from './types-N2ua11te.js';
1
+ import { A as AnyFunction } from './types-pElgImr7.js';
2
2
 
3
3
  /**
4
4
  * A generic batch processing queue, implemented as a set. (So items are
@@ -80,9 +80,9 @@ declare function batch<T>(process: (items: Set<T>) => void, sched?: (cb: () => u
80
80
  * export function myDecorator<T,D extends {value?: SomeFnType<T>}>(clsOrProto:any, name: string|symbol, desc: D): D
81
81
  *
82
82
  * // Implementation
83
- * export function myDecorator<T>(factory: SomeFnType<T>, ...args: any[]): SomeFnType<T> {
83
+ * export function myDecorator<T>(fn: SomeFnType<T>, ...args: any[]): SomeFnType<T> {
84
84
  * // extra args means we're being used as a decorator, so run as decorator:
85
- * if (args.length) return decorateMethod(myDecorator, factory, ...args as [any, any]);
85
+ * if (args.length) return decorateMethod(myDecorator, fn, ...args as [any, any]);
86
86
  * // No extra args, we're b
87
87
  * return () => {
88
88
  * }
@@ -137,6 +137,48 @@ declare function setMap<K, V>(map: {
137
137
  * @category Functions and Decorators
138
138
  */
139
139
  declare function isFunction(f: any): f is Function;
140
+ /**
141
+ * Is the given value a plain synchronous function?
142
+ *
143
+ * Returns false if the function is an ES6 class (non-emulated!), async,
144
+ * generator, or async generator function. Returns true for regular, arrow, and
145
+ * bound regular functions.
146
+ *
147
+ * Note: a function can return a promise or generator or implement a class, and
148
+ * yet still not *be* an async function, generator function, or native class.
149
+ * This function doesn't detect/reject any *emulated* versions of those things,
150
+ * only native-to-the-engine async/generator functions and classes. (It also
151
+ * returns false for {@link CallableObject} instances, or similarly-created
152
+ * function subclasses.)
153
+ *
154
+ * @category Functions and Decorators
155
+ */
156
+ declare function isPlainFunction(f: any): f is Function;
157
+ /**
158
+ * Is the given value a class?
159
+ *
160
+ * This function detects ES6 native classes, but also ES5-style emmulated
161
+ * classes, if they're either a subclass (i.e. inherit from something other than
162
+ * Object), or a base class with public instance methods or other property
163
+ * descriptors on its prototype.
164
+ *
165
+ * It has NO false positives: if it returns true, the thing is definitely a
166
+ * class by the above rules. But it *can* return a false negative for a plain
167
+ * constructor function with no base class and no prototype methods.
168
+ *
169
+ * @category Functions and Decorators
170
+ */
171
+ declare function isClass<T>(f: any): f is new () => T;
172
+ /**
173
+ * Is `ob` a non-null plain object? (i.e. object literal or created via
174
+ * `Object.create(null, ...)`)
175
+ *
176
+ * @returns true if ob's a non-null of type `object` with a null prototype
177
+ * or a constructor named `Object`.
178
+ *
179
+ * @category Data Structures
180
+ */
181
+ declare function isPlainObject(ob: any): boolean;
140
182
  /**
141
183
  * A base class for creating callable objects.
142
184
  *
@@ -173,13 +215,16 @@ declare const CallableObject: new <T extends AnyFunction>(fn: T) => T;
173
215
  * @function
174
216
  */
175
217
  declare const apply: typeof Reflect.apply;
218
+ /**
219
+ * Syntax sugar for an IIFE (i.e. to use `call(() => ...)` instead of `(()=> ...)()` )
220
+ *
221
+ * @category Functions and Decorators
222
+ */
223
+ declare function call<F extends () => any>(fn: F): ReturnType<F>;
176
224
  /**
177
225
  * Like `fn.call(thisArg, ...args)`, but monomorphic, and the `thisArg`
178
226
  * parameter can be omitted or null.
179
227
  *
180
- * This is mostly useful as syntax sugar for an immediately-evaluated function
181
- * expression, replacing `(() => {...})()` with `call(() => {...})`.
182
- *
183
228
  * @category Functions and Decorators
184
229
  */
185
230
  declare function call<F extends AnyFunction>(fn: F, thisArg?: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F>;
@@ -198,4 +243,4 @@ declare const GeneratorBase: abstract new () => Generator;
198
243
  */
199
244
  declare function isGeneratorFunction<G extends Generator<any, any, any> = Generator>(fn: any): fn is (this: any, ...args: any[]) => G;
200
245
 
201
- export { type Batch, CallableObject, GeneratorBase, apply, arrayEq, batch, call, decorateMethod, isArray, isFunction, isGeneratorFunction, setMap };
246
+ export { type Batch, CallableObject, GeneratorBase, apply, arrayEq, batch, call, decorateMethod, isArray, isClass, isFunction, isGeneratorFunction, isPlainFunction, isPlainObject, setMap };
package/dist/utils.mjs CHANGED
@@ -1 +1 @@
1
- export { C as CallableObject, G as GeneratorBase, c as apply, f as arrayEq, e as batch, h as call, b as decorateMethod, g as isArray, i as isFunction, a as isGeneratorFunction, s as setMap } from './utils-cyEhnyp7.mjs';
1
+ export { C as CallableObject, G as GeneratorBase, c as apply, g as arrayEq, h as batch, l as call, b as decorateMethod, j as isArray, e as isClass, i as isFunction, a as isGeneratorFunction, f as isPlainFunction, k as isPlainObject, s as setMap } from './utils-BgqyDPjA.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uneventful",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "description": "Declarative, event-driven reactivity: signals, streams, structured concurrency, and easy resource cleanup",
5
5
  "keywords": [
6
6
  "signals",
@@ -52,12 +52,12 @@
52
52
  }
53
53
  },
54
54
  "scripts": {
55
- "coverage": "c8 -r lcov mocha -n loader=ts-node/esm",
55
+ "coverage": "cross-env TS_NODE_PROJECT=specs/tsconfig.json c8 -r lcov mocha -n loader=ts-node/esm",
56
56
  "docs": "typedoc",
57
- "watch": "mocha -r tsx --watch",
57
+ "watch": "pnpm run test --watch",
58
58
  "watch-docs": "typedoc --watch",
59
59
  "watch-prep": "pkgroll --watch",
60
- "test": "mocha -r tsx && pkgroll",
60
+ "test": "tsx --tsconfig specs/tsconfig.json node_modules/mocha/bin/mocha.js",
61
61
  "prepare": "pkgroll --clean-dist"
62
62
  },
63
63
  "mocha": {
@@ -69,22 +69,21 @@
69
69
  "README.md"
70
70
  ]
71
71
  },
72
- "ts-node": {
73
- "esm": true,
74
- "transpileOnly": true,
75
- "experimentalSpecifierResolution": "node"
76
- },
77
72
  "packageManager": "pnpm@7.33.6",
78
73
  "devDependencies": {
79
74
  "@types/chai": "^4.3.10",
80
75
  "@types/chai-as-promised": "^7.1.8",
76
+ "@types/markdown-it": "^14.1.2",
77
+ "@types/markdown-it-footnote": "^3.0.4",
81
78
  "@types/mocha": "^10.0.4",
82
- "@types/node": "^16",
79
+ "@types/node": "^18",
83
80
  "@types/sinon": "^17.0.1",
84
81
  "@types/sinon-chai": "^3.2.12",
85
82
  "c8": "^10",
86
83
  "chai": "^4.3.10",
87
84
  "chai-as-promised": "^7.1.1",
85
+ "cross-env": "^7.0.3",
86
+ "markdown-it-footnote": "^4.0.0",
88
87
  "mocha": "^10.2.0",
89
88
  "monkey-around": "^3",
90
89
  "pkgroll": "^2.1.1",
@@ -93,7 +92,7 @@
93
92
  "ts-expect": "^1.3.0",
94
93
  "ts-node": "^10.9.1",
95
94
  "tsx": "^4.6.1",
96
- "typedoc": "0.28.2",
97
- "typescript": "^5.4.5"
95
+ "typedoc": "pjeby/typedoc#no-merged-comments",
96
+ "typescript": "^5.9.3"
98
97
  }
99
98
  }
@@ -1,111 +0,0 @@
1
- import { g as getJob, H as currentJob, I as pulls, s as start, l as isValue, f as isError, e as markHandled } from './jobutils-Dvu-e99o.mjs';
2
- import { i as isFunction } from './utils-cyEhnyp7.mjs';
3
-
4
- function backpressure(inlet = defaultInlet) {
5
- const job = getJob();
6
- return (cb) => {
7
- if (!job.result() && inlet.isOpen()) {
8
- if (cb)
9
- inlet.onReady(cb, job);
10
- return inlet.isReady();
11
- }
12
- return false;
13
- };
14
- }
15
- const IsStream = "uneventful/is-stream";
16
- function connect(src, sink, inlet) {
17
- return getJob().connect(src, sink, inlet);
18
- }
19
- function throttle(job = currentJob) {
20
- return new _Throttle(job);
21
- }
22
- class _Throttle {
23
- /** @internal */
24
- constructor(_job) {
25
- this._job = _job;
26
- /** @internal */
27
- this._callbacks = void 0;
28
- this._isReady = true;
29
- this._isPulling = false;
30
- }
31
- isOpen() {
32
- return !this._job?.result();
33
- }
34
- /** Is the connection ready to receive data? */
35
- isReady() {
36
- return this.isOpen() && this._isReady;
37
- }
38
- onReady(cb, job) {
39
- if (!this.isOpen())
40
- return this;
41
- const _callbacks = this._callbacks ||= /* @__PURE__ */ new Map();
42
- const unlink = job.release(() => _callbacks.delete(cb));
43
- if (this.isReady() && this && !_callbacks.size) {
44
- pulls.add(this);
45
- }
46
- _callbacks.set(cb, unlink);
47
- return this;
48
- }
49
- pause() {
50
- this._isReady = false;
51
- return this;
52
- }
53
- doPull() {
54
- if (this._isPulling)
55
- return;
56
- const { _callbacks } = this;
57
- if (!_callbacks?.size)
58
- return;
59
- this._isPulling = true;
60
- try {
61
- for (let [cb, unlink] of _callbacks) {
62
- if (!this.isReady())
63
- break;
64
- unlink();
65
- _callbacks.delete(cb);
66
- cb();
67
- }
68
- } finally {
69
- this._isPulling = false;
70
- }
71
- }
72
- resume() {
73
- if (this.isOpen()) {
74
- this._isReady = true;
75
- this.doPull();
76
- }
77
- }
78
- }
79
- const defaultInlet = throttle();
80
- function pipe() {
81
- var v = arguments[0];
82
- for (var i = 1; i < arguments.length; i++)
83
- v = arguments[i](v);
84
- return v;
85
- }
86
- function compose(...fns) {
87
- return (val) => pipe(val, ...fns);
88
- }
89
- function into(...args) {
90
- return (src) => src(...args);
91
- }
92
-
93
- function callOrWait(source, method, handler, noArgs) {
94
- if (source && isFunction(source[method]))
95
- return source[method]();
96
- if (!isFunction(source))
97
- mustBeSourceOrSignal();
98
- return (source.length === 0 ? noArgs(source) : false) || start((job) => {
99
- connect(source, (v) => handler(job, v)).do((r) => {
100
- if (isValue(r))
101
- job.throw(new Error("Stream ended"));
102
- else if (isError(r))
103
- job.throw(markHandled(r));
104
- });
105
- });
106
- }
107
- function mustBeSourceOrSignal() {
108
- throw new TypeError("not a source or signal");
109
- }
110
-
111
- export { IsStream as I, callOrWait as a, backpressure as b, connect as c, compose as d, into as i, mustBeSourceOrSignal as m, pipe as p, throttle as t };