@macroforge/mcp-server 0.1.33 → 0.1.35

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 (50) hide show
  1. package/README.md +68 -0
  2. package/dist/index.d.ts +32 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +46 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/tools/docs-loader.d.ts +133 -5
  7. package/dist/tools/docs-loader.d.ts.map +1 -1
  8. package/dist/tools/docs-loader.js +131 -15
  9. package/dist/tools/docs-loader.js.map +1 -1
  10. package/dist/tools/index.d.ts +48 -1
  11. package/dist/tools/index.d.ts.map +1 -1
  12. package/dist/tools/index.js +163 -14
  13. package/dist/tools/index.js.map +1 -1
  14. package/docs/api/api-overview.md +24 -46
  15. package/docs/api/expand-sync.md +24 -51
  16. package/docs/api/native-plugin.md +24 -56
  17. package/docs/api/position-mapper.md +34 -76
  18. package/docs/api/transform-sync.md +27 -59
  19. package/docs/builtin-macros/clone.md +45 -104
  20. package/docs/builtin-macros/debug.md +33 -104
  21. package/docs/builtin-macros/default.md +78 -114
  22. package/docs/builtin-macros/deserialize.md +93 -273
  23. package/docs/builtin-macros/hash.md +58 -100
  24. package/docs/builtin-macros/macros-overview.md +42 -103
  25. package/docs/builtin-macros/ord.md +65 -133
  26. package/docs/builtin-macros/partial-eq.md +53 -179
  27. package/docs/builtin-macros/partial-ord.md +67 -159
  28. package/docs/builtin-macros/serialize.md +64 -194
  29. package/docs/concepts/architecture.md +40 -99
  30. package/docs/concepts/derive-system.md +129 -125
  31. package/docs/concepts/how-macros-work.md +52 -84
  32. package/docs/custom-macros/custom-overview.md +17 -39
  33. package/docs/custom-macros/rust-setup.md +22 -55
  34. package/docs/custom-macros/ts-macro-derive.md +43 -107
  35. package/docs/custom-macros/ts-quote.md +177 -507
  36. package/docs/getting-started/first-macro.md +108 -33
  37. package/docs/getting-started/installation.md +32 -73
  38. package/docs/integration/cli.md +70 -156
  39. package/docs/integration/configuration.md +32 -75
  40. package/docs/integration/integration-overview.md +16 -55
  41. package/docs/integration/mcp-server.md +30 -69
  42. package/docs/integration/svelte-preprocessor.md +60 -83
  43. package/docs/integration/typescript-plugin.md +32 -74
  44. package/docs/integration/vite-plugin.md +30 -79
  45. package/docs/language-servers/ls-overview.md +22 -46
  46. package/docs/language-servers/svelte.md +30 -69
  47. package/docs/language-servers/zed.md +34 -72
  48. package/docs/roadmap/roadmap.md +54 -130
  49. package/docs/sections.json +3 -262
  50. package/package.json +2 -2
@@ -1,223 +1,93 @@
1
1
  # Serialize
2
2
 
3
- *The `Serialize` macro generates a `toJSON()` method that converts your object to a JSON-compatible format with automatic handling of complex types like Date, Map, Set, and nested objects.*
3
+ The `Serialize` macro generates JSON serialization methods with **cycle detection**
4
+ and object identity tracking. This enables serialization of complex object graphs
5
+ including circular references.
4
6
 
5
- ## Basic Usage
7
+ ## Generated Methods
6
8
 
7
- <MacroExample before={data.examples.basic.before} after={data.examples.basic.after} />
9
+ | Type | Generated Code | Description |
10
+ |------|----------------|-------------|
11
+ | Class | `toStringifiedJSON()`, `toObject()`, `__serialize(ctx)` | Instance methods |
12
+ | Enum | `toStringifiedJSONEnumName(value)`, `__serializeEnumName` | Standalone functions |
13
+ | Interface | `toStringifiedJSONInterfaceName(value)`, etc. | Standalone functions |
14
+ | Type Alias | `toStringifiedJSONTypeName(value)`, etc. | Standalone functions |
8
15
 
9
- ```typescript
10
- const user = new User("Alice", 30);
11
- console.log(JSON.stringify(user));
12
- // {"name":"Alice","age":30,"createdAt":"2024-01-15T10:30:00.000Z"}
13
- ```
14
-
15
- ## Automatic Type Handling
16
-
17
- Serialize automatically handles various TypeScript types:
18
-
19
- | `string`, `number`, `boolean`
20
- | Direct copy
21
-
22
- | `Date`
23
- | `.toISOString()`
24
-
25
- | `T[]`
26
- | Maps items, calling `toJSON()` if available
27
-
28
- | `Map<K, V>`
29
- | `Object.fromEntries()`
16
+ ## Configuration
30
17
 
31
- | `Set<T>`
32
- | `Array.from()`
18
+ The `functionNamingStyle` option in `macroforge.json` controls naming:
19
+ - `"suffix"` (default): Suffixes with type name (e.g., `toStringifiedJSONMyType`)
20
+ - `"prefix"`: Prefixes with type name (e.g., `myTypeToStringifiedJSON`)
21
+ - `"generic"`: Uses TypeScript generics (e.g., `toStringifiedJSON<T extends MyType>`)
22
+ - `"namespace"`: Legacy namespace wrapping
33
23
 
34
- | Nested objects
35
- | Calls `toJSON()` if available
36
-
37
- ## Serde Options
38
-
39
- Use the `@serde` decorator for fine-grained control over serialization:
40
-
41
- ### Renaming Fields
42
-
43
- <MacroExample before={data.examples.rename.before} after={data.examples.rename.after} />
44
-
45
- ```typescript
46
- const user = new User();
47
- user.id = "123";
48
- user.name = "Alice";
49
- console.log(JSON.stringify(user));
50
- // {"user_id":"123","full_name":"Alice"}
51
- ```
24
+ ## Cycle Detection Protocol
52
25
 
53
- ### Skipping Fields
26
+ The generated code handles circular references using `__id` and `__ref` markers:
54
27
 
55
- <MacroExample before={data.examples.skip.before} after={data.examples.skip.after} />
56
-
57
- <Alert type="tip" title="skip vs skip_serializing">
58
- Use `skip: true` to exclude from both serialization and deserialization.
59
- Use `skip_serializing: true` to only skip during serialization.
60
- </Alert>
61
-
62
- ### Rename All Fields
63
-
64
- Apply a naming convention to all fields at the container level:
65
-
66
- <InteractiveMacro code={`/** @derive(Serialize) */
67
- /** @serde({ rename_all: "camelCase" }) */
68
- class ApiResponse {
69
- user_name: string;
70
- created_at: Date;
71
- is_active: boolean;
72
- }`} />
73
-
74
- Supported conventions:
75
-
76
- - `camelCase`
77
-
78
- - `snake_case`
79
-
80
- - `PascalCase`
81
-
82
- - `SCREAMING_SNAKE_CASE`
83
-
84
- - `kebab-case`
85
-
86
- ### Flattening Nested Objects
87
-
88
- <InteractiveMacro code={`/** @derive(Serialize) */
89
- class Address {
90
- city: string;
91
- zip: string;
28
+ ```json
29
+ {
30
+ "__type": "User",
31
+ "__id": 1,
32
+ "name": "Alice",
33
+ "friend": { "__ref": 2 } // Reference to object with __id: 2
92
34
  }
93
-
94
- /** @derive(Serialize) */
95
- class User {
96
- name: string;
97
-
98
- /** @serde({ flatten: true }) */
99
- address: Address;
100
- }`} />
101
-
102
- ```typescript
103
- const user = new User();
104
- user.name = "Alice";
105
- user.address = { city: "NYC", zip: "10001" };
106
- console.log(JSON.stringify(user));
107
- // {"name":"Alice","city":"NYC","zip":"10001"}
108
35
  ```
109
36
 
110
- ## All Options
111
-
112
- ### Container Options (on class/interface)
113
-
114
- | `rename_all`
115
- | `string`
116
- | Apply naming convention to all fields
117
-
118
- ### Field Options (on properties)
119
-
120
- | `rename`
121
- | `string`
122
- | Use a different JSON key
123
-
124
- | `skip`
125
- | `boolean`
126
- | Exclude from serialization and deserialization
37
+ When an object is serialized:
38
+ 1. Check if it's already been serialized (has an `__id`)
39
+ 2. If so, return `{ "__ref": existingId }` instead
40
+ 3. Otherwise, register the object and serialize its fields
127
41
 
128
- | `skip_serializing`
129
- | `boolean`
130
- | Exclude from serialization only
42
+ ## Type-Specific Serialization
131
43
 
132
- | `flatten`
133
- | `boolean`
134
- | Merge nested object fields into parent
44
+ | Type | Serialization Strategy |
45
+ |------|------------------------|
46
+ | Primitives | Direct value |
47
+ | `Date` | `toISOString()` |
48
+ | Arrays | For primitive-like element types, pass through; for `Date`/`Date | null`, map to ISO strings; otherwise map and call `__serialize(ctx)` when available |
49
+ | `Map<K,V>` | For primitive-like values, `Object.fromEntries(map.entries())`; for `Date`/`Date | null`, convert to ISO strings; otherwise call `__serialize(ctx)` per value when available |
50
+ | `Set<T>` | Convert to array; element handling matches `Array<T>` |
51
+ | Nullable | Include `null` explicitly; for primitive-like and `Date` unions the generator avoids runtime `__serialize` checks |
52
+ | Objects | Call `__serialize(ctx)` if available (to support user-defined implementations) |
135
53
 
136
- ## Interface Support
54
+ Note: the generator specializes some code paths based on the declared TypeScript type to
55
+ avoid runtime feature detection on primitives and literal unions.
137
56
 
138
- Serialize also works with interfaces. For interfaces, a namespace is generated with a `toJSON` function:
57
+ ## Field-Level Options
139
58
 
140
- <MacroExample before={data.examples.interface.before} after={data.examples.interface.after} />
59
+ The `@serde` decorator supports:
141
60
 
142
- ```typescript
143
- const response: ApiResponse = {
144
- status: 200,
145
- message: "OK",
146
- timestamp: new Date()
147
- };
148
-
149
- console.log(JSON.stringify(ApiResponse.toJSON(response)));
150
- // {"status":200,"message":"OK","timestamp":"2024-01-15T10:30:00.000Z"}
151
- ```
152
-
153
- ## Enum Support
154
-
155
- Serialize also works with enums. The `toJSON` function returns the underlying enum value (string or number):
61
+ - `skip` / `skip_serializing` - Exclude field from serialization
62
+ - `rename = "jsonKey"` - Use different JSON property name
63
+ - `flatten` - Merge nested object's fields into parent
156
64
 
157
- <MacroExample before={data.examples.enum.before} after={data.examples.enum.after} />
65
+ ## Example
158
66
 
159
67
  ```typescript
160
- console.log(Status.toJSON(Status.Active)); // "active"
161
- console.log(Status.toJSON(Status.Pending)); // "pending"
162
- ```
163
-
164
- Works with numeric enums too:
165
-
166
- <InteractiveMacro code={`/** @derive(Serialize) */
167
- enum Priority {
168
- Low = 1,
169
- Medium = 2,
170
- High = 3,
171
- }`} />
172
-
173
- ```typescript
174
- console.log(Priority.toJSON(Priority.High)); // 3
175
- ```
176
-
177
- ## Type Alias Support
178
-
179
- Serialize works with type aliases. For object types, fields are serialized with full type handling:
68
+ @derive(Serialize)
69
+ class User {
70
+ id: number;
180
71
 
181
- <MacroExample before={data.examples.typeAlias.before} after={data.examples.typeAlias.after} />
72
+ @serde(rename = "userName")
73
+ name: string;
182
74
 
183
- ```typescript
184
- const profile: UserProfile = {
185
- id: "123",
186
- name: "Alice",
187
- createdAt: new Date("2024-01-15")
188
- };
189
-
190
- console.log(JSON.stringify(UserProfile.toJSON(profile)));
191
- // {"id":"123","name":"Alice","createdAt":"2024-01-15T00:00:00.000Z"}
192
- ```
75
+ @serde(skip_serializing)
76
+ password: string;
193
77
 
194
- For union types, the value is returned directly:
78
+ @serde(flatten)
79
+ metadata: UserMetadata;
80
+ }
195
81
 
196
- <InteractiveMacro code={`/** @derive(Serialize) */
197
- type ApiStatus = "loading" | "success" | "error";`} />
82
+ // Usage:
83
+ const user = new User();
84
+ const json = user.toStringifiedJSON();
85
+ // => '{"__type":"User","__id":1,"id":1,"userName":"Alice",...}'
198
86
 
199
- ```typescript
200
- console.log(ApiStatus.toJSON("success")); // "success"
87
+ const obj = user.toObject();
88
+ // => { __type: "User", __id: 1, id: 1, userName: "Alice", ... }
201
89
  ```
202
90
 
203
- ## Combining with Deserialize
91
+ ## Required Import
204
92
 
205
- Use both Serialize and Deserialize for complete JSON round-trip support:
206
-
207
- <InteractiveMacro code={`/** @derive(Serialize, Deserialize) */
208
- class User {
209
- name: string;
210
- createdAt: Date;
211
- }`} />
212
-
213
- ```typescript
214
- // Serialize
215
- const user = new User();
216
- user.name = "Alice";
217
- user.createdAt = new Date();
218
- const json = JSON.stringify(user);
219
-
220
- // Deserialize
221
- const parsed = User.fromJSON(JSON.parse(json));
222
- console.log(parsed.createdAt instanceof Date); // true
223
- ```
93
+ The generated code automatically imports `SerializeContext` from `macroforge/serde`.
@@ -1,96 +1,41 @@
1
1
  # Architecture
2
-
3
- *Macroforge is built as a native Node.js module using Rust and NAPI-RS. It leverages SWC for fast TypeScript parsing and code generation.*
4
-
5
- ## Overview
6
-
7
- <ArchitectureDiagram layers={[
8
- { title: "Node.js / Vite" },
9
- { title: "NAPI-RS Bindings" },
10
- { title: "Macro Crates", items: ["macroforge_ts_syn", "macroforge_ts_quote", "macroforge_ts_macros"] },
11
- { title: "SWC Core", items: ["TypeScript parsing & codegen"] }
12
- ]} />
13
-
14
- ## Core Components
15
-
16
- ### SWC Core
17
-
18
- The foundation layer provides:
19
-
20
- - Fast TypeScript/JavaScript parsing
21
-
22
- - AST representation
23
-
24
- - Code generation (AST source code)
25
-
26
- ### macroforge_ts_syn
27
-
28
- A Rust crate that provides:
29
-
30
- - TypeScript-specific AST types
31
-
32
- - Parsing utilities for macro input
33
-
34
- - Derive input structures (class fields, decorators, etc.)
35
-
36
- ### macroforge_ts_quote
37
-
38
- Template-based code generation similar to Rust's `quote!`:
39
-
40
- - `ts_template!` - Generate TypeScript code from templates
41
-
42
- - `body!` - Generate class body members
43
-
44
- - Control flow: `{"{#for}"}`, `{"{#if}"}`, `{"{$let}"}`
45
-
46
- ### macroforge_ts_macros
47
-
48
- The procedural macro attribute for defining derive macros:
49
-
50
- - `#[ts_macro_derive(Name)]` attribute
51
-
52
- - Automatic registration with the macro system
53
-
54
- - Error handling and span tracking
55
-
56
- ### NAPI-RS Bindings
57
-
58
- Bridges Rust and Node.js:
59
-
60
- - Exposes `expandSync`, `transformSync`, etc.
61
-
62
- - Provides the `NativePlugin` class for caching
63
-
64
- - Handles data marshaling between Rust and JavaScript
65
-
66
- ## Data Flow
67
-
68
- <Flowchart steps={[
69
- { title: "1. Source Code", description: "TypeScript with @derive" },
70
- { title: "2. NAPI-RS", description: "receives JavaScript string" },
71
- { title: "3. SWC Parser", description: "parses to AST" },
72
- { title: "4. Macro Expander", description: "finds @derive decorators" },
73
- { title: "5. For Each Macro", description: "extract data, run macro, generate AST nodes" },
74
- { title: "6. Merge", description: "generated nodes into AST" },
75
- { title: "7. SWC Codegen", description: "generates source code" },
76
- { title: "8. Return", description: "to JavaScript with source mapping" }
77
- ]} />
78
-
79
- ## Performance Characteristics
80
-
81
- - **Thread-safe**: Each expansion runs in an isolated thread with a 32MB stack
82
-
83
- - **Caching**: `NativePlugin` caches results by file version
84
-
85
- - **Binary search**: Position mapping uses O(log n) lookups
86
-
87
- - **Zero-copy**: SWC's arena allocator minimizes allocations
88
-
89
- ## Re-exported Crates
90
-
91
- For custom macro development, `macroforge_ts` re-exports everything you need:
92
-
93
- ```rust
2
+ *Macroforge is built as a native Node.js module using Rust and NAPI-RS. It leverages SWC for fast TypeScript parsing and code generation.*
3
+ ## Overview
4
+ <div class="border border-border bg-card p-4 text-center rounded-t-lg "><div class="font-semibold text-foreground">Node.js / Vite <div class="font-semibold text-foreground">NAPI-RS Bindings <div class="font-semibold text-foreground">Macro Crates <div class="px-3 py-1.5 bg-muted rounded text-sm text-muted-foreground font-mono">macroforge_ts_synmacroforge_ts_quotemacroforge_ts_macros<div class="font-semibold text-foreground">SWC Core <div class="px-3 py-1.5 bg-muted rounded text-sm text-muted-foreground font-mono">TypeScript parsing & codegen ## Core Components
5
+ ### SWC Core
6
+ The foundation layer provides:
7
+ - Fast TypeScript/JavaScript parsing
8
+ - AST representation
9
+ - Code generation (AST → source code)
10
+ ### macroforge_ts_syn
11
+ A Rust crate that provides:
12
+ - TypeScript-specific AST types
13
+ - Parsing utilities for macro input
14
+ - Derive input structures (class fields, decorators, etc.)
15
+ ### macroforge_ts_quote
16
+ Template-based code generation similar to Rust's `quote!`:
17
+ - `ts_template!` - Generate TypeScript code from templates
18
+ - `body!` - Generate class body members
19
+ - Control flow: `{#for}`, `{#if}`, `{$let}`
20
+ ### macroforge_ts_macros
21
+ The procedural macro attribute for defining derive macros:
22
+ - `#[ts_macro_derive(Name)]` attribute
23
+ - Automatic registration with the macro system
24
+ - Error handling and span tracking
25
+ ### NAPI-RS Bindings
26
+ Bridges Rust and Node.js:
27
+ - Exposes `expandSync`, `transformSync`, etc.
28
+ - Provides the `NativePlugin` class for caching
29
+ - Handles data marshaling between Rust and JavaScript
30
+ ## Data Flow
31
+ <div class="w-full max-w-md border border-border rounded-lg bg-card p-4 text-center shadow-sm"><div class="font-semibold text-foreground">1. Source Code TypeScript with @derive <div class="font-semibold text-foreground">2. NAPI-RS receives JavaScript string <div class="font-semibold text-foreground">3. SWC Parser parses to AST <div class="font-semibold text-foreground">4. Macro Expander finds @derive decorators <div class="font-semibold text-foreground">5. For Each Macro extract data, run macro, generate AST nodes <div class="font-semibold text-foreground">6. Merge generated nodes into AST <div class="font-semibold text-foreground">7. SWC Codegen generates source code <div class="font-semibold text-foreground">8. Return to JavaScript with source mapping ## Performance Characteristics
32
+ - **Thread-safe**: Each expansion runs in an isolated thread with a 32MB stack
33
+ - **Caching**: `NativePlugin` caches results by file version
34
+ - **Binary search**: Position mapping uses O(log n) lookups
35
+ - **Zero-copy**: SWC's arena allocator minimizes allocations
36
+ ## Re-exported Crates
37
+ For custom macro development, `macroforge_ts` re-exports everything you need:
38
+ ```
94
39
  // Convenient re-exports for macro development
95
40
  use macroforge_ts::macros::{ts_macro_derive, body, ts_template, above, below, signature};
96
41
  use macroforge_ts::ts_syn::{Data, DeriveInput, MacroforgeError, TsStream, parse_ts_macro_input};
@@ -99,10 +44,6 @@ use macroforge_ts::ts_syn::{Data, DeriveInput, MacroforgeError, TsStream, parse_
99
44
  use macroforge_ts::swc_core;
100
45
  use macroforge_ts::swc_common;
101
46
  use macroforge_ts::swc_ecma_ast;
102
- ```
103
-
104
- ## Next Steps
105
-
106
- - [Write custom macros]({base}/docs/custom-macros)
107
-
108
- - [Explore the API reference]({base}/docs/api)
47
+ ``` ## Next Steps
48
+ - [Write custom macros](../../docs/custom-macros)
49
+ - [Explore the API reference](../../docs/api)