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/README.md
CHANGED
|
@@ -97,7 +97,7 @@ In order for all this to work, of course, Uneventful has to keep track of the "a
|
|
|
97
97
|
- If you're in the body of a `start()` function, that job is active
|
|
98
98
|
- if you're in the body of a `start()`-ed *generator* function, the same applies, but also any generator functions you `yield *` to in the generator function will still have the job active.
|
|
99
99
|
- Callbacks **must** be wrapped with `restarting()` or a job's `.bind()` method (or invoked via a job's `.run()` method) in order to have a job active.
|
|
100
|
-
- If you're in a function directly called from an any place where there's an active job, that job is still active.
|
|
100
|
+
- If you're in a (non-async) function directly called from an any place where there's an active job, that job is still active.
|
|
101
101
|
|
|
102
102
|
Early versions of Uneventful also tried to automatically wrap event handlers to run in their owning jobs, but it turned out that this is fairly wasteful in practice! Most event handlers are defined inside of jobs, and so have easy access to their job instance in a variable (as provided by `start()`). So they can explicitly target `job.start()` or `job.must()` to create subjobs or register cleanups, etc., without needing an implicit current job.
|
|
103
103
|
|
|
@@ -137,22 +137,22 @@ Why the differences? Uneventful is all about *making clear what your code is do
|
|
|
137
137
|
|
|
138
138
|
Beyond these superficial differences, though, there are some deeper ones.
|
|
139
139
|
|
|
140
|
-
First off, in Uneventful, *signals are also streams*. When signals are used in APIs that expect streams (including `each()
|
|
140
|
+
First off, in Uneventful, *signals are also streams*. When signals are used in APIs that expect streams (including `each()`!), they send their current value on the initial subscription, followed by new values when their values change.
|
|
141
141
|
|
|
142
|
-
And they also support *backpressure*: if you iterate over a signal's values with `each()`, then the changes are based on sampling the value when the loop isn't busy (i.e. during the `yield next`). This makes it really easy to (for example) loop over the various
|
|
142
|
+
And they also support *backpressure*: if you iterate over a signal's values with `each()`, then the changes are based on sampling the value when the loop isn't busy (i.e. during the `yield next`). This makes it really easy to (for example) loop over the various values of an input field and do remote searches with them, while maintaining a desired search frequency or level of connection saturation by using `sleep()` delays in the loop.
|
|
143
143
|
|
|
144
144
|
Second, you can also *turn streams into signals*, by passing them to `cached()`. So if you want a signal that tracks the current mouse position or modifier keys' state, just use `cached(fromDomEvent(...))` or `pipe(fromDomEvent(...), map(...), cached)`, and off you go! As long as the resulting signal is observed by a rule (directly or indirectly) it subscribes to the stream and returns the most recent value. And as soon as all its observers go away, the underlying source is unsubscribed, so there are no dangling event listeners.
|
|
145
145
|
|
|
146
146
|
But wait, there's more: Unlike most libraries' "effects", Uneventful's rules *start asynchronously* and can be *independently scheduled*. This means, for example, that it's easy to make rules that run only in, say, animation frames:
|
|
147
147
|
|
|
148
148
|
```ts
|
|
149
|
-
import {
|
|
149
|
+
import { rule } from "uneventful";
|
|
150
150
|
|
|
151
151
|
/**
|
|
152
152
|
* An alternate version of rule() that runs in animation frames
|
|
153
153
|
* instead of microticks
|
|
154
154
|
*/
|
|
155
|
-
const animate =
|
|
155
|
+
const animate = rule.factory(requestAnimationFrame);
|
|
156
156
|
|
|
157
157
|
animate(() => {
|
|
158
158
|
// Code here will not run until the next animation frame.
|
|
@@ -175,7 +175,7 @@ Also unlike other frameworks, you can have rules that run on different schedules
|
|
|
175
175
|
|
|
176
176
|
Schedulers also let you appropriately debounce or sample changes for some of your rules so you can avoid unnecessary updates. Instead of requiring an immediate response to every change of an observable value, or explicit batching declarations, Uneventful just marks dependencies dirty, and queues affected rules to be run by their corresponding scheduler(s).
|
|
177
177
|
|
|
178
|
-
(This means, for example, that you can have rules that update data models immediately, other rules that update visible UI in the next animation frame, and still others that update a server or database every few seconds, without needing anything more complicated than using rule
|
|
178
|
+
(This means, for example, that you can have rules that update data models immediately, other rules that update visible UI in the next animation frame, and still others that update a server or database every few seconds, without needing anything more complicated than using rule factories tied to different schedulers when creating them.)
|
|
179
179
|
|
|
180
180
|
#### What's Next
|
|
181
181
|
So far, we've highlighted just a handful of Uneventful's coolest and most impactful features, showing how you can:
|
|
@@ -189,5 +189,5 @@ And at the same time, this has actually been a pretty superficial tour: we haven
|
|
|
189
189
|
|
|
190
190
|
(Also, at some point you'll be able to use the "Calibre Connect" Obsidian plugin I'm working on as an example of how to use these things to create responsive search and tame Electron WebFrames while keeping track of whether a connection to a remote server is available, handling logins and background processes and integrating a plugin to a larger application, not to mention controlling lots of features via settings.)
|
|
191
191
|
|
|
192
|
-
In the meantime, this library should now be available for installation and experimentation via [npm](https://www.npmjs.com/package/uneventful). Enjoy!
|
|
192
|
+
In the meantime, this library should now be available for installation and experimentation via [npm](https://www.npmjs.com/package/uneventful), as [an ESM-only package](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c). Enjoy!
|
|
193
193
|
|