or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-react-cache

A basic cache for React applications designed for experimental features with suspense-based data fetching

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-cache@2.0.x

To install, run

npx @tessl/cli install tessl/npm-react-cache@2.0.0

0

# React Cache

1

2

React Cache is a basic cache for React applications that provides suspense-based data fetching capabilities. It serves as a reference implementation for more advanced caching solutions and is designed to work alongside experimental React features.

3

4

**⚠️ Experimental Package**: This package is explicitly unstable and not recommended for production use. The API will change between versions.

5

6

## Package Information

7

8

- **Package Name**: react-cache

9

- **Package Type**: npm

10

- **Language**: JavaScript (with Flow types)

11

- **Installation**: This is a private package within the React monorepo and not directly installable

12

- **React Version**: Requires React ^17.0.0 (peer dependency)

13

14

## Core Imports

15

16

```javascript

17

import { unstable_createResource, unstable_setGlobalCacheLimit } from "react-cache";

18

```

19

20

CommonJS:

21

22

```javascript

23

const { unstable_createResource, unstable_setGlobalCacheLimit } = require("react-cache");

24

```

25

26

## Basic Usage

27

28

```javascript

29

import React, { Suspense } from "react";

30

import { unstable_createResource } from "react-cache";

31

32

// Create a resource for fetching user data

33

const UserResource = unstable_createResource(

34

async (userId) => {

35

const response = await fetch(`/api/users/${userId}`);

36

return response.json();

37

},

38

(userId) => `user-${userId}` // Optional hash function for cache keys

39

);

40

41

function UserProfile({ userId }) {

42

// This will suspend if data is not cached, or return cached data

43

const user = UserResource.read(userId);

44

45

return (

46

<div>

47

<h1>{user.name}</h1>

48

<p>{user.email}</p>

49

</div>

50

);

51

}

52

53

function App() {

54

return (

55

<Suspense fallback={<div>Loading...</div>}>

56

<UserProfile userId={123} />

57

</Suspense>

58

);

59

}

60

```

61

62

## Architecture

63

64

React Cache is built around several key components:

65

66

- **Resource Pattern**: Resources encapsulate async data fetching with built-in caching

67

- **Suspense Integration**: Uses React's suspense mechanism by throwing promises during pending states

68

- **LRU Cache**: Internal Least Recently Used cache with configurable limits and automatic cleanup

69

- **Status Tracking**: Three-state system (Pending/Resolved/Rejected) for cache entries

70

- **Hash Functions**: Customizable key generation for cache storage

71

72

## Capabilities

73

74

### Resource Creation

75

76

Creates a cached resource that integrates with React Suspense for data fetching.

77

78

```javascript { .api }

79

/**

80

* Creates a resource that can cache async data fetching results

81

* @param fetch - Function that returns a thenable (promise-like) for data fetching

82

* @param maybeHashInput - Optional hash function for generating cache keys (defaults to identity function)

83

* @returns Resource object with read and preload methods

84

*/

85

function unstable_createResource<I, K, V>(

86

fetch: (input: I) => Thenable<V>,

87

maybeHashInput?: (input: I) => K

88

): Resource<I, V>;

89

90

interface Resource<I, V> {

91

/**

92

* Reads cached data or suspends if data is not available

93

* Throws the promise if pending, throws error if rejected, returns value if resolved

94

*/

95

read(input: I): V;

96

97

/**

98

* Preloads data into cache without returning the value

99

* Useful for prefetching data before it's needed

100

*/

101

preload(input: I): void;

102

}

103

```

104

105

**Usage Example:**

106

107

```javascript

108

// Simple resource with identity hash function

109

const SimpleResource = unstable_createResource(async (id) => {

110

return fetch(`/api/data/${id}`).then(r => r.json());

111

});

112

113

// Resource with custom hash function for complex inputs

114

const ComplexResource = unstable_createResource(

115

async ({ userId, type, filters }) => {

116

const params = new URLSearchParams({ userId, type, ...filters });

117

return fetch(`/api/complex?${params}`).then(r => r.json());

118

},

119

({ userId, type, filters }) => `${userId}-${type}-${JSON.stringify(filters)}`

120

);

121

122

// Preload data before component renders

123

ComplexResource.preload({ userId: 123, type: 'profile', filters: { active: true } });

124

```

125

126

### Global Cache Configuration

127

128

Sets the global cache limit for all resources.

129

130

```javascript { .api }

131

/**

132

* Sets the global cache limit for all resources

133

* @param limit - Maximum number of cached entries across all resources

134

*/

135

function unstable_setGlobalCacheLimit(limit: number): void;

136

```

137

138

**Usage Example:**

139

140

```javascript

141

import { unstable_setGlobalCacheLimit } from "react-cache";

142

143

// Set global cache to hold maximum 1000 entries

144

unstable_setGlobalCacheLimit(1000);

145

146

// Default limit is 500 entries

147

```

148

149

## Types

150

151

### Resource Interface

152

153

```javascript { .api }

154

/**

155

* Resource interface for cached data fetching

156

*/

157

interface Resource<I, V> {

158

read(input: I): V;

159

preload(input: I): void;

160

}

161

```

162

163

### Core Types

164

165

```javascript { .api }

166

/**

167

* Promise-like interface used by React Cache

168

*/

169

interface Thenable<T> {

170

then<U>(

171

onFulfill?: (value: T) => U | Thenable<U>,

172

onReject?: (error: any) => U | Thenable<U>

173

): Thenable<U>;

174

}

175

```

176

177

### Cache Entry States

178

179

```javascript { .api }

180

/**

181

* Internal cache entry result types (for reference)

182

*/

183

type PendingResult = {

184

status: 0;

185

value: Thenable<any>; // The suspender thenable

186

};

187

188

type ResolvedResult<V> = {

189

status: 1;

190

value: V;

191

};

192

193

type RejectedResult = {

194

status: 2;

195

value: any; // The error

196

};

197

198

type Result<V> = PendingResult | ResolvedResult<V> | RejectedResult;

199

```

200

201

## Error Handling

202

203

React Cache integrates with React's error boundaries for error handling:

204

205

```javascript

206

// Errors thrown by fetch functions will be re-thrown when read() is called

207

const ErrorProneResource = unstable_createResource(async (id) => {

208

const response = await fetch(`/api/data/${id}`);

209

if (!response.ok) {

210

throw new Error(`Failed to fetch: ${response.status}`);

211

}

212

return response.json();

213

});

214

215

function ErrorBoundary({ children }) {

216

return (

217

<React.ErrorBoundary

218

fallback={<div>Something went wrong!</div>}

219

onError={(error) => console.error('Cache error:', error)}

220

>

221

{children}

222

</React.ErrorBoundary>

223

);

224

}

225

```

226

227

## Important Constraints

228

229

- **Render Phase Only**: `read()` and `preload()` methods can only be called during React component render phase

230

- **Suspense Required**: Components using `resource.read()` must be wrapped in a `<Suspense>` boundary

231

- **Key Limitations**: Default hash function only supports primitive types (string, number, symbol, boolean, null, undefined)

232

- **React Version**: Requires React 17.0.0 or higher

233

- **Experimental Status**: API is subject to breaking changes without notice