@zeix/cause-effect 0.17.0 → 0.17.1
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 +19 -5
- package/.cursorrules +8 -3
- package/.github/copilot-instructions.md +9 -4
- package/CLAUDE.md +96 -262
- package/README.md +232 -421
- package/archive/computed.ts +2 -2
- package/archive/memo.ts +3 -2
- package/archive/task.ts +2 -2
- package/index.dev.js +59 -26
- package/index.js +1 -1
- package/index.ts +11 -3
- package/package.json +1 -1
- package/src/classes/collection.ts +38 -28
- package/src/classes/computed.ts +3 -3
- package/src/classes/list.ts +8 -7
- package/src/classes/ref.ts +68 -0
- package/src/errors.ts +21 -0
- package/src/match.ts +5 -12
- package/src/resolve.ts +3 -2
- package/src/util.ts +0 -4
- package/test/collection.test.ts +104 -47
- package/test/ref.test.ts +227 -0
- package/types/index.d.ts +5 -4
- package/types/src/classes/collection.d.ts +21 -7
- package/types/src/classes/list.d.ts +4 -4
- package/types/src/classes/ref.d.ts +39 -0
- package/types/src/errors.d.ts +6 -1
- package/types/src/util.d.ts +1 -2
package/test/ref.test.ts
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { expect, mock, test } from 'bun:test'
|
|
2
|
+
import { isRef, Ref } from '../src/classes/ref'
|
|
3
|
+
import { createEffect } from '../src/effect'
|
|
4
|
+
|
|
5
|
+
test('Ref - basic functionality', () => {
|
|
6
|
+
const obj = { name: 'test', value: 42 }
|
|
7
|
+
const ref = new Ref(obj)
|
|
8
|
+
|
|
9
|
+
expect(ref.get()).toBe(obj)
|
|
10
|
+
expect(ref[Symbol.toStringTag]).toBe('Ref')
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
test('Ref - isRef type guard', () => {
|
|
14
|
+
const ref = new Ref({ test: true })
|
|
15
|
+
const notRef = { test: true }
|
|
16
|
+
|
|
17
|
+
expect(isRef(ref)).toBe(true)
|
|
18
|
+
expect(isRef(notRef)).toBe(false)
|
|
19
|
+
expect(isRef(null)).toBe(false)
|
|
20
|
+
expect(isRef(undefined)).toBe(false)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('Ref - validation with guard function', () => {
|
|
24
|
+
const isConfig = (
|
|
25
|
+
value: unknown,
|
|
26
|
+
): value is { host: string; port: number } =>
|
|
27
|
+
typeof value === 'object' &&
|
|
28
|
+
value !== null &&
|
|
29
|
+
'host' in value &&
|
|
30
|
+
'port' in value &&
|
|
31
|
+
typeof value.host === 'string' &&
|
|
32
|
+
typeof value.port === 'number'
|
|
33
|
+
|
|
34
|
+
const validConfig = { host: 'localhost', port: 3000 }
|
|
35
|
+
const invalidConfig = { host: 'localhost' } // missing port
|
|
36
|
+
|
|
37
|
+
expect(() => new Ref(validConfig, isConfig)).not.toThrow()
|
|
38
|
+
expect(() => new Ref(invalidConfig, isConfig)).toThrow()
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('Ref - reactive subscriptions', () => {
|
|
42
|
+
const server = { status: 'offline', connections: 0 }
|
|
43
|
+
const ref = new Ref(server)
|
|
44
|
+
|
|
45
|
+
let effectRunCount = 0
|
|
46
|
+
let lastStatus: string = ''
|
|
47
|
+
|
|
48
|
+
createEffect(() => {
|
|
49
|
+
const current = ref.get()
|
|
50
|
+
lastStatus = current.status
|
|
51
|
+
effectRunCount++
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
expect(effectRunCount).toBe(1)
|
|
55
|
+
expect(lastStatus).toBe('offline')
|
|
56
|
+
|
|
57
|
+
// Simulate external change without going through reactive system
|
|
58
|
+
server.status = 'online'
|
|
59
|
+
server.connections = 5
|
|
60
|
+
|
|
61
|
+
// Effect shouldn't re-run yet (reference hasn't changed)
|
|
62
|
+
expect(effectRunCount).toBe(1)
|
|
63
|
+
|
|
64
|
+
// Notify that the external object has changed
|
|
65
|
+
ref.notify()
|
|
66
|
+
|
|
67
|
+
expect(effectRunCount).toBe(2)
|
|
68
|
+
expect(lastStatus).toBe('online')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('Ref - notify triggers watchers even with same reference', () => {
|
|
72
|
+
const fileObj = { path: '/test.txt', size: 100, modified: Date.now() }
|
|
73
|
+
const ref = new Ref(fileObj)
|
|
74
|
+
|
|
75
|
+
const mockCallback = mock(() => {})
|
|
76
|
+
|
|
77
|
+
createEffect(() => {
|
|
78
|
+
ref.get()
|
|
79
|
+
mockCallback()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
expect(mockCallback).toHaveBeenCalledTimes(1)
|
|
83
|
+
|
|
84
|
+
// Simulate file modification (same object reference, different content)
|
|
85
|
+
fileObj.size = 200
|
|
86
|
+
fileObj.modified = Date.now()
|
|
87
|
+
|
|
88
|
+
// Notify about external change
|
|
89
|
+
ref.notify()
|
|
90
|
+
|
|
91
|
+
expect(mockCallback).toHaveBeenCalledTimes(2)
|
|
92
|
+
|
|
93
|
+
// Multiple notifies should trigger multiple times
|
|
94
|
+
ref.notify()
|
|
95
|
+
expect(mockCallback).toHaveBeenCalledTimes(3)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('Ref - multiple effects with same ref', () => {
|
|
99
|
+
const database = { connected: false, queries: 0 }
|
|
100
|
+
const ref = new Ref(database)
|
|
101
|
+
|
|
102
|
+
const effect1Mock = mock(() => {})
|
|
103
|
+
const effect2Mock = mock((_connected: boolean) => {})
|
|
104
|
+
|
|
105
|
+
createEffect(() => {
|
|
106
|
+
ref.get()
|
|
107
|
+
effect1Mock()
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
createEffect(() => {
|
|
111
|
+
const db = ref.get()
|
|
112
|
+
effect2Mock(db.connected)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
expect(effect1Mock).toHaveBeenCalledTimes(1)
|
|
116
|
+
expect(effect2Mock).toHaveBeenCalledTimes(1)
|
|
117
|
+
expect(effect2Mock).toHaveBeenCalledWith(false)
|
|
118
|
+
|
|
119
|
+
// Simulate database connection change
|
|
120
|
+
database.connected = true
|
|
121
|
+
database.queries = 10
|
|
122
|
+
ref.notify()
|
|
123
|
+
|
|
124
|
+
expect(effect1Mock).toHaveBeenCalledTimes(2)
|
|
125
|
+
expect(effect2Mock).toHaveBeenCalledTimes(2)
|
|
126
|
+
expect(effect2Mock).toHaveBeenLastCalledWith(true)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
test('Ref - with Bun.file() scenario', () => {
|
|
130
|
+
// Mock a file-like object that could change externally
|
|
131
|
+
const fileRef = {
|
|
132
|
+
name: 'config.json',
|
|
133
|
+
size: 1024,
|
|
134
|
+
lastModified: Date.now(),
|
|
135
|
+
// Simulate file methods
|
|
136
|
+
exists: () => true,
|
|
137
|
+
text: () => Promise.resolve('{"version": "1.0"}'),
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const ref = new Ref(fileRef)
|
|
141
|
+
|
|
142
|
+
let sizeChanges = 0
|
|
143
|
+
createEffect(() => {
|
|
144
|
+
const file = ref.get()
|
|
145
|
+
if (file.size > 1000) sizeChanges++
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
expect(sizeChanges).toBe(1) // Initial run
|
|
149
|
+
|
|
150
|
+
// Simulate file growing (external change)
|
|
151
|
+
fileRef.size = 2048
|
|
152
|
+
fileRef.lastModified = Date.now()
|
|
153
|
+
ref.notify()
|
|
154
|
+
|
|
155
|
+
expect(sizeChanges).toBe(2) // Effect re-ran and condition still met
|
|
156
|
+
|
|
157
|
+
// Simulate file shrinking
|
|
158
|
+
fileRef.size = 500
|
|
159
|
+
ref.notify()
|
|
160
|
+
|
|
161
|
+
expect(sizeChanges).toBe(2) // Effect re-ran but condition no longer met
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
test('Ref - validation errors', () => {
|
|
165
|
+
// @ts-expect-error deliberatly provoked error
|
|
166
|
+
expect(() => new Ref(null)).toThrow()
|
|
167
|
+
// @ts-expect-error deliberatly provoked error
|
|
168
|
+
expect(() => new Ref(undefined)).toThrow()
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
test('Ref - server config object scenario', () => {
|
|
172
|
+
const config = {
|
|
173
|
+
host: 'localhost',
|
|
174
|
+
port: 3000,
|
|
175
|
+
ssl: false,
|
|
176
|
+
maxConnections: 100,
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const configRef = new Ref(config)
|
|
180
|
+
const connectionAttempts: string[] = []
|
|
181
|
+
|
|
182
|
+
createEffect(() => {
|
|
183
|
+
const cfg = configRef.get()
|
|
184
|
+
const protocol = cfg.ssl ? 'https' : 'http'
|
|
185
|
+
connectionAttempts.push(`${protocol}://${cfg.host}:${cfg.port}`)
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
expect(connectionAttempts).toEqual(['http://localhost:3000'])
|
|
189
|
+
|
|
190
|
+
// Simulate config reload from file/environment
|
|
191
|
+
config.ssl = true
|
|
192
|
+
config.port = 8443
|
|
193
|
+
configRef.notify()
|
|
194
|
+
|
|
195
|
+
expect(connectionAttempts).toEqual([
|
|
196
|
+
'http://localhost:3000',
|
|
197
|
+
'https://localhost:8443',
|
|
198
|
+
])
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
test('Ref - handles complex nested objects', () => {
|
|
202
|
+
const apiResponse = {
|
|
203
|
+
status: 200,
|
|
204
|
+
data: {
|
|
205
|
+
users: [{ id: 1, name: 'Alice' }],
|
|
206
|
+
pagination: { page: 1, total: 1 },
|
|
207
|
+
},
|
|
208
|
+
headers: { 'content-type': 'application/json' },
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const ref = new Ref(apiResponse)
|
|
212
|
+
let userCount = 0
|
|
213
|
+
|
|
214
|
+
createEffect(() => {
|
|
215
|
+
const response = ref.get()
|
|
216
|
+
userCount = response.data.users.length
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
expect(userCount).toBe(1)
|
|
220
|
+
|
|
221
|
+
// Simulate API response update
|
|
222
|
+
apiResponse.data.users.push({ id: 2, name: 'Bob' })
|
|
223
|
+
apiResponse.data.pagination.total = 2
|
|
224
|
+
ref.notify()
|
|
225
|
+
|
|
226
|
+
expect(userCount).toBe(2)
|
|
227
|
+
})
|
package/types/index.d.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @name Cause & Effect
|
|
3
|
-
* @version 0.17.
|
|
3
|
+
* @version 0.17.1
|
|
4
4
|
* @author Esther Brunner
|
|
5
5
|
*/
|
|
6
|
-
export { Collection, type CollectionCallback, isCollection, TYPE_COLLECTION, } from './src/classes/collection';
|
|
6
|
+
export { type Collection, type CollectionCallback, type CollectionSource, DerivedCollection, isCollection, TYPE_COLLECTION, } from './src/classes/collection';
|
|
7
7
|
export { type Computed, createComputed, isComputed, isMemoCallback, isTaskCallback, Memo, type MemoCallback, Task, type TaskCallback, TYPE_COMPUTED, } from './src/classes/computed';
|
|
8
8
|
export { type ArrayToRecord, isList, type KeyConfig, List, TYPE_LIST, } from './src/classes/list';
|
|
9
|
+
export { isRef, Ref, TYPE_REF } from './src/classes/ref';
|
|
9
10
|
export { isState, State, TYPE_STATE } from './src/classes/state';
|
|
10
11
|
export { BaseStore, createStore, isStore, type Store, TYPE_STORE, } from './src/classes/store';
|
|
11
12
|
export { type DiffResult, diff, isEqual, type UnknownArray, type UnknownRecord, } from './src/diff';
|
|
12
13
|
export { createEffect, type EffectCallback, type MaybeCleanup, } from './src/effect';
|
|
13
|
-
export { CircularDependencyError, DuplicateKeyError, InvalidCallbackError, InvalidSignalValueError, NullishSignalValueError, ReadonlySignalError, } from './src/errors';
|
|
14
|
+
export { CircularDependencyError, createError, DuplicateKeyError, type Guard, guardMutableSignal, InvalidCallbackError, InvalidCollectionSourceError, InvalidSignalValueError, NullishSignalValueError, ReadonlySignalError, validateCallback, validateSignalValue, } from './src/errors';
|
|
14
15
|
export { type MatchHandlers, match } from './src/match';
|
|
15
16
|
export { type ResolveResult, resolve } from './src/resolve';
|
|
16
17
|
export { createSignal, isMutableSignal, isSignal, type Signal, type SignalValues, type UnknownSignalRecord, } from './src/signal';
|
|
17
18
|
export { batchSignalWrites, type Cleanup, createWatcher, emitNotification, flushPendingReactions, type Listener, type Listeners, type Notifications, notifyWatchers, subscribeActiveWatcher, trackSignalReads, type Watcher, } from './src/system';
|
|
18
|
-
export { isAbortError, isAsyncFunction, isFunction, isNumber, isObjectOfType, isRecord, isRecordOrArray, isString, isSymbol,
|
|
19
|
+
export { isAbortError, isAsyncFunction, isFunction, isNumber, isObjectOfType, isRecord, isRecordOrArray, isString, isSymbol, UNSET, valueString, } from './src/util';
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
+
import type { Signal } from '../signal';
|
|
1
2
|
import { type Cleanup, type Listener, type Listeners } from '../system';
|
|
2
3
|
import { type Computed } from './computed';
|
|
3
4
|
import { type List } from './list';
|
|
4
|
-
type CollectionSource<T extends {}> = List<T> | Collection<T
|
|
5
|
+
type CollectionSource<T extends {}> = List<T> | Collection<T>;
|
|
5
6
|
type CollectionCallback<T extends {}, U extends {}> = ((sourceValue: U) => T) | ((sourceValue: U, abort: AbortSignal) => Promise<T>);
|
|
7
|
+
type Collection<T extends {}> = {
|
|
8
|
+
readonly [Symbol.toStringTag]: 'Collection';
|
|
9
|
+
readonly [Symbol.isConcatSpreadable]: true;
|
|
10
|
+
[Symbol.iterator](): IterableIterator<Signal<T>>;
|
|
11
|
+
get: () => T[];
|
|
12
|
+
at: (index: number) => Signal<T> | undefined;
|
|
13
|
+
byKey: (key: string) => Signal<T> | undefined;
|
|
14
|
+
keyAt: (index: number) => string | undefined;
|
|
15
|
+
indexOfKey: (key: string) => number | undefined;
|
|
16
|
+
on: <K extends keyof Listeners>(type: K, listener: Listener<K>) => Cleanup;
|
|
17
|
+
deriveCollection: <R extends {}>(callback: CollectionCallback<R, T>) => DerivedCollection<R, T>;
|
|
18
|
+
readonly length: number;
|
|
19
|
+
};
|
|
6
20
|
declare const TYPE_COLLECTION: "Collection";
|
|
7
|
-
declare class
|
|
21
|
+
declare class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
8
22
|
#private;
|
|
9
23
|
constructor(source: CollectionSource<U> | (() => CollectionSource<U>), callback: CollectionCallback<T, U>);
|
|
10
24
|
get [Symbol.toStringTag](): 'Collection';
|
|
11
|
-
get [Symbol.isConcatSpreadable]():
|
|
25
|
+
get [Symbol.isConcatSpreadable](): true;
|
|
12
26
|
[Symbol.iterator](): IterableIterator<Computed<T>>;
|
|
13
27
|
get length(): number;
|
|
14
28
|
get(): T[];
|
|
@@ -18,8 +32,8 @@ declare class Collection<T extends {}, U extends {}> {
|
|
|
18
32
|
keyAt(index: number): string | undefined;
|
|
19
33
|
indexOfKey(key: string): number;
|
|
20
34
|
on<K extends keyof Listeners>(type: K, listener: Listener<K>): Cleanup;
|
|
21
|
-
deriveCollection<R extends {}>(callback: (sourceValue: T) => R):
|
|
22
|
-
deriveCollection<R extends {}>(callback: (sourceValue: T, abort: AbortSignal) => Promise<R>):
|
|
35
|
+
deriveCollection<R extends {}>(callback: (sourceValue: T) => R): DerivedCollection<R, T>;
|
|
36
|
+
deriveCollection<R extends {}>(callback: (sourceValue: T, abort: AbortSignal) => Promise<R>): DerivedCollection<R, T>;
|
|
23
37
|
}
|
|
24
38
|
/**
|
|
25
39
|
* Check if a value is a collection signal
|
|
@@ -28,5 +42,5 @@ declare class Collection<T extends {}, U extends {}> {
|
|
|
28
42
|
* @param {unknown} value - Value to check
|
|
29
43
|
* @returns {boolean} - True if value is a collection signal, false otherwise
|
|
30
44
|
*/
|
|
31
|
-
declare const isCollection: <T extends {}, U extends {}>(value: unknown) => value is
|
|
32
|
-
export { Collection, type CollectionSource, type CollectionCallback, isCollection, TYPE_COLLECTION, };
|
|
45
|
+
declare const isCollection: <T extends {}, U extends {}>(value: unknown) => value is DerivedCollection<T, U>;
|
|
46
|
+
export { type Collection, type CollectionSource, type CollectionCallback, DerivedCollection, isCollection, TYPE_COLLECTION, };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type UnknownArray } from '../diff';
|
|
2
2
|
import { type Cleanup, type Listener, type Notifications } from '../system';
|
|
3
|
-
import {
|
|
3
|
+
import { DerivedCollection } from './collection';
|
|
4
4
|
import { State } from './state';
|
|
5
5
|
type ArrayToRecord<T extends UnknownArray> = {
|
|
6
6
|
[key: string]: T extends Array<infer U extends {}> ? U : never;
|
|
@@ -11,7 +11,7 @@ declare class List<T extends {}> {
|
|
|
11
11
|
#private;
|
|
12
12
|
constructor(initialValue: T[], keyConfig?: KeyConfig<T>);
|
|
13
13
|
get [Symbol.toStringTag](): 'List';
|
|
14
|
-
get [Symbol.isConcatSpreadable]():
|
|
14
|
+
get [Symbol.isConcatSpreadable](): true;
|
|
15
15
|
[Symbol.iterator](): IterableIterator<State<T>>;
|
|
16
16
|
get length(): number;
|
|
17
17
|
get(): T[];
|
|
@@ -27,8 +27,8 @@ declare class List<T extends {}> {
|
|
|
27
27
|
sort(compareFn?: (a: T, b: T) => number): void;
|
|
28
28
|
splice(start: number, deleteCount?: number, ...items: T[]): T[];
|
|
29
29
|
on<K extends keyof Notifications>(type: K, listener: Listener<K>): Cleanup;
|
|
30
|
-
deriveCollection<R extends {}>(callback: (sourceValue: T) => R):
|
|
31
|
-
deriveCollection<R extends {}>(callback: (sourceValue: T, abort: AbortSignal) => Promise<R>):
|
|
30
|
+
deriveCollection<R extends {}>(callback: (sourceValue: T) => R): DerivedCollection<R, T>;
|
|
31
|
+
deriveCollection<R extends {}>(callback: (sourceValue: T, abort: AbortSignal) => Promise<R>): DerivedCollection<R, T>;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Check if the provided value is a List instance
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Guard } from '../errors';
|
|
2
|
+
declare const TYPE_REF = "Ref";
|
|
3
|
+
/**
|
|
4
|
+
* Create a new ref signal.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.17.1
|
|
7
|
+
*/
|
|
8
|
+
declare class Ref<T extends {}> {
|
|
9
|
+
#private;
|
|
10
|
+
/**
|
|
11
|
+
* Create a new ref signal.
|
|
12
|
+
*
|
|
13
|
+
* @param {T} value - Reference to external object
|
|
14
|
+
* @param {Guard<T>} guard - Optional guard function to validate the value
|
|
15
|
+
* @throws {NullishSignalValueError} - If the value is null or undefined
|
|
16
|
+
* @throws {InvalidSignalValueError} - If the value is invalid
|
|
17
|
+
*/
|
|
18
|
+
constructor(value: T, guard?: Guard<T>);
|
|
19
|
+
get [Symbol.toStringTag](): string;
|
|
20
|
+
/**
|
|
21
|
+
* Get the value of the ref signal.
|
|
22
|
+
*
|
|
23
|
+
* @returns {T} - Object reference
|
|
24
|
+
*/
|
|
25
|
+
get(): T;
|
|
26
|
+
/**
|
|
27
|
+
* Notify watchers of relevant changes in the external reference
|
|
28
|
+
*/
|
|
29
|
+
notify(): void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if the provided value is a Ref instance
|
|
33
|
+
*
|
|
34
|
+
* @since 0.17.1
|
|
35
|
+
* @param {unknown} value - Value to check
|
|
36
|
+
* @returns {boolean} - True if the value is a Ref instance, false otherwise
|
|
37
|
+
*/
|
|
38
|
+
declare const isRef: <T extends {}>(value: unknown) => value is Ref<T>;
|
|
39
|
+
export { TYPE_REF, Ref, isRef };
|
package/types/src/errors.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type MutableSignal } from './signal';
|
|
2
|
+
type Guard<T> = (value: unknown) => value is T;
|
|
2
3
|
declare class CircularDependencyError extends Error {
|
|
3
4
|
constructor(where: string);
|
|
4
5
|
}
|
|
@@ -8,6 +9,9 @@ declare class DuplicateKeyError extends Error {
|
|
|
8
9
|
declare class InvalidCallbackError extends TypeError {
|
|
9
10
|
constructor(where: string, value: unknown);
|
|
10
11
|
}
|
|
12
|
+
declare class InvalidCollectionSourceError extends TypeError {
|
|
13
|
+
constructor(where: string, value: unknown);
|
|
14
|
+
}
|
|
11
15
|
declare class InvalidSignalValueError extends TypeError {
|
|
12
16
|
constructor(where: string, value: unknown);
|
|
13
17
|
}
|
|
@@ -17,7 +21,8 @@ declare class NullishSignalValueError extends TypeError {
|
|
|
17
21
|
declare class ReadonlySignalError extends Error {
|
|
18
22
|
constructor(what: string, value: unknown);
|
|
19
23
|
}
|
|
24
|
+
declare const createError: (reason: unknown) => Error;
|
|
20
25
|
declare const validateCallback: (where: string, value: unknown, guard?: (value: unknown) => boolean) => void;
|
|
21
26
|
declare const validateSignalValue: (where: string, value: unknown, guard?: (value: unknown) => boolean) => void;
|
|
22
27
|
declare const guardMutableSignal: <T extends {}>(what: string, value: unknown, signal: unknown) => signal is MutableSignal<T>;
|
|
23
|
-
export { CircularDependencyError, DuplicateKeyError, InvalidCallbackError, InvalidSignalValueError, NullishSignalValueError, ReadonlySignalError, validateCallback, validateSignalValue, guardMutableSignal, };
|
|
28
|
+
export { type Guard, CircularDependencyError, DuplicateKeyError, InvalidCallbackError, InvalidCollectionSourceError, InvalidSignalValueError, NullishSignalValueError, ReadonlySignalError, createError, validateCallback, validateSignalValue, guardMutableSignal, };
|
package/types/src/util.d.ts
CHANGED
|
@@ -14,6 +14,5 @@ declare const isRecordOrArray: <T extends Record<string | number, unknown> | Rea
|
|
|
14
14
|
declare const isUniformArray: <T>(value: unknown, guard?: (item: T) => item is T & {}) => value is T[];
|
|
15
15
|
declare const hasMethod: <T extends object & Record<string, (...args: unknown[]) => unknown>>(obj: T, methodName: string) => obj is T & Record<string, (...args: unknown[]) => unknown>;
|
|
16
16
|
declare const isAbortError: (error: unknown) => boolean;
|
|
17
|
-
declare const toError: (reason: unknown) => Error;
|
|
18
17
|
declare const valueString: (value: unknown) => string;
|
|
19
|
-
export { UNSET, isString, isNumber, isSymbol, isFunction, isAsyncFunction, isSyncFunction, isNonNullObject, isObjectOfType, isRecord, isRecordOrArray, isUniformArray, hasMethod, isAbortError,
|
|
18
|
+
export { UNSET, isString, isNumber, isSymbol, isFunction, isAsyncFunction, isSyncFunction, isNonNullObject, isObjectOfType, isRecord, isRecordOrArray, isUniformArray, hasMethod, isAbortError, valueString, };
|