easy-signal 3.2.6 → 4.0.0
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 +39 -38
- package/dist/atom.d.ts +40 -0
- package/dist/atom.js +137 -0
- package/dist/atom.js.map +1 -0
- package/dist/debounce.d.ts +12 -0
- package/dist/debounce.js +36 -0
- package/dist/debounce.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/{eventSignal.d.ts → signal.d.ts} +8 -8
- package/dist/{eventSignal.js → signal.js} +2 -2
- package/dist/signal.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +6 -4
- package/src/atom.ts +188 -0
- package/src/debounce.ts +42 -0
- package/src/index.ts +4 -3
- package/src/{eventSignal.ts → signal.ts} +10 -8
- package/src/types.ts +3 -0
- package/tsconfig.json +1 -1
- package/dist/eventSignal.js.map +0 -1
- package/dist/reactiveSignal.d.ts +0 -104
- package/dist/reactiveSignal.js +0 -227
- package/dist/reactiveSignal.js.map +0 -1
- package/dist/signalStore.d.ts +0 -12
- package/dist/signalStore.js +0 -14
- package/dist/signalStore.js.map +0 -1
- package/src/reactiveSignal.ts +0 -342
- package/src/signalStore.ts +0 -21
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Easy Signal
|
|
2
2
|
|
|
3
|
-
Two
|
|
4
|
-
event
|
|
5
|
-
to react to changes
|
|
3
|
+
Two interfaces for creating two types of signals. The first (and original signal in this module) is a function that
|
|
4
|
+
defines an event and can be triggered and listened to with the single function. The second is a reactive data store that
|
|
5
|
+
allows to react to changes (popularized by solid-js). These two are `Signal` and `Atom`.
|
|
6
6
|
|
|
7
7
|
Full type safety with TypeScript with both use-cases.
|
|
8
8
|
|
|
@@ -12,24 +12,24 @@ Full type safety with TypeScript with both use-cases.
|
|
|
12
12
|
npm install easy-signal
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Signal Usage
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
A Signal is a function that represents a single event. The function can be used to subscribe to be notified of
|
|
18
18
|
the events as well as to trigger them.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Signals offer similar functionality as the browser's `eventDispatcher` API, but rather than a general API for any
|
|
21
21
|
event, each event would use its own signal. This allows each signal to have a specific function signature as opposed to
|
|
22
22
|
the browser's generic `event` object. This is a great system in TypeScript being able to see the exact data each event
|
|
23
23
|
produces.
|
|
24
24
|
|
|
25
|
-
###
|
|
25
|
+
### Signal Basic Usage
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
28
|
// file seconds.ts
|
|
29
|
-
import {
|
|
29
|
+
import { signal } from 'easy-signal';
|
|
30
30
|
|
|
31
31
|
// Create the signal and export it for use. Optionally provide the subscriber signature
|
|
32
|
-
export const onSecond =
|
|
32
|
+
export const onSecond = signal<number>();
|
|
33
33
|
|
|
34
34
|
// Passing a non-function value will dispatch the event
|
|
35
35
|
setInterval(() => {
|
|
@@ -51,9 +51,9 @@ Errors may also be listened to from the signal by passing `ForErrors` as the sec
|
|
|
51
51
|
and errors may be dispatched by passing an Error object to the signal method.
|
|
52
52
|
|
|
53
53
|
```ts
|
|
54
|
-
import {
|
|
54
|
+
import { signal, ForErrors } from 'easy-signal';
|
|
55
55
|
|
|
56
|
-
const dataStream =
|
|
56
|
+
const dataStream = signal();
|
|
57
57
|
|
|
58
58
|
dataStream(data => console.log('data is:' data));
|
|
59
59
|
dataStream(error => console.log('Error is:' error), ForErrors);
|
|
@@ -65,10 +65,10 @@ stream.on('error', err => dataStream(err));
|
|
|
65
65
|
To get a subscriber-only method for external use, pass in the `GetOnSignal` constant.
|
|
66
66
|
|
|
67
67
|
```ts
|
|
68
|
-
import {
|
|
68
|
+
import { signal, GetOnSignal } from 'easy-signal';
|
|
69
69
|
|
|
70
70
|
function getMyAPI() {
|
|
71
|
-
const doSomething =
|
|
71
|
+
const doSomething = signal();
|
|
72
72
|
|
|
73
73
|
// doSomething() will trigger subscribers that were added in onSomething(...). This protects the signal from being
|
|
74
74
|
// triggered/dispatched outside of `getMyAPI`. Sometimes you may want more control to prevent just anyone from
|
|
@@ -90,32 +90,30 @@ const onSomething = signal();
|
|
|
90
90
|
onSomething(ClearSignal); // clears signal
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
##
|
|
93
|
+
## Atom Usage
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
data
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
which will be updated whenever they are.
|
|
95
|
+
An Atom is a function that represents a single piece of data. The function can be used to get the data and set the
|
|
96
|
+
data. A `subscribe` function allows reacting to changes on the data in an atom. An `observe` function allows for a
|
|
97
|
+
function to be rerun whenever any atoms it depends on are changed. And a `derived` function allows a readonly atom to
|
|
98
|
+
be created which depends on, or is derived from, other atoms.
|
|
100
99
|
|
|
101
|
-
###
|
|
100
|
+
### Atom Basic Usage
|
|
102
101
|
|
|
103
|
-
Here we will use an example similar to the
|
|
104
|
-
be stored and can be accessed any time, whereas the
|
|
102
|
+
Here we will use an example similar to the Signal, but unlike the Signal, the current seconds since epoch will
|
|
103
|
+
be stored and can be accessed any time, whereas the Signal only fires an event with the data provided. This
|
|
105
104
|
particular example isn't very compelling.
|
|
106
105
|
|
|
107
106
|
```ts
|
|
108
107
|
// file seconds.ts
|
|
109
|
-
import {
|
|
108
|
+
import { atom } from 'easy-signal';
|
|
110
109
|
|
|
111
110
|
// Create the signal and export it for use. Optionally provide the subscriber signature
|
|
112
|
-
export const onSecond =
|
|
111
|
+
export const onSecond = atom(0);
|
|
113
112
|
|
|
114
113
|
// Passing a non-function value will dispatch the event
|
|
115
114
|
setInterval(() => {
|
|
116
115
|
const currentSecond = Math.floor(Date.now() / 1000);
|
|
117
116
|
onSecond(currentSecond);
|
|
118
|
-
// or onSecond(currentValue => newValue) to update
|
|
119
117
|
});
|
|
120
118
|
```
|
|
121
119
|
|
|
@@ -131,36 +129,39 @@ const unsubscribe = onSecond.subscribe(seconds => {
|
|
|
131
129
|
});
|
|
132
130
|
```
|
|
133
131
|
|
|
134
|
-
###
|
|
132
|
+
### `observe` Basic Usage
|
|
135
133
|
|
|
136
|
-
To take action whenever data changes, you can observe or more signals by accessing them in a function call.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
updates from being too frequent. Providing no Timing will call the function immediately after any data is changed.
|
|
134
|
+
To take action whenever data changes, you can observe one or more signals by accessing them in a function call. Below,
|
|
135
|
+
we update the content of the DOM whenever the user or billing data is updated, but we only do it after an animation
|
|
136
|
+
frame to prevent the DOM updates from being too frequent.
|
|
140
137
|
|
|
141
138
|
Because `user()` and `billing()` are called the first time the observe function is run, it automatically subscribes to
|
|
142
139
|
know when they are changed so that the function may be rerun.
|
|
143
140
|
|
|
144
141
|
```ts
|
|
145
|
-
import {
|
|
142
|
+
import { atom, observe, onAnimationFrame } from 'easy-signal';
|
|
146
143
|
|
|
147
|
-
const user =
|
|
148
|
-
const billing =
|
|
144
|
+
const user = atom(userData);
|
|
145
|
+
const billing = atom(billingData);
|
|
149
146
|
|
|
150
|
-
const
|
|
147
|
+
const updateDom = onAnimationFrame((name, plan) => {
|
|
151
148
|
document.body.innerText = `${user().name} has the plan ${billing().plan}`;
|
|
152
|
-
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const unobserve = observe(() => {
|
|
152
|
+
updateDom(user().name, billing().plan);
|
|
153
|
+
});
|
|
153
154
|
```
|
|
154
155
|
|
|
155
|
-
###
|
|
156
|
+
### `derived` Basic Usage
|
|
156
157
|
|
|
157
158
|
Create read-only signals whose value is derived from other signals and which will be updated whenever they are.
|
|
158
159
|
|
|
159
160
|
```ts
|
|
160
|
-
import {
|
|
161
|
+
import { derived } from 'easy-signal';
|
|
161
162
|
import { user, billing } from 'my-other-signals';
|
|
162
163
|
|
|
163
|
-
const delinquent =
|
|
164
|
+
const delinquent = derived(() => {
|
|
164
165
|
if (user().subscribed) {
|
|
165
166
|
return billing().status === 'delinquent';
|
|
166
167
|
}
|
package/dist/atom.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Subscriber, Unsubscriber } from './types';
|
|
2
|
+
export type Invalidator<T> = (value?: T) => void;
|
|
3
|
+
export type StartStopNotifier<T> = (set: Atom<T>) => Unsubscriber | void;
|
|
4
|
+
export type { Subscriber, Unsubscriber };
|
|
5
|
+
export interface Derived<T> {
|
|
6
|
+
/**
|
|
7
|
+
* Return the current value.
|
|
8
|
+
*/
|
|
9
|
+
(): T;
|
|
10
|
+
/**
|
|
11
|
+
* Subscribe to changes with a callback. Returns an unsubscribe function.
|
|
12
|
+
*/
|
|
13
|
+
subscribe(callback: Subscriber<T>, invalidate?: Invalidator<T>): Unsubscriber;
|
|
14
|
+
}
|
|
15
|
+
export interface Atom<T> extends Derived<T> {
|
|
16
|
+
/**
|
|
17
|
+
* Set the value and inform subscribers.
|
|
18
|
+
*/
|
|
19
|
+
(value: T): void;
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated use atom(value) instead, kept for Svelte 3 compatibility (e.g. $store = value)
|
|
22
|
+
*/
|
|
23
|
+
set(value: T): void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a `Readable` atom that allows reading by subscription.
|
|
27
|
+
*/
|
|
28
|
+
export declare function readable<T>(value?: T, start?: StartStopNotifier<T>): Derived<T>;
|
|
29
|
+
/**
|
|
30
|
+
* Create a `Writable` atom that allows both updating and reading by subscription.
|
|
31
|
+
*/
|
|
32
|
+
export declare function atom<T>(value: T, start?: StartStopNotifier<T>): Atom<T>;
|
|
33
|
+
/**
|
|
34
|
+
* Observe atoms and derived values by synchronizing one or more readable atoms within an aggregation function.
|
|
35
|
+
*/
|
|
36
|
+
export declare function observe<T>(fn: () => T): Unsubscriber;
|
|
37
|
+
/**
|
|
38
|
+
* Create a `Readable` atom that derives its value from other atoms and updates when those atoms change.
|
|
39
|
+
*/
|
|
40
|
+
export declare function derived<T>(fn: () => T, initialValue?: T): Derived<T>;
|
package/dist/atom.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
const noop = () => { };
|
|
2
|
+
// Ensure 2 versions of the signal library can work together
|
|
3
|
+
const symbol = Symbol.for('reactiveAtoms');
|
|
4
|
+
const root = globalThis[symbol] ||
|
|
5
|
+
(globalThis[symbol] = {
|
|
6
|
+
context: null,
|
|
7
|
+
subscriberQueue: new Map(),
|
|
8
|
+
trackingDependencies: null,
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Creates a `Readable` atom that allows reading by subscription.
|
|
12
|
+
*/
|
|
13
|
+
export function readable(value, start) {
|
|
14
|
+
const core = atom(value, start);
|
|
15
|
+
const readable = () => core();
|
|
16
|
+
return Object.assign(readable, { subscribe: core.subscribe });
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create a `Writable` atom that allows both updating and reading by subscription.
|
|
20
|
+
*/
|
|
21
|
+
export function atom(value, start = noop) {
|
|
22
|
+
let stop;
|
|
23
|
+
let started = false;
|
|
24
|
+
const subscribers = new Map();
|
|
25
|
+
function atom(newValue) {
|
|
26
|
+
if (newValue === undefined) {
|
|
27
|
+
if (!subscribers.size && !started) {
|
|
28
|
+
started = true;
|
|
29
|
+
try {
|
|
30
|
+
(start(atom) || noop)();
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
started = false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (root.trackingDependencies) {
|
|
37
|
+
root.trackingDependencies.add(atom);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
else if (value !== newValue) {
|
|
42
|
+
value = newValue;
|
|
43
|
+
if (stop) {
|
|
44
|
+
// atom is ready
|
|
45
|
+
const runQueue = !root.subscriberQueue.size;
|
|
46
|
+
subscribers.forEach((invalidate, subscriber) => {
|
|
47
|
+
if (!root.subscriberQueue.has(subscriber)) {
|
|
48
|
+
invalidate();
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// move to the end of the queue
|
|
52
|
+
root.subscriberQueue.delete(subscriber);
|
|
53
|
+
}
|
|
54
|
+
root.subscriberQueue.set(subscriber, value);
|
|
55
|
+
});
|
|
56
|
+
if (runQueue) {
|
|
57
|
+
const iter = root.subscriberQueue.entries();
|
|
58
|
+
while (root.subscriberQueue.size > 0) {
|
|
59
|
+
const [subscriber, value] = iter.next().value;
|
|
60
|
+
root.subscriberQueue.delete(subscriber);
|
|
61
|
+
subscriber(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function subscribe(subscriber, invalidate = noop) {
|
|
68
|
+
subscribers.set(subscriber, invalidate);
|
|
69
|
+
if (subscribers.size === 1) {
|
|
70
|
+
stop = start(atom) || noop;
|
|
71
|
+
}
|
|
72
|
+
invalidate();
|
|
73
|
+
subscriber(value);
|
|
74
|
+
return () => {
|
|
75
|
+
subscribers.delete(subscriber);
|
|
76
|
+
if (subscribers.size === 0) {
|
|
77
|
+
stop();
|
|
78
|
+
stop = null;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return Object.assign(atom, { subscribe, set: (value) => atom(value) });
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Observe atoms and derived values by synchronizing one or more readable atoms within an aggregation function.
|
|
86
|
+
*/
|
|
87
|
+
export function observe(fn) {
|
|
88
|
+
return derived(fn).subscribe(noop);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a `Readable` atom that derives its value from other atoms and updates when those atoms change.
|
|
92
|
+
*/
|
|
93
|
+
export function derived(fn, initialValue) {
|
|
94
|
+
const dependencies = new Map();
|
|
95
|
+
return readable(initialValue, set => {
|
|
96
|
+
let inited = false;
|
|
97
|
+
let pending = 0;
|
|
98
|
+
const subscriber = () => --pending === 0 && inited && sync();
|
|
99
|
+
const invalidate = () => pending++;
|
|
100
|
+
const sync = () => {
|
|
101
|
+
const [oldDeps, newDeps] = trackDependencies(new Set(dependencies.keys()), () => {
|
|
102
|
+
const result = fn();
|
|
103
|
+
set(result);
|
|
104
|
+
});
|
|
105
|
+
oldDeps.forEach(dep => {
|
|
106
|
+
dependencies.get(dep)();
|
|
107
|
+
dependencies.delete(dep);
|
|
108
|
+
});
|
|
109
|
+
inited = false;
|
|
110
|
+
newDeps.forEach(atom => {
|
|
111
|
+
const unsubscribe = atom.subscribe(subscriber, invalidate);
|
|
112
|
+
dependencies.set(atom, unsubscribe);
|
|
113
|
+
});
|
|
114
|
+
inited = true;
|
|
115
|
+
};
|
|
116
|
+
sync();
|
|
117
|
+
return function stop() {
|
|
118
|
+
dependencies.forEach(unsub => unsub());
|
|
119
|
+
dependencies.clear();
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function trackDependencies(existing, fn) {
|
|
124
|
+
const priorDependencies = root.trackingDependencies;
|
|
125
|
+
const newDeps = (root.trackingDependencies = new Set());
|
|
126
|
+
try {
|
|
127
|
+
fn();
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
root.trackingDependencies = priorDependencies;
|
|
131
|
+
const oldDeps = new Set(existing);
|
|
132
|
+
newDeps.forEach(oldDeps.delete, oldDeps);
|
|
133
|
+
existing.forEach(newDeps.delete, newDeps);
|
|
134
|
+
return [oldDeps, newDeps];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=atom.js.map
|
package/dist/atom.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atom.js","sourceRoot":"","sources":["../src/atom.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function to debounce the execution of a function until the next microtask.
|
|
3
|
+
*/
|
|
4
|
+
export declare function onTick<T extends (...args: any[]) => void>(fn: T): T;
|
|
5
|
+
/**
|
|
6
|
+
* A function to debounce the execution of a function until the next setTimeout(..., 0).
|
|
7
|
+
*/
|
|
8
|
+
export declare function onTimeout<T extends (...args: any[]) => void>(fn: T): T;
|
|
9
|
+
/**
|
|
10
|
+
* A function to debounce the execution of a function until the next animation frame.
|
|
11
|
+
*/
|
|
12
|
+
export declare function onAnimationFrame<T extends (...args: any[]) => void>(fn: T): T;
|
package/dist/debounce.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function debounce(scheduler, fn) {
|
|
2
|
+
let nextArgs;
|
|
3
|
+
return ((...args) => {
|
|
4
|
+
nextArgs = args;
|
|
5
|
+
if (!nextArgs) {
|
|
6
|
+
scheduler(() => {
|
|
7
|
+
const args = nextArgs;
|
|
8
|
+
nextArgs = null;
|
|
9
|
+
fn(...args);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
nextArgs = args;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
const tick = (callback) => Promise.resolve().then(callback);
|
|
16
|
+
const timeout = (callback) => setTimeout(callback);
|
|
17
|
+
const frame = (callback) => requestAnimationFrame(callback);
|
|
18
|
+
/**
|
|
19
|
+
* A function to debounce the execution of a function until the next microtask.
|
|
20
|
+
*/
|
|
21
|
+
export function onTick(fn) {
|
|
22
|
+
return debounce(tick, fn);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A function to debounce the execution of a function until the next setTimeout(..., 0).
|
|
26
|
+
*/
|
|
27
|
+
export function onTimeout(fn) {
|
|
28
|
+
return debounce(timeout, fn);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A function to debounce the execution of a function until the next animation frame.
|
|
32
|
+
*/
|
|
33
|
+
export function onAnimationFrame(fn) {
|
|
34
|
+
return debounce(frame, fn);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=debounce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debounce.js","sourceRoot":"","sources":["../src/debounce.ts"],"names":[],"mappings":"AAEA,SAAS,QAAQ,CAAqC,SAAoB,EAAE,EAAK;IAC/E,IAAI,QAAe,CAAC;IAEpB,OAAO,CAAC,CAAC,GAAG,IAAW,EAAE,EAAE;QACzB,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,SAAS,CAAC,GAAG,EAAE;gBACb,MAAM,IAAI,GAAG,QAAQ,CAAC;gBACtB,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC;QACD,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC,CAAM,CAAC;AACV,CAAC;AAED,MAAM,IAAI,GAAc,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACvE,MAAM,OAAO,GAAc,CAAC,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9D,MAAM,KAAK,GAAc,CAAC,QAAQ,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,UAAU,MAAM,CAAqC,EAAK;IAC9D,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAqC,EAAK;IAC/D,OAAO,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAqC,EAAK;IACxE,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
1
|
+
export * from './atom';
|
|
2
|
+
export * from './debounce';
|
|
3
|
+
export * from './signal';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
1
|
+
export * from './atom';
|
|
2
|
+
export * from './debounce';
|
|
3
|
+
export * from './signal';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
1
|
+
import type { Unsubscriber } from './types';
|
|
2
|
+
type Args<T> = T extends (...args: infer A) => any ? A : never;
|
|
3
|
+
export type SignalSubscriber = (...args: any[]) => any;
|
|
4
|
+
export type ErrorSubscriber = (error: Error) => any;
|
|
5
|
+
export type { Unsubscriber };
|
|
6
|
+
export type OnSignal<T extends SignalSubscriber = SignalSubscriber> = {
|
|
6
7
|
(subscriber: T): Unsubscriber;
|
|
7
8
|
(errorListener: ErrorSubscriber, what: typeof ForErrors): Unsubscriber;
|
|
8
9
|
};
|
|
9
|
-
export
|
|
10
|
+
export type Signal<T extends SignalSubscriber = SignalSubscriber> = OnSignal<T> & {
|
|
10
11
|
(...args: Args<T>): Promise<void>;
|
|
11
12
|
(data: Error): Promise<void>;
|
|
12
13
|
(data: typeof ClearSignal): void;
|
|
@@ -32,5 +33,4 @@ export declare const ForErrors: unique symbol;
|
|
|
32
33
|
* onLoad('data'); // logs 'loaded data'
|
|
33
34
|
* onLoad(new Error('error')); // logs 'error Error: error'
|
|
34
35
|
*/
|
|
35
|
-
export declare function
|
|
36
|
-
export {};
|
|
36
|
+
export declare function signal<T extends SignalSubscriber = SignalSubscriber>(): Signal<T>;
|
|
@@ -18,7 +18,7 @@ export const ForErrors = Symbol();
|
|
|
18
18
|
* onLoad('data'); // logs 'loaded data'
|
|
19
19
|
* onLoad(new Error('error')); // logs 'error Error: error'
|
|
20
20
|
*/
|
|
21
|
-
export function
|
|
21
|
+
export function signal() {
|
|
22
22
|
const subscribers = new Set();
|
|
23
23
|
const errorListeners = new Set();
|
|
24
24
|
function onSignal(subscriber, what) {
|
|
@@ -49,4 +49,4 @@ export function eventSignal() {
|
|
|
49
49
|
}
|
|
50
50
|
return signal;
|
|
51
51
|
}
|
|
52
|
-
//# sourceMappingURL=
|
|
52
|
+
//# sourceMappingURL=signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"AAmBA,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC;AACrC,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC;AAElC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,MAAM;IACpB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAChD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEnD,SAAS,QAAQ,CAAC,UAA+B,EAAE,IAAuB;QACxE,MAAM,SAAS,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC;QACpE,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1B,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC,CAAC;IACJ,CAAC;IAQD,SAAS,MAAM,CAAC,GAAG,IAAW;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;YAC9B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;aAAM,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/B,WAAW,CAAC,KAAK,EAAE,CAAC;YACpB,cAAc,CAAC,KAAK,EAAE,CAAC;QACzB,CAAC;aAAM,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;YAChC,OAAO,QAAuB,CAAC;QACjC,CAAC;aAAM,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YAChC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC/F,CAAC;aAAM,CAAC;YACN,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/types.d.ts
ADDED
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "easy-signal",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A
|
|
3
|
+
"version": "4.0.0",
|
|
4
|
+
"description": "A package with 2 types of signals, an small and simple event signal, and a reactive value-based signal called atoms.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsc",
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
"events",
|
|
18
18
|
"typescript",
|
|
19
19
|
"subscriber",
|
|
20
|
-
"dispatcher"
|
|
20
|
+
"dispatcher",
|
|
21
|
+
"reactive",
|
|
22
|
+
"atom"
|
|
21
23
|
],
|
|
22
24
|
"author": "Jacob Wright",
|
|
23
25
|
"license": "MIT",
|
|
@@ -26,6 +28,6 @@
|
|
|
26
28
|
},
|
|
27
29
|
"homepage": "https://github.com/dabblewriter/easy-signal#readme",
|
|
28
30
|
"devDependencies": {
|
|
29
|
-
"typescript": "^4.
|
|
31
|
+
"typescript": "^5.4.5"
|
|
30
32
|
}
|
|
31
33
|
}
|