@macroforge/mcp-server 0.1.33 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/docs-loader.d.ts +133 -5
- package/dist/tools/docs-loader.d.ts.map +1 -1
- package/dist/tools/docs-loader.js +131 -15
- package/dist/tools/docs-loader.js.map +1 -1
- package/dist/tools/index.d.ts +48 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +163 -14
- package/dist/tools/index.js.map +1 -1
- package/docs/api/api-overview.md +24 -46
- package/docs/api/expand-sync.md +24 -51
- package/docs/api/native-plugin.md +24 -56
- package/docs/api/position-mapper.md +34 -76
- package/docs/api/transform-sync.md +27 -59
- package/docs/builtin-macros/clone.md +150 -68
- package/docs/builtin-macros/debug.md +216 -81
- package/docs/builtin-macros/default.md +234 -91
- package/docs/builtin-macros/deserialize.md +891 -166
- package/docs/builtin-macros/hash.md +238 -82
- package/docs/builtin-macros/macros-overview.md +42 -103
- package/docs/builtin-macros/ord.md +205 -92
- package/docs/builtin-macros/partial-eq.md +178 -97
- package/docs/builtin-macros/partial-ord.md +209 -98
- package/docs/builtin-macros/serialize.md +326 -137
- package/docs/concepts/architecture.md +40 -99
- package/docs/concepts/derive-system.md +132 -125
- package/docs/concepts/how-macros-work.md +52 -84
- package/docs/custom-macros/custom-overview.md +17 -39
- package/docs/custom-macros/rust-setup.md +22 -55
- package/docs/custom-macros/ts-macro-derive.md +43 -107
- package/docs/custom-macros/ts-quote.md +177 -507
- package/docs/getting-started/first-macro.md +108 -33
- package/docs/getting-started/installation.md +32 -73
- package/docs/integration/cli.md +70 -156
- package/docs/integration/configuration.md +32 -75
- package/docs/integration/integration-overview.md +16 -55
- package/docs/integration/mcp-server.md +30 -69
- package/docs/integration/svelte-preprocessor.md +60 -83
- package/docs/integration/typescript-plugin.md +32 -74
- package/docs/integration/vite-plugin.md +30 -79
- package/docs/language-servers/ls-overview.md +22 -46
- package/docs/language-servers/svelte.md +30 -69
- package/docs/language-servers/zed.md +34 -72
- package/docs/roadmap/roadmap.md +54 -130
- package/docs/sections.json +3 -262
- package/package.json +2 -2
|
@@ -1,12 +1,47 @@
|
|
|
1
1
|
# Ord
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
*The `Ord` macro generates a `compareTo()` method for **total ordering** comparison. This is analogous to Rust's `Ord` trait, enabling objects to be sorted and compared with a guaranteed ordering relationship.*
|
|
3
|
+
## Basic Usage
|
|
4
|
+
**Before:**
|
|
5
|
+
```
|
|
6
|
+
/** @derive(Ord) */
|
|
7
|
+
class Version {
|
|
8
|
+
major: number;
|
|
9
|
+
minor: number;
|
|
10
|
+
patch: number;
|
|
11
|
+
|
|
12
|
+
constructor(major: number, minor: number, patch: number) {
|
|
13
|
+
this.major = major;
|
|
14
|
+
this.minor = minor;
|
|
15
|
+
this.patch = patch;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
**After:**
|
|
20
|
+
```
|
|
21
|
+
class Version {
|
|
22
|
+
major: number;
|
|
23
|
+
minor: number;
|
|
24
|
+
patch: number;
|
|
25
|
+
|
|
26
|
+
constructor(major: number, minor: number, patch: number) {
|
|
27
|
+
this.major = major;
|
|
28
|
+
this.minor = minor;
|
|
29
|
+
this.patch = patch;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
compareTo(other: Version): number {
|
|
33
|
+
if (this === other) return 0;
|
|
34
|
+
const typedOther = other;
|
|
35
|
+
const cmp0 = this.major < typedOther.major ? -1 : this.major > typedOther.major ? 1 : 0;
|
|
36
|
+
if (cmp0 !== 0) return cmp0;
|
|
37
|
+
const cmp1 = this.minor < typedOther.minor ? -1 : this.minor > typedOther.minor ? 1 : 0;
|
|
38
|
+
if (cmp1 !== 0) return cmp1;
|
|
39
|
+
const cmp2 = this.patch < typedOther.patch ? -1 : this.patch > typedOther.patch ? 1 : 0;
|
|
40
|
+
if (cmp2 !== 0) return cmp2;
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
``` ```
|
|
10
45
|
const v1 = new Version(1, 0, 0);
|
|
11
46
|
const v2 = new Version(1, 2, 0);
|
|
12
47
|
const v3 = new Version(1, 2, 0);
|
|
@@ -14,60 +49,79 @@ const v3 = new Version(1, 2, 0);
|
|
|
14
49
|
console.log(v1.compareTo(v2)); // -1 (v1 < v2)
|
|
15
50
|
console.log(v2.compareTo(v1)); // 1 (v2 > v1)
|
|
16
51
|
console.log(v2.compareTo(v3)); // 0 (v2 == v3)
|
|
52
|
+
``` ## Comparison Logic
|
|
53
|
+
The Ord macro compares fields in declaration order (lexicographic ordering). For each type:
|
|
54
|
+
- `number` / `bigint` → Direct numeric comparison
|
|
55
|
+
- `string` → Uses `localeCompare()` clamped to -1/0/1
|
|
56
|
+
- `boolean` → `false < true`
|
|
57
|
+
- `Date` → Compares timestamps via `getTime()`
|
|
58
|
+
- `Array` → Lexicographic: compares element-by-element, then length
|
|
59
|
+
- `Map/Set` → Size and content comparison
|
|
60
|
+
- `Object` → Calls `compareTo()` if available, otherwise 0
|
|
61
|
+
- `null/undefined` → Treated as equal (returns 0)
|
|
62
|
+
## Return Values
|
|
63
|
+
The `compareTo()` method always returns:
|
|
64
|
+
- `-1` → `this` is less than `other`
|
|
65
|
+
- `0` → `this` equals `other`
|
|
66
|
+
- `1` → `this` is greater than `other`
|
|
67
|
+
Unlike `PartialOrd`, the `Ord` macro never returns `null` - it provides total ordering.
|
|
68
|
+
## Field Options
|
|
69
|
+
### @ord(skip)
|
|
70
|
+
Use `@ord(skip)` to exclude a field from ordering comparison:
|
|
71
|
+
**Before:**
|
|
17
72
|
```
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
73
|
+
/** @derive(Ord) */
|
|
74
|
+
class Task {
|
|
75
|
+
priority: number;
|
|
76
|
+
name: string;
|
|
77
|
+
|
|
78
|
+
/** @ord(skip) */
|
|
79
|
+
createdAt: Date;
|
|
80
|
+
|
|
81
|
+
constructor(priority: number, name: string, createdAt: Date) {
|
|
82
|
+
this.priority = priority;
|
|
83
|
+
this.name = name;
|
|
84
|
+
this.createdAt = createdAt;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
**After:**
|
|
89
|
+
```
|
|
90
|
+
class Task {
|
|
91
|
+
priority: number;
|
|
92
|
+
name: string;
|
|
93
|
+
|
|
94
|
+
createdAt: Date;
|
|
95
|
+
|
|
96
|
+
constructor(priority: number, name: string, createdAt: Date) {
|
|
97
|
+
this.priority = priority;
|
|
98
|
+
this.name = name;
|
|
99
|
+
this.createdAt = createdAt;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
compareTo(other: Task): number {
|
|
103
|
+
if (this === other) return 0;
|
|
104
|
+
const typedOther = other;
|
|
105
|
+
const cmp0 =
|
|
106
|
+
this.priority < typedOther.priority ? -1 : this.priority > typedOther.priority ? 1 : 0;
|
|
107
|
+
if (cmp0 !== 0) return cmp0;
|
|
108
|
+
const cmp1 = ((cmp) => (cmp < 0 ? -1 : cmp > 0 ? 1 : 0))(
|
|
109
|
+
this.name.localeCompare(typedOther.name)
|
|
110
|
+
);
|
|
111
|
+
if (cmp1 !== 0) return cmp1;
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
``` ```
|
|
60
116
|
const t1 = new Task(1, "Bug fix", new Date("2024-01-01"));
|
|
61
117
|
const t2 = new Task(1, "Bug fix", new Date("2024-12-01"));
|
|
62
118
|
|
|
63
119
|
console.log(t1.compareTo(t2)); // 0 (createdAt is skipped)
|
|
120
|
+
``` ## Sorting Arrays
|
|
121
|
+
The generated `compareTo()` method works directly with `Array.sort()`:
|
|
122
|
+
**Source:**
|
|
64
123
|
```
|
|
65
|
-
|
|
66
|
-
## Sorting Arrays
|
|
67
|
-
|
|
68
|
-
The generated `compareTo()` method works directly with `Array.sort()`:
|
|
69
|
-
|
|
70
|
-
<InteractiveMacro code={`/** @derive(Ord) */
|
|
124
|
+
/** @derive(Ord) */
|
|
71
125
|
class Score {
|
|
72
126
|
points: number;
|
|
73
127
|
name: string;
|
|
@@ -76,9 +130,8 @@ class Score {
|
|
|
76
130
|
this.points = points;
|
|
77
131
|
this.name = name;
|
|
78
132
|
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
133
|
+
}
|
|
134
|
+
``` ```
|
|
82
135
|
const scores = [
|
|
83
136
|
new Score(100, "Alice"),
|
|
84
137
|
new Score(50, "Bob"),
|
|
@@ -93,15 +146,34 @@ scores.sort((a, b) => a.compareTo(b));
|
|
|
93
146
|
// Sort descending
|
|
94
147
|
scores.sort((a, b) => b.compareTo(a));
|
|
95
148
|
// Result: [Charlie(150), Alice(100), Alice(50), Bob(50)]
|
|
149
|
+
``` ## Interface Support
|
|
150
|
+
Ord works with interfaces. For interfaces, a namespace is generated with a `compareTo` function:
|
|
151
|
+
**Before:**
|
|
96
152
|
```
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
```
|
|
153
|
+
/** @derive(Ord) */
|
|
154
|
+
interface Point {
|
|
155
|
+
x: number;
|
|
156
|
+
y: number;
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
**After:**
|
|
160
|
+
```
|
|
161
|
+
interface Point {
|
|
162
|
+
x: number;
|
|
163
|
+
y: number;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export namespace Point {
|
|
167
|
+
export function compareTo(self: Point, other: Point): number {
|
|
168
|
+
if (self === other) return 0;
|
|
169
|
+
const cmp0 = self.x < other.x ? -1 : self.x > other.x ? 1 : 0;
|
|
170
|
+
if (cmp0 !== 0) return cmp0;
|
|
171
|
+
const cmp1 = self.y < other.y ? -1 : self.y > other.y ? 1 : 0;
|
|
172
|
+
if (cmp1 !== 0) return cmp1;
|
|
173
|
+
return 0;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
``` ```
|
|
105
177
|
const points: Point[] = [
|
|
106
178
|
{ x: 5, y: 10 },
|
|
107
179
|
{ x: 1, y: 20 },
|
|
@@ -110,38 +182,80 @@ const points: Point[] = [
|
|
|
110
182
|
|
|
111
183
|
points.sort((a, b) => Point.compareTo(a, b));
|
|
112
184
|
// Result: [{ x: 1, y: 20 }, { x: 5, y: 5 }, { x: 5, y: 10 }]
|
|
185
|
+
``` ## Enum Support
|
|
186
|
+
Ord works with enums. For numeric enums, it compares the numeric values; for string enums, it uses string comparison:
|
|
187
|
+
**Before:**
|
|
113
188
|
```
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
```
|
|
189
|
+
/** @derive(Ord) */
|
|
190
|
+
enum Priority {
|
|
191
|
+
Low = 0,
|
|
192
|
+
Medium = 1,
|
|
193
|
+
High = 2,
|
|
194
|
+
Critical = 3
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
**After:**
|
|
198
|
+
```
|
|
199
|
+
enum Priority {
|
|
200
|
+
Low = 0,
|
|
201
|
+
Medium = 1,
|
|
202
|
+
High = 2,
|
|
203
|
+
Critical = 3
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export namespace Priority {
|
|
207
|
+
export function compareTo(a: Priority, b: Priority): number {
|
|
208
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
209
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
210
|
+
}
|
|
211
|
+
if (typeof a === 'string' && typeof b === 'string') {
|
|
212
|
+
const cmp = a.localeCompare(b);
|
|
213
|
+
return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
|
|
214
|
+
}
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
``` ```
|
|
122
219
|
console.log(Priority.compareTo(Priority.Low, Priority.High)); // -1
|
|
123
220
|
console.log(Priority.compareTo(Priority.Critical, Priority.Low)); // 1
|
|
124
221
|
console.log(Priority.compareTo(Priority.Medium, Priority.Medium)); // 0
|
|
222
|
+
``` ## Type Alias Support
|
|
223
|
+
Ord works with type aliases. For object types, it uses lexicographic field comparison:
|
|
224
|
+
**Before:**
|
|
125
225
|
```
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
```
|
|
226
|
+
/** @derive(Ord) */
|
|
227
|
+
type Coordinate = {
|
|
228
|
+
x: number;
|
|
229
|
+
y: number;
|
|
230
|
+
};
|
|
231
|
+
```
|
|
232
|
+
**After:**
|
|
233
|
+
```
|
|
234
|
+
type Coordinate = {
|
|
235
|
+
x: number;
|
|
236
|
+
y: number;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
export namespace Coordinate {
|
|
240
|
+
export function compareTo(a: Coordinate, b: Coordinate): number {
|
|
241
|
+
if (a === b) return 0;
|
|
242
|
+
const cmp0 = a.x < b.x ? -1 : a.x > b.x ? 1 : 0;
|
|
243
|
+
if (cmp0 !== 0) return cmp0;
|
|
244
|
+
const cmp1 = a.y < b.y ? -1 : a.y > b.y ? 1 : 0;
|
|
245
|
+
if (cmp1 !== 0) return cmp1;
|
|
246
|
+
return 0;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
``` ```
|
|
134
250
|
const c1: Coordinate = { x: 10, y: 20 };
|
|
135
251
|
const c2: Coordinate = { x: 10, y: 30 };
|
|
136
252
|
|
|
137
253
|
console.log(Coordinate.compareTo(c1, c2)); // -1 (c1 < c2)
|
|
254
|
+
``` ## Ord vs PartialOrd
|
|
255
|
+
Use `Ord` when all values of a type are comparable. Use `PartialOrd` when some values might be incomparable (e.g., different types at runtime).
|
|
256
|
+
**Source:**
|
|
138
257
|
```
|
|
139
|
-
|
|
140
|
-
## Ord vs PartialOrd
|
|
141
|
-
|
|
142
|
-
Use `Ord` when all values of a type are comparable. Use `PartialOrd` when some values might be incomparable (e.g., different types at runtime).
|
|
143
|
-
|
|
144
|
-
<InteractiveMacro code={`// Ord: Total ordering - never returns null
|
|
258
|
+
// Ord: Total ordering - never returns null
|
|
145
259
|
/** @derive(Ord) */
|
|
146
260
|
class Version {
|
|
147
261
|
major: number;
|
|
@@ -150,9 +264,8 @@ class Version {
|
|
|
150
264
|
this.major = major;
|
|
151
265
|
this.minor = minor;
|
|
152
266
|
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
267
|
+
}
|
|
268
|
+
``` ```
|
|
156
269
|
const v1 = new Version(1, 0);
|
|
157
270
|
const v2 = new Version(2, 0);
|
|
158
271
|
console.log(v1.compareTo(v2)); // Always -1, 0, or 1
|