or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-context.mdbuild-plugins.mdcontext-creation.mdindex.mdnamespace-management.md

namespace-management.mddocs/

0

# Namespace Management

1

2

Namespace management provides a global context registry system to avoid conflicts between different library versions and enable context sharing across modules.

3

4

## API Reference

5

6

```typescript { .api }

7

/**

8

* Create a namespace for managing multiple contexts

9

* @param defaultOpts - Default options applied to all contexts in namespace

10

* @returns Namespace instance for managing contexts by key

11

*/

12

function createNamespace<T = any>(defaultOpts: ContextOptions): ContextNamespace;

13

14

/**

15

* Get context from the default global namespace

16

* @param key - Unique key identifying the context (recommend using package name)

17

* @param opts - Context options, merged with namespace defaults

18

* @returns Context instance for the given key

19

*/

20

function getContext<T>(key: string, opts?: ContextOptions): UseContext<T>;

21

22

/**

23

* Get use function for named context from default global namespace

24

* @param key - Unique key identifying the context

25

* @param opts - Context options

26

* @returns Function that returns current context value when called

27

*/

28

function useContext<T>(key: string, opts?: ContextOptions): () => T;

29

30

interface ContextNamespace {

31

/**

32

* Get or create a context by key within the namespace

33

* @param key - Unique key for the context

34

* @param opts - Context options, merged with namespace defaults

35

* @returns Context instance for the key

36

*/

37

get<T>(key: string, opts?: ContextOptions): UseContext<T>;

38

}

39

40

/**

41

* The default global namespace instance

42

*/

43

const defaultNamespace: ContextNamespace;

44

```

45

46

## Basic Usage

47

48

### Using Default Global Namespace

49

50

```typescript

51

import { useContext, getContext } from "unctx";

52

53

interface UserSession {

54

userId: string;

55

token: string;

56

permissions: string[];

57

}

58

59

// Get context use function (recommended for library authors)

60

const useUserSession = useContext<UserSession>("my-auth-lib");

61

62

// Or get full context instance

63

const userSessionContext = getContext<UserSession>("my-auth-lib");

64

65

// Set up context in your library initialization

66

userSessionContext.set({

67

userId: "user-123",

68

token: "jwt-token",

69

permissions: ["read", "write"]

70

});

71

72

// Use in any module

73

function authenticatedFetch(url: string) {

74

const session = useUserSession();

75

return fetch(url, {

76

headers: {

77

'Authorization': `Bearer ${session.token}`

78

}

79

});

80

}

81

```

82

83

### Creating Custom Namespaces

84

85

```typescript

86

import { createNamespace } from "unctx";

87

import { AsyncLocalStorage } from "node:async_hooks";

88

89

// Create namespace with default async context support

90

const myLibNamespace = createNamespace({

91

asyncContext: true,

92

AsyncLocalStorage

93

});

94

95

interface DatabaseConnection {

96

host: string;

97

database: string;

98

transaction?: string;

99

}

100

101

// Get context from custom namespace

102

const dbContext = myLibNamespace.get<DatabaseConnection>("database");

103

104

// All contexts in this namespace inherit async support

105

await dbContext.callAsync(

106

{ host: "localhost", database: "myapp" },

107

async () => {

108

const db = dbContext.use();

109

await executeQuery(db);

110

}

111

);

112

```

113

114

## Version Safety

115

116

Namespaces prevent conflicts when multiple versions of a library are present:

117

118

```typescript

119

// Library v1.0 code

120

import { useContext } from "unctx";

121

const useMyLib = useContext<ConfigV1>("my-awesome-lib");

122

123

// Library v2.0 code (different interface)

124

import { useContext } from "unctx";

125

const useMyLib = useContext<ConfigV2>("my-awesome-lib");

126

127

// Both can coexist without conflicts - they share the same context

128

// but are typed differently in each version

129

```

130

131

## Library Integration Patterns

132

133

### Library Author Pattern

134

135

```typescript

136

// In your library (my-http-client/src/context.ts)

137

import { useContext, getContext } from "unctx";

138

139

interface HttpClientConfig {

140

baseURL: string;

141

timeout: number;

142

retries: number;

143

}

144

145

// Export the use function for consumers

146

export const useHttpConfig = useContext<HttpClientConfig>("my-http-client");

147

148

// Keep the full context internal for library setup

149

const httpConfigContext = getContext<HttpClientConfig>("my-http-client");

150

151

export function configureHttpClient(config: HttpClientConfig) {

152

httpConfigContext.set(config);

153

}

154

155

// In your library methods

156

export function makeRequest(endpoint: string) {

157

const config = useHttpConfig();

158

return fetch(`${config.baseURL}${endpoint}`, {

159

timeout: config.timeout

160

});

161

}

162

```

163

164

### Library Consumer Pattern

165

166

```typescript

167

// In application code

168

import { configureHttpClient, makeRequest } from "my-http-client";

169

170

// Configure library globally

171

configureHttpClient({

172

baseURL: "https://api.example.com",

173

timeout: 5000,

174

retries: 3

175

});

176

177

// Use throughout application

178

async function fetchUserData(userId: string) {

179

// Library automatically uses configured context

180

return makeRequest(`/users/${userId}`);

181

}

182

```

183

184

## Namespace Context Inheritance

185

186

```typescript

187

import { createNamespace } from "unctx";

188

189

// Create namespace with default options

190

const appNamespace = createNamespace({

191

asyncContext: true // All contexts get async support

192

});

193

194

// Contexts inherit namespace defaults

195

const userContext = appNamespace.get<User>("user");

196

const sessionContext = appNamespace.get<Session>("session");

197

198

// Both contexts have async support enabled

199

await userContext.callAsync(userData, async () => {

200

await sessionContext.callAsync(sessionData, async () => {

201

// Both contexts available across async boundaries

202

const user = userContext.use();

203

const session = sessionContext.use();

204

205

await processUserSession(user, session);

206

});

207

});

208

```

209

210

## Context Isolation

211

212

Different namespaces provide complete isolation:

213

214

```typescript

215

import { createNamespace } from "unctx";

216

217

const libANamespace = createNamespace();

218

const libBNamespace = createNamespace();

219

220

const libAContext = libANamespace.get<string>("shared-key");

221

const libBContext = libBNamespace.get<number>("shared-key");

222

223

// These are completely separate contexts despite same key

224

libAContext.set("string value");

225

libBContext.set(42);

226

227

console.log(libAContext.use()); // "string value"

228

console.log(libBContext.use()); // 42

229

```

230

231

## Best Practices

232

233

### Key Naming Convention

234

235

```typescript

236

// Use package name as key to avoid conflicts

237

const useMyLib = useContext<Config>("@company/my-lib");

238

239

// For scoped packages, use full scope

240

const useScoped = useContext<Data>("@scope/package-name");

241

242

// Add version suffix if needed for breaking changes

243

const useMyLibV2 = useContext<ConfigV2>("my-lib-v2");

244

```

245

246

### Error Handling

247

248

```typescript

249

import { getContext } from "unctx";

250

251

const appContext = getContext<AppState>("my-app");

252

253

function safeGetAppState(): AppState | null {

254

try {

255

return appContext.use();

256

} catch {

257

// Context not available, return fallback

258

return null;

259

}

260

}

261

262

// Or use tryUse for safe access

263

function getAppStateWithFallback(): AppState {

264

return appContext.tryUse() ?? getDefaultAppState();

265

}

266

```

267

268

### Cleanup and Lifecycle

269

270

```typescript

271

import { getContext } from "unctx";

272

273

const resourceContext = getContext<Resource>("my-resource");

274

275

// Application shutdown cleanup

276

export function cleanup() {

277

const resource = resourceContext.tryUse();

278

if (resource) {

279

resource.cleanup();

280

resourceContext.unset();

281

}

282

}

283

284

// Test isolation

285

beforeEach(() => {

286

resourceContext.unset();

287

});

288

```