@zeix/cause-effect 0.15.2 → 0.16.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/.ai-context.md +254 -0
- package/.cursorrules +54 -0
- package/.github/copilot-instructions.md +132 -0
- package/CLAUDE.md +319 -0
- package/README.md +136 -166
- package/eslint.config.js +1 -1
- package/index.dev.js +125 -129
- package/index.js +1 -1
- package/index.ts +22 -22
- package/package.json +1 -1
- package/src/computed.ts +40 -29
- package/src/effect.ts +15 -12
- package/src/errors.ts +8 -0
- package/src/signal.ts +6 -6
- package/src/state.ts +27 -20
- package/src/store.ts +99 -121
- package/src/system.ts +122 -0
- package/src/util.ts +1 -6
- package/test/batch.test.ts +18 -11
- package/test/benchmark.test.ts +4 -4
- package/test/computed.test.ts +507 -71
- package/test/effect.test.ts +60 -60
- package/test/match.test.ts +25 -25
- package/test/resolve.test.ts +16 -16
- package/test/signal.test.ts +7 -7
- package/test/state.test.ts +212 -25
- package/test/store.test.ts +476 -183
- package/test/util/dependency-graph.ts +1 -1
- package/types/index.d.ts +8 -8
- package/types/src/collection.d.ts +26 -0
- package/types/src/computed.d.ts +9 -9
- package/types/src/effect.d.ts +3 -3
- package/types/src/errors.d.ts +4 -1
- package/types/src/state.d.ts +5 -5
- package/types/src/store.d.ts +27 -41
- package/types/src/system.d.ts +44 -0
- package/types/src/util.d.ts +1 -2
- package/src/scheduler.ts +0 -172
package/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @name Cause & Effect
|
|
3
|
-
* @version 0.
|
|
3
|
+
* @version 0.16.0
|
|
4
4
|
* @author Esther Brunner
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export {
|
|
8
8
|
type Computed,
|
|
9
9
|
type ComputedCallback,
|
|
10
|
-
|
|
10
|
+
createComputed,
|
|
11
11
|
isComputed,
|
|
12
12
|
isComputedCallback,
|
|
13
13
|
TYPE_COMPUTED,
|
|
@@ -20,9 +20,14 @@ export {
|
|
|
20
20
|
type UnknownRecord,
|
|
21
21
|
type UnknownRecordOrArray,
|
|
22
22
|
} from './src/diff'
|
|
23
|
-
export {
|
|
23
|
+
export {
|
|
24
|
+
createEffect,
|
|
25
|
+
type EffectCallback,
|
|
26
|
+
type MaybeCleanup,
|
|
27
|
+
} from './src/effect'
|
|
24
28
|
export {
|
|
25
29
|
CircularDependencyError,
|
|
30
|
+
InvalidCallbackError,
|
|
26
31
|
InvalidSignalValueError,
|
|
27
32
|
NullishSignalValueError,
|
|
28
33
|
StoreKeyExistsError,
|
|
@@ -31,18 +36,6 @@ export {
|
|
|
31
36
|
} from './src/errors'
|
|
32
37
|
export { type MatchHandlers, match } from './src/match'
|
|
33
38
|
export { type ResolveResult, resolve } from './src/resolve'
|
|
34
|
-
export {
|
|
35
|
-
batch,
|
|
36
|
-
type Cleanup,
|
|
37
|
-
enqueue,
|
|
38
|
-
flush,
|
|
39
|
-
notify,
|
|
40
|
-
observe,
|
|
41
|
-
subscribe,
|
|
42
|
-
type Updater,
|
|
43
|
-
type Watcher,
|
|
44
|
-
watch,
|
|
45
|
-
} from './src/scheduler'
|
|
46
39
|
export {
|
|
47
40
|
isMutableSignal,
|
|
48
41
|
isSignal,
|
|
@@ -51,18 +44,24 @@ export {
|
|
|
51
44
|
toSignal,
|
|
52
45
|
type UnknownSignalRecord,
|
|
53
46
|
} from './src/signal'
|
|
54
|
-
export { isState, type State,
|
|
47
|
+
export { createState, isState, type State, TYPE_STATE } from './src/state'
|
|
55
48
|
export {
|
|
49
|
+
createStore,
|
|
56
50
|
isStore,
|
|
57
51
|
type Store,
|
|
58
|
-
type
|
|
59
|
-
type StoreChangeEvent,
|
|
60
|
-
type StoreEventMap,
|
|
61
|
-
type StoreRemoveEvent,
|
|
62
|
-
type StoreSortEvent,
|
|
63
|
-
store,
|
|
52
|
+
type StoreChanges,
|
|
64
53
|
TYPE_STORE,
|
|
65
54
|
} from './src/store'
|
|
55
|
+
export {
|
|
56
|
+
batch,
|
|
57
|
+
type Cleanup,
|
|
58
|
+
createWatcher,
|
|
59
|
+
flush,
|
|
60
|
+
notify,
|
|
61
|
+
observe,
|
|
62
|
+
subscribe,
|
|
63
|
+
type Watcher,
|
|
64
|
+
} from './src/system'
|
|
66
65
|
export {
|
|
67
66
|
isAbortError,
|
|
68
67
|
isAsyncFunction,
|
|
@@ -74,4 +73,5 @@ export {
|
|
|
74
73
|
isSymbol,
|
|
75
74
|
toError,
|
|
76
75
|
UNSET,
|
|
76
|
+
valueString,
|
|
77
77
|
} from './src/util'
|
package/package.json
CHANGED
package/src/computed.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { isEqual } from './diff'
|
|
2
|
-
import { CircularDependencyError } from './errors'
|
|
3
2
|
import {
|
|
3
|
+
CircularDependencyError,
|
|
4
|
+
InvalidCallbackError,
|
|
5
|
+
NullishSignalValueError,
|
|
6
|
+
} from './errors'
|
|
7
|
+
import {
|
|
8
|
+
createWatcher,
|
|
4
9
|
flush,
|
|
5
10
|
notify,
|
|
6
11
|
observe,
|
|
7
12
|
subscribe,
|
|
8
13
|
type Watcher,
|
|
9
|
-
|
|
10
|
-
} from './scheduler'
|
|
14
|
+
} from './system'
|
|
11
15
|
import {
|
|
12
16
|
isAbortError,
|
|
13
17
|
isAsyncFunction,
|
|
@@ -15,17 +19,18 @@ import {
|
|
|
15
19
|
isObjectOfType,
|
|
16
20
|
toError,
|
|
17
21
|
UNSET,
|
|
22
|
+
valueString,
|
|
18
23
|
} from './util'
|
|
19
24
|
|
|
20
25
|
/* === Types === */
|
|
21
26
|
|
|
22
27
|
type Computed<T extends {}> = {
|
|
23
|
-
[Symbol.toStringTag]: 'Computed'
|
|
28
|
+
readonly [Symbol.toStringTag]: 'Computed'
|
|
24
29
|
get(): T
|
|
25
30
|
}
|
|
26
31
|
type ComputedCallback<T extends {} & { then?: undefined }> =
|
|
27
|
-
| ((abort: AbortSignal) => Promise<T>)
|
|
28
|
-
| (() => T)
|
|
32
|
+
| ((oldValue: T, abort: AbortSignal) => Promise<T>)
|
|
33
|
+
| ((oldValue: T) => T)
|
|
29
34
|
|
|
30
35
|
/* === Constants === */
|
|
31
36
|
|
|
@@ -37,14 +42,21 @@ const TYPE_COMPUTED = 'Computed'
|
|
|
37
42
|
* Create a derived signal from existing signals
|
|
38
43
|
*
|
|
39
44
|
* @since 0.9.0
|
|
40
|
-
* @param {ComputedCallback<T>}
|
|
45
|
+
* @param {ComputedCallback<T>} callback - Computation callback function
|
|
41
46
|
* @returns {Computed<T>} - Computed signal
|
|
42
47
|
*/
|
|
43
|
-
const
|
|
48
|
+
const createComputed = <T extends {}>(
|
|
49
|
+
callback: ComputedCallback<T>,
|
|
50
|
+
initialValue: T = UNSET,
|
|
51
|
+
): Computed<T> => {
|
|
52
|
+
if (!isComputedCallback(callback))
|
|
53
|
+
throw new InvalidCallbackError('computed', valueString(callback))
|
|
54
|
+
if (initialValue == null) throw new NullishSignalValueError('computed')
|
|
55
|
+
|
|
44
56
|
const watchers: Set<Watcher> = new Set()
|
|
45
57
|
|
|
46
58
|
// Internal state
|
|
47
|
-
let value: T =
|
|
59
|
+
let value: T = initialValue
|
|
48
60
|
let error: Error | undefined
|
|
49
61
|
let controller: AbortController | undefined
|
|
50
62
|
let dirty = true
|
|
@@ -75,22 +87,22 @@ const computed = <T extends {}>(fn: ComputedCallback<T>): Computed<T> => {
|
|
|
75
87
|
error = newError
|
|
76
88
|
}
|
|
77
89
|
const settle =
|
|
78
|
-
<T>(
|
|
90
|
+
<T>(fn: (arg: T) => void) =>
|
|
79
91
|
(arg: T) => {
|
|
80
92
|
computing = false
|
|
81
93
|
controller = undefined
|
|
82
|
-
|
|
94
|
+
fn(arg)
|
|
83
95
|
if (changed) notify(watchers)
|
|
84
96
|
}
|
|
85
97
|
|
|
86
98
|
// Own watcher: called when notified from sources (push)
|
|
87
|
-
const
|
|
99
|
+
const watcher = createWatcher(() => {
|
|
88
100
|
dirty = true
|
|
89
101
|
controller?.abort()
|
|
90
102
|
if (watchers.size) notify(watchers)
|
|
91
|
-
else
|
|
103
|
+
else watcher.cleanup()
|
|
92
104
|
})
|
|
93
|
-
|
|
105
|
+
watcher.unwatch(() => {
|
|
94
106
|
controller?.abort()
|
|
95
107
|
})
|
|
96
108
|
|
|
@@ -99,7 +111,7 @@ const computed = <T extends {}>(fn: ComputedCallback<T>): Computed<T> => {
|
|
|
99
111
|
observe(() => {
|
|
100
112
|
if (computing) throw new CircularDependencyError('computed')
|
|
101
113
|
changed = false
|
|
102
|
-
if (isAsyncFunction(
|
|
114
|
+
if (isAsyncFunction(callback)) {
|
|
103
115
|
// Return current value until promise resolves
|
|
104
116
|
if (controller) return value
|
|
105
117
|
controller = new AbortController()
|
|
@@ -108,9 +120,7 @@ const computed = <T extends {}>(fn: ComputedCallback<T>): Computed<T> => {
|
|
|
108
120
|
() => {
|
|
109
121
|
computing = false
|
|
110
122
|
controller = undefined
|
|
111
|
-
|
|
112
|
-
// Retry computation with updated state
|
|
113
|
-
compute()
|
|
123
|
+
compute() // Retry computation with updated state
|
|
114
124
|
},
|
|
115
125
|
{
|
|
116
126
|
once: true,
|
|
@@ -120,7 +130,9 @@ const computed = <T extends {}>(fn: ComputedCallback<T>): Computed<T> => {
|
|
|
120
130
|
let result: T | Promise<T>
|
|
121
131
|
computing = true
|
|
122
132
|
try {
|
|
123
|
-
result = controller
|
|
133
|
+
result = controller
|
|
134
|
+
? callback(value, controller.signal)
|
|
135
|
+
: (callback as (oldValue: T) => T)(value)
|
|
124
136
|
} catch (e) {
|
|
125
137
|
if (isAbortError(e)) nil()
|
|
126
138
|
else err(e)
|
|
@@ -131,16 +143,16 @@ const computed = <T extends {}>(fn: ComputedCallback<T>): Computed<T> => {
|
|
|
131
143
|
else if (null == result || UNSET === result) nil()
|
|
132
144
|
else ok(result)
|
|
133
145
|
computing = false
|
|
134
|
-
},
|
|
146
|
+
}, watcher)
|
|
135
147
|
|
|
136
|
-
|
|
148
|
+
return {
|
|
137
149
|
[Symbol.toStringTag]: TYPE_COMPUTED,
|
|
138
150
|
|
|
139
151
|
/**
|
|
140
152
|
* Get the current value of the computed
|
|
141
153
|
*
|
|
142
154
|
* @since 0.9.0
|
|
143
|
-
* @returns {T} -
|
|
155
|
+
* @returns {T} - Current value of the computed
|
|
144
156
|
*/
|
|
145
157
|
get: (): T => {
|
|
146
158
|
subscribe(watchers)
|
|
@@ -150,15 +162,14 @@ const computed = <T extends {}>(fn: ComputedCallback<T>): Computed<T> => {
|
|
|
150
162
|
return value
|
|
151
163
|
},
|
|
152
164
|
}
|
|
153
|
-
return c
|
|
154
165
|
}
|
|
155
166
|
|
|
156
167
|
/**
|
|
157
|
-
* Check if a value is a computed
|
|
168
|
+
* Check if a value is a computed signal
|
|
158
169
|
*
|
|
159
170
|
* @since 0.9.0
|
|
160
|
-
* @param {unknown} value -
|
|
161
|
-
* @returns {boolean} - true if value is a computed
|
|
171
|
+
* @param {unknown} value - Value to check
|
|
172
|
+
* @returns {boolean} - true if value is a computed signal, false otherwise
|
|
162
173
|
*/
|
|
163
174
|
const isComputed = /*#__PURE__*/ <T extends {}>(
|
|
164
175
|
value: unknown,
|
|
@@ -168,18 +179,18 @@ const isComputed = /*#__PURE__*/ <T extends {}>(
|
|
|
168
179
|
* Check if the provided value is a callback that may be used as input for toSignal() to derive a computed state
|
|
169
180
|
*
|
|
170
181
|
* @since 0.12.0
|
|
171
|
-
* @param {unknown} value -
|
|
182
|
+
* @param {unknown} value - Value to check
|
|
172
183
|
* @returns {boolean} - true if value is a callback or callbacks object, false otherwise
|
|
173
184
|
*/
|
|
174
185
|
const isComputedCallback = /*#__PURE__*/ <T extends {}>(
|
|
175
186
|
value: unknown,
|
|
176
|
-
): value is ComputedCallback<T> => isFunction(value) && value.length <
|
|
187
|
+
): value is ComputedCallback<T> => isFunction(value) && value.length < 3
|
|
177
188
|
|
|
178
189
|
/* === Exports === */
|
|
179
190
|
|
|
180
191
|
export {
|
|
181
192
|
TYPE_COMPUTED,
|
|
182
|
-
|
|
193
|
+
createComputed,
|
|
183
194
|
isComputed,
|
|
184
195
|
isComputedCallback,
|
|
185
196
|
type Computed,
|
package/src/effect.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CircularDependencyError } from './errors'
|
|
2
|
-
import { type Cleanup,
|
|
3
|
-
import { isAbortError, isAsyncFunction, isFunction } from './util'
|
|
1
|
+
import { CircularDependencyError, InvalidCallbackError } from './errors'
|
|
2
|
+
import { type Cleanup, createWatcher, observe } from './system'
|
|
3
|
+
import { isAbortError, isAsyncFunction, isFunction, valueString } from './util'
|
|
4
4
|
|
|
5
5
|
/* === Types === */
|
|
6
6
|
|
|
@@ -24,12 +24,15 @@ type EffectCallback =
|
|
|
24
24
|
* @param {EffectCallback} callback - Synchronous or asynchronous effect callback
|
|
25
25
|
* @returns {Cleanup} - Cleanup function for the effect
|
|
26
26
|
*/
|
|
27
|
-
const
|
|
28
|
-
|
|
27
|
+
const createEffect = (callback: EffectCallback): Cleanup => {
|
|
28
|
+
if (!isFunction(callback) || callback.length > 1)
|
|
29
|
+
throw new InvalidCallbackError('effect', valueString(callback))
|
|
30
|
+
|
|
31
|
+
const isAsync = isAsyncFunction(callback)
|
|
29
32
|
let running = false
|
|
30
33
|
let controller: AbortController | undefined
|
|
31
34
|
|
|
32
|
-
const
|
|
35
|
+
const watcher = createWatcher(() =>
|
|
33
36
|
observe(() => {
|
|
34
37
|
if (running) throw new CircularDependencyError('effect')
|
|
35
38
|
running = true
|
|
@@ -52,7 +55,7 @@ const effect = (callback: EffectCallback): Cleanup => {
|
|
|
52
55
|
isFunction(cleanup) &&
|
|
53
56
|
controller === currentController
|
|
54
57
|
)
|
|
55
|
-
|
|
58
|
+
watcher.unwatch(cleanup)
|
|
56
59
|
})
|
|
57
60
|
.catch(error => {
|
|
58
61
|
if (!isAbortError(error))
|
|
@@ -60,7 +63,7 @@ const effect = (callback: EffectCallback): Cleanup => {
|
|
|
60
63
|
})
|
|
61
64
|
} else {
|
|
62
65
|
cleanup = (callback as () => MaybeCleanup)()
|
|
63
|
-
if (isFunction(cleanup))
|
|
66
|
+
if (isFunction(cleanup)) watcher.unwatch(cleanup)
|
|
64
67
|
}
|
|
65
68
|
} catch (error) {
|
|
66
69
|
if (!isAbortError(error))
|
|
@@ -68,16 +71,16 @@ const effect = (callback: EffectCallback): Cleanup => {
|
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
running = false
|
|
71
|
-
},
|
|
74
|
+
}, watcher),
|
|
72
75
|
)
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
watcher()
|
|
75
78
|
return () => {
|
|
76
79
|
controller?.abort()
|
|
77
|
-
|
|
80
|
+
watcher.cleanup()
|
|
78
81
|
}
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
/* === Exports === */
|
|
82
85
|
|
|
83
|
-
export { type MaybeCleanup, type EffectCallback,
|
|
86
|
+
export { type MaybeCleanup, type EffectCallback, createEffect }
|
package/src/errors.ts
CHANGED
|
@@ -5,6 +5,13 @@ class CircularDependencyError extends Error {
|
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
class InvalidCallbackError extends TypeError {
|
|
9
|
+
constructor(where: string, value: string) {
|
|
10
|
+
super(`Invalid ${where} callback ${value}`)
|
|
11
|
+
this.name = 'InvalidCallbackError'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
class InvalidSignalValueError extends TypeError {
|
|
9
16
|
constructor(where: string, value: string) {
|
|
10
17
|
super(`Invalid signal value ${value} in ${where}`)
|
|
@@ -48,6 +55,7 @@ class StoreKeyReadonlyError extends Error {
|
|
|
48
55
|
|
|
49
56
|
export {
|
|
50
57
|
CircularDependencyError,
|
|
58
|
+
InvalidCallbackError,
|
|
51
59
|
InvalidSignalValueError,
|
|
52
60
|
NullishSignalValueError,
|
|
53
61
|
StoreKeyExistsError,
|
package/src/signal.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Computed,
|
|
3
3
|
type ComputedCallback,
|
|
4
|
-
|
|
4
|
+
createComputed,
|
|
5
5
|
isComputed,
|
|
6
6
|
isComputedCallback,
|
|
7
7
|
} from './computed'
|
|
8
|
-
import { isState, type State
|
|
9
|
-
import { isStore, type Store
|
|
8
|
+
import { createState, isState, type State } from './state'
|
|
9
|
+
import { createStore, isStore, type Store } from './store'
|
|
10
10
|
import { isRecord } from './util'
|
|
11
11
|
|
|
12
12
|
/* === Types === */
|
|
@@ -71,9 +71,9 @@ function toSignal<T extends {}>(
|
|
|
71
71
|
: State<T>
|
|
72
72
|
function toSignal<T extends {}>(value: T) {
|
|
73
73
|
if (isSignal<T>(value)) return value
|
|
74
|
-
if (isComputedCallback(value)) return
|
|
75
|
-
if (Array.isArray(value) || isRecord(value)) return
|
|
76
|
-
return
|
|
74
|
+
if (isComputedCallback(value)) return createComputed(value)
|
|
75
|
+
if (Array.isArray(value) || isRecord(value)) return createStore(value)
|
|
76
|
+
return createState(value)
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/* === Exports === */
|
package/src/state.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { isEqual } from './diff'
|
|
2
|
-
import { NullishSignalValueError } from './errors'
|
|
3
|
-
import { notify, subscribe, type Watcher } from './
|
|
4
|
-
import { isObjectOfType, UNSET } from './util'
|
|
2
|
+
import { InvalidCallbackError, NullishSignalValueError } from './errors'
|
|
3
|
+
import { notify, subscribe, type Watcher } from './system'
|
|
4
|
+
import { isFunction, isObjectOfType, UNSET, valueString } from './util'
|
|
5
5
|
|
|
6
6
|
/* === Types === */
|
|
7
7
|
|
|
8
8
|
type State<T extends {}> = {
|
|
9
|
-
[Symbol.toStringTag]: 'State'
|
|
9
|
+
readonly [Symbol.toStringTag]: 'State'
|
|
10
10
|
get(): T
|
|
11
|
-
set(
|
|
12
|
-
update(
|
|
11
|
+
set(newValue: T): void
|
|
12
|
+
update(updater: (oldValue: T) => T): void
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/* === Constants === */
|
|
@@ -25,18 +25,20 @@ const TYPE_STATE = 'State'
|
|
|
25
25
|
* @param {T} initialValue - initial value of the state
|
|
26
26
|
* @returns {State<T>} - new state signal
|
|
27
27
|
*/
|
|
28
|
-
const
|
|
28
|
+
const createState = /*#__PURE__*/ <T extends {}>(initialValue: T): State<T> => {
|
|
29
|
+
if (initialValue == null) throw new NullishSignalValueError('state')
|
|
30
|
+
|
|
29
31
|
const watchers: Set<Watcher> = new Set()
|
|
30
32
|
let value: T = initialValue
|
|
31
33
|
|
|
32
|
-
const
|
|
34
|
+
const state: State<T> = {
|
|
33
35
|
[Symbol.toStringTag]: TYPE_STATE,
|
|
34
36
|
|
|
35
37
|
/**
|
|
36
38
|
* Get the current value of the state
|
|
37
39
|
*
|
|
38
40
|
* @since 0.9.0
|
|
39
|
-
* @returns {T} -
|
|
41
|
+
* @returns {T} - Current value of the state
|
|
40
42
|
*/
|
|
41
43
|
get: (): T => {
|
|
42
44
|
subscribe(watchers)
|
|
@@ -47,13 +49,13 @@ const state = /*#__PURE__*/ <T extends {}>(initialValue: T): State<T> => {
|
|
|
47
49
|
* Set a new value of the state
|
|
48
50
|
*
|
|
49
51
|
* @since 0.9.0
|
|
50
|
-
* @param {T}
|
|
52
|
+
* @param {T} newValue - New value of the state
|
|
51
53
|
* @returns {void}
|
|
52
54
|
*/
|
|
53
|
-
set: (
|
|
54
|
-
if (
|
|
55
|
-
if (isEqual(value,
|
|
56
|
-
value =
|
|
55
|
+
set: (newValue: T): void => {
|
|
56
|
+
if (newValue == null) throw new NullishSignalValueError('state')
|
|
57
|
+
if (isEqual(value, newValue)) return
|
|
58
|
+
value = newValue
|
|
57
59
|
notify(watchers)
|
|
58
60
|
|
|
59
61
|
// Setting to UNSET clears the watchers so the signal can be garbage collected
|
|
@@ -64,15 +66,20 @@ const state = /*#__PURE__*/ <T extends {}>(initialValue: T): State<T> => {
|
|
|
64
66
|
* Update the state with a new value using a function
|
|
65
67
|
*
|
|
66
68
|
* @since 0.10.0
|
|
67
|
-
* @param {(v: T) => T}
|
|
68
|
-
* @returns {void}
|
|
69
|
+
* @param {(v: T) => T} updater - Function to update the state
|
|
70
|
+
* @returns {void}
|
|
69
71
|
*/
|
|
70
|
-
update: (
|
|
71
|
-
|
|
72
|
+
update: (updater: (oldValue: T) => T): void => {
|
|
73
|
+
if (!isFunction(updater))
|
|
74
|
+
throw new InvalidCallbackError(
|
|
75
|
+
'state update',
|
|
76
|
+
valueString(updater),
|
|
77
|
+
)
|
|
78
|
+
state.set(updater(value))
|
|
72
79
|
},
|
|
73
80
|
}
|
|
74
81
|
|
|
75
|
-
return
|
|
82
|
+
return state
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
/**
|
|
@@ -88,4 +95,4 @@ const isState = /*#__PURE__*/ <T extends {}>(
|
|
|
88
95
|
|
|
89
96
|
/* === Exports === */
|
|
90
97
|
|
|
91
|
-
export { TYPE_STATE, isState,
|
|
98
|
+
export { TYPE_STATE, isState, createState, type State }
|