@zeix/cause-effect 0.17.0 → 0.17.2
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 +26 -5
- package/.cursorrules +8 -3
- package/.github/copilot-instructions.md +13 -4
- package/CLAUDE.md +191 -262
- package/README.md +268 -420
- package/archive/collection.ts +23 -25
- package/archive/computed.ts +5 -4
- package/archive/list.ts +21 -28
- package/archive/memo.ts +4 -2
- package/archive/state.ts +2 -1
- package/archive/store.ts +21 -32
- package/archive/task.ts +6 -9
- package/index.dev.js +411 -220
- package/index.js +1 -1
- package/index.ts +25 -8
- package/package.json +1 -1
- package/src/classes/collection.ts +103 -77
- package/src/classes/composite.ts +28 -33
- package/src/classes/computed.ts +90 -31
- package/src/classes/list.ts +39 -33
- package/src/classes/ref.ts +96 -0
- package/src/classes/state.ts +41 -8
- package/src/classes/store.ts +47 -30
- package/src/diff.ts +2 -1
- package/src/effect.ts +19 -9
- package/src/errors.ts +31 -1
- package/src/match.ts +5 -12
- package/src/resolve.ts +3 -2
- package/src/signal.ts +0 -1
- package/src/system.ts +159 -43
- package/src/util.ts +0 -10
- package/test/collection.test.ts +383 -67
- package/test/computed.test.ts +268 -11
- package/test/effect.test.ts +2 -2
- package/test/list.test.ts +249 -21
- package/test/ref.test.ts +381 -0
- package/test/state.test.ts +13 -13
- package/test/store.test.ts +473 -28
- package/types/index.d.ts +6 -5
- package/types/src/classes/collection.d.ts +27 -12
- package/types/src/classes/composite.d.ts +4 -4
- package/types/src/classes/computed.d.ts +17 -0
- package/types/src/classes/list.d.ts +6 -6
- package/types/src/classes/ref.d.ts +48 -0
- package/types/src/classes/state.d.ts +9 -0
- package/types/src/classes/store.d.ts +4 -4
- package/types/src/effect.d.ts +1 -2
- package/types/src/errors.d.ts +9 -1
- package/types/src/system.d.ts +40 -24
- package/types/src/util.d.ts +1 -3
package/src/diff.ts
CHANGED
package/src/effect.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { CircularDependencyError, InvalidCallbackError } from './errors'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type Cleanup,
|
|
4
|
+
createWatcher,
|
|
5
|
+
HOOK_CLEANUP,
|
|
6
|
+
type MaybeCleanup,
|
|
7
|
+
trackSignalReads,
|
|
8
|
+
} from './system'
|
|
3
9
|
import { isAbortError, isAsyncFunction, isFunction } from './util'
|
|
4
10
|
|
|
5
11
|
/* === Types === */
|
|
6
12
|
|
|
7
|
-
// biome-ignore lint/suspicious/noConfusingVoidType: optional Cleanup return type
|
|
8
|
-
type MaybeCleanup = Cleanup | undefined | void
|
|
9
|
-
|
|
10
13
|
type EffectCallback =
|
|
11
14
|
| (() => MaybeCleanup)
|
|
12
15
|
| ((abort: AbortSignal) => Promise<MaybeCleanup>)
|
|
@@ -55,19 +58,22 @@ const createEffect = (callback: EffectCallback): Cleanup => {
|
|
|
55
58
|
isFunction(cleanup) &&
|
|
56
59
|
controller === currentController
|
|
57
60
|
)
|
|
58
|
-
watcher.
|
|
61
|
+
watcher.on(HOOK_CLEANUP, cleanup)
|
|
59
62
|
})
|
|
60
63
|
.catch(error => {
|
|
61
64
|
if (!isAbortError(error))
|
|
62
|
-
console.error(
|
|
65
|
+
console.error(
|
|
66
|
+
'Error in async effect callback:',
|
|
67
|
+
error,
|
|
68
|
+
)
|
|
63
69
|
})
|
|
64
70
|
} else {
|
|
65
71
|
cleanup = callback()
|
|
66
|
-
if (isFunction(cleanup)) watcher.
|
|
72
|
+
if (isFunction(cleanup)) watcher.on(HOOK_CLEANUP, cleanup)
|
|
67
73
|
}
|
|
68
74
|
} catch (error) {
|
|
69
75
|
if (!isAbortError(error))
|
|
70
|
-
console.error('
|
|
76
|
+
console.error('Error in effect callback:', error)
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
running = false
|
|
@@ -77,7 +83,11 @@ const createEffect = (callback: EffectCallback): Cleanup => {
|
|
|
77
83
|
watcher()
|
|
78
84
|
return () => {
|
|
79
85
|
controller?.abort()
|
|
80
|
-
|
|
86
|
+
try {
|
|
87
|
+
watcher.stop()
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error('Error in effect cleanup:', error)
|
|
90
|
+
}
|
|
81
91
|
}
|
|
82
92
|
}
|
|
83
93
|
|
package/src/errors.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { isMutableSignal, type MutableSignal } from './signal'
|
|
2
|
-
import {
|
|
2
|
+
import { UNSET } from './system'
|
|
3
|
+
import { isFunction, isSymbol, valueString } from './util'
|
|
4
|
+
|
|
5
|
+
/* === Types === */
|
|
6
|
+
|
|
7
|
+
type Guard<T> = (value: unknown) => value is T
|
|
8
|
+
|
|
9
|
+
/* === Classes === */
|
|
3
10
|
|
|
4
11
|
class CircularDependencyError extends Error {
|
|
5
12
|
constructor(where: string) {
|
|
@@ -26,6 +33,20 @@ class InvalidCallbackError extends TypeError {
|
|
|
26
33
|
}
|
|
27
34
|
}
|
|
28
35
|
|
|
36
|
+
class InvalidCollectionSourceError extends TypeError {
|
|
37
|
+
constructor(where: string, value: unknown) {
|
|
38
|
+
super(`Invalid ${where} source ${valueString(value)}`)
|
|
39
|
+
this.name = 'InvalidCollectionSourceError'
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
class InvalidHookError extends TypeError {
|
|
44
|
+
constructor(where: string, type: string) {
|
|
45
|
+
super(`Invalid hook "${type}" in ${where}`)
|
|
46
|
+
this.name = 'InvalidHookError'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
29
50
|
class InvalidSignalValueError extends TypeError {
|
|
30
51
|
constructor(where: string, value: unknown) {
|
|
31
52
|
super(`Invalid signal value ${valueString(value)} in ${where}`)
|
|
@@ -49,6 +70,11 @@ class ReadonlySignalError extends Error {
|
|
|
49
70
|
}
|
|
50
71
|
}
|
|
51
72
|
|
|
73
|
+
/* === Functions === */
|
|
74
|
+
|
|
75
|
+
const createError = /*#__PURE__*/ (reason: unknown): Error =>
|
|
76
|
+
reason instanceof Error ? reason : Error(String(reason))
|
|
77
|
+
|
|
52
78
|
const validateCallback = (
|
|
53
79
|
where: string,
|
|
54
80
|
value: unknown,
|
|
@@ -77,12 +103,16 @@ const guardMutableSignal = <T extends {}>(
|
|
|
77
103
|
}
|
|
78
104
|
|
|
79
105
|
export {
|
|
106
|
+
type Guard,
|
|
80
107
|
CircularDependencyError,
|
|
81
108
|
DuplicateKeyError,
|
|
82
109
|
InvalidCallbackError,
|
|
110
|
+
InvalidCollectionSourceError,
|
|
111
|
+
InvalidHookError,
|
|
83
112
|
InvalidSignalValueError,
|
|
84
113
|
NullishSignalValueError,
|
|
85
114
|
ReadonlySignalError,
|
|
115
|
+
createError,
|
|
86
116
|
validateCallback,
|
|
87
117
|
validateSignalValue,
|
|
88
118
|
guardMutableSignal,
|
package/src/match.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { createError } from './errors'
|
|
1
2
|
import type { ResolveResult } from './resolve'
|
|
2
3
|
import type { SignalValues, UnknownSignalRecord } from './signal'
|
|
3
|
-
import { toError } from './util'
|
|
4
4
|
|
|
5
5
|
/* === Types === */
|
|
6
6
|
|
|
@@ -32,17 +32,10 @@ function match<S extends UnknownSignalRecord>(
|
|
|
32
32
|
if (result.pending) handlers.nil?.()
|
|
33
33
|
else if (result.errors) handlers.err?.(result.errors)
|
|
34
34
|
else if (result.ok) handlers.ok(result.values)
|
|
35
|
-
} catch (
|
|
36
|
-
|
|
37
|
-
if (
|
|
38
|
-
handlers.err
|
|
39
|
-
(!result.errors || !result.errors.includes(toError(error)))
|
|
40
|
-
)
|
|
41
|
-
handlers.err(
|
|
42
|
-
result.errors
|
|
43
|
-
? [...result.errors, toError(error)]
|
|
44
|
-
: [toError(error)],
|
|
45
|
-
)
|
|
35
|
+
} catch (e) {
|
|
36
|
+
const error = createError(e)
|
|
37
|
+
if (handlers.err && (!result.errors || !result.errors.includes(error)))
|
|
38
|
+
handlers.err(result.errors ? [...result.errors, error] : [error])
|
|
46
39
|
else throw error
|
|
47
40
|
}
|
|
48
41
|
}
|
package/src/resolve.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { UnknownRecord } from './diff'
|
|
2
|
+
import { createError } from './errors'
|
|
2
3
|
import type { SignalValues, UnknownSignalRecord } from './signal'
|
|
3
|
-
import {
|
|
4
|
+
import { UNSET } from './system'
|
|
4
5
|
|
|
5
6
|
/* === Types === */
|
|
6
7
|
|
|
@@ -33,7 +34,7 @@ function resolve<S extends UnknownSignalRecord>(signals: S): ResolveResult<S> {
|
|
|
33
34
|
if (value === UNSET) pending = true
|
|
34
35
|
else values[key] = value
|
|
35
36
|
} catch (e) {
|
|
36
|
-
errors.push(
|
|
37
|
+
errors.push(createError(e))
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
|
package/src/signal.ts
CHANGED
|
@@ -10,7 +10,6 @@ import { isList, List } from './classes/list'
|
|
|
10
10
|
import { isState, State } from './classes/state'
|
|
11
11
|
import { createStore, isStore, type Store } from './classes/store'
|
|
12
12
|
import type { UnknownRecord } from './diff'
|
|
13
|
-
// import type { Collection } from './signals/collection'
|
|
14
13
|
import { isRecord, isUniformArray } from './util'
|
|
15
14
|
|
|
16
15
|
/* === Types === */
|
package/src/system.ts
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
/* === Types === */
|
|
2
2
|
|
|
3
|
+
import { createError, InvalidHookError } from './errors'
|
|
4
|
+
import { isFunction } from './util'
|
|
5
|
+
|
|
3
6
|
type Cleanup = () => void
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
onCleanup(cleanup: Cleanup): void
|
|
8
|
-
stop(): void
|
|
9
|
-
}
|
|
8
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: optional Cleanup return type
|
|
9
|
+
type MaybeCleanup = Cleanup | undefined | void
|
|
10
10
|
|
|
11
|
-
type
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
remove: readonly string[]
|
|
15
|
-
sort: readonly string[]
|
|
16
|
-
}
|
|
11
|
+
type Hook = 'add' | 'change' | 'cleanup' | 'remove' | 'sort' | 'watch'
|
|
12
|
+
type CleanupHook = 'cleanup'
|
|
13
|
+
type WatchHook = 'watch'
|
|
17
14
|
|
|
18
|
-
type
|
|
19
|
-
payload: Notifications[K],
|
|
20
|
-
) => void
|
|
15
|
+
type HookCallback = (payload?: readonly string[]) => MaybeCleanup
|
|
21
16
|
|
|
22
|
-
type
|
|
23
|
-
[K in
|
|
17
|
+
type HookCallbacks = {
|
|
18
|
+
[K in Hook]?: Set<HookCallback>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type Watcher = {
|
|
22
|
+
(): void
|
|
23
|
+
on(type: CleanupHook, cleanup: Cleanup): void
|
|
24
|
+
stop(): void
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/* === Internal === */
|
|
@@ -28,14 +29,29 @@ type Listeners = {
|
|
|
28
29
|
// Currently active watcher
|
|
29
30
|
let activeWatcher: Watcher | undefined
|
|
30
31
|
|
|
32
|
+
// Map of signal watchers to their cleanup functions
|
|
33
|
+
const unwatchMap = new WeakMap<Set<Watcher>, Set<Cleanup>>()
|
|
34
|
+
|
|
31
35
|
// Queue of pending watcher reactions for batched change notifications
|
|
32
36
|
const pendingReactions = new Set<() => void>()
|
|
33
37
|
let batchDepth = 0
|
|
34
38
|
|
|
39
|
+
/* === Constants === */
|
|
40
|
+
|
|
41
|
+
// biome-ignore lint/suspicious/noExplicitAny: Deliberately using any to be used as a placeholder value in any signal
|
|
42
|
+
const UNSET: any = Symbol()
|
|
43
|
+
|
|
44
|
+
const HOOK_ADD = 'add'
|
|
45
|
+
const HOOK_CHANGE = 'change'
|
|
46
|
+
const HOOK_CLEANUP = 'cleanup'
|
|
47
|
+
const HOOK_REMOVE = 'remove'
|
|
48
|
+
const HOOK_SORT = 'sort'
|
|
49
|
+
const HOOK_WATCH = 'watch'
|
|
50
|
+
|
|
35
51
|
/* === Functions === */
|
|
36
52
|
|
|
37
53
|
/**
|
|
38
|
-
* Create a watcher
|
|
54
|
+
* Create a watcher to observe changes to a signal.
|
|
39
55
|
*
|
|
40
56
|
* A watcher is a reaction function with onCleanup and stop methods
|
|
41
57
|
*
|
|
@@ -46,43 +62,86 @@ let batchDepth = 0
|
|
|
46
62
|
const createWatcher = (react: () => void): Watcher => {
|
|
47
63
|
const cleanups = new Set<Cleanup>()
|
|
48
64
|
const watcher = react as Partial<Watcher>
|
|
49
|
-
watcher.
|
|
50
|
-
cleanups.add(cleanup)
|
|
65
|
+
watcher.on = (type: CleanupHook, cleanup: Cleanup) => {
|
|
66
|
+
if (type === HOOK_CLEANUP) cleanups.add(cleanup)
|
|
67
|
+
else throw new InvalidHookError('watcher', type)
|
|
51
68
|
}
|
|
52
69
|
watcher.stop = () => {
|
|
53
|
-
|
|
54
|
-
|
|
70
|
+
try {
|
|
71
|
+
for (const cleanup of cleanups) cleanup()
|
|
72
|
+
} finally {
|
|
73
|
+
cleanups.clear()
|
|
74
|
+
}
|
|
55
75
|
}
|
|
56
76
|
return watcher as Watcher
|
|
57
77
|
}
|
|
58
78
|
|
|
59
79
|
/**
|
|
60
|
-
* Subscribe by adding active watcher to the Set of watchers of a signal
|
|
80
|
+
* Subscribe by adding active watcher to the Set of watchers of a signal.
|
|
61
81
|
*
|
|
62
82
|
* @param {Set<Watcher>} watchers - Watchers of the signal
|
|
83
|
+
* @param {Set<HookCallback>} watchHookCallbacks - HOOK_WATCH callbacks of the signal
|
|
63
84
|
*/
|
|
64
|
-
const subscribeActiveWatcher = (
|
|
85
|
+
const subscribeActiveWatcher = (
|
|
86
|
+
watchers: Set<Watcher>,
|
|
87
|
+
watchHookCallbacks?: Set<HookCallback>,
|
|
88
|
+
): void => {
|
|
89
|
+
// Check if we need to trigger HOOK_WATCH callbacks
|
|
90
|
+
if (!watchers.size && watchHookCallbacks?.size) {
|
|
91
|
+
const unwatch = triggerHook(watchHookCallbacks)
|
|
92
|
+
if (unwatch) {
|
|
93
|
+
const unwatchCallbacks =
|
|
94
|
+
unwatchMap.get(watchers) ?? new Set<Cleanup>()
|
|
95
|
+
unwatchCallbacks.add(unwatch)
|
|
96
|
+
if (!unwatchMap.has(watchers))
|
|
97
|
+
unwatchMap.set(watchers, unwatchCallbacks)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Only if active watcher is not already subscribed
|
|
65
102
|
if (activeWatcher && !watchers.has(activeWatcher)) {
|
|
66
103
|
const watcher = activeWatcher
|
|
67
|
-
|
|
104
|
+
|
|
105
|
+
watcher.on(HOOK_CLEANUP, () => {
|
|
106
|
+
// Remove the watcher from the Set of watchers
|
|
107
|
+
watchers.delete(watcher)
|
|
108
|
+
|
|
109
|
+
// If it was the last watcher, call unwatch callbacks
|
|
110
|
+
if (!watchers.size) {
|
|
111
|
+
const unwatchCallbacks = unwatchMap.get(watchers)
|
|
112
|
+
if (unwatchCallbacks) {
|
|
113
|
+
try {
|
|
114
|
+
for (const unwatch of unwatchCallbacks) unwatch()
|
|
115
|
+
} finally {
|
|
116
|
+
unwatchCallbacks.clear()
|
|
117
|
+
unwatchMap.delete(watchers)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// Here the active watcher is added to the Set of watchers
|
|
68
124
|
watchers.add(watcher)
|
|
69
125
|
}
|
|
70
126
|
}
|
|
71
127
|
|
|
72
128
|
/**
|
|
73
|
-
* Notify watchers of a signal change
|
|
129
|
+
* Notify watchers of a signal change.
|
|
74
130
|
*
|
|
75
131
|
* @param {Set<Watcher>} watchers - Watchers of the signal
|
|
132
|
+
* @returns {boolean} - Whether any watchers were notified
|
|
76
133
|
*/
|
|
77
|
-
const notifyWatchers = (watchers: Set<Watcher>) => {
|
|
134
|
+
const notifyWatchers = (watchers: Set<Watcher>): boolean => {
|
|
135
|
+
if (!watchers.size) return false
|
|
78
136
|
for (const react of watchers) {
|
|
79
137
|
if (batchDepth) pendingReactions.add(react)
|
|
80
138
|
else react()
|
|
81
139
|
}
|
|
140
|
+
return true
|
|
82
141
|
}
|
|
83
142
|
|
|
84
143
|
/**
|
|
85
|
-
* Flush all pending reactions of enqueued watchers
|
|
144
|
+
* Flush all pending reactions of enqueued watchers.
|
|
86
145
|
*/
|
|
87
146
|
const flushPendingReactions = () => {
|
|
88
147
|
while (pendingReactions.size) {
|
|
@@ -93,7 +152,7 @@ const flushPendingReactions = () => {
|
|
|
93
152
|
}
|
|
94
153
|
|
|
95
154
|
/**
|
|
96
|
-
* Batch multiple signal writes
|
|
155
|
+
* Batch multiple signal writes.
|
|
97
156
|
*
|
|
98
157
|
* @param {() => void} callback - Function with multiple signal writes to be batched
|
|
99
158
|
*/
|
|
@@ -108,7 +167,7 @@ const batchSignalWrites = (callback: () => void) => {
|
|
|
108
167
|
}
|
|
109
168
|
|
|
110
169
|
/**
|
|
111
|
-
* Run a function with signal reads in a tracking context (or temporarily untrack)
|
|
170
|
+
* Run a function with signal reads in a tracking context (or temporarily untrack).
|
|
112
171
|
*
|
|
113
172
|
* @param {Watcher | false} watcher - Watcher to be called when the signal changes
|
|
114
173
|
* or false for temporary untracking while inserting auto-hydrating DOM nodes
|
|
@@ -126,34 +185,91 @@ const trackSignalReads = (watcher: Watcher | false, run: () => void): void => {
|
|
|
126
185
|
}
|
|
127
186
|
|
|
128
187
|
/**
|
|
129
|
-
*
|
|
188
|
+
* Trigger a hook.
|
|
130
189
|
*
|
|
131
|
-
* @param {Set<
|
|
132
|
-
* @param {
|
|
190
|
+
* @param {Set<HookCallback> | undefined} callbacks - Callbacks to be called when the hook is triggered
|
|
191
|
+
* @param {readonly string[] | undefined} payload - Payload to be sent to listeners
|
|
192
|
+
* @return {Cleanup | undefined} Cleanup function to be called when the hook is unmounted
|
|
133
193
|
*/
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
payload
|
|
137
|
-
) => {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
194
|
+
const triggerHook = (
|
|
195
|
+
callbacks: Set<HookCallback> | undefined,
|
|
196
|
+
payload?: readonly string[],
|
|
197
|
+
): Cleanup | undefined => {
|
|
198
|
+
if (!callbacks) return
|
|
199
|
+
|
|
200
|
+
const cleanups: Cleanup[] = []
|
|
201
|
+
const errors: Error[] = []
|
|
202
|
+
|
|
203
|
+
const throwError = (inCleanup?: boolean) => {
|
|
204
|
+
if (errors.length) {
|
|
205
|
+
if (errors.length === 1) throw errors[0]
|
|
206
|
+
throw new AggregateError(
|
|
207
|
+
errors,
|
|
208
|
+
`Errors in hook ${inCleanup ? 'cleanup' : 'callback'}:`,
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
for (const callback of callbacks) {
|
|
214
|
+
try {
|
|
215
|
+
const cleanup = callback(payload)
|
|
216
|
+
if (isFunction(cleanup)) cleanups.push(cleanup)
|
|
217
|
+
} catch (error) {
|
|
218
|
+
errors.push(createError(error))
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
throwError()
|
|
222
|
+
|
|
223
|
+
if (!cleanups.length) return
|
|
224
|
+
if (cleanups.length === 1) return cleanups[0]
|
|
225
|
+
return () => {
|
|
226
|
+
for (const cleanup of cleanups) {
|
|
227
|
+
try {
|
|
228
|
+
cleanup()
|
|
229
|
+
} catch (error) {
|
|
230
|
+
errors.push(createError(error))
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
throwError(true)
|
|
141
234
|
}
|
|
142
235
|
}
|
|
143
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Check whether a hook type is handled in a signal.
|
|
239
|
+
*
|
|
240
|
+
* @param {Hook} type - Type of hook to check
|
|
241
|
+
* @param {T} handled - List of handled hook types
|
|
242
|
+
* @returns {type is T[number]} - Whether the hook type is handled
|
|
243
|
+
*/
|
|
244
|
+
const isHandledHook = <T extends readonly Hook[]>(
|
|
245
|
+
type: Hook,
|
|
246
|
+
handled: T,
|
|
247
|
+
): type is T[number] => handled.includes(type)
|
|
248
|
+
|
|
144
249
|
/* === Exports === */
|
|
145
250
|
|
|
146
251
|
export {
|
|
147
252
|
type Cleanup,
|
|
253
|
+
type MaybeCleanup,
|
|
148
254
|
type Watcher,
|
|
149
|
-
type
|
|
150
|
-
type
|
|
151
|
-
type
|
|
255
|
+
type Hook,
|
|
256
|
+
type CleanupHook,
|
|
257
|
+
type WatchHook,
|
|
258
|
+
type HookCallback,
|
|
259
|
+
type HookCallbacks,
|
|
260
|
+
HOOK_ADD,
|
|
261
|
+
HOOK_CHANGE,
|
|
262
|
+
HOOK_CLEANUP,
|
|
263
|
+
HOOK_REMOVE,
|
|
264
|
+
HOOK_SORT,
|
|
265
|
+
HOOK_WATCH,
|
|
266
|
+
UNSET,
|
|
152
267
|
createWatcher,
|
|
153
268
|
subscribeActiveWatcher,
|
|
154
269
|
notifyWatchers,
|
|
155
270
|
flushPendingReactions,
|
|
156
271
|
batchSignalWrites,
|
|
157
272
|
trackSignalReads,
|
|
158
|
-
|
|
273
|
+
triggerHook,
|
|
274
|
+
isHandledHook,
|
|
159
275
|
}
|
package/src/util.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/* === Constants === */
|
|
2
|
-
|
|
3
|
-
// biome-ignore lint/suspicious/noExplicitAny: Deliberately using any to be used as a placeholder value in any signal
|
|
4
|
-
const UNSET: any = Symbol()
|
|
5
|
-
|
|
6
1
|
/* === Utility Functions === */
|
|
7
2
|
|
|
8
3
|
const isString = /*#__PURE__*/ (value: unknown): value is string =>
|
|
@@ -63,9 +58,6 @@ const hasMethod = /*#__PURE__*/ <
|
|
|
63
58
|
const isAbortError = /*#__PURE__*/ (error: unknown): boolean =>
|
|
64
59
|
error instanceof DOMException && error.name === 'AbortError'
|
|
65
60
|
|
|
66
|
-
const toError = /*#__PURE__*/ (reason: unknown): Error =>
|
|
67
|
-
reason instanceof Error ? reason : Error(String(reason))
|
|
68
|
-
|
|
69
61
|
const valueString = /*#__PURE__*/ (value: unknown): string =>
|
|
70
62
|
isString(value)
|
|
71
63
|
? `"${value}"`
|
|
@@ -76,7 +68,6 @@ const valueString = /*#__PURE__*/ (value: unknown): string =>
|
|
|
76
68
|
/* === Exports === */
|
|
77
69
|
|
|
78
70
|
export {
|
|
79
|
-
UNSET,
|
|
80
71
|
isString,
|
|
81
72
|
isNumber,
|
|
82
73
|
isSymbol,
|
|
@@ -90,6 +81,5 @@ export {
|
|
|
90
81
|
isUniformArray,
|
|
91
82
|
hasMethod,
|
|
92
83
|
isAbortError,
|
|
93
|
-
toError,
|
|
94
84
|
valueString,
|
|
95
85
|
}
|