@wardic/core 1.0.0-rc.4 → 1.0.0-rc.5
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/dist/Clock.d.ts.map +1 -1
- package/dist/Clock.js +20 -12
- package/dist/Clock.js.map +1 -1
- package/dist/FrameLoop.d.ts +12 -1
- package/dist/FrameLoop.d.ts.map +1 -1
- package/dist/FrameLoop.js +23 -1
- package/dist/FrameLoop.js.map +1 -1
- package/dist/LiveValue.d.ts +2 -2
- package/dist/LiveValue.d.ts.map +1 -1
- package/dist/LiveValue.js +5 -4
- package/dist/LiveValue.js.map +1 -1
- package/dist/Probe.d.ts +4 -46
- package/dist/Probe.d.ts.map +1 -1
- package/dist/Probe.js +5 -5
- package/dist/Probe.js.map +1 -1
- package/dist/ScrollSource.d.ts +62 -0
- package/dist/ScrollSource.d.ts.map +1 -0
- package/dist/ScrollSource.js +21 -0
- package/dist/ScrollSource.js.map +1 -0
- package/dist/SharedSource.d.ts +35 -15
- package/dist/SharedSource.d.ts.map +1 -1
- package/dist/SharedSource.js +84 -108
- package/dist/SharedSource.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/frameLoop.d.ts +17 -0
- package/dist/internal/frameLoop.d.ts.map +1 -1
- package/dist/internal/frameLoop.js +33 -20
- package/dist/internal/frameLoop.js.map +1 -1
- package/dist/internal/hearing.d.ts +13 -0
- package/dist/internal/hearing.d.ts.map +1 -0
- package/dist/internal/hearing.js +71 -0
- package/dist/internal/hearing.js.map +1 -0
- package/package.json +1 -1
- package/src/Clock.ts +29 -17
- package/src/FrameLoop.ts +24 -1
- package/src/LiveValue.ts +7 -6
- package/src/Probe.ts +7 -53
- package/src/ScrollSource.ts +68 -0
- package/src/SharedSource.ts +113 -146
- package/src/index.ts +2 -1
- package/src/internal/frameLoop.ts +41 -18
- package/src/internal/hearing.ts +76 -0
package/dist/SharedSource.d.ts
CHANGED
|
@@ -1,34 +1,54 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Shared sources, for the Streams an Environment hands out: each hot and counted, so however many
|
|
3
|
+
* subscribe, one underlying source runs, started by the first subscriber and stopped when the last one
|
|
4
|
+
* leaves. `byTarget` keeps one per target, one observer on each element, and `make` one for the whole
|
|
5
|
+
* Environment. An Environment builds its sources with these, as `@wardic/dom` does, and `counted` shares
|
|
6
|
+
* anything else it opens per target.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* import * as SharedSource from "@wardic/core/SharedSource"
|
|
10
|
+
*
|
|
11
|
+
* const resize = yield* SharedSource.byTarget((target) => Effect.succeed(resizesOf(target)))
|
|
12
|
+
* // Both share one observer on `card`:
|
|
13
|
+
* Stream.runForEach(resize(card), onLayout)
|
|
14
|
+
* Stream.runForEach(resize(card), onScroll)
|
|
15
|
+
*/
|
|
2
16
|
import * as Effect from "effect/Effect";
|
|
3
|
-
import
|
|
17
|
+
import * as Scope from "effect/Scope";
|
|
4
18
|
import * as Stream from "effect/Stream";
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Values shared by key and counted: the first hold of a key opens its value with `open`, later holds
|
|
21
|
+
* share it, and the last one's release closes it with `close`. A key is held by identity and never
|
|
22
|
+
* hashed, so a DOM node is its own key. `open` runs inline, so it mustn't wait.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // One listener set per container, however many readers hold it
|
|
26
|
+
* const containers = SharedSource.counted(
|
|
27
|
+
* (container: Element) => ({ remove: listenTo(container) }),
|
|
28
|
+
* (listening) => Effect.sync(listening.remove),
|
|
29
|
+
* )
|
|
30
|
+
* const listening = yield* containers(list) // held until the current Scope closes
|
|
31
|
+
*/
|
|
32
|
+
export declare const counted: <K, V>(open: (key: K) => V, close: (value: V) => Effect.Effect<void>) => ((key: K) => Effect.Effect<V, never, Scope.Scope>);
|
|
13
33
|
/**
|
|
14
34
|
* A shared source per target: a function from a target to a Stream that's hot and counted for that
|
|
15
35
|
* target. The first subscriber for a target starts `lookup(target)`'s source, later ones share it, and it
|
|
16
|
-
* stops when the last one for that target leaves
|
|
36
|
+
* stops when the last one for that target leaves.
|
|
17
37
|
*
|
|
18
38
|
* @example
|
|
19
39
|
* // `resizesOf(target)`: an Environment's own Stream of a target's sizes
|
|
20
40
|
* const resize = yield* SharedSource.byTarget((target) => Effect.succeed(resizesOf(target)))
|
|
21
41
|
*/
|
|
22
|
-
export declare const byTarget: <A>(lookup: (target: unknown) => Effect.Effect<Stream.Stream<A>, never, Scope.Scope
|
|
42
|
+
export declare const byTarget: <A>(lookup: (target: unknown) => Effect.Effect<Stream.Stream<A>, never, Scope.Scope>) => Effect.Effect<(target: unknown) => Stream.Stream<A>, never, Scope.Scope>;
|
|
23
43
|
/**
|
|
24
44
|
* One shared source for the whole Environment: a Stream that's hot and counted. The first subscriber
|
|
25
|
-
* starts `acquire`'s source, later ones share it, and it stops when the last one leaves
|
|
26
|
-
*
|
|
45
|
+
* starts `acquire`'s source, later ones share it, and it stops when the last one leaves. `byTarget`'s
|
|
46
|
+
* form without a target.
|
|
27
47
|
*
|
|
28
48
|
* @example
|
|
29
49
|
* // `viewportChanges`: an Environment's own Stream of its viewport's size
|
|
30
50
|
* const viewport = yield* SharedSource.make(Effect.succeed(viewportChanges))
|
|
31
51
|
* Stream.runForEach(viewport, onResize) // one listener, however many subscribe
|
|
32
52
|
*/
|
|
33
|
-
export declare const make: <A>(acquire: Effect.Effect<Stream.Stream<A>, never, Scope.Scope
|
|
53
|
+
export declare const make: <A>(acquire: Effect.Effect<Stream.Stream<A>, never, Scope.Scope>) => Effect.Effect<Stream.Stream<A>, never, Scope.Scope>;
|
|
34
54
|
//# sourceMappingURL=SharedSource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedSource.d.ts","sourceRoot":"","sources":["../src/SharedSource.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SharedSource.d.ts","sourceRoot":"","sources":["../src/SharedSource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgBH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAKvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAUvC;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,CAAC,QACpB,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,SACZ,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KACvC,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAoBnD,CAAA;AAwDD;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,EAAE,CAAC,CAAC,EACvB,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAC7E,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAUxE,CAAA;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,EAAE,CAAC,CAAC,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KACzD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CASnD,CAAA"}
|
package/dist/SharedSource.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Shared sources, for the Streams an Environment hands out: each hot and counted, so however many
|
|
3
3
|
* subscribe, one underlying source runs, started by the first subscriber and stopped when the last one
|
|
4
4
|
* leaves. `byTarget` keeps one per target, one observer on each element, and `make` one for the whole
|
|
5
|
-
* Environment. An Environment builds its sources with these, as `@wardic/dom` does
|
|
5
|
+
* Environment. An Environment builds its sources with these, as `@wardic/dom` does, and `counted` shares
|
|
6
|
+
* anything else it opens per target.
|
|
6
7
|
*
|
|
7
8
|
* @example
|
|
8
9
|
* import * as SharedSource from "@wardic/core/SharedSource"
|
|
@@ -13,146 +14,121 @@
|
|
|
13
14
|
* Stream.runForEach(resize(card), onScroll)
|
|
14
15
|
*/
|
|
15
16
|
// CONTEXT.md's **Shared source** contract (#37, ADR-0041 *Amendment (#37)*). An Environment's **Input
|
|
16
|
-
// feeds** are shared by `InputFeed.byTarget` instead, with no
|
|
17
|
+
// feeds** are shared by `InputFeed.byTarget` instead, with no fiber (#318).
|
|
17
18
|
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
// `Stream.broadcast` do this too, but put 2.2 KB gzip on every app (`bun run size`), so the pump stays.
|
|
19
|
+
// One shape under both constructors (#518, ADR-0067 *Amendment (#518)*, decision 3): a target's entry in
|
|
20
|
+
// a `counted` map holds its subscribers' hearings and, while any subscriber holds it, a pump that runs the
|
|
21
|
+
// cold source and hands each element to every hearing, which resumes a waiting subscriber inside the
|
|
22
|
+
// call, as the `PubSub` did. The first subscriber opens the entry and starts the pump; the
|
|
23
|
+
// last one's release interrupts it, and the cold source's finalizers run (a listener is removed). The
|
|
24
|
+
// source's end ends every subscriber, and its failure fails them (#618, decision 6). It replaced a
|
|
25
|
+
// `PubSub` per source in Effect's `RcMap` and `RcRef`, whose code every app shipped (4.1 KB gzipped with
|
|
26
|
+
// `Clock.ticks`' and the DOM's scroll containers'), and whose `idleTimeToLive` nothing passed.
|
|
27
27
|
//
|
|
28
28
|
// Tier 2 (ADR-0008), for Environment authors, as `InputSource.heldPointer` is (#31's rule: Wardic ships
|
|
29
29
|
// what makes a new Environment little work). Observability: each constructor emits a
|
|
30
|
-
// `wardic.sharedSource.*` span and a debug log on subscribe; the per-event
|
|
31
|
-
import * as Cause from "effect/Cause";
|
|
30
|
+
// `wardic.sharedSource.*` span and a debug log on subscribe; the per-event path stays quiet.
|
|
32
31
|
import * as Effect from "effect/Effect";
|
|
33
|
-
import * as Equal from "effect/Equal";
|
|
34
32
|
import * as Exit from "effect/Exit";
|
|
35
|
-
import
|
|
36
|
-
import * as
|
|
37
|
-
import * as Match from "effect/Match";
|
|
38
|
-
import * as MutableRef from "effect/MutableRef";
|
|
33
|
+
import * as Fiber from "effect/Fiber";
|
|
34
|
+
import * as Iter from "effect/Iterable";
|
|
39
35
|
import * as Option from "effect/Option";
|
|
40
|
-
import * as
|
|
41
|
-
import * as PubSub from "effect/PubSub";
|
|
42
|
-
import * as RcMap from "effect/RcMap";
|
|
43
|
-
import * as RcRef from "effect/RcRef";
|
|
36
|
+
import * as Scope from "effect/Scope";
|
|
44
37
|
import * as Stream from "effect/Stream";
|
|
45
|
-
import * as
|
|
38
|
+
import * as Hearing from "./internal/hearing.js";
|
|
46
39
|
import { tracedStream } from "./internal/tracing.js";
|
|
47
40
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
41
|
+
* Values shared by key and counted: the first hold of a key opens its value with `open`, later holds
|
|
42
|
+
* share it, and the last one's release closes it with `close`. A key is held by identity and never
|
|
43
|
+
* hashed, so a DOM node is its own key. `open` runs inline, so it mustn't wait.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // One listener set per container, however many readers hold it
|
|
47
|
+
* const containers = SharedSource.counted(
|
|
48
|
+
* (container: Element) => ({ remove: listenTo(container) }),
|
|
49
|
+
* (listening) => Effect.sync(listening.remove),
|
|
50
|
+
* )
|
|
51
|
+
* const listening = yield* containers(list) // held until the current Scope closes
|
|
53
52
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
53
|
+
// #518: what `RcMap` gave the DOM's scroll containers (#618, M7), with no Scope per entry and no `Hash`.
|
|
54
|
+
export const counted = (open, close) => {
|
|
55
|
+
const held = new Map();
|
|
56
|
+
const acquire = (key) => Effect.sync(() => {
|
|
57
|
+
const entry = Option.getOrElse(Option.fromUndefinedOr(held.get(key)), () => {
|
|
58
|
+
const opened = { value: open(key), count: 0 };
|
|
59
|
+
held.set(key, opened);
|
|
60
|
+
return opened;
|
|
61
|
+
});
|
|
62
|
+
entry.count++;
|
|
63
|
+
return entry;
|
|
64
|
+
});
|
|
65
|
+
const release = (key, entry) => Effect.suspend(() => {
|
|
66
|
+
entry.count--;
|
|
67
|
+
if (entry.count > 0)
|
|
68
|
+
return Effect.void;
|
|
69
|
+
if (held.get(key) === entry)
|
|
70
|
+
held.delete(key);
|
|
71
|
+
return close(entry.value);
|
|
72
|
+
});
|
|
73
|
+
return (key) => Effect.map(Effect.acquireRelease(acquire(key), (entry) => release(key, entry)), (entry) => entry.value);
|
|
68
74
|
};
|
|
69
|
-
/**
|
|
70
|
-
const
|
|
71
|
-
/**
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
/** A fresh source's entry, with no subscriber, no pump and no end. */
|
|
76
|
+
const fanned = () => ({ hearings: new Set(), pump: Option.none(), ended: Option.none() });
|
|
77
|
+
/** The pump: `acquire`'s source, each element to every subscriber; its end, kept and handed to each. */
|
|
78
|
+
const pumpOf = (entry, acquire) => Effect.scoped(Effect.flatMap(acquire, (source) => Stream.runForEach(source, (a) => Effect.sync(() => Iter.forEach(entry.hearings, (hearing) => hearing.hear(a)))))).pipe(Effect.onExit((exit) => Effect.sync(() => {
|
|
79
|
+
entry.ended = Option.some(exit);
|
|
80
|
+
Iter.forEach(entry.hearings, (hearing) => hearing.end(exit));
|
|
81
|
+
})));
|
|
82
|
+
/** An entry's pump stopped, its last subscriber gone. */
|
|
83
|
+
const stop = (entry) => Option.match(entry.pump, { onNone: () => Effect.void, onSome: (pump) => Effect.asVoid(Fiber.interrupt(pump)) });
|
|
76
84
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* distinct targets. This wrapper is equal by reference, with a stable per-instance hash, so `RcMap`
|
|
81
|
-
* never inspects the target and each distinct target is its own entry. One wrapper is cached per
|
|
82
|
-
* target (the `WeakMap` in {@link byTarget}).
|
|
85
|
+
* A subscriber to `key`'s shared source: its hearing on the entry while its Stream runs, the pump started
|
|
86
|
+
* for the first, in `scope`, the shared source's. One that subscribes after the source ended gets the end
|
|
87
|
+
* alone.
|
|
83
88
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.target = target;
|
|
91
|
-
this.hash = nextTargetHash++;
|
|
92
|
-
}
|
|
93
|
-
[Hash.symbol]() {
|
|
94
|
-
return this.hash;
|
|
95
|
-
}
|
|
96
|
-
[Equal.symbol](that) {
|
|
97
|
-
return this === that;
|
|
89
|
+
const subscriberOf = (hold, key, acquire, scope) => Stream.unwrap(Effect.gen(function* () {
|
|
90
|
+
const entry = yield* hold(key);
|
|
91
|
+
const hearing = Hearing.make();
|
|
92
|
+
if (Option.isSome(entry.ended)) {
|
|
93
|
+
hearing.end(entry.ended.value);
|
|
94
|
+
return hearing.stream;
|
|
98
95
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
// Its hearing first, so what the pump hands on as it starts reaches it.
|
|
97
|
+
entry.hearings.add(hearing);
|
|
98
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => entry.hearings.delete(hearing)));
|
|
99
|
+
if (Option.isNone(entry.pump))
|
|
100
|
+
entry.pump = Option.some(yield* Effect.forkIn(pumpOf(entry, acquire()), scope, { startImmediately: true }));
|
|
101
|
+
return hearing.stream;
|
|
102
|
+
}));
|
|
104
103
|
/**
|
|
105
104
|
* A shared source per target: a function from a target to a Stream that's hot and counted for that
|
|
106
105
|
* target. The first subscriber for a target starts `lookup(target)`'s source, later ones share it, and it
|
|
107
|
-
* stops when the last one for that target leaves
|
|
106
|
+
* stops when the last one for that target leaves.
|
|
108
107
|
*
|
|
109
108
|
* @example
|
|
110
109
|
* // `resizesOf(target)`: an Environment's own Stream of a target's sizes
|
|
111
110
|
* const resize = yield* SharedSource.byTarget((target) => Effect.succeed(resizesOf(target)))
|
|
112
111
|
*/
|
|
113
|
-
export const byTarget = /*#__PURE__*/ Effect.fnUntraced(function* (lookup
|
|
112
|
+
export const byTarget = /*#__PURE__*/ Effect.fnUntraced(function* (lookup) {
|
|
114
113
|
yield* Effect.logDebug("wardic.sharedSource.byTarget: create");
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const keys = new WeakMap();
|
|
119
|
-
const keyFor = (target) => Option.match(Option.liftPredicate(target, Predicate.isObjectOrArray), {
|
|
120
|
-
onNone: () => target,
|
|
121
|
-
onSome: (object) => Option.getOrElse(Option.fromUndefinedOr(keys.get(object)), () => {
|
|
122
|
-
const key = new TargetKey(object);
|
|
123
|
-
keys.set(object, key);
|
|
124
|
-
return key;
|
|
125
|
-
}),
|
|
126
|
-
});
|
|
127
|
-
const map = yield* RcMap.make({
|
|
128
|
-
lookup: (key) => fanIn(lookup(targetOf(key))),
|
|
129
|
-
...idleOf(options),
|
|
130
|
-
});
|
|
131
|
-
return (target) => tracedStream(Stream.unwrap(Effect.gen(function* () {
|
|
132
|
-
yield* Effect.logDebug("wardic.sharedSource.byTarget: subscribe");
|
|
133
|
-
return subscriberOf(yield* RcMap.get(map, keyFor(target)));
|
|
134
|
-
})), "wardic.sharedSource.byTarget");
|
|
114
|
+
const scope = yield* Scope.Scope;
|
|
115
|
+
const hold = counted(fanned, stop);
|
|
116
|
+
return (target) => tracedStream(Stream.unwrap(Effect.as(Effect.logDebug("wardic.sharedSource.byTarget: subscribe"), subscriberOf(hold, target, () => lookup(target), scope))), "wardic.sharedSource.byTarget");
|
|
135
117
|
});
|
|
136
118
|
/**
|
|
137
119
|
* One shared source for the whole Environment: a Stream that's hot and counted. The first subscriber
|
|
138
|
-
* starts `acquire`'s source, later ones share it, and it stops when the last one leaves
|
|
139
|
-
*
|
|
120
|
+
* starts `acquire`'s source, later ones share it, and it stops when the last one leaves. `byTarget`'s
|
|
121
|
+
* form without a target.
|
|
140
122
|
*
|
|
141
123
|
* @example
|
|
142
124
|
* // `viewportChanges`: an Environment's own Stream of its viewport's size
|
|
143
125
|
* const viewport = yield* SharedSource.make(Effect.succeed(viewportChanges))
|
|
144
126
|
* Stream.runForEach(viewport, onResize) // one listener, however many subscribe
|
|
145
127
|
*/
|
|
146
|
-
|
|
147
|
-
export const make = /*#__PURE__*/ Effect.fnUntraced(function* (acquire, options) {
|
|
128
|
+
export const make = /*#__PURE__*/ Effect.fnUntraced(function* (acquire) {
|
|
148
129
|
yield* Effect.logDebug("wardic.sharedSource.make: create");
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
});
|
|
153
|
-
return tracedStream(Stream.unwrap(Effect.gen(function* () {
|
|
154
|
-
yield* Effect.logDebug("wardic.sharedSource.make: subscribe");
|
|
155
|
-
return subscriberOf(yield* RcRef.get(ref));
|
|
156
|
-
})), "wardic.sharedSource.make");
|
|
130
|
+
const scope = yield* Scope.Scope;
|
|
131
|
+
const hold = counted(fanned, stop);
|
|
132
|
+
return tracedStream(Stream.unwrap(Effect.as(Effect.logDebug("wardic.sharedSource.make: subscribe"), subscriberOf(hold, undefined, () => acquire, scope))), "wardic.sharedSource.make");
|
|
157
133
|
});
|
|
158
134
|
//# sourceMappingURL=SharedSource.js.map
|
package/dist/SharedSource.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedSource.js","sourceRoot":"","sources":["../src/SharedSource.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SharedSource.js","sourceRoot":"","sources":["../src/SharedSource.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Each Primitive is a machine (`Machine`), run as a `Stream` over the Clock's ticks
|
|
8
8
|
* (`Machine.toStream`) or on the Frame loop (`Machine.run`). The services (`Clock`,
|
|
9
|
-
* `RefreshFrameSource`, `Renderer`, `InputSource`, `Probe`, `InterpolatorRegistry`, `FrameLoop`,
|
|
9
|
+
* `RefreshFrameSource`, `Renderer`, `InputSource`, `Probe`, `ScrollSource`, `InterpolatorRegistry`, `FrameLoop`,
|
|
10
10
|
* `DefaultTransition`) are each `X.X`, with the shared constructors the Environments build on
|
|
11
11
|
* (`Clock.layer`, `Clock.fromRefreshFrames`, `InputSource.heldPointer`, `InputFeed.byTarget`,
|
|
12
12
|
* `InterpolatorRegistry.layer`, `FrameLoop.layer`, `DefaultTransition.layerOneSpring`). Each module's
|
|
@@ -45,6 +45,7 @@ export * as RefreshFrameSource from "./RefreshFrameSource.ts";
|
|
|
45
45
|
export * as Renderer from "./Renderer.ts";
|
|
46
46
|
export * as Reorder from "./Reorder.ts";
|
|
47
47
|
export * as Scalar from "./Scalar.ts";
|
|
48
|
+
export * as ScrollSource from "./ScrollSource.ts";
|
|
48
49
|
export * as Sequence from "./Sequence.ts";
|
|
49
50
|
export * as SharedSource from "./SharedSource.ts";
|
|
50
51
|
export * as Spring from "./Spring.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,oBAAoB,MAAM,2BAA2B,CAAA;AACjE,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,oBAAoB,MAAM,2BAA2B,CAAA;AACjE,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Each Primitive is a machine (`Machine`), run as a `Stream` over the Clock's ticks
|
|
8
8
|
* (`Machine.toStream`) or on the Frame loop (`Machine.run`). The services (`Clock`,
|
|
9
|
-
* `RefreshFrameSource`, `Renderer`, `InputSource`, `Probe`, `InterpolatorRegistry`, `FrameLoop`,
|
|
9
|
+
* `RefreshFrameSource`, `Renderer`, `InputSource`, `Probe`, `ScrollSource`, `InterpolatorRegistry`, `FrameLoop`,
|
|
10
10
|
* `DefaultTransition`) are each `X.X`, with the shared constructors the Environments build on
|
|
11
11
|
* (`Clock.layer`, `Clock.fromRefreshFrames`, `InputSource.heldPointer`, `InputFeed.byTarget`,
|
|
12
12
|
* `InterpolatorRegistry.layer`, `FrameLoop.layer`, `DefaultTransition.layerOneSpring`). Each module's
|
|
@@ -47,6 +47,7 @@ export * as RefreshFrameSource from "./RefreshFrameSource.js";
|
|
|
47
47
|
export * as Renderer from "./Renderer.js";
|
|
48
48
|
export * as Reorder from "./Reorder.js";
|
|
49
49
|
export * as Scalar from "./Scalar.js";
|
|
50
|
+
export * as ScrollSource from "./ScrollSource.js";
|
|
50
51
|
export * as Sequence from "./Sequence.js";
|
|
51
52
|
export * as SharedSource from "./SharedSource.js";
|
|
52
53
|
export * as Spring from "./Spring.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,oGAAoG;AACpG,uGAAuG;AACvG,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,oBAAoB,MAAM,2BAA2B,CAAA;AACjE,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,oGAAoG;AACpG,uGAAuG;AACvG,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,oBAAoB,MAAM,2BAA2B,CAAA;AACjE,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as Cause from "effect/Cause";
|
|
2
2
|
import * as Context from "effect/Context";
|
|
3
3
|
import * as Effect from "effect/Effect";
|
|
4
|
+
import type * as Metric from "effect/Metric";
|
|
4
5
|
import * as Option from "effect/Option";
|
|
5
6
|
import type * as Scope from "effect/Scope";
|
|
6
7
|
import * as Clock from "../Clock.ts";
|
|
@@ -43,6 +44,22 @@ export interface Shape {
|
|
|
43
44
|
*/
|
|
44
45
|
readonly afterTick: (hook: () => undefined) => Effect.Effect<void, never, Scope.Scope>;
|
|
45
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* The Frame loop's metrics: the running animations, the runs that settled and failed, and each tick's
|
|
49
|
+
* ms. None unless an app gives them (`FrameLoop.layerMetrics`, #518), so an app that reads none ships and
|
|
50
|
+
* updates none.
|
|
51
|
+
*/
|
|
52
|
+
export interface Metrics {
|
|
53
|
+
readonly animations: Metric.Gauge<number>;
|
|
54
|
+
readonly settled: Metric.Counter<number>;
|
|
55
|
+
readonly failed: Metric.Counter<number>;
|
|
56
|
+
readonly tickMs: Metric.Histogram<number>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Where a run's fiber finds the metrics. The loop takes them from the first run that has them: an app
|
|
60
|
+
* gives them beside its Environment, which the loop's own build doesn't see, as `CheckFrames` is read.
|
|
61
|
+
*/
|
|
62
|
+
export declare const MetricsGiven: Context.Reference<Metrics | undefined>;
|
|
46
63
|
/**
|
|
47
64
|
* A check for development, off by default: on, every run started where it's on checks each Frame before
|
|
48
65
|
* its sink gets it, and fails with `NonFiniteFrame` on a NaN or an Infinity. Read once a run, from the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frameLoop.d.ts","sourceRoot":"","sources":["../../src/internal/frameLoop.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAGzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"frameLoop.d.ts","sourceRoot":"","sources":["../../src/internal/frameLoop.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
*
|
|
30
30
|
* Observability: a span per run, named after its Primitive (`machine.span`), and one per burst
|
|
31
31
|
* (`wardic.frameloop`). A run's `<name>: start` debug log, annotated with its span's attributes,
|
|
32
|
-
* built only when a Debug log would be kept (#542). Per tick, no span or log
|
|
33
|
-
* animations and a histogram of ms per tick,
|
|
34
|
-
* runs that settled or failed in it, counted as
|
|
35
|
-
* `afterTick` hook, its first (#542). The histogram ends
|
|
36
|
-
* alone, not the gate's flush (ADR-0033).
|
|
32
|
+
* built only when a Debug log would be kept (#542). Per tick, no span or log. With the metrics an app
|
|
33
|
+
* gives (`FrameLoop.layerMetrics`, #518): a gauge of running animations and a histogram of ms per tick,
|
|
34
|
+
* each one `updateUnsafe` (ADR-0027, decision 6), and the runs that settled or failed in it, counted as
|
|
35
|
+
* they end and added at its end by the loop's own `afterTick` hook, its first (#542). The histogram ends
|
|
36
|
+
* before the hooks, so it measures the steps alone, not the gate's flush (ADR-0033).
|
|
37
37
|
*
|
|
38
38
|
* A run's span is opened without a stack frame (ADR-0040, decision 3): `useSpan` with the span as
|
|
39
39
|
* the `ParentSpan`, not `withSpan`, whose frame Effect stamps on an interrupted run's cause and
|
|
@@ -57,7 +57,6 @@ import * as Exit from "effect/Exit";
|
|
|
57
57
|
import * as FiberHandle from "effect/FiberHandle";
|
|
58
58
|
import { constUndefined, identity } from "effect/Function";
|
|
59
59
|
import * as LogLevel from "effect/LogLevel";
|
|
60
|
-
import * as Metric from "effect/Metric";
|
|
61
60
|
import * as Option from "effect/Option";
|
|
62
61
|
import * as Predicate from "effect/Predicate";
|
|
63
62
|
import * as References from "effect/References";
|
|
@@ -66,12 +65,13 @@ import * as Tracer from "effect/Tracer";
|
|
|
66
65
|
import * as Clock from "../Clock.js";
|
|
67
66
|
import * as Supersede from "../Supersede.js";
|
|
68
67
|
import { isTraced, traced } from "./tracing.js";
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Where a run's fiber finds the metrics. The loop takes them from the first run that has them: an app
|
|
70
|
+
* gives them beside its Environment, which the loop's own build doesn't see, as `CheckFrames` is read.
|
|
71
|
+
*/
|
|
72
|
+
// #518, ADR-0067 *Amendment (#518)*, decision 2.
|
|
73
|
+
export const MetricsGiven = Context.Reference("@wardic/core/FrameLoop/Metrics", {
|
|
74
|
+
defaultValue: constUndefined,
|
|
75
75
|
});
|
|
76
76
|
/**
|
|
77
77
|
* A check for development, off by default: on, every run started where it's on checks each Frame before
|
|
@@ -174,6 +174,8 @@ export const make = Effect.fnUntraced(function* () {
|
|
|
174
174
|
// once per tick. An interruption is neither, nor a superseded run, which the loop doesn't end.
|
|
175
175
|
let settledCount = 0;
|
|
176
176
|
let failedCount = 0;
|
|
177
|
+
// The metrics, once a run brings them (#518).
|
|
178
|
+
let metrics;
|
|
177
179
|
/** End `entry`'s run: removed, counted, and its fiber resumed with `exit` (inline, within the tick). */
|
|
178
180
|
const end = (entry, exit) => {
|
|
179
181
|
entry.removed = true;
|
|
@@ -185,10 +187,12 @@ export const make = Effect.fnUntraced(function* () {
|
|
|
185
187
|
};
|
|
186
188
|
/** The runs ended since the last count, into the counters: once per tick, and as a burst ends. */
|
|
187
189
|
const countEnds = () => {
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
if (Predicate.isNotUndefined(metrics)) {
|
|
191
|
+
if (settledCount > 0)
|
|
192
|
+
metrics.settled.updateUnsafe(settledCount, buildContext);
|
|
193
|
+
if (failedCount > 0)
|
|
194
|
+
metrics.failed.updateUnsafe(failedCount, buildContext);
|
|
195
|
+
}
|
|
192
196
|
settledCount = 0;
|
|
193
197
|
failedCount = 0;
|
|
194
198
|
return undefined;
|
|
@@ -234,7 +238,10 @@ export const make = Effect.fnUntraced(function* () {
|
|
|
234
238
|
// The first lane's loops stay inline in `tick`: moved into a function shared with the last lane,
|
|
235
239
|
// Node's `chase/loop` ran 55% slower (`bench:core`, ADR-0027 *Amendment (#137)*).
|
|
236
240
|
const tick = (dt) => {
|
|
237
|
-
|
|
241
|
+
// The tick's start, read only for the metrics' histogram (#518).
|
|
242
|
+
let t0 = 0;
|
|
243
|
+
if (Predicate.isNotUndefined(metrics))
|
|
244
|
+
t0 = performance.now();
|
|
238
245
|
// Both counts before any step: a run added during the tick, to either lane, waits for the next.
|
|
239
246
|
const count = entries.length;
|
|
240
247
|
const lastCount = lastEntries.length;
|
|
@@ -267,8 +274,10 @@ export const make = Effect.fnUntraced(function* () {
|
|
|
267
274
|
entries.length = kept;
|
|
268
275
|
if (lastEntries.length > 0)
|
|
269
276
|
kept += compactLast();
|
|
270
|
-
|
|
271
|
-
|
|
277
|
+
if (Predicate.isNotUndefined(metrics)) {
|
|
278
|
+
metrics.animations.updateUnsafe(kept, buildContext);
|
|
279
|
+
metrics.tickMs.updateUnsafe(performance.now() - t0, buildContext);
|
|
280
|
+
}
|
|
272
281
|
// The end of the tick: everything for this Refresh frame is written (ADR-0033). After
|
|
273
282
|
// `tickMs`, which stays the cost of the steps alone.
|
|
274
283
|
const ended = hooks;
|
|
@@ -299,7 +308,8 @@ export const make = Effect.fnUntraced(function* () {
|
|
|
299
308
|
if (!entry.removed)
|
|
300
309
|
end(entry, ending);
|
|
301
310
|
});
|
|
302
|
-
|
|
311
|
+
if (Predicate.isNotUndefined(metrics))
|
|
312
|
+
metrics.animations.updateUnsafe(0, buildContext);
|
|
303
313
|
countEnds();
|
|
304
314
|
};
|
|
305
315
|
const ticking = clock.ticks.pipe(Stream.map(tick), Stream.takeUntil(identity), Stream.runDrain, Effect.onExit((exit) => Effect.sync(() => endAll(exit))), (self) => traced(self, "wardic.frameloop", { root: true }), Effect.provideContext(buildContext));
|
|
@@ -323,6 +333,9 @@ export const make = Effect.fnUntraced(function* () {
|
|
|
323
333
|
const runIn = (lane) => ((machine, sink, options) => Effect.withFiber((fiber) => {
|
|
324
334
|
// Its start log only when a Debug log would be kept (#542): Effect's own rule, read once.
|
|
325
335
|
const logged = !LogLevel.isGreaterThan(fiber.getRef(References.MinimumLogLevel), "Debug");
|
|
336
|
+
// The metrics from the first run whose fiber has them (#518); none is read once they're in.
|
|
337
|
+
if (Predicate.isUndefined(metrics))
|
|
338
|
+
metrics = fiber.getRef(MetricsGiven);
|
|
326
339
|
if (!isTraced(fiber))
|
|
327
340
|
return added(lane, machine, sink, options, undefined, logged);
|
|
328
341
|
return Effect.useSpan(machine.span.name, { attributes: machine.span.attributes }, (span) => Effect.provideService(added(lane, machine, sink, options, span, logged), Tracer.ParentSpan, span));
|