or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-observables.mdhelper-functions.mdindex.mdpersistence.mdreact-integration.md
tile.json

core-observables.mddocs/

0

# Core Observables

1

2

Core observable creation and manipulation functions for reactive state management. These functions form the foundation of Legend State's reactive system.

3

4

## Capabilities

5

6

### Observable Creation

7

8

Creates observables from values with proxy-based reactivity.

9

10

```typescript { .api }

11

/**

12

* Creates an observable from any value with automatic proxy wrapping

13

* @param value - Initial value for the observable

14

* @returns Observable wrapper around the value

15

*/

16

function observable<T>(value?: T): Observable<T>;

17

/**

18

* Creates an observable from a Promise value

19

* @param value - Promise to wrap in observable

20

* @returns Observable that includes loading state

21

*/

22

function observable<T>(value: Promise<T>): Observable<T & WithState>;

23

24

/**

25

* Creates a primitive observable that wraps a single value

26

* @param value - Initial primitive value

27

* @returns ObservablePrimitive for the value

28

*/

29

function observablePrimitive<T>(value?: T): ObservablePrimitive<T>;

30

/**

31

* Creates a primitive observable from a Promise value

32

* @param value - Promise to wrap in observable

33

* @returns ObservablePrimitive that includes loading state

34

*/

35

function observablePrimitive<T>(value: Promise<T>): ObservablePrimitive<T & WithState>;

36

```

37

38

### Computed Observables

39

40

Creates computed values that automatically update when dependencies change.

41

42

```typescript { .api }

43

/**

44

* Creates a computed observable that automatically tracks dependencies

45

* @param compute - Function to compute the value

46

* @returns Computed observable that updates when dependencies change

47

*/

48

function computed<T>(compute: () => T): ObservableComputed<T>;

49

50

/**

51

* Creates a two-way computed observable with custom setter

52

* @param compute - Function to compute the value

53

* @param set - Function to handle value updates

54

* @returns Two-way computed observable

55

*/

56

function computed<T, T2 = T>(

57

compute: () => T,

58

set: (value: T2) => void

59

): ObservableComputedTwoWay<T, T2>;

60

```

61

62

### Observable Tracking

63

64

Track selector execution and manage observable change listening.

65

66

```typescript { .api }

67

/**

68

* Tracks a selector function and sets up automatic updates

69

* @param selector - Function to track for changes

70

* @param update - Update function called when dependencies change

71

* @param observeEvent - Optional observe event for cancellation

72

* @param observeOptions - Options for observation behavior

73

* @returns Object with value, dispose function, and resubscribe function

74

*/

75

function trackSelector<T>(

76

selector: Selector<T>,

77

update: (params: ListenerParams) => void,

78

observeEvent?: ObserveEvent<T>,

79

observeOptions?: ObserveOptions

80

): { value: T; dispose?: () => void; resubscribe?: () => () => void };

81

82

/**

83

* Sets up a change listener on a node value

84

* @param node - The node to listen to

85

* @param callback - Callback function for changes

86

* @param options - Listener options

87

* @returns Function to dispose the listener

88

*/

89

function onChange(

90

node: NodeValue,

91

callback: ListenerFn,

92

options?: {

93

trackingType?: TrackingType;

94

initial?: boolean;

95

immediate?: boolean;

96

noArgs?: boolean;

97

}

98

): () => void;

99

```

100

101

### Batching Operations

102

103

Groups multiple observable updates into a single batch to optimize performance.

104

105

```typescript { .api }

106

/**

107

* Executes function with all observable updates batched

108

* @param fn - Function to execute with batched updates

109

*/

110

function batch(fn: () => void): void;

111

112

/**

113

* Starts batching mode for manual control

114

*/

115

function beginBatch(): void;

116

117

/**

118

* Ends batching mode and flushes pending updates

119

*/

120

function endBatch(): void;

121

```

122

123

### Events

124

125

Creates event emitters for decoupled communication.

126

127

```typescript { .api }

128

/**

129

* Creates an event emitter

130

* @returns Event emitter instance

131

*/

132

function event(): EventEmitter;

133

134

interface EventEmitter {

135

fire(data?: any): void;

136

on(callback: (data?: any) => void): () => void;

137

}

138

```

139

140

### Observer Function

141

142

Sets up observers that react to observable changes.

143

144

```typescript { .api }

145

/**

146

* Observes changes to observables and executes reaction function

147

* @param selector - Function that accesses observables to track

148

* @param reaction - Function called when dependencies change

149

* @returns Dispose function to stop observing

150

*/

151

function observe<T>(

152

selector: () => T,

153

reaction: (value: T) => void

154

): () => void;

155

```

156

157

### When Functions

158

159

Provides Promise-based waiting for specific conditions.

160

161

```typescript { .api }

162

/**

163

* Returns a Promise that resolves when the predicate returns truthy

164

* @param predicate - Function to evaluate for truthiness

165

* @returns Promise that resolves with the truthy value

166

*/

167

function when<T>(predicate: () => T): Promise<T>;

168

169

/**

170

* Like when() but waits for observable values to be ready (not loading)

171

* @param predicate - Function to evaluate for ready state

172

* @returns Promise that resolves when value is ready

173

*/

174

function whenReady<T>(predicate: () => T): Promise<T>;

175

```

176

177

### Proxy Creation

178

179

Creates observable proxies for existing objects.

180

181

```typescript { .api }

182

/**

183

* Creates an observable proxy around an existing object

184

* @param target - Object to make observable

185

* @returns Observable proxy of the target object

186

*/

187

function proxy<T>(target: T): ObservableProxy<T>;

188

```

189

190

### Selector Tracking

191

192

Provides dependency tracking utilities for advanced use cases.

193

194

```typescript { .api }

195

/**

196

* Tracks dependencies of a selector function

197

* @param selector - Function to track dependencies for

198

* @returns Object with selector and tracking information

199

*/

200

function trackSelector<T>(selector: () => T): TrackedSelector<T>;

201

202

interface TrackedSelector<T> {

203

selector: () => T;

204

dependencies: Observable[];

205

dispose: () => void;

206

}

207

```

208

209

## Observable Interface

210

211

```typescript { .api }

212

interface Observable<T> {

213

/** Get the current value, tracking for changes */

214

get(): T;

215

/** Get the current value without tracking for changes */

216

peek(): T;

217

/** Set a new value */

218

set(value: T | ((prev: T) => T) | Promise<T>): void;

219

/** Listen for changes to this observable */

220

onChange(

221

callback: ListenerFn<T>,

222

options?: ChangeListenerOptions

223

): () => void;

224

/** Assign properties to object observables */

225

assign(value: Partial<T>): void;

226

/** Delete this observable */

227

delete(): void;

228

}

229

230

interface ObservablePrimitive<T> extends Observable<T> {

231

/** Toggle boolean values */

232

toggle(): T; // Only available for boolean types

233

}

234

235

interface ChangeListenerOptions {

236

trackingType?: boolean | symbol;

237

initial?: boolean;

238

immediate?: boolean;

239

noArgs?: boolean;

240

}

241

```

242

243

**Usage Examples:**

244

245

```typescript

246

import { observable, computed, batch, when } from "@legendapp/state";

247

248

// Create observables

249

const counter$ = observable(0);

250

const user$ = observable({

251

name: "Alice",

252

age: 30,

253

preferences: {

254

theme: "dark"

255

}

256

});

257

258

// Create computed values

259

const doubled$ = computed(() => counter$.get() * 2);

260

const greeting$ = computed(() => `Hello, ${user$.name.get()}!`);

261

262

// Batch updates

263

batch(() => {

264

counter$.set(5);

265

user$.name.set("Bob");

266

user$.age.set(25);

267

}); // Only fires listeners once at the end

268

269

// Wait for conditions

270

await when(() => counter$.get() > 10);

271

console.log("Counter exceeded 10!");

272

273

// Listen for changes

274

const dispose = user$.onChange(({ value }) => {

275

console.log("User changed:", value);

276

});

277

278

// Access nested properties

279

user$.preferences.theme.set("light");

280

console.log(user$.preferences.theme.get()); // "light"

281

282

// Clean up

283

dispose();

284

```