or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

environment-utilities.mdimmutable-arrays.mdimmutable-objects.mdindex.mdmath-operations.mdreactive-utilities.mdtype-definitions.md

reactive-utilities.mddocs/

0

# Reactive Utilities

1

2

Core utilities for working with Solid.js reactivity system, including accessor manipulation, signal creation, and lifecycle management. These functions are designed to integrate seamlessly with Solid.js's reactive patterns and signal-based state management.

3

4

## Capabilities

5

6

### MaybeAccessor Access

7

8

Functions for working with values that may or may not be accessors (reactive functions).

9

10

```typescript { .api }

11

/**

12

* Accesses the value of a MaybeAccessor

13

* @param v - Value or accessor function to access

14

* @returns The accessed value

15

*/

16

function access<T extends MaybeAccessor<any>>(v: T): MaybeAccessorValue<T>;

17

18

/**

19

* Access an array of MaybeAccessors

20

* @param list - Array of values or accessor functions

21

* @returns Array of accessed values

22

*/

23

function accessArray<A extends MaybeAccessor<any>>(

24

list: readonly A[]

25

): MaybeAccessorValue<A>[];

26

27

/**

28

* Run the function if the accessed value is not undefined nor null

29

* @param value - MaybeAccessor to check and access

30

* @param fn - Function to run with the non-null value

31

*/

32

function withAccess<T, A extends MaybeAccessor<T>, V = MaybeAccessorValue<A>>(

33

value: A,

34

fn: (value: NonNullable<V>) => void

35

): void;

36

37

/**

38

* Convert MaybeAccessor to Accessor

39

* @param v - Value or accessor to convert

40

* @returns Accessor function

41

*/

42

function asAccessor<A extends MaybeAccessor<unknown>>(

43

v: A

44

): Accessor<MaybeAccessorValue<A>>;

45

46

/**

47

* If value is a function – call it with given arguments – otherwise get the value as is

48

* @param valueOrFn - Value or function to access

49

* @param args - Arguments to pass if valueOrFn is a function

50

* @returns Accessed value or function result

51

*/

52

function accessWith<T>(

53

valueOrFn: T,

54

...args: T extends AnyFunction ? Parameters<T> : never

55

): T extends AnyFunction ? ReturnType<T> : T;

56

```

57

58

**Usage Examples:**

59

60

```typescript

61

import { createSignal } from "solid-js";

62

import { access, accessArray, withAccess, asAccessor } from "@solid-primitives/utils";

63

64

// Basic access

65

const value = access("hello"); // "hello"

66

const signalValue = access(() => "world"); // "world"

67

68

// Array access

69

const values = accessArray([1, () => 2, 3]); // [1, 2, 3]

70

71

// Conditional access

72

withAccess(() => "value", (val) => {

73

console.log(val); // "value"

74

});

75

76

// Convert to accessor

77

const accessor = asAccessor("static value");

78

console.log(accessor()); // "static value"

79

```

80

81

### Signal Creation

82

83

Enhanced signal creation functions with special capabilities like hydration support.

84

85

```typescript { .api }

86

/**

87

* A hydratable version of createSignal. Uses serverValue on server and update function on client.

88

* During hydration uses serverValue as initial and updates once hydration is complete.

89

* @param serverValue - Initial value for server

90

* @param update - Function called on client to initialize value

91

* @param options - Signal options

92

* @returns Signal tuple [state, setState]

93

*/

94

function createHydratableSignal<T>(

95

serverValue: T,

96

update: () => T,

97

options?: SignalOptions<T>

98

): ReturnType<typeof createSignal<T>>;

99

100

/** @deprecated use createHydratableSignal instead */

101

const createHydrateSignal: typeof createHydratableSignal;

102

```

103

104

**Usage Examples:**

105

106

```typescript

107

import { createHydratableSignal } from "@solid-primitives/utils";

108

109

// Server-side rendering compatible signal

110

const [theme, setTheme] = createHydratableSignal(

111

"light", // Server default

112

() => localStorage.getItem("theme") || "light" // Client initialization

113

);

114

115

// With options

116

const [count, setCount] = createHydratableSignal(

117

0,

118

() => parseInt(sessionStorage.getItem("count") || "0"),

119

{ equals: false }

120

);

121

```

122

123

### Deferred Effects

124

125

Advanced effect utilities for handling delayed and conditional reactive updates.

126

127

```typescript { .api }

128

/**

129

* Solid's `on` helper, but always defers and returns provided initial value instead of undefined

130

* @param deps - Dependencies to watch (accessor or array of accessors)

131

* @param fn - Effect function

132

* @param initialValue - Initial value to return

133

* @returns Effect function

134

*/

135

function defer<S, Next extends Prev, Prev = Next>(

136

deps: AccessorArray<S> | Accessor<S>,

137

fn: (input: S, prevInput: S, prev: undefined | NoInfer<Prev>) => Next,

138

initialValue: Next

139

): EffectFunction<undefined | NoInfer<Next>, NoInfer<Next>>;

140

141

function defer<S, Next extends Prev, Prev = Next>(

142

deps: AccessorArray<S> | Accessor<S>,

143

fn: (input: S, prevInput: S, prev: undefined | NoInfer<Prev>) => Next,

144

initialValue?: undefined

145

): EffectFunction<undefined | NoInfer<Next>>;

146

```

147

148

**Usage Examples:**

149

150

```typescript

151

import { createSignal, createEffect } from "solid-js";

152

import { defer } from "@solid-primitives/utils";

153

154

const [count, setCount] = createSignal(0);

155

156

createEffect(defer(

157

count,

158

(value, prevValue, prev) => {

159

console.log(`Count changed from ${prevValue} to ${value}`);

160

return value * 2;

161

},

162

0 // Initial value

163

));

164

```

165

166

### Lifecycle Utilities

167

168

Functions for working with Solid.js lifecycle hooks and cleanup.

169

170

```typescript { .api }

171

/**

172

* Solid's onCleanup that doesn't warn in development if used outside of a component

173

*/

174

const tryOnCleanup: typeof onCleanup;

175

```

176

177

### Callback Management

178

179

Utilities for managing and executing multiple callback functions.

180

181

```typescript { .api }

182

/**

183

* Create a callback stack for managing multiple callbacks

184

* @returns Object with push, execute, and clear methods

185

*/

186

function createCallbackStack<A0 = void, A1 = void, A2 = void, A3 = void>(): {

187

push: (...callbacks: ((arg0: A0, arg1: A1, arg2: A2, arg3: A3) => void)[]) => void;

188

execute: (arg0: A0, arg1: A1, arg2: A2, arg3: A3) => void;

189

clear: VoidFunction;

190

};

191

192

/**

193

* Group synchronous function calls into microtasks

194

* @param fn - Function to group calls for

195

* @returns Grouped function

196

*/

197

function createMicrotask<A extends any[] | []>(fn: (...a: A) => void): (...a: A) => void;

198

```

199

200

**Usage Examples:**

201

202

```typescript

203

import { createCallbackStack, createMicrotask } from "@solid-primitives/utils";

204

205

// Callback stack

206

const stack = createCallbackStack<string>();

207

stack.push(

208

(msg) => console.log("First:", msg),

209

(msg) => console.log("Second:", msg)

210

);

211

stack.execute("Hello"); // Logs both messages and clears stack

212

213

// Microtask grouping

214

const logGrouped = createMicrotask((message: string) => {

215

console.log("Grouped:", message);

216

});

217

218

logGrouped("A");

219

logGrouped("B"); // Only the last call "B" will execute

220

```

221

222

### Array Utilities

223

224

Reactive-specific array manipulation and diffing utilities.

225

226

```typescript { .api }

227

/**

228

* Handle items removed and added to the array by diffing by reference

229

* @param current - New array instance

230

* @param prev - Previous array copy

231

* @param handleAdded - Called for every added item

232

* @param handleRemoved - Called for every removed item

233

*/

234

function handleDiffArray<T>(

235

current: readonly T[],

236

prev: readonly T[],

237

handleAdded: (item: T) => void,

238

handleRemoved: (item: T) => void

239

): void;

240

```

241

242

**Usage Examples:**

243

244

```typescript

245

import { createSignal, createEffect } from "solid-js";

246

import { handleDiffArray } from "@solid-primitives/utils";

247

248

const [items, setItems] = createSignal<string[]>([]);

249

let prevItems: string[] = [];

250

251

createEffect(() => {

252

const currentItems = items();

253

handleDiffArray(

254

currentItems,

255

prevItems,

256

(item) => console.log("Added:", item),

257

(item) => console.log("Removed:", item)

258

);

259

prevItems = [...currentItems];

260

});

261

```

262

263

## Types

264

265

```typescript { .api }

266

type MaybeAccessor<T> = T | Accessor<T>;

267

type MaybeAccessorValue<T extends MaybeAccessor<any>> = T extends () => any ? ReturnType<T> : T;

268

type OnAccessEffectFunction<S, Prev, Next extends Prev = Prev> = (

269

input: AccessReturnTypes<S>,

270

prevInput: AccessReturnTypes<S>,

271

v: Prev

272

) => Next;

273

type AccessReturnTypes<S> = S extends MaybeAccessor<any>[]

274

? { [I in keyof S]: AccessReturnTypes<S[I]>; }

275

: MaybeAccessorValue<S>;

276

```