@macroforge/mcp-server 0.1.17 → 0.1.21

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.
@@ -4,18 +4,9 @@
4
4
 
5
5
  ## Basic Usage
6
6
 
7
- ```typescript
8
- /** @derive(PartialEq) */
9
- class Point {
10
- x: number;
11
- y: number;
12
-
13
- constructor(x: number, y: number) {
14
- this.x = x;
15
- this.y = y;
16
- }
17
- }
7
+ <MacroExample before={data.examples.basic.before} after={data.examples.basic.after} />
18
8
 
9
+ ```typescript
19
10
  const p1 = new Point(10, 20);
20
11
  const p2 = new Point(10, 20);
21
12
  const p3 = new Point(5, 5);
@@ -25,19 +16,6 @@ console.log(p1.equals(p3)); // false (different values)
25
16
  console.log(p1 === p2); // false (different references)
26
17
  ```
27
18
 
28
- ## Generated Code
29
-
30
- The PartialEq macro generates an equals method that compares each field:
31
-
32
- ```typescript
33
- equals(other: unknown): boolean {
34
- if (this === other) return true;
35
- if (!(other instanceof Point)) return false;
36
- const typedOther = other as Point;
37
- return this.x === typedOther.x && this.y === typedOther.y;
38
- }
39
- ```
40
-
41
19
  ## How It Works
42
20
 
43
21
  The PartialEq macro performs field-by-field comparison using these strategies:
@@ -60,22 +38,9 @@ The PartialEq macro performs field-by-field comparison using these strategies:
60
38
 
61
39
  Use `@partialEq(skip)` to exclude a field from equality comparison:
62
40
 
63
- ```typescript
64
- /** @derive(PartialEq) */
65
- class User {
66
- id: number;
67
- name: string;
68
-
69
- /** @partialEq(skip) */
70
- createdAt: Date; // Not compared
71
-
72
- constructor(id: number, name: string, createdAt: Date) {
73
- this.id = id;
74
- this.name = name;
75
- this.createdAt = createdAt;
76
- }
77
- }
41
+ <MacroExample before={data.examples.skip.before} after={data.examples.skip.after} />
78
42
 
43
+ ```typescript
79
44
  const user1 = new User(1, "Alice", new Date("2024-01-01"));
80
45
  const user2 = new User(1, "Alice", new Date("2024-12-01"));
81
46
 
@@ -86,27 +51,18 @@ console.log(user1.equals(user2)); // true (createdAt is skipped)
86
51
 
87
52
  The generated `equals()` method accepts `unknown` and performs runtime type checking:
88
53
 
89
- ```typescript
90
- /** @derive(PartialEq) */
54
+ <InteractiveMacro code={`/** @derive(PartialEq) */
91
55
  class User {
92
56
  name: string;
93
57
  constructor(name: string) {
94
58
  this.name = name;
95
59
  }
96
- }
97
-
98
- /** @derive(PartialEq) */
99
- class Admin {
100
- name: string;
101
- constructor(name: string) {
102
- this.name = name;
103
- }
104
- }
60
+ }`} />
105
61
 
62
+ ```typescript
106
63
  const user = new User("Alice");
107
- const admin = new Admin("Alice");
108
64
 
109
- console.log(user.equals(admin)); // false (different types)
65
+ console.log(user.equals(new User("Alice"))); // true
110
66
  console.log(user.equals("Alice")); // false (not a User instance)
111
67
  ```
112
68
 
@@ -114,8 +70,7 @@ console.log(user.equals("Alice")); // false (not a User instance)
114
70
 
115
71
  For objects with nested fields, PartialEq recursively calls `equals()` if available:
116
72
 
117
- ```typescript
118
- /** @derive(PartialEq) */
73
+ <InteractiveMacro code={`/** @derive(PartialEq) */
119
74
  class Address {
120
75
  city: string;
121
76
  zip: string;
@@ -135,8 +90,9 @@ class Person {
135
90
  this.name = name;
136
91
  this.address = address;
137
92
  }
138
- }
93
+ }`} />
139
94
 
95
+ ```typescript
140
96
  const addr1 = new Address("NYC", "10001");
141
97
  const addr2 = new Address("NYC", "10001");
142
98
 
@@ -146,47 +102,13 @@ const p2 = new Person("Alice", addr2);
146
102
  console.log(p1.equals(p2)); // true (deep equality via Address.equals)
147
103
  ```
148
104
 
149
- ## With Arrays
150
-
151
- ```typescript
152
- /** @derive(PartialEq) */
153
- class Team {
154
- name: string;
155
- members: string[];
156
-
157
- constructor(name: string, members: string[]) {
158
- this.name = name;
159
- this.members = members;
160
- }
161
- }
162
-
163
- const t1 = new Team("Alpha", ["Alice", "Bob"]);
164
- const t2 = new Team("Alpha", ["Alice", "Bob"]);
165
- const t3 = new Team("Alpha", ["Alice", "Charlie"]);
166
-
167
- console.log(t1.equals(t2)); // true
168
- console.log(t1.equals(t3)); // false
169
- ```
170
-
171
105
  ## Interface Support
172
106
 
173
107
  PartialEq works with interfaces. For interfaces, a namespace is generated with an `equals` function:
174
108
 
175
- ```typescript
176
- /** @derive(PartialEq) */
177
- interface Point {
178
- x: number;
179
- y: number;
180
- }
181
-
182
- // Generated:
183
- // export namespace Point {
184
- // export function equals(self: Point, other: Point): boolean {
185
- // if (self === other) return true;
186
- // return self.x === other.x && self.y === other.y;
187
- // }
188
- // }
109
+ <MacroExample before={data.examples.interface.before} after={data.examples.interface.after} />
189
110
 
111
+ ```typescript
190
112
  const p1: Point = { x: 10, y: 20 };
191
113
  const p2: Point = { x: 10, y: 20 };
192
114
  const p3: Point = { x: 5, y: 5 };
@@ -199,21 +121,9 @@ console.log(Point.equals(p1, p3)); // false
199
121
 
200
122
  PartialEq works with enums. For enums, strict equality comparison is used:
201
123
 
202
- ```typescript
203
- /** @derive(PartialEq) */
204
- enum Status {
205
- Active = "active",
206
- Inactive = "inactive",
207
- Pending = "pending",
208
- }
209
-
210
- // Generated:
211
- // export namespace Status {
212
- // export function equals(a: Status, b: Status): boolean {
213
- // return a === b;
214
- // }
215
- // }
124
+ <MacroExample before={data.examples.enum.before} after={data.examples.enum.after} />
216
125
 
126
+ ```typescript
217
127
  console.log(Status.equals(Status.Active, Status.Active)); // true
218
128
  console.log(Status.equals(Status.Active, Status.Inactive)); // false
219
129
  ```
@@ -222,21 +132,9 @@ console.log(Status.equals(Status.Active, Status.Inactive)); // false
222
132
 
223
133
  PartialEq works with type aliases. For object types, field-by-field comparison is used:
224
134
 
225
- ```typescript
226
- /** @derive(PartialEq) */
227
- type Point = {
228
- x: number;
229
- y: number;
230
- };
231
-
232
- // Generated:
233
- // export namespace Point {
234
- // export function equals(a: Point, b: Point): boolean {
235
- // if (a === b) return true;
236
- // return a.x === b.x && a.y === b.y;
237
- // }
238
- // }
135
+ <MacroExample before={data.examples.typeAlias.before} after={data.examples.typeAlias.after} />
239
136
 
137
+ ```typescript
240
138
  const p1: Point = { x: 10, y: 20 };
241
139
  const p2: Point = { x: 10, y: 20 };
242
140
 
@@ -245,10 +143,10 @@ console.log(Point.equals(p1, p2)); // true
245
143
 
246
144
  For union types, strict equality is used:
247
145
 
248
- ```typescript
249
- /** @derive(PartialEq) */
250
- type ApiStatus = "loading" | "success" | "error";
146
+ <InteractiveMacro code={`/** @derive(PartialEq) */
147
+ type ApiStatus = "loading" | "success" | "error";`} />
251
148
 
149
+ ```typescript
252
150
  console.log(ApiStatus.equals("success", "success")); // true
253
151
  console.log(ApiStatus.equals("success", "error")); // false
254
152
  ```
@@ -257,8 +155,7 @@ console.log(ApiStatus.equals("success", "error")); // false
257
155
 
258
156
  ### Finding Items in Arrays
259
157
 
260
- ```typescript
261
- /** @derive(PartialEq) */
158
+ <InteractiveMacro code={`/** @derive(PartialEq) */
262
159
  class Product {
263
160
  sku: string;
264
161
  name: string;
@@ -267,8 +164,9 @@ class Product {
267
164
  this.sku = sku;
268
165
  this.name = name;
269
166
  }
270
- }
167
+ }`} />
271
168
 
169
+ ```typescript
272
170
  const products = [
273
171
  new Product("A1", "Widget"),
274
172
  new Product("B2", "Gadget"),
@@ -285,8 +183,7 @@ console.log(found); // Product { sku: "B2", name: "Gadget" }
285
183
 
286
184
  When using objects as keys in Map-like structures, combine PartialEq with Hash:
287
185
 
288
- ```typescript
289
- /** @derive(PartialEq, Hash) */
186
+ <InteractiveMacro code={`/** @derive(PartialEq, Hash) */
290
187
  class Key {
291
188
  id: number;
292
189
  type: string;
@@ -295,8 +192,9 @@ class Key {
295
192
  this.id = id;
296
193
  this.type = type;
297
194
  }
298
- }
195
+ }`} />
299
196
 
197
+ ```typescript
300
198
  const k1 = new Key(1, "user");
301
199
  const k2 = new Key(1, "user");
302
200
 
@@ -4,16 +4,9 @@
4
4
 
5
5
  ## Basic Usage
6
6
 
7
- ```typescript
8
- /** @derive(PartialOrd) */
9
- class Temperature {
10
- celsius: number;
11
-
12
- constructor(celsius: number) {
13
- this.celsius = celsius;
14
- }
15
- }
7
+ <MacroExample before={data.examples.basic.before} after={data.examples.basic.after} />
16
8
 
9
+ ```typescript
17
10
  const t1 = new Temperature(20);
18
11
  const t2 = new Temperature(30);
19
12
  const t3 = new Temperature(20);
@@ -26,22 +19,6 @@ console.log(t1.compareTo(t3)); // 0 (t1 == t3)
26
19
  console.log(t1.compareTo("not a Temperature")); // null
27
20
  ```
28
21
 
29
- ## Generated Code
30
-
31
- The PartialOrd macro generates a compareTo method with runtime type checking:
32
-
33
- ```typescript
34
- compareTo(other: unknown): number | null {
35
- if (this === other) return 0;
36
- if (!(other instanceof Temperature)) return null;
37
- const typedOther = other as Temperature;
38
- const cmp0 = (this.celsius < typedOther.celsius ? -1 : this.celsius > typedOther.celsius ? 1 : 0);
39
- if (cmp0 === null) return null;
40
- if (cmp0 !== 0) return cmp0;
41
- return 0;
42
- }
43
- ```
44
-
45
22
  ## Return Values
46
23
 
47
24
  The `compareTo()` method returns:
@@ -78,22 +55,9 @@ The PartialOrd macro compares fields in declaration order with type checking:
78
55
 
79
56
  Use `@ord(skip)` to exclude a field from ordering comparison:
80
57
 
81
- ```typescript
82
- /** @derive(PartialOrd) */
83
- class Item {
84
- price: number;
85
- name: string;
86
-
87
- /** @ord(skip) */
88
- description: string; // Not used for ordering
89
-
90
- constructor(price: number, name: string, description: string) {
91
- this.price = price;
92
- this.name = name;
93
- this.description = description;
94
- }
95
- }
58
+ <MacroExample before={data.examples.skip.before} after={data.examples.skip.after} />
96
59
 
60
+ ```typescript
97
61
  const i1 = new Item(10, "Widget", "A useful widget");
98
62
  const i2 = new Item(10, "Widget", "Different description");
99
63
 
@@ -104,16 +68,16 @@ console.log(i1.compareTo(i2)); // 0 (description is skipped)
104
68
 
105
69
  When using PartialOrd, always handle the `null` case:
106
70
 
107
- ```typescript
108
- /** @derive(PartialOrd) */
71
+ <InteractiveMacro code={`/** @derive(PartialOrd) */
109
72
  class Value {
110
73
  amount: number;
111
74
 
112
75
  constructor(amount: number) {
113
76
  this.amount = amount;
114
77
  }
115
- }
78
+ }`} />
116
79
 
80
+ ```typescript
117
81
  function safeCompare(a: Value, b: unknown): string {
118
82
  const result = a.compareTo(b);
119
83
  if (result === null) {
@@ -136,16 +100,16 @@ console.log(safeCompare(v, "string")); // "incomparable"
136
100
 
137
101
  When sorting, handle `null` values appropriately:
138
102
 
139
- ```typescript
140
- /** @derive(PartialOrd) */
103
+ <InteractiveMacro code={`/** @derive(PartialOrd) */
141
104
  class Score {
142
105
  value: number;
143
106
 
144
107
  constructor(value: number) {
145
108
  this.value = value;
146
109
  }
147
- }
110
+ }`} />
148
111
 
112
+ ```typescript
149
113
  const scores = [
150
114
  new Score(100),
151
115
  new Score(50),
@@ -161,25 +125,9 @@ scores.sort((a, b) => a.compareTo(b) ?? 0);
161
125
 
162
126
  PartialOrd works with interfaces. For interfaces, a namespace is generated with a `compareTo` function:
163
127
 
164
- ```typescript
165
- /** @derive(PartialOrd) */
166
- interface Measurement {
167
- value: number;
168
- unit: string;
169
- }
170
-
171
- // Generated:
172
- // export namespace Measurement {
173
- // export function compareTo(self: Measurement, other: Measurement): number | null {
174
- // if (self === other) return 0;
175
- // const cmp0 = (self.value < other.value ? -1 : self.value > other.value ? 1 : 0);
176
- // if (cmp0 !== 0) return cmp0;
177
- // const cmp1 = self.unit.localeCompare(other.unit);
178
- // if (cmp1 !== 0) return cmp1 < 0 ? -1 : 1;
179
- // return 0;
180
- // }
181
- // }
128
+ <MacroExample before={data.examples.interface.before} after={data.examples.interface.after} />
182
129
 
130
+ ```typescript
183
131
  const m1: Measurement = { value: 10, unit: "kg" };
184
132
  const m2: Measurement = { value: 10, unit: "lb" };
185
133
 
@@ -190,21 +138,9 @@ console.log(Measurement.compareTo(m1, m2)); // 1 (kg > lb alphabetically)
190
138
 
191
139
  PartialOrd works with enums:
192
140
 
193
- ```typescript
194
- /** @derive(PartialOrd) */
195
- enum Size {
196
- Small = 1,
197
- Medium = 2,
198
- Large = 3
199
- }
200
-
201
- // Generated:
202
- // export namespace Size {
203
- // export function compareTo(a: Size, b: Size): number | null {
204
- // return a < b ? -1 : a > b ? 1 : 0;
205
- // }
206
- // }
141
+ <MacroExample before={data.examples.enum.before} after={data.examples.enum.after} />
207
142
 
143
+ ```typescript
208
144
  console.log(Size.compareTo(Size.Small, Size.Large)); // -1
209
145
  console.log(Size.compareTo(Size.Large, Size.Small)); // 1
210
146
  ```
@@ -213,25 +149,9 @@ console.log(Size.compareTo(Size.Large, Size.Small)); // 1
213
149
 
214
150
  PartialOrd works with type aliases:
215
151
 
216
- ```typescript
217
- /** @derive(PartialOrd) */
218
- type Interval = {
219
- start: number;
220
- end: number;
221
- };
222
-
223
- // Generated:
224
- // export namespace Interval {
225
- // export function compareTo(a: Interval, b: Interval): number | null {
226
- // if (a === b) return 0;
227
- // const cmp0 = (a.start < b.start ? -1 : a.start > b.start ? 1 : 0);
228
- // if (cmp0 !== 0) return cmp0;
229
- // const cmp1 = (a.end < b.end ? -1 : a.end > b.end ? 1 : 0);
230
- // if (cmp1 !== 0) return cmp1;
231
- // return 0;
232
- // }
233
- // }
152
+ <MacroExample before={data.examples.typeAlias.before} after={data.examples.typeAlias.after} />
234
153
 
154
+ ```typescript
235
155
  const i1: Interval = { start: 0, end: 10 };
236
156
  const i2: Interval = { start: 0, end: 20 };
237
157
 
@@ -246,8 +166,7 @@ Choose between `Ord` and `PartialOrd` based on your use case:
246
166
 
247
167
  - **PartialOrd** → Use when comparing with `unknown` types or when some values might be incomparable
248
168
 
249
- ```typescript
250
- // PartialOrd is safer for public APIs that accept unknown input
169
+ <InteractiveMacro code={`// PartialOrd is safer for public APIs that accept unknown input
251
170
  /** @derive(PartialOrd) */
252
171
  class SafeValue {
253
172
  data: number;
@@ -260,8 +179,9 @@ class SafeValue {
260
179
  const result = this.compareTo(other);
261
180
  return result !== null && result > 0;
262
181
  }
263
- }
182
+ }`} />
264
183
 
184
+ ```typescript
265
185
  const safe = new SafeValue(100);
266
186
  console.log(safe.isGreaterThan(new SafeValue(50))); // true
267
187
  console.log(safe.isGreaterThan("invalid")); // false