uneventful 0.0.10 → 0.0.11
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 +2 -2
- package/dist/{call-or-wait-DORP7nkp.mjs → call-or-wait-EzXJX5Dq.mjs} +12 -13
- package/dist/ext.d.ts +260 -0
- package/dist/ext.mjs +112 -0
- package/dist/{jobutils-CmHay7sf.mjs → jobutils-Dvu-e99o.mjs} +47 -52
- package/dist/mod.d.ts +2 -0
- package/dist/mod.mjs +9 -9
- package/dist/shared.mjs +2 -3
- package/dist/signals.d.ts +1 -0
- package/dist/signals.mjs +63 -51
- package/dist/{utils-DnMz1K-o.mjs → utils-cyEhnyp7.mjs} +4 -2
- package/dist/utils.d.ts +14 -1
- package/dist/utils.mjs +1 -2
- package/package.json +20 -10
- package/dist/call-or-wait-DORP7nkp.mjs.map +0 -1
- package/dist/jobutils-CmHay7sf.mjs.map +0 -1
- package/dist/mod.mjs.map +0 -1
- package/dist/shared.mjs.map +0 -1
- package/dist/signals.mjs.map +0 -1
- package/dist/utils-DnMz1K-o.mjs.map +0 -1
- package/dist/utils.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -67,12 +67,12 @@ function supportDragDrop(parentNode: HTMLElement) {
|
|
|
67
67
|
return start(function*(job) {
|
|
68
68
|
const mouseDown = fromDomEvent(parentNode, "mousedown");
|
|
69
69
|
for (const {item: event, next} of yield *each(mouseDown)) {
|
|
70
|
-
if (event.target.matches(".drag-handle") {
|
|
70
|
+
if (event.target.matches(".drag-handle")) {
|
|
71
71
|
const dropTarget = yield *drag(event.target.closest(".draggable"));
|
|
72
72
|
// do something with the dropTarget here
|
|
73
73
|
}
|
|
74
74
|
yield next; // wait for next mousedown
|
|
75
|
-
}
|
|
75
|
+
}
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { g as getJob,
|
|
2
|
-
import { i as isFunction } from './utils-
|
|
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
3
|
|
|
4
4
|
function backpressure(inlet = defaultInlet) {
|
|
5
5
|
const job = getJob();
|
|
@@ -16,7 +16,7 @@ const IsStream = "uneventful/is-stream";
|
|
|
16
16
|
function connect(src, sink, inlet) {
|
|
17
17
|
return getJob().connect(src, sink, inlet);
|
|
18
18
|
}
|
|
19
|
-
function throttle(job =
|
|
19
|
+
function throttle(job = currentJob) {
|
|
20
20
|
return new _Throttle(job);
|
|
21
21
|
}
|
|
22
22
|
class _Throttle {
|
|
@@ -93,20 +93,19 @@ function into(...args) {
|
|
|
93
93
|
function callOrWait(source, method, handler, noArgs) {
|
|
94
94
|
if (source && isFunction(source[method]))
|
|
95
95
|
return source[method]();
|
|
96
|
-
if (isFunction(source))
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
104
|
});
|
|
105
|
-
|
|
105
|
+
});
|
|
106
106
|
}
|
|
107
107
|
function mustBeSourceOrSignal() {
|
|
108
108
|
throw new TypeError("not a source or signal");
|
|
109
109
|
}
|
|
110
110
|
|
|
111
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 };
|
|
112
|
-
//# sourceMappingURL=call-or-wait-DORP7nkp.mjs.map
|
package/dist/ext.d.ts
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { P as PlainFunction } from './types-N2ua11te.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This module provides helpers for creating *extensions*: a way of extending
|
|
5
|
+
* objects with additional (possibly private) data or methods via a WeakMap.
|
|
6
|
+
*
|
|
7
|
+
* An extension property links a type of object (known as the "target") with a
|
|
8
|
+
* specific type of extension, via a factory function or class. When you use an
|
|
9
|
+
* extension property for a specific target, the extension is automatically
|
|
10
|
+
* created (via the factory) if it doesn't already exist.
|
|
11
|
+
*
|
|
12
|
+
* Extension properties and methods are created either by inheriting from the
|
|
13
|
+
* {@link Ext} class, or by wrapping factory functions with {@link ext}() or
|
|
14
|
+
* {@link method}().
|
|
15
|
+
*
|
|
16
|
+
* @module uneventful/ext
|
|
17
|
+
*
|
|
18
|
+
* @experimental
|
|
19
|
+
*
|
|
20
|
+
* @summary Tools for extending objects with extra state and behavior, without
|
|
21
|
+
* directly modifying them.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create an extension accessor function that returns a memoized
|
|
26
|
+
* value for a given target object or function.
|
|
27
|
+
*
|
|
28
|
+
* (Memoization is done via WeakMap, so the cached extensions will be freed
|
|
29
|
+
* automatically once the target is garbage-collected.)
|
|
30
|
+
*
|
|
31
|
+
* @template Target The type of target object that will be extended. Both the
|
|
32
|
+
* passed-in factory function and the returned accessor function will take a
|
|
33
|
+
* parameter of this type, which must be an object or function type. (So it's
|
|
34
|
+
* suitable for weak referencing.)
|
|
35
|
+
*
|
|
36
|
+
* @template ExtType The type of extension that will be cached. Both the
|
|
37
|
+
* passed-in factory function and the returned accessor will return a value of
|
|
38
|
+
* this type.
|
|
39
|
+
*
|
|
40
|
+
* @param factory Function called with a target object or function and a weakmap
|
|
41
|
+
* to create a new extension for that target. The result is cached in the
|
|
42
|
+
* weakmap so the factory is called at most once per target (unless you alter
|
|
43
|
+
* the weakmap contents directly).
|
|
44
|
+
*
|
|
45
|
+
* @param map Optional: the weakmap to use to store the extensions. This allows
|
|
46
|
+
* you to manipulate the map contents (e.g. remove items or clear it) from
|
|
47
|
+
* outside the factory function. If no map is provided, one is created
|
|
48
|
+
* automatically, but then it's only accessible via the factory function's
|
|
49
|
+
* second parameter.
|
|
50
|
+
*
|
|
51
|
+
* @returns A function that always returns the same extension for a given target
|
|
52
|
+
* (assuming you don't alter the WeakMap), calling the factory function if an
|
|
53
|
+
* extension doesn't exist yet for that target.
|
|
54
|
+
*/
|
|
55
|
+
declare function ext<Target extends WeakKey, ExtType extends Object>(factory: (tgt: Target, map: WeakMap<Target, ExtType>) => ExtType, map?: WeakMap<Target, ExtType>): (tgt: Target) => ExtType;
|
|
56
|
+
/**
|
|
57
|
+
* Create an extension *method*: a function that invokes a memoized closure for
|
|
58
|
+
* a given target object or function.
|
|
59
|
+
*
|
|
60
|
+
* This function is almost identical to {@link ext}(), except that instead of an
|
|
61
|
+
* accessor function, this returns a function that will *call* the extension
|
|
62
|
+
* (method closure) corresponding to the target, passing along any extra
|
|
63
|
+
* arguments.
|
|
64
|
+
*
|
|
65
|
+
* This is useful when you want to create an extension type that only has one
|
|
66
|
+
* public method, and you'd rather not create a whole class for it: just set up
|
|
67
|
+
* its state as variables in your factory function and return a closure. Then,
|
|
68
|
+
* you can simply call `myMethod(target, ...args)`, which will look up the
|
|
69
|
+
* (possibly cached) closure for `target` and call it with `(...args)`. (You
|
|
70
|
+
* could do the same thing with an {@link ext}() accessor, but then the API
|
|
71
|
+
* would be `myMethod(target)(...args)`.)
|
|
72
|
+
*
|
|
73
|
+
* @template Target The type of target object that will be extended. Both the
|
|
74
|
+
* passed-in factory function and the returned accessor function will take a
|
|
75
|
+
* parameter of this type, which must be an object or function type. (So it's
|
|
76
|
+
* suitable for weak referencing.)
|
|
77
|
+
*
|
|
78
|
+
* @template Method The type of the closure that will be cached. The passed-in
|
|
79
|
+
* factory function must return a value of this type, and the resulting wrapper
|
|
80
|
+
* function will be of the same type but with an added initial `target`
|
|
81
|
+
* parameter. (Note: if this type has more than one call signature, only the
|
|
82
|
+
* *last* overload will be used in the resulting method signature, due to
|
|
83
|
+
* TypeScript compiler limitations.)
|
|
84
|
+
*
|
|
85
|
+
* @param factory Function called with a target object or function and a weakmap
|
|
86
|
+
* to create a method closure for that target. The result is cached in the
|
|
87
|
+
* weakmap so the factory is called at most once per target (unless you alter
|
|
88
|
+
* the weakmap contents directly).
|
|
89
|
+
*
|
|
90
|
+
* @param map Optional: the weakmap to use to store the method closures. This
|
|
91
|
+
* allows you to manipulate the map contents (e.g. remove items or clear it)
|
|
92
|
+
* from outside the factory function. If no map is provided, one is created
|
|
93
|
+
* automatically, but then it's only accessible via the factory function's
|
|
94
|
+
* second parameter.
|
|
95
|
+
*
|
|
96
|
+
* @returns A wrapper function that always invokes the same closure for a given
|
|
97
|
+
* target (assuming you don't alter the WeakMap), calling the factory function
|
|
98
|
+
* if a method closure doesn't exist yet for that target. When called, the
|
|
99
|
+
* wrapper function returns the result of calling the closure with the same
|
|
100
|
+
* arguments (minus an initial `target` argument).
|
|
101
|
+
*/
|
|
102
|
+
declare function method<Target extends object, Method extends PlainFunction>(factory: (tgt: Target, map: WeakMap<Target, Method>) => Method, map?: WeakMap<Target, Method>): (tgt: Target, ...args: Parameters<Method>) => ReturnType<Method>;
|
|
103
|
+
/** Helper types for working with {@link Ext} Subclasses */
|
|
104
|
+
declare namespace Ext {
|
|
105
|
+
/** Get the target type of an {@link Ext} subclass constructor */
|
|
106
|
+
type Target<T extends Ext.Class> = InstanceType<T>["of"];
|
|
107
|
+
/**
|
|
108
|
+
* Get the type of extension that will be returned by the static API.
|
|
109
|
+
*
|
|
110
|
+
* Defaults to the subclass instance type, but can be overridden by `declare
|
|
111
|
+
* readonly __type__: OtherType` in a subclass, so long as the
|
|
112
|
+
* {@link Ext.__new__ `__new__()`} method is also overridden to return that
|
|
113
|
+
* type.
|
|
114
|
+
*/
|
|
115
|
+
type Type<T extends Ext.Class> = InstanceType<T> extends {
|
|
116
|
+
__type__: infer R;
|
|
117
|
+
} ? (unknown extends R ? InstanceType<T> : R) : InstanceType<T>;
|
|
118
|
+
/** The type of weakmap passed to {@link Ext.__new__ `__new__()`} */
|
|
119
|
+
type Map<Class extends Ext.Class> = WeakMap<Ext.Target<Class>, any>;
|
|
120
|
+
/**
|
|
121
|
+
* The type constraint for static generics in the API; you probably won't use this directly.
|
|
122
|
+
*/
|
|
123
|
+
type Class = typeof Ext<WeakKey>;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* A base class for more complex extension types, providing static accessor and
|
|
127
|
+
* management APIs. (e.g. `MyExt.for(aTarget)`, `MyExt.delete(aTarget)`, etc.)
|
|
128
|
+
*
|
|
129
|
+
* To create an extension class, just subclass Ext with an appropriate target
|
|
130
|
+
* type, e.g.:
|
|
131
|
+
*
|
|
132
|
+
* ```ts
|
|
133
|
+
* class MyExt extends Ext<MyTargetType> {
|
|
134
|
+
* // ...
|
|
135
|
+
* }
|
|
136
|
+
* ```
|
|
137
|
+
* You can then use `MyExt.for()`, `.delete()`, `.has()`, etc. on instances of
|
|
138
|
+
* `MyTargetType`, to manage the `MyExt` instances attached to them.
|
|
139
|
+
*
|
|
140
|
+
* @template Target The type of target this extension will extend.
|
|
141
|
+
*
|
|
142
|
+
* @categoryDescription Extension Management
|
|
143
|
+
*
|
|
144
|
+
* Static methods for working with extensions of the subclass type, e.g.
|
|
145
|
+
* `MyExt.for(someTarget)`.
|
|
146
|
+
*
|
|
147
|
+
* @categoryDescription Lifecycle Hooks
|
|
148
|
+
*
|
|
149
|
+
* Instance and static members you can override to customize extension creation,
|
|
150
|
+
* deletion, target and return types.
|
|
151
|
+
*/
|
|
152
|
+
declare abstract class Ext<Target extends WeakKey = WeakKey> {
|
|
153
|
+
/**
|
|
154
|
+
* The target the extension was created for (set automatically by the base
|
|
155
|
+
* class constructor). You can narrow the target type either by extending
|
|
156
|
+
* `Ext<SomeType>` directly, or by using `declare readonly of: SomeType` in
|
|
157
|
+
* your subclass.
|
|
158
|
+
*
|
|
159
|
+
* @category Lifecycle Hooks
|
|
160
|
+
*/
|
|
161
|
+
readonly of: Target;
|
|
162
|
+
/**
|
|
163
|
+
* A "virtual" property you can override in subclasses to change the static
|
|
164
|
+
* interface's return type. For example, if a subclass does `declare readonly __type__:
|
|
165
|
+
* Promise<this>`, and overrides `__new__`() to return a promise, then the
|
|
166
|
+
* static APIs for the subclass (like `.for()`) will return promises instead
|
|
167
|
+
* of instances. (See the {@link __new__ `__new__`} method for more
|
|
168
|
+
* details.)
|
|
169
|
+
*
|
|
170
|
+
* Note: this property is not actually set by any code, so you can't do anything
|
|
171
|
+
* other than declare it. It's just a hack to work around TypeScript's limited
|
|
172
|
+
* type parameterization for static generics.
|
|
173
|
+
*
|
|
174
|
+
* @category Lifecycle Hooks
|
|
175
|
+
*/
|
|
176
|
+
readonly __type__: unknown;
|
|
177
|
+
/**
|
|
178
|
+
* @deprecated Use .for() instead!
|
|
179
|
+
*
|
|
180
|
+
* Never directly call the constructor of an Ext subclass except from the
|
|
181
|
+
* {@link __new__ `__new__()`} method - otherwise you run the risk of having
|
|
182
|
+
* multiple instances for the same target. (And it may accept invalid
|
|
183
|
+
* parameter values if you've redefined the type of the {@link Ext.of `of`}
|
|
184
|
+
* property in a sub-subclass.)
|
|
185
|
+
*/
|
|
186
|
+
constructor(of: Target);
|
|
187
|
+
/**
|
|
188
|
+
* Get or create an extension instance for the given target.
|
|
189
|
+
* @category Extension Management
|
|
190
|
+
*/
|
|
191
|
+
static for<Class extends Ext.Class>(this: Class, tgt: Ext.Target<Class>): Ext.Type<Class>;
|
|
192
|
+
/**
|
|
193
|
+
* Get the current extension instance for the given target, or `undefined`
|
|
194
|
+
* if there isn't one.
|
|
195
|
+
*
|
|
196
|
+
* @category Extension Management
|
|
197
|
+
*/
|
|
198
|
+
static get<Class extends Ext.Class>(this: Class, tgt: Ext.Target<Class>): Ext.Type<Class> | undefined;
|
|
199
|
+
/**
|
|
200
|
+
* Does an extension currently exist for the given target?
|
|
201
|
+
*
|
|
202
|
+
* @category Extension Management
|
|
203
|
+
*/
|
|
204
|
+
static has<Class extends Ext.Class>(this: Class, tgt: Ext.Target<Class>): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Delete the current extension for the given target (if one exists), after calling the
|
|
207
|
+
* {@link __del__ `__del__()`} method on it.
|
|
208
|
+
*
|
|
209
|
+
* @category Extension Management
|
|
210
|
+
*/
|
|
211
|
+
static delete<Class extends Ext.Class>(this: Class, tgt: Ext.Target<Class>): void;
|
|
212
|
+
/**
|
|
213
|
+
* This method is called by {@link for}() to create the extension instance
|
|
214
|
+
* for a target. You can override this method to customize instance creation
|
|
215
|
+
* behavior, e.g. to execute the constructor within a job, or create a
|
|
216
|
+
* promise for an extension instance to be asynchronously initiaized, etc.
|
|
217
|
+
*
|
|
218
|
+
* If you will be creating something other than an instance of the subclass,
|
|
219
|
+
* you must also redeclare the type of the {@link __type__ `__type__`}
|
|
220
|
+
* property. For example:
|
|
221
|
+
*
|
|
222
|
+
* ```ts
|
|
223
|
+
* class AsyncExt extends Ext {
|
|
224
|
+
* declare readonly __type__: Job<this>
|
|
225
|
+
*
|
|
226
|
+
* // simulate slow initialization
|
|
227
|
+
* *setup() { yield *sleep(100); return this; }
|
|
228
|
+
*
|
|
229
|
+
* static __new__<Class extends typeof AsyncExt>(
|
|
230
|
+
* tgt: Ext.Target<Class>, map: Ext.Map<Class>
|
|
231
|
+
* ) {
|
|
232
|
+
* const ext = new this(tgt);
|
|
233
|
+
* map.set(tgt, root.start(ext.setup()) as Ext.Type<Class>);
|
|
234
|
+
* }
|
|
235
|
+
* }
|
|
236
|
+
* ```
|
|
237
|
+
*
|
|
238
|
+
* Now, `AsyncExt.for(someTarget)` will create and cache a Job yielding an
|
|
239
|
+
* extension whose `setup()` has finished. (And subclasses of `AsyncExt`
|
|
240
|
+
* will share the same behavior, while being subtyped appropriately.)
|
|
241
|
+
*
|
|
242
|
+
* (Note: your `__new__` method *must* store what it created in the supplied
|
|
243
|
+
* map for the given target, and the value it sets must conform to the
|
|
244
|
+
* declared `__type__`, which is *not* checked for you by TypeScript!)
|
|
245
|
+
*
|
|
246
|
+
* @category Lifecycle Hooks
|
|
247
|
+
*/
|
|
248
|
+
static __new__<Class extends Ext.Class>(this: Class, tgt: Ext.Target<Class>, map: Ext.Map<Class>): void;
|
|
249
|
+
/**
|
|
250
|
+
* This method is called by {@link delete}() if it finds an existing
|
|
251
|
+
* extension for the target. You can override it in a subclass to do any
|
|
252
|
+
* necessary cleanup on the extension. (If you need to retrieve the
|
|
253
|
+
* extension, you can call .get() on the target.)
|
|
254
|
+
*
|
|
255
|
+
* @category Lifecycle Hooks
|
|
256
|
+
*/
|
|
257
|
+
static __del__<Class extends Ext.Class>(this: Class, _target: Ext.Target<Class>): void;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { Ext, ext, method };
|
package/dist/ext.mjs
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { s as setMap } from './utils-cyEhnyp7.mjs';
|
|
2
|
+
|
|
3
|
+
function ext(factory, map = /* @__PURE__ */ new WeakMap()) {
|
|
4
|
+
return (tgt) => map.has(tgt) ? map.get(tgt) : setMap(map, tgt, factory(tgt, map));
|
|
5
|
+
}
|
|
6
|
+
function method(factory, map = /* @__PURE__ */ new WeakMap()) {
|
|
7
|
+
return (tgt, ...args) => (map.get(tgt) ?? setMap(map, tgt, factory(tgt, map)))(...args);
|
|
8
|
+
}
|
|
9
|
+
const classMap = /* @__PURE__ */ ext((cls) => /* @__PURE__ */ new WeakMap());
|
|
10
|
+
class Ext {
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated Use .for() instead!
|
|
13
|
+
*
|
|
14
|
+
* Never directly call the constructor of an Ext subclass except from the
|
|
15
|
+
* {@link __new__ `__new__()`} method - otherwise you run the risk of having
|
|
16
|
+
* multiple instances for the same target. (And it may accept invalid
|
|
17
|
+
* parameter values if you've redefined the type of the {@link Ext.of `of`}
|
|
18
|
+
* property in a sub-subclass.)
|
|
19
|
+
*/
|
|
20
|
+
constructor(of) {
|
|
21
|
+
this.of = of;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get or create an extension instance for the given target.
|
|
25
|
+
* @category Extension Management
|
|
26
|
+
*/
|
|
27
|
+
static for(tgt) {
|
|
28
|
+
const map = classMap(this);
|
|
29
|
+
return map.get(tgt) ?? (this.__new__(tgt, map), map.get(tgt));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the current extension instance for the given target, or `undefined`
|
|
33
|
+
* if there isn't one.
|
|
34
|
+
*
|
|
35
|
+
* @category Extension Management
|
|
36
|
+
*/
|
|
37
|
+
static get(tgt) {
|
|
38
|
+
return classMap(this).get(tgt);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Does an extension currently exist for the given target?
|
|
42
|
+
*
|
|
43
|
+
* @category Extension Management
|
|
44
|
+
*/
|
|
45
|
+
static has(tgt) {
|
|
46
|
+
return classMap(this).has(tgt);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Delete the current extension for the given target (if one exists), after calling the
|
|
50
|
+
* {@link __del__ `__del__()`} method on it.
|
|
51
|
+
*
|
|
52
|
+
* @category Extension Management
|
|
53
|
+
*/
|
|
54
|
+
static delete(tgt) {
|
|
55
|
+
const map = classMap(this);
|
|
56
|
+
if (map.has(tgt)) {
|
|
57
|
+
this.__del__(tgt);
|
|
58
|
+
map.delete(tgt);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* This method is called by {@link for}() to create the extension instance
|
|
63
|
+
* for a target. You can override this method to customize instance creation
|
|
64
|
+
* behavior, e.g. to execute the constructor within a job, or create a
|
|
65
|
+
* promise for an extension instance to be asynchronously initiaized, etc.
|
|
66
|
+
*
|
|
67
|
+
* If you will be creating something other than an instance of the subclass,
|
|
68
|
+
* you must also redeclare the type of the {@link __type__ `__type__`}
|
|
69
|
+
* property. For example:
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* class AsyncExt extends Ext {
|
|
73
|
+
* declare readonly __type__: Job<this>
|
|
74
|
+
*
|
|
75
|
+
* // simulate slow initialization
|
|
76
|
+
* *setup() { yield *sleep(100); return this; }
|
|
77
|
+
*
|
|
78
|
+
* static __new__<Class extends typeof AsyncExt>(
|
|
79
|
+
* tgt: Ext.Target<Class>, map: Ext.Map<Class>
|
|
80
|
+
* ) {
|
|
81
|
+
* const ext = new this(tgt);
|
|
82
|
+
* map.set(tgt, root.start(ext.setup()) as Ext.Type<Class>);
|
|
83
|
+
* }
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* Now, `AsyncExt.for(someTarget)` will create and cache a Job yielding an
|
|
88
|
+
* extension whose `setup()` has finished. (And subclasses of `AsyncExt`
|
|
89
|
+
* will share the same behavior, while being subtyped appropriately.)
|
|
90
|
+
*
|
|
91
|
+
* (Note: your `__new__` method *must* store what it created in the supplied
|
|
92
|
+
* map for the given target, and the value it sets must conform to the
|
|
93
|
+
* declared `__type__`, which is *not* checked for you by TypeScript!)
|
|
94
|
+
*
|
|
95
|
+
* @category Lifecycle Hooks
|
|
96
|
+
*/
|
|
97
|
+
static __new__(tgt, map) {
|
|
98
|
+
map.set(tgt, new this(tgt, map));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* This method is called by {@link delete}() if it finds an existing
|
|
102
|
+
* extension for the target. You can override it in a subclass to do any
|
|
103
|
+
* necessary cleanup on the extension. (If you need to retrieve the
|
|
104
|
+
* extension, you can call .get() on the target.)
|
|
105
|
+
*
|
|
106
|
+
* @category Lifecycle Hooks
|
|
107
|
+
*/
|
|
108
|
+
static __del__(_target) {
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { Ext, ext, method };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as batch, d as defer, i as isFunction, G as GeneratorBase, c as apply } from './utils-
|
|
1
|
+
import { e as batch, d as defer, i as isFunction, G as GeneratorBase, c as apply } from './utils-cyEhnyp7.mjs';
|
|
2
2
|
|
|
3
3
|
function resolve(request, val) {
|
|
4
4
|
request("next", val);
|
|
@@ -44,12 +44,13 @@ function markHandled(res) {
|
|
|
44
44
|
return res.err;
|
|
45
45
|
}
|
|
46
46
|
function getResult(res) {
|
|
47
|
-
if (isValue(res))
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
47
|
+
if (!isValue(res)) {
|
|
48
|
+
res.op;
|
|
49
|
+
fulfillPromise(noop, (e) => {
|
|
50
|
+
throw e;
|
|
51
|
+
}, res);
|
|
52
|
+
}
|
|
53
|
+
return res.val;
|
|
53
54
|
}
|
|
54
55
|
function fulfillPromise(resolve2, reject2, res) {
|
|
55
56
|
if (isError(res))
|
|
@@ -66,31 +67,25 @@ function propagateResult(job, res) {
|
|
|
66
67
|
class CancelError extends Error {
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
var
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return { job, cell };
|
|
84
|
-
}
|
|
85
|
-
function freeCtx(s) {
|
|
86
|
-
s.job = s.cell = null;
|
|
87
|
-
freelist.push(s);
|
|
70
|
+
var currentJob, currentCell;
|
|
71
|
+
const cells = [], jobs = [];
|
|
72
|
+
function pushCtx(job, cell) {
|
|
73
|
+
jobs.push(currentJob);
|
|
74
|
+
cells.push(currentCell);
|
|
75
|
+
currentJob = job;
|
|
76
|
+
currentCell = cell;
|
|
77
|
+
}
|
|
78
|
+
function popCtx() {
|
|
79
|
+
currentJob = jobs.pop();
|
|
80
|
+
currentCell = cells.pop();
|
|
81
|
+
}
|
|
82
|
+
function cellJob() {
|
|
83
|
+
return currentJob ||= currentCell?.getJob();
|
|
88
84
|
}
|
|
89
85
|
|
|
90
86
|
const catchers = /* @__PURE__ */ new WeakMap(), defaultCatch = (e) => {
|
|
91
87
|
Promise.reject(e);
|
|
92
88
|
};
|
|
93
|
-
const nullCtx = makeCtx();
|
|
94
89
|
const owners = /* @__PURE__ */ new WeakMap();
|
|
95
90
|
const pulls = /* @__PURE__ */ batch((pulls2) => {
|
|
96
91
|
for (const conn of pulls2) {
|
|
@@ -127,8 +122,7 @@ function qlen(c) {
|
|
|
127
122
|
return c ? c.v : 0;
|
|
128
123
|
}
|
|
129
124
|
function pop(c) {
|
|
130
|
-
|
|
131
|
-
return unlink(c, c.p);
|
|
125
|
+
return qlen(c) ? unlink(c, c.p) : void 0;
|
|
132
126
|
}
|
|
133
127
|
class Node {
|
|
134
128
|
constructor() {
|
|
@@ -185,22 +179,23 @@ function unlinker(chain2, node) {
|
|
|
185
179
|
}
|
|
186
180
|
|
|
187
181
|
function getJob() {
|
|
188
|
-
const job =
|
|
182
|
+
const job = currentJob || cellJob();
|
|
189
183
|
if (job)
|
|
190
184
|
return job;
|
|
191
185
|
throw new Error("No job is currently active");
|
|
192
186
|
}
|
|
193
187
|
function recalcJob(job) {
|
|
194
188
|
return (cb) => {
|
|
195
|
-
|
|
189
|
+
currentJob.must(job.release(cb));
|
|
196
190
|
};
|
|
197
191
|
}
|
|
198
192
|
function runChain(res, cbs) {
|
|
199
|
-
|
|
193
|
+
let cb;
|
|
194
|
+
while (cb = pop(cbs))
|
|
200
195
|
try {
|
|
201
|
-
|
|
196
|
+
cb(res);
|
|
202
197
|
} catch (e) {
|
|
203
|
-
|
|
198
|
+
_detached.asyncThrow(e);
|
|
204
199
|
}
|
|
205
200
|
cbs && recycle(cbs);
|
|
206
201
|
return void 0;
|
|
@@ -212,14 +207,15 @@ class _Job {
|
|
|
212
207
|
const res = this._done ||= CancelResult, cbs = this._cbs;
|
|
213
208
|
if (!cbs && !isUnhandled(res))
|
|
214
209
|
return;
|
|
215
|
-
const ct = inProcess.size
|
|
210
|
+
const ct = inProcess.size;
|
|
211
|
+
pushCtx();
|
|
216
212
|
if (!ct)
|
|
217
213
|
inProcess.add(null);
|
|
218
214
|
if (cbs && cbs.u)
|
|
219
215
|
cbs.u = runChain(res, cbs.u);
|
|
220
216
|
inProcess.add(this);
|
|
221
217
|
if (ct) {
|
|
222
|
-
|
|
218
|
+
popCtx();
|
|
223
219
|
return;
|
|
224
220
|
}
|
|
225
221
|
inProcess.delete(null);
|
|
@@ -230,7 +226,7 @@ class _Job {
|
|
|
230
226
|
if (isUnhandled(item._done))
|
|
231
227
|
item.throw(markHandled(item._done));
|
|
232
228
|
}
|
|
233
|
-
|
|
229
|
+
popCtx();
|
|
234
230
|
};
|
|
235
231
|
this._done = void 0;
|
|
236
232
|
// Chain whose .u stores a second chain for `release()` callbacks
|
|
@@ -268,7 +264,7 @@ class _Job {
|
|
|
268
264
|
});
|
|
269
265
|
}
|
|
270
266
|
result() {
|
|
271
|
-
return this._done ||
|
|
267
|
+
return this._done || currentCell?.recalcWhen(this, recalcJob) || void 0;
|
|
272
268
|
}
|
|
273
269
|
get [Symbol.toStringTag]() {
|
|
274
270
|
return "Job";
|
|
@@ -380,21 +376,21 @@ class _Job {
|
|
|
380
376
|
return this.start((job) => void src(sink, job, inlet));
|
|
381
377
|
}
|
|
382
378
|
run(fn, ...args) {
|
|
383
|
-
|
|
379
|
+
pushCtx(this);
|
|
384
380
|
try {
|
|
385
381
|
return fn(...args);
|
|
386
382
|
} finally {
|
|
387
|
-
|
|
383
|
+
popCtx();
|
|
388
384
|
}
|
|
389
385
|
}
|
|
390
386
|
bind(fn) {
|
|
391
387
|
const job = this;
|
|
392
388
|
return function() {
|
|
393
|
-
|
|
389
|
+
pushCtx(job);
|
|
394
390
|
try {
|
|
395
391
|
return apply(fn, this, arguments);
|
|
396
392
|
} finally {
|
|
397
|
-
|
|
393
|
+
popCtx();
|
|
398
394
|
}
|
|
399
395
|
};
|
|
400
396
|
}
|
|
@@ -469,8 +465,8 @@ function newRoot() {
|
|
|
469
465
|
return root;
|
|
470
466
|
}
|
|
471
467
|
function runGen(g, job) {
|
|
472
|
-
let it = g[Symbol.iterator](), running = true,
|
|
473
|
-
let done =
|
|
468
|
+
let it = g[Symbol.iterator](), running = true, j = job, ct = 0;
|
|
469
|
+
let done = job.release(() => {
|
|
474
470
|
job = void 0;
|
|
475
471
|
++ct;
|
|
476
472
|
step("return", void 0);
|
|
@@ -485,7 +481,7 @@ function runGen(g, job) {
|
|
|
485
481
|
if (running) {
|
|
486
482
|
return defer(step.bind(null, method, arg));
|
|
487
483
|
}
|
|
488
|
-
|
|
484
|
+
pushCtx(j);
|
|
489
485
|
try {
|
|
490
486
|
running = true;
|
|
491
487
|
try {
|
|
@@ -519,13 +515,13 @@ function runGen(g, job) {
|
|
|
519
515
|
}
|
|
520
516
|
} catch (e) {
|
|
521
517
|
it = job = void 0;
|
|
522
|
-
|
|
518
|
+
j.throw(e);
|
|
523
519
|
}
|
|
524
520
|
it = void 0;
|
|
525
521
|
done?.();
|
|
526
522
|
done = void 0;
|
|
527
523
|
} finally {
|
|
528
|
-
|
|
524
|
+
popCtx();
|
|
529
525
|
running = false;
|
|
530
526
|
}
|
|
531
527
|
}
|
|
@@ -538,7 +534,7 @@ function start(init, fn) {
|
|
|
538
534
|
return getJob().start(init, fn);
|
|
539
535
|
}
|
|
540
536
|
function isJobActive() {
|
|
541
|
-
return !!
|
|
537
|
+
return !!currentJob;
|
|
542
538
|
}
|
|
543
539
|
const timers = /* @__PURE__ */ new WeakMap();
|
|
544
540
|
function timeout(ms = 0, job = getJob()) {
|
|
@@ -584,14 +580,14 @@ function restarting(task2) {
|
|
|
584
580
|
inner.asyncCatch((e) => outer.asyncThrow(e));
|
|
585
581
|
return function() {
|
|
586
582
|
inner.restart().must(outer.release(end));
|
|
587
|
-
|
|
583
|
+
pushCtx(inner);
|
|
588
584
|
try {
|
|
589
585
|
return apply(task2, this, arguments);
|
|
590
586
|
} catch (e) {
|
|
591
587
|
inner.restart();
|
|
592
588
|
throw e;
|
|
593
589
|
} finally {
|
|
594
|
-
|
|
590
|
+
popCtx();
|
|
595
591
|
}
|
|
596
592
|
};
|
|
597
593
|
}
|
|
@@ -603,5 +599,4 @@ function task(fn, _ctx, desc) {
|
|
|
603
599
|
};
|
|
604
600
|
}
|
|
605
601
|
|
|
606
|
-
export { timeout as A, abortSignal as B, CancelResult as C, task as D, ErrorResult as E,
|
|
607
|
-
//# sourceMappingURL=jobutils-CmHay7sf.mjs.map
|
|
602
|
+
export { timeout as A, abortSignal as B, CancelResult as C, task as D, ErrorResult as E, pushCtx as F, popCtx as G, currentJob as H, pulls as I, ValueResult as V, rejecter as a, resolve as b, root as c, isUnhandled as d, markHandled as e, isError as f, getJob as g, fulfillPromise as h, isCancel as i, restarting as j, currentCell as k, isValue as l, must as m, noop as n, reject as o, isHandled as p, getResult as q, resolver as r, start as s, propagateResult as t, CancelError as u, nativePromise as v, makeJob as w, detached as x, newRoot as y, isJobActive as z };
|
package/dist/mod.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { a as Each, E as EachResult, N as NextMethod, U as UntilMethod, e as eac
|
|
|
6
6
|
* Invoke a no-argument function as a microtask, using queueMicrotask or Promise.resolve().then()
|
|
7
7
|
*
|
|
8
8
|
* @category Scheduling
|
|
9
|
+
* @function
|
|
9
10
|
*/
|
|
10
11
|
declare let defer: (cb: () => any) => void;
|
|
11
12
|
|
|
@@ -53,6 +54,7 @@ declare function nativePromise<T>(job: Job<T>): Promise<T>;
|
|
|
53
54
|
* a detached (parentless) job otherwise.
|
|
54
55
|
*
|
|
55
56
|
* @category Jobs
|
|
57
|
+
* @function
|
|
56
58
|
*/
|
|
57
59
|
declare const makeJob: <T>(parent?: Job, stop?: CleanupFn) => Job<T>;
|
|
58
60
|
/**
|