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