@macroforge/mcp-server 0.1.17

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.
Files changed (46) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +47 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/tools/docs-loader.d.ts +30 -0
  6. package/dist/tools/docs-loader.d.ts.map +1 -0
  7. package/dist/tools/docs-loader.js +112 -0
  8. package/dist/tools/docs-loader.js.map +1 -0
  9. package/dist/tools/index.d.ts +6 -0
  10. package/dist/tools/index.d.ts.map +1 -0
  11. package/dist/tools/index.js +348 -0
  12. package/dist/tools/index.js.map +1 -0
  13. package/docs/api/api-overview.md +75 -0
  14. package/docs/api/expand-sync.md +121 -0
  15. package/docs/api/native-plugin.md +106 -0
  16. package/docs/api/position-mapper.md +127 -0
  17. package/docs/api/transform-sync.md +98 -0
  18. package/docs/builtin-macros/clone.md +180 -0
  19. package/docs/builtin-macros/debug.md +222 -0
  20. package/docs/builtin-macros/default.md +192 -0
  21. package/docs/builtin-macros/deserialize.md +662 -0
  22. package/docs/builtin-macros/hash.md +205 -0
  23. package/docs/builtin-macros/macros-overview.md +169 -0
  24. package/docs/builtin-macros/ord.md +258 -0
  25. package/docs/builtin-macros/partial-eq.md +306 -0
  26. package/docs/builtin-macros/partial-ord.md +268 -0
  27. package/docs/builtin-macros/serialize.md +321 -0
  28. package/docs/concepts/architecture.md +139 -0
  29. package/docs/concepts/derive-system.md +173 -0
  30. package/docs/concepts/how-macros-work.md +124 -0
  31. package/docs/custom-macros/custom-overview.md +84 -0
  32. package/docs/custom-macros/rust-setup.md +146 -0
  33. package/docs/custom-macros/ts-macro-derive.md +307 -0
  34. package/docs/custom-macros/ts-quote.md +696 -0
  35. package/docs/getting-started/first-macro.md +120 -0
  36. package/docs/getting-started/installation.md +110 -0
  37. package/docs/integration/cli.md +207 -0
  38. package/docs/integration/configuration.md +116 -0
  39. package/docs/integration/integration-overview.md +51 -0
  40. package/docs/integration/typescript-plugin.md +96 -0
  41. package/docs/integration/vite-plugin.md +126 -0
  42. package/docs/language-servers/ls-overview.md +47 -0
  43. package/docs/language-servers/svelte-ls.md +80 -0
  44. package/docs/language-servers/zed-extensions.md +84 -0
  45. package/docs/sections.json +258 -0
  46. package/package.json +48 -0
@@ -0,0 +1,306 @@
1
+ # PartialEq
2
+
3
+ *The `PartialEq` macro generates an `equals()` method for value-based equality comparison between objects.*
4
+
5
+ ## Basic Usage
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
+ }
18
+
19
+ const p1 = new Point(10, 20);
20
+ const p2 = new Point(10, 20);
21
+ const p3 = new Point(5, 5);
22
+
23
+ console.log(p1.equals(p2)); // true (same values)
24
+ console.log(p1.equals(p3)); // false (different values)
25
+ console.log(p1 === p2); // false (different references)
26
+ ```
27
+
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
+ ## How It Works
42
+
43
+ The PartialEq macro performs field-by-field comparison using these strategies:
44
+
45
+ - **Primitives** (string, number, boolean, null, undefined) → Strict equality (`===`)
46
+
47
+ - **Date** → Compares timestamps via `getTime()`
48
+
49
+ - **Array** → Length check + element-by-element comparison
50
+
51
+ - **Map** → Size check + entry comparison
52
+
53
+ - **Set** → Size check + membership verification
54
+
55
+ - **Objects** → Calls `equals()` if available, otherwise `===`
56
+
57
+ ## Field Options
58
+
59
+ ### @partialEq(skip)
60
+
61
+ Use `@partialEq(skip)` to exclude a field from equality comparison:
62
+
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
+ }
78
+
79
+ const user1 = new User(1, "Alice", new Date("2024-01-01"));
80
+ const user2 = new User(1, "Alice", new Date("2024-12-01"));
81
+
82
+ console.log(user1.equals(user2)); // true (createdAt is skipped)
83
+ ```
84
+
85
+ ## Type Safety
86
+
87
+ The generated `equals()` method accepts `unknown` and performs runtime type checking:
88
+
89
+ ```typescript
90
+ /** @derive(PartialEq) */
91
+ class User {
92
+ name: string;
93
+ constructor(name: string) {
94
+ this.name = name;
95
+ }
96
+ }
97
+
98
+ /** @derive(PartialEq) */
99
+ class Admin {
100
+ name: string;
101
+ constructor(name: string) {
102
+ this.name = name;
103
+ }
104
+ }
105
+
106
+ const user = new User("Alice");
107
+ const admin = new Admin("Alice");
108
+
109
+ console.log(user.equals(admin)); // false (different types)
110
+ console.log(user.equals("Alice")); // false (not a User instance)
111
+ ```
112
+
113
+ ## With Nested Objects
114
+
115
+ For objects with nested fields, PartialEq recursively calls `equals()` if available:
116
+
117
+ ```typescript
118
+ /** @derive(PartialEq) */
119
+ class Address {
120
+ city: string;
121
+ zip: string;
122
+
123
+ constructor(city: string, zip: string) {
124
+ this.city = city;
125
+ this.zip = zip;
126
+ }
127
+ }
128
+
129
+ /** @derive(PartialEq) */
130
+ class Person {
131
+ name: string;
132
+ address: Address;
133
+
134
+ constructor(name: string, address: Address) {
135
+ this.name = name;
136
+ this.address = address;
137
+ }
138
+ }
139
+
140
+ const addr1 = new Address("NYC", "10001");
141
+ const addr2 = new Address("NYC", "10001");
142
+
143
+ const p1 = new Person("Alice", addr1);
144
+ const p2 = new Person("Alice", addr2);
145
+
146
+ console.log(p1.equals(p2)); // true (deep equality via Address.equals)
147
+ ```
148
+
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
+ ## Interface Support
172
+
173
+ PartialEq works with interfaces. For interfaces, a namespace is generated with an `equals` function:
174
+
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
+ // }
189
+
190
+ const p1: Point = { x: 10, y: 20 };
191
+ const p2: Point = { x: 10, y: 20 };
192
+ const p3: Point = { x: 5, y: 5 };
193
+
194
+ console.log(Point.equals(p1, p2)); // true
195
+ console.log(Point.equals(p1, p3)); // false
196
+ ```
197
+
198
+ ## Enum Support
199
+
200
+ PartialEq works with enums. For enums, strict equality comparison is used:
201
+
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
+ // }
216
+
217
+ console.log(Status.equals(Status.Active, Status.Active)); // true
218
+ console.log(Status.equals(Status.Active, Status.Inactive)); // false
219
+ ```
220
+
221
+ ## Type Alias Support
222
+
223
+ PartialEq works with type aliases. For object types, field-by-field comparison is used:
224
+
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
+ // }
239
+
240
+ const p1: Point = { x: 10, y: 20 };
241
+ const p2: Point = { x: 10, y: 20 };
242
+
243
+ console.log(Point.equals(p1, p2)); // true
244
+ ```
245
+
246
+ For union types, strict equality is used:
247
+
248
+ ```typescript
249
+ /** @derive(PartialEq) */
250
+ type ApiStatus = "loading" | "success" | "error";
251
+
252
+ console.log(ApiStatus.equals("success", "success")); // true
253
+ console.log(ApiStatus.equals("success", "error")); // false
254
+ ```
255
+
256
+ ## Common Patterns
257
+
258
+ ### Finding Items in Arrays
259
+
260
+ ```typescript
261
+ /** @derive(PartialEq) */
262
+ class Product {
263
+ sku: string;
264
+ name: string;
265
+
266
+ constructor(sku: string, name: string) {
267
+ this.sku = sku;
268
+ this.name = name;
269
+ }
270
+ }
271
+
272
+ const products = [
273
+ new Product("A1", "Widget"),
274
+ new Product("B2", "Gadget"),
275
+ new Product("C3", "Gizmo")
276
+ ];
277
+
278
+ const target = new Product("B2", "Gadget");
279
+ const found = products.find(p => p.equals(target));
280
+
281
+ console.log(found); // Product { sku: "B2", name: "Gadget" }
282
+ ```
283
+
284
+ ### Use with Hash
285
+
286
+ When using objects as keys in Map-like structures, combine PartialEq with Hash:
287
+
288
+ ```typescript
289
+ /** @derive(PartialEq, Hash) */
290
+ class Key {
291
+ id: number;
292
+ type: string;
293
+
294
+ constructor(id: number, type: string) {
295
+ this.id = id;
296
+ this.type = type;
297
+ }
298
+ }
299
+
300
+ const k1 = new Key(1, "user");
301
+ const k2 = new Key(1, "user");
302
+
303
+ // Equal objects should have equal hash codes
304
+ console.log(k1.equals(k2)); // true
305
+ console.log(k1.hashCode() === k2.hashCode()); // true
306
+ ```
@@ -0,0 +1,268 @@
1
+ # PartialOrd
2
+
3
+ *The `PartialOrd` macro generates a `compareTo()` method that implements partial ordering, returning `-1`, `0`, `1`, or `null` for incomparable values.*
4
+
5
+ ## Basic Usage
6
+
7
+ ```typescript
8
+ /** @derive(PartialOrd) */
9
+ class Temperature {
10
+ celsius: number;
11
+
12
+ constructor(celsius: number) {
13
+ this.celsius = celsius;
14
+ }
15
+ }
16
+
17
+ const t1 = new Temperature(20);
18
+ const t2 = new Temperature(30);
19
+ const t3 = new Temperature(20);
20
+
21
+ console.log(t1.compareTo(t2)); // -1 (t1 < t2)
22
+ console.log(t2.compareTo(t1)); // 1 (t2 > t1)
23
+ console.log(t1.compareTo(t3)); // 0 (t1 == t3)
24
+
25
+ // Returns null for incomparable types
26
+ console.log(t1.compareTo("not a Temperature")); // null
27
+ ```
28
+
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
+ ## Return Values
46
+
47
+ The `compareTo()` method returns:
48
+
49
+ - `-1` → `this` is less than `other`
50
+
51
+ - `0` → `this` equals `other`
52
+
53
+ - `1` → `this` is greater than `other`
54
+
55
+ - `null` → Values are incomparable (e.g., different types)
56
+
57
+ ## Comparison Logic
58
+
59
+ The PartialOrd macro compares fields in declaration order with type checking:
60
+
61
+ - `number` / `bigint` → Direct numeric comparison
62
+
63
+ - `string` → Uses `localeCompare()`
64
+
65
+ - `boolean` → `false < true`
66
+
67
+ - `Date` → Compares timestamps; returns `null` if not both Date instances
68
+
69
+ - `Array` → Lexicographic comparison; returns `null` if not both arrays
70
+
71
+ - `Object` → Calls `compareTo()` if available
72
+
73
+ - **Type mismatch** → Returns `null`
74
+
75
+ ## Field Options
76
+
77
+ ### @ord(skip)
78
+
79
+ Use `@ord(skip)` to exclude a field from ordering comparison:
80
+
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
+ }
96
+
97
+ const i1 = new Item(10, "Widget", "A useful widget");
98
+ const i2 = new Item(10, "Widget", "Different description");
99
+
100
+ console.log(i1.compareTo(i2)); // 0 (description is skipped)
101
+ ```
102
+
103
+ ## Handling Null Results
104
+
105
+ When using PartialOrd, always handle the `null` case:
106
+
107
+ ```typescript
108
+ /** @derive(PartialOrd) */
109
+ class Value {
110
+ amount: number;
111
+
112
+ constructor(amount: number) {
113
+ this.amount = amount;
114
+ }
115
+ }
116
+
117
+ function safeCompare(a: Value, b: unknown): string {
118
+ const result = a.compareTo(b);
119
+ if (result === null) {
120
+ return "incomparable";
121
+ } else if (result < 0) {
122
+ return "less than";
123
+ } else if (result > 0) {
124
+ return "greater than";
125
+ } else {
126
+ return "equal";
127
+ }
128
+ }
129
+
130
+ const v = new Value(100);
131
+ console.log(safeCompare(v, new Value(50))); // "greater than"
132
+ console.log(safeCompare(v, "string")); // "incomparable"
133
+ ```
134
+
135
+ ## Sorting with PartialOrd
136
+
137
+ When sorting, handle `null` values appropriately:
138
+
139
+ ```typescript
140
+ /** @derive(PartialOrd) */
141
+ class Score {
142
+ value: number;
143
+
144
+ constructor(value: number) {
145
+ this.value = value;
146
+ }
147
+ }
148
+
149
+ const scores = [
150
+ new Score(100),
151
+ new Score(50),
152
+ new Score(75)
153
+ ];
154
+
155
+ // Safe sort that handles null (treats null as equal)
156
+ scores.sort((a, b) => a.compareTo(b) ?? 0);
157
+ // Result: [Score(50), Score(75), Score(100)]
158
+ ```
159
+
160
+ ## Interface Support
161
+
162
+ PartialOrd works with interfaces. For interfaces, a namespace is generated with a `compareTo` function:
163
+
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
+ // }
182
+
183
+ const m1: Measurement = { value: 10, unit: "kg" };
184
+ const m2: Measurement = { value: 10, unit: "lb" };
185
+
186
+ console.log(Measurement.compareTo(m1, m2)); // 1 (kg > lb alphabetically)
187
+ ```
188
+
189
+ ## Enum Support
190
+
191
+ PartialOrd works with enums:
192
+
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
+ // }
207
+
208
+ console.log(Size.compareTo(Size.Small, Size.Large)); // -1
209
+ console.log(Size.compareTo(Size.Large, Size.Small)); // 1
210
+ ```
211
+
212
+ ## Type Alias Support
213
+
214
+ PartialOrd works with type aliases:
215
+
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
+ // }
234
+
235
+ const i1: Interval = { start: 0, end: 10 };
236
+ const i2: Interval = { start: 0, end: 20 };
237
+
238
+ console.log(Interval.compareTo(i1, i2)); // -1
239
+ ```
240
+
241
+ ## PartialOrd vs Ord
242
+
243
+ Choose between `Ord` and `PartialOrd` based on your use case:
244
+
245
+ - **Ord** → Use when all values are always comparable (never returns null)
246
+
247
+ - **PartialOrd** → Use when comparing with `unknown` types or when some values might be incomparable
248
+
249
+ ```typescript
250
+ // PartialOrd is safer for public APIs that accept unknown input
251
+ /** @derive(PartialOrd) */
252
+ class SafeValue {
253
+ data: number;
254
+ constructor(data: number) {
255
+ this.data = data;
256
+ }
257
+
258
+ // Can safely compare with any value
259
+ isGreaterThan(other: unknown): boolean {
260
+ const result = this.compareTo(other);
261
+ return result !== null && result > 0;
262
+ }
263
+ }
264
+
265
+ const safe = new SafeValue(100);
266
+ console.log(safe.isGreaterThan(new SafeValue(50))); // true
267
+ console.log(safe.isGreaterThan("invalid")); // false
268
+ ```