or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-management.mdindex.mdplugin-system.mdprocessing-pipeline.md

configuration-management.mddocs/

0

# Configuration Management

1

2

Processor configuration, data storage, and state management system with freezing capabilities for controlling processor modifications and sharing data across plugins.

3

4

## Capabilities

5

6

### Data Method

7

8

Manages processor-specific data storage accessible to all plugins.

9

10

```typescript { .api }

11

/**

12

* Get or set processor data

13

* @returns Complete data object when called with no arguments

14

*/

15

data(): Data;

16

17

/**

18

* Get specific data value

19

* @param key - Data key to retrieve

20

* @returns Value associated with the key

21

*/

22

data<Key extends keyof Data>(key: Key): Data[Key];

23

24

/**

25

* Set specific data key-value pair

26

* @param key - Data key to set

27

* @param value - Value to associate with key

28

* @returns Processor instance for chaining

29

*/

30

data<Key extends keyof Data>(key: Key, value: Data[Key]): Processor;

31

32

/**

33

* Replace entire data object

34

* @param dataset - New data object to set

35

* @returns Processor instance for chaining

36

*/

37

data(dataset: Data): Processor;

38

```

39

40

**Usage Examples:**

41

42

```javascript

43

import { unified } from "unified";

44

45

const processor = unified();

46

47

// Get all data

48

const allData = processor.data();

49

console.log(allData); // {}

50

51

// Set individual key-value pairs

52

processor

53

.data("author", "John Doe")

54

.data("version", "1.0.0")

55

.data("config", { strict: true });

56

57

// Get specific values

58

const author = processor.data("author"); // "John Doe"

59

const config = processor.data("config"); // { strict: true }

60

61

// Set entire data object

62

processor.data({

63

title: "My Document",

64

settings: { format: "html" },

65

metadata: { created: new Date() }

66

});

67

68

// Get complete data object

69

const data = processor.data();

70

// { title: "My Document", settings: {...}, metadata: {...} }

71

```

72

73

### Settings Management

74

75

Special data handling for parser and compiler settings via the `settings` key.

76

77

```javascript

78

// Set settings via data method

79

processor.data("settings", {

80

bullet: "*",

81

emphasis: "_",

82

strong: "*"

83

});

84

85

// Access settings

86

const settings = processor.data("settings");

87

88

// Merge additional settings

89

const existingSettings = processor.data("settings") || {};

90

processor.data("settings", {

91

...existingSettings,

92

newSetting: "value"

93

});

94

```

95

96

### Data in Plugins

97

98

Plugins can access and modify processor data for cross-plugin communication.

99

100

```javascript

101

function dataAwarePlugin(options = {}) {

102

// Access data during plugin setup

103

const existingConfig = this.data("config") || {};

104

105

// Merge plugin options with existing config

106

this.data("config", { ...existingConfig, ...options });

107

108

// Set plugin-specific data

109

this.data("pluginState", { initialized: true });

110

111

return function transformer(tree, file) {

112

// Access data during transformation

113

const config = this.data("config");

114

const pluginState = this.data("pluginState");

115

116

// Use data to guide transformation

117

if (config.strict && !pluginState.validated) {

118

// Perform strict validation

119

}

120

};

121

}

122

123

// Usage

124

processor

125

.use(dataAwarePlugin, { strict: true })

126

.use(anotherPlugin);

127

```

128

129

### Cross-Plugin Data Sharing

130

131

Share data between plugins for coordinated behavior.

132

133

```javascript

134

// First plugin sets shared data

135

function configPlugin(options) {

136

this.data("sharedConfig", {

137

theme: options.theme || "default",

138

features: options.features || []

139

});

140

}

141

142

// Second plugin uses shared data

143

function themedPlugin() {

144

return function transformer(tree, file) {

145

const config = this.data("sharedConfig");

146

147

if (config && config.theme === "dark") {

148

// Apply dark theme transformations

149

}

150

151

if (config && config.features.includes("syntax-highlight")) {

152

// Enable syntax highlighting

153

}

154

};

155

}

156

157

// Usage

158

processor

159

.use(configPlugin, {

160

theme: "dark",

161

features: ["syntax-highlight", "line-numbers"]

162

})

163

.use(themedPlugin);

164

```

165

166

## Processor State Management

167

168

### Freeze Method

169

170

Freezes processor configuration to prevent further modifications.

171

172

```typescript { .api }

173

/**

174

* Freeze processor to prevent configuration changes

175

* @returns The frozen processor instance

176

*/

177

freeze(): Processor;

178

```

179

180

**Usage Examples:**

181

182

```javascript

183

const processor = unified()

184

.use(someParser)

185

.use(someTransformer);

186

187

// Freeze the processor

188

const frozenProcessor = processor.freeze();

189

190

// Attempt to modify frozen processor (throws error)

191

try {

192

frozenProcessor.use(anotherPlugin);

193

} catch (error) {

194

console.log(error.message);

195

// "Cannot call `use` on a frozen processor..."

196

}

197

198

// Reading operations still work

199

const data = frozenProcessor.data(); // ✓ Works

200

const result = frozenProcessor.processSync("content"); // ✓ Works

201

```

202

203

### Processor Copying

204

205

Create new unfrozen processors from existing configurations.

206

207

```javascript

208

const baseProcessor = unified()

209

.use(commonParser)

210

.use(baseTransformer)

211

.freeze();

212

213

// Create variants without affecting base

214

const htmlProcessor = baseProcessor() // Call as function

215

.use(htmlCompiler);

216

217

const textProcessor = baseProcessor()

218

.use(textCompiler);

219

220

// Base processor remains unchanged

221

console.log(baseProcessor.frozen); // true

222

console.log(htmlProcessor.frozen); // false

223

console.log(textProcessor.frozen); // false

224

```

225

226

### Automatic Freezing

227

228

Processors automatically freeze when processing methods are called.

229

230

```javascript

231

const processor = unified()

232

.use(someParser)

233

.use(someTransformer);

234

235

console.log(processor.frozen); // false

236

237

// First processing call freezes the processor

238

const result = processor.parse("content");

239

240

console.log(processor.frozen); // true

241

242

// Subsequent modification attempts fail

243

try {

244

processor.use(anotherPlugin); // Throws error

245

} catch (error) {

246

console.log("Processor is now frozen");

247

}

248

```

249

250

## Advanced Configuration Patterns

251

252

### Environment-Based Configuration

253

254

Configure processors based on runtime environment.

255

256

```javascript

257

function createProcessor(env = "production") {

258

const processor = unified().use(baseParser);

259

260

// Environment-specific data

261

processor.data("environment", env);

262

processor.data("debug", env === "development");

263

264

if (env === "development") {

265

processor

266

.use(debugPlugin)

267

.use(validationPlugin, { strict: true });

268

} else {

269

processor

270

.use(optimizationPlugin)

271

.use(minificationPlugin);

272

}

273

274

return processor;

275

}

276

277

// Usage

278

const devProcessor = createProcessor("development");

279

const prodProcessor = createProcessor("production");

280

```

281

282

### Configuration Validation

283

284

Validate processor configuration before processing.

285

286

```javascript

287

function validateConfig() {

288

return function validator(tree, file) {

289

const data = this.data();

290

291

// Check required configuration

292

if (!data.settings) {

293

throw new Error("Settings are required");

294

}

295

296

if (!data.settings.format) {

297

throw new Error("Output format must be specified");

298

}

299

300

// Validate configuration values

301

const validFormats = ["html", "markdown", "text"];

302

if (!validFormats.includes(data.settings.format)) {

303

throw new Error(`Invalid format: ${data.settings.format}`);

304

}

305

};

306

}

307

308

// Usage

309

processor

310

.use(configPlugin, { format: "html" })

311

.use(validateConfig)

312

.use(outputPlugin);

313

```

314

315

### Plugin State Management

316

317

Manage plugin-specific state across multiple transformations.

318

319

```javascript

320

function statefulPlugin() {

321

// Initialize plugin state

322

this.data("pluginState", {

323

processedCount: 0,

324

cache: new Map(),

325

initialized: Date.now()

326

});

327

328

return function transformer(tree, file) {

329

const state = this.data("pluginState");

330

331

// Update state

332

state.processedCount++;

333

334

// Use cached results

335

const cacheKey = JSON.stringify(tree);

336

if (state.cache.has(cacheKey)) {

337

return state.cache.get(cacheKey);

338

}

339

340

// Process and cache result

341

const result = processTree(tree);

342

state.cache.set(cacheKey, result);

343

344

return result;

345

};

346

}

347

```

348

349

## Error Handling

350

351

### Configuration Errors

352

- Frozen processor modifications: `"Cannot call \`data\` on a frozen processor"`

353

- Invalid data operations: Type errors for incorrect key/value types

354

355

### Data Access Patterns

356

- Undefined keys return `undefined`

357

- No prototypal property access (uses `hasOwnProperty`)

358

- Functions can be stored as data values

359

360

### State Consistency

361

- Data changes are immediate and visible to all subsequent plugins

362

- Freezing prevents accidental configuration changes during processing

363

- Copying preserves data but creates new mutable instances