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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # Easy Signal
2
2
 
3
- Two simple interfaces for creating two types of signals. The first (and original signal in this module) is a defined
4
- event that can be triggered and listened to with a single function. The second is a defined data store that allows you
5
- to react to changes to that data (popularized by solid-js). These two are `EventSignal` and `ReactiveSignal`.
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
- ## EventSignal Usage
15
+ ## Signal Usage
16
16
 
17
- An EventSignal is a function that represents a single event. The function can be used to subscribe to be notified of
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
- EventSignals offer similar functionality as the browser's `eventDispatcher` API, but rather than a general API for any
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
- ### EventSignal Basic Usage
25
+ ### Signal Basic Usage
26
26
 
27
27
  ```ts
28
28
  // file seconds.ts
29
- import { eventSignal } from 'easy-signal';
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 = eventSignal<number>();
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 { eventSignal, ForErrors } from 'easy-signal';
54
+ import { signal, ForErrors } from 'easy-signal';
55
55
 
56
- const dataStream = eventSignal();
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 { eventSignal, GetOnSignal } from 'easy-signal';
68
+ import { signal, GetOnSignal } from 'easy-signal';
69
69
 
70
70
  function getMyAPI() {
71
- const doSomething = eventSignal();
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
- ## ReactiveSignal Usage
93
+ ## Atom Usage
94
94
 
95
- A ReactiveSignal is a function that represents a single piece of data. The function can be used to get the data, set the
96
- data, and update the data with an updater function. To subscribe to changes use the separate `subscribe` function. The
97
- ReactiveSignal allows for Observers to be created, which are functions that will be rerun whenever any ReactiveSignals
98
- they access are updated, and ComputedSignals which are read-only signals whose value is derived from other signals and
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
- ### ReactiveSignal Basic Usage
100
+ ### Atom Basic Usage
102
101
 
103
- Here we will use an example similar to the EventSignal, but unlike the EventSignal, the current seconds since epoch will
104
- be stored and can be accessed any time, whereas the EventSignal only fires an event with the data provided. This
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 { reactiveSignal } from 'easy-signal';
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 = reactiveSignal(0);
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
- ### Observer Basic Usage
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. You can also
137
- prevent that function from being called too often when data changes by using the Timings. Below, we update the content
138
- of the DOM whenever the user or billing data is updated, but we only do it after an animation frame to prevent the DOM
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 { reactiveSignal, observe, Timing } from 'easy-signal';
142
+ import { atom, observe, onAnimationFrame } from 'easy-signal';
146
143
 
147
- const user = reactiveSignal(userData);
148
- const billing = reactiveSignal(billingData);
144
+ const user = atom(userData);
145
+ const billing = atom(billingData);
149
146
 
150
- const unobserve = observe(() => {
147
+ const updateDom = onAnimationFrame((name, plan) => {
151
148
  document.body.innerText = `${user().name} has the plan ${billing().plan}`;
152
- }, Timing.AnimationFrame);
149
+ });
150
+
151
+ const unobserve = observe(() => {
152
+ updateDom(user().name, billing().plan);
153
+ });
153
154
  ```
154
155
 
155
- ### ComputedSignal Basic Usage
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 { computedSignal } from 'easy-signal';
161
+ import { derived } from 'easy-signal';
161
162
  import { user, billing } from 'my-other-signals';
162
163
 
163
- const delinquent = computedSignal(() => {
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
@@ -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;
@@ -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 './eventSignal';
2
- export * from './reactiveSignal';
3
- export * from './signalStore';
1
+ export * from './atom';
2
+ export * from './debounce';
3
+ export * from './signal';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export * from './eventSignal';
2
- export * from './reactiveSignal';
3
- export * from './signalStore';
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,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,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
- declare type Args<T> = T extends (...args: infer A) => any ? A : never;
2
- export declare type EventSignalSubscriber = (...args: any[]) => any;
3
- export declare type ErrorSubscriber = (error: Error) => any;
4
- export declare type Unsubscriber = () => void;
5
- export declare type OnSignal<T extends EventSignalSubscriber = EventSignalSubscriber> = {
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 declare type EventSignal<T extends EventSignalSubscriber = EventSignalSubscriber> = OnSignal<T> & {
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 eventSignal<T extends EventSignalSubscriber = EventSignalSubscriber>(): EventSignal<T>;
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 eventSignal() {
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=eventSignal.js.map
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"}
@@ -0,0 +1,2 @@
1
+ export type Unsubscriber = () => void;
2
+ export type Subscriber<T> = (value: T) => void;
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -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": "3.2.6",
4
- "description": "A tiny (25 LOC), simple utility for alerting subscribers when an event happens, allowing for error handling and clearing.",
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.8.2"
31
+ "typescript": "^5.4.5"
30
32
  }
31
33
  }