Core context management module for Milkdown editor providing dependency injection and state management
npx @tessl/cli install tessl/npm-milkdown--ctx@7.15.00
# @milkdown/ctx
1
2
@milkdown/ctx is the core context management module for the Milkdown editor framework. It provides a sophisticated dependency injection and state management system through Container and Slice patterns, along with timing/scheduling capabilities and comprehensive debugging tools. The package enables plugin-based architecture where components can inject dependencies, manage reactive state, and coordinate through a well-defined context system.
3
4
## Package Information
5
6
- **Package Name**: @milkdown/ctx
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @milkdown/ctx`
10
11
## Core Imports
12
13
```typescript
14
import {
15
Container,
16
Slice,
17
SliceType,
18
createSlice,
19
Ctx,
20
Clock,
21
Timer,
22
TimerType,
23
createTimer,
24
Inspector,
25
type Meta,
26
type MilkdownPlugin,
27
type Telemetry,
28
type TimerStatus
29
} from "@milkdown/ctx";
30
```
31
32
For CommonJS:
33
34
```javascript
35
const {
36
Container,
37
Slice,
38
SliceType,
39
createSlice,
40
Ctx,
41
Clock,
42
Timer,
43
TimerType,
44
createTimer,
45
Inspector
46
} = require("@milkdown/ctx");
47
```
48
49
## Basic Usage
50
51
```typescript
52
import { Container, createSlice, Ctx, Clock } from "@milkdown/ctx";
53
54
// Create a container and clock
55
const container = new Container();
56
const clock = new Clock();
57
58
// Create a slice type for state management
59
const counterSlice = createSlice(0, "counter");
60
61
// Create context and inject the slice
62
const ctx = new Ctx(container, clock);
63
ctx.inject(counterSlice, 5);
64
65
// Use the context to access and update state
66
const currentValue = ctx.get(counterSlice); // 5
67
ctx.update(counterSlice, (prev) => prev + 1);
68
console.log(ctx.get(counterSlice)); // 6
69
70
// React to state changes
71
const slice = ctx.use(counterSlice);
72
const unsubscribe = slice.on((value) => {
73
console.log("Counter changed to:", value);
74
});
75
```
76
77
## Architecture
78
79
@milkdown/ctx is built around several key architectural patterns:
80
81
- **Container-Slice Pattern**: Central container manages typed slices for dependency injection and state management
82
- **Reactive Updates**: Slices support watchers for reactive programming with on/off subscription model
83
- **Context Orchestration**: Ctx class provides unified access to containers and clocks with metadata support
84
- **Timer Coordination**: Clock manages promise-based timers for scheduling and synchronization
85
- **Inspector Integration**: Built-in debugging and telemetry collection for runtime analysis
86
- **Plugin Architecture**: MilkdownPlugin type enables modular extensions with setup/run/cleanup lifecycle
87
88
## Capabilities
89
90
### Context Management
91
92
Core dependency injection and state management through Container and Slice system. Provides type-safe reactive state with watcher support for building plugin-based architectures.
93
94
```typescript { .api }
95
class Container {
96
get<T, N extends string = string>(slice: SliceType<T, N> | N): Slice<T, N>;
97
remove<T, N extends string = string>(slice: SliceType<T, N> | N): void;
98
has<T, N extends string = string>(slice: SliceType<T, N> | N): boolean;
99
}
100
101
class Slice<T = any, N extends string = string> {
102
readonly type: SliceType<T, N>;
103
on(watcher: (value: T) => unknown): () => void;
104
once(watcher: (value: T) => unknown): () => void;
105
off(watcher: (value: T) => unknown): void;
106
offAll(): void;
107
set(value: T): void;
108
get(): T;
109
update(updater: (prev: T) => T): void;
110
}
111
112
class SliceType<T = any, N extends string = string> {
113
readonly id: symbol;
114
readonly name: N;
115
constructor(value: T, name: N);
116
create(container: SliceMap, value?: T): Slice<T, N>;
117
}
118
119
function createSlice<T = any, N extends string = string>(value: T, name: N): SliceType<T, N>;
120
```
121
122
[Context Management](./context-management.md)
123
124
### Plugin Orchestration
125
126
Central orchestration class providing unified access to containers, clocks, and debugging capabilities for plugin development and state coordination.
127
128
```typescript { .api }
129
class Ctx {
130
readonly meta: Meta | undefined;
131
readonly inspector: Inspector | undefined;
132
133
constructor(container: Container, clock: Clock, meta?: Meta);
134
produce(meta?: Meta): Ctx;
135
inject<T>(sliceType: SliceType<T>, value?: T): Ctx;
136
remove<T, N extends string = string>(sliceType: SliceType<T, N> | N): Ctx;
137
record(timerType: TimerType): Ctx;
138
clearTimer(timerType: TimerType): Ctx;
139
isInjected<T, N extends string = string>(sliceType: SliceType<T, N> | N): boolean;
140
isRecorded(timerType: TimerType): boolean;
141
use<T, N extends string = string>(sliceType: SliceType<T, N> | N): Slice<T, N>;
142
get<T, N extends string>(sliceType: SliceType<T, N> | N): T;
143
set<T, N extends string>(sliceType: SliceType<T, N> | N, value: T): void;
144
update<T, N extends string>(sliceType: SliceType<T, N> | N, updater: (prev: T) => T): void;
145
timer(timer: TimerType): Timer;
146
done(timer: TimerType): void;
147
wait(timer: TimerType): Promise<void>;
148
waitTimers(slice: SliceType<TimerType[]>): Promise<void>;
149
}
150
151
type MilkdownPlugin = { meta?: Meta } & ((ctx: Ctx) => CtxRunner);
152
```
153
154
[Plugin Orchestration](./plugin-orchestration.md)
155
156
### Timer Coordination
157
158
Promise-based timer system with event-driven resolution for scheduling and synchronization in plugin architectures.
159
160
```typescript { .api }
161
class Clock {
162
readonly store: TimerMap;
163
get(timer: TimerType): Timer;
164
remove(timer: TimerType): void;
165
has(timer: TimerType): boolean;
166
}
167
168
class Timer {
169
readonly type: TimerType;
170
readonly status: TimerStatus;
171
start(): Promise<void>;
172
done(): void;
173
}
174
175
class TimerType {
176
readonly id: symbol;
177
readonly name: string;
178
readonly timeout: number;
179
constructor(name: string, timeout?: number);
180
create(clock: TimerMap): Timer;
181
}
182
183
function createTimer(name: string, timeout?: number): TimerType;
184
185
type TimerStatus = 'pending' | 'resolved' | 'rejected';
186
```
187
188
[Timer Coordination](./timer-coordination.md)
189
190
### Runtime Inspection
191
192
Debugging and telemetry system for monitoring ctx operations, slice usage, and timer execution in development and production environments.
193
194
```typescript { .api }
195
class Inspector {
196
constructor(container: Container, clock: Clock, meta: Meta);
197
read(): Telemetry;
198
}
199
200
interface Meta {
201
displayName: string;
202
description?: string;
203
package: string;
204
group?: string;
205
additional?: Record<string, any>;
206
}
207
208
interface Telemetry {
209
metadata: Meta;
210
injectedSlices: { name: string; value: unknown }[];
211
consumedSlices: { name: string; value: unknown }[];
212
recordedTimers: { name: string; duration: number; status: TimerStatus }[];
213
waitTimers: { name: string; duration: number; status: TimerStatus }[];
214
}
215
```
216
217
[Runtime Inspection](./runtime-inspection.md)
218
219
## Types
220
221
```typescript { .api }
222
type SliceMap = Map<symbol, Slice>;
223
type TimerMap = Map<symbol, Timer>;
224
type Cleanup = () => void | Promise<void>;
225
type RunnerReturnType = void | Promise<void> | Cleanup | Promise<Cleanup>;
226
type CtxRunner = () => RunnerReturnType;
227
```