@macroforge/mcp-server 0.1.39 → 0.1.42
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/docs/api/api-overview.md +32 -32
- package/docs/api/expand-sync.md +30 -30
- package/docs/api/native-plugin.md +38 -38
- package/docs/api/position-mapper.md +18 -18
- package/docs/api/transform-sync.md +31 -31
- package/docs/builtin-macros/default.md +6 -6
- package/docs/builtin-macros/macros-overview.md +84 -84
- package/docs/builtin-macros/partial-ord.md +18 -20
- package/docs/concepts/architecture.md +16 -16
- package/docs/concepts/derive-system.md +89 -68
- package/docs/concepts/how-macros-work.md +13 -12
- package/docs/custom-macros/custom-overview.md +36 -36
- package/docs/custom-macros/rust-setup.md +71 -71
- package/docs/custom-macros/ts-macro-derive.md +167 -167
- package/docs/custom-macros/ts-quote.md +347 -347
- package/docs/getting-started/first-macro.md +57 -55
- package/docs/getting-started/installation.md +34 -35
- package/docs/integration/cli.md +43 -43
- package/docs/integration/configuration.md +41 -41
- package/docs/integration/integration-overview.md +4 -4
- package/docs/integration/mcp-server.md +22 -22
- package/docs/integration/svelte-preprocessor.md +87 -87
- package/docs/integration/typescript-plugin.md +23 -24
- package/docs/integration/vite-plugin.md +40 -40
- package/docs/language-servers/svelte.md +15 -16
- package/docs/language-servers/zed.md +14 -15
- package/package.json +2 -2
|
@@ -3,31 +3,32 @@
|
|
|
3
3
|
## Compile-Time Expansion
|
|
4
4
|
Unlike runtime solutions that use reflection or proxies, Macroforge expands macros at compile time:
|
|
5
5
|
1. **Parse**: Your TypeScript code is parsed into an AST using SWC
|
|
6
|
-
2. **Find**: Macroforge finds
|
|
6
|
+
2. **Find**: Macroforge finds <code class="shiki-inline"><span class="line"><span style="--shiki-dark:#E1E4E8;--shiki-light:#24292E">@derive</code> decorators and their associated items
|
|
7
7
|
3. **Expand**: Each macro generates new code based on the class structure
|
|
8
8
|
4. **Output**: The transformed TypeScript is written out, ready for normal compilation
|
|
9
|
-
|
|
9
|
+
<div><div class="flex items-center justify-between gap-2 px-4 py-2 bg-muted rounded-t-lg border border-b-0 border-border">
|
|
10
|
+
**Before:**
|
|
10
11
|
```
|
|
11
12
|
/** @derive(Debug) */
|
|
12
|
-
class User
|
|
13
|
+
class User {
|
|
13
14
|
name: string;
|
|
14
|
-
|
|
15
|
-
```
|
|
15
|
+
}
|
|
16
|
+
``` <div class="flex items-center justify-between gap-2 px-4 py-2 bg-muted rounded-t-lg border border-b-0 border-border">
|
|
16
17
|
**After:**
|
|
17
18
|
```
|
|
18
|
-
class User
|
|
19
|
+
class User {
|
|
19
20
|
name: string;
|
|
20
21
|
|
|
21
|
-
static toString(value: User): string
|
|
22
|
+
static toString(value: User): string {
|
|
22
23
|
return userToString(value);
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
}
|
|
25
|
+
}
|
|
25
26
|
|
|
26
|
-
export function userToString(value: User): string
|
|
27
|
+
export function userToString(value: User): string {
|
|
27
28
|
const parts: string[] = [];
|
|
28
29
|
parts.push('name: ' + value.name);
|
|
29
|
-
return 'User
|
|
30
|
-
|
|
30
|
+
return 'User { ' + parts.join(', ') + ' }';
|
|
31
|
+
}
|
|
31
32
|
``` ## Zero Runtime Overhead
|
|
32
33
|
Because code generation happens at compile time, there's no:
|
|
33
34
|
- Runtime reflection or metadata
|
|
@@ -3,57 +3,57 @@
|
|
|
3
3
|
## Overview
|
|
4
4
|
Custom macros are written in Rust and compiled to native Node.js addons. The process involves:
|
|
5
5
|
1. Creating a Rust crate with NAPI bindings
|
|
6
|
-
2. Defining macro functions with
|
|
7
|
-
3. Using
|
|
6
|
+
2. Defining macro functions with <code class="shiki-inline"><span class="line"><span style="--shiki-dark:#E1E4E8;--shiki-light:#24292E">#[ts_macro_derive]</code>
|
|
7
|
+
3. Using <code class="shiki-inline"><span class="line"><span style="--shiki-dark:#E1E4E8;--shiki-light:#24292E">macroforge_ts_quote</code> to generate TypeScript code
|
|
8
8
|
4. Building and publishing as an npm package
|
|
9
9
|
## Quick Example
|
|
10
10
|
```
|
|
11
|
-
use
|
|
12
|
-
use
|
|
11
|
+
use macroforge_ts::macros::{ts_macro_derive, body};
|
|
12
|
+
use macroforge_ts::ts_syn::{Data, DeriveInput, MacroforgeError, TsStream, parse_ts_macro_input};
|
|
13
13
|
|
|
14
14
|
#[ts_macro_derive(
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
JSON,
|
|
16
|
+
description = "Generates toJSON() returning a plain object"
|
|
17
17
|
)]
|
|
18
|
-
pub
|
|
19
|
-
|
|
18
|
+
pub fn derive_json(mut input: TsStream) -> Result<TsStream, MacroforgeError> {
|
|
19
|
+
let input = parse_ts_macro_input!(input as DeriveInput);
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
21
|
+
match &input.data {
|
|
22
|
+
Data::Class(class) => {
|
|
23
|
+
Ok(body! {
|
|
24
|
+
toJSON(): Record<string, unknown> {
|
|
25
|
+
return {
|
|
26
|
+
{#for field in class.field_names()}
|
|
27
|
+
@{field}: this.@{field},
|
|
28
|
+
{/for}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
_ => Err(MacroforgeError::new(
|
|
34
|
+
input.decorator_span(),
|
|
35
|
+
"@derive(JSON) only works on classes",
|
|
36
|
+
)),
|
|
37
|
+
}
|
|
38
38
|
}
|
|
39
39
|
``` ## Using Custom Macros
|
|
40
40
|
Once your macro package is published, users can import and use it:
|
|
41
41
|
```
|
|
42
|
-
|
|
42
|
+
/** import macro { JSON } from "@my/macros"; */
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
class
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
/** @derive(JSON) */
|
|
45
|
+
class User {
|
|
46
|
+
name: string;
|
|
47
|
+
age: number;
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
constructor(name: string, age: number) {
|
|
50
|
+
this.name = name;
|
|
51
|
+
this.age = age;
|
|
52
|
+
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const
|
|
56
|
-
console.log(user.toJSON())
|
|
55
|
+
const user = new User("Alice", 30);
|
|
56
|
+
console.log(user.toJSON()); // { name: "Alice", age: 30 }
|
|
57
57
|
``` > **Note:** The import macro comment tells Macroforge which package provides the macro. ## Getting Started
|
|
58
58
|
Follow these guides to create your own macros:
|
|
59
59
|
- [Set up a Rust macro crate](../docs/custom-macros/rust-setup)
|
|
@@ -3,109 +3,109 @@
|
|
|
3
3
|
## Prerequisites
|
|
4
4
|
- Rust toolchain (1.88 or later)
|
|
5
5
|
- Node.js 24 or later
|
|
6
|
-
- NAPI-RS CLI:
|
|
6
|
+
- NAPI-RS CLI: <code class="shiki-inline"><span class="line"><span style="--shiki-dark:#B392F0;--shiki-light:#6F42C1">cargo<span style="--shiki-dark:#9ECBFF;--shiki-light:#032F62"> install<span style="--shiki-dark:#9ECBFF;--shiki-light:#032F62"> macroforge_ts</code>
|
|
7
7
|
## Create the Project
|
|
8
8
|
```
|
|
9
|
-
|
|
10
|
-
mkdir
|
|
11
|
-
cd
|
|
9
|
+
# Create a new directory
|
|
10
|
+
mkdir my-macros
|
|
11
|
+
cd my-macros
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
napi
|
|
13
|
+
# Initialize with NAPI-RS
|
|
14
|
+
napi new --platform --name my-macros
|
|
15
15
|
``` ## Configure Cargo.toml
|
|
16
|
-
Update your
|
|
16
|
+
Update your <code class="shiki-inline"><span class="line"><span style="--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic;--shiki-light:#B31D28;--shiki-light-font-style:italic">Cargo.toml</code> with the required dependencies:
|
|
17
17
|
```
|
|
18
18
|
[package]
|
|
19
|
-
name
|
|
20
|
-
version
|
|
21
|
-
edition
|
|
19
|
+
name = "my-macros"
|
|
20
|
+
version = "0.1.0"
|
|
21
|
+
edition = "2024"
|
|
22
22
|
|
|
23
23
|
[lib]
|
|
24
|
-
crate-type
|
|
24
|
+
crate-type = ["cdylib"]
|
|
25
25
|
|
|
26
26
|
[dependencies]
|
|
27
|
-
macroforge_ts
|
|
28
|
-
napi
|
|
29
|
-
napi-derive
|
|
27
|
+
macroforge_ts = "0.1"
|
|
28
|
+
napi = { version = "3", features = ["napi8", "compat-mode"] }
|
|
29
|
+
napi-derive = "3"
|
|
30
30
|
|
|
31
31
|
[build-dependencies]
|
|
32
|
-
napi-build
|
|
32
|
+
napi-build = "2"
|
|
33
33
|
|
|
34
34
|
[profile.release]
|
|
35
|
-
lto
|
|
36
|
-
strip
|
|
35
|
+
lto = true
|
|
36
|
+
strip = true
|
|
37
37
|
``` ## Create build.rs
|
|
38
38
|
```
|
|
39
|
-
fn
|
|
40
|
-
|
|
39
|
+
fn main() {
|
|
40
|
+
napi_build::setup();
|
|
41
41
|
}
|
|
42
42
|
``` ## Create src/lib.rs
|
|
43
43
|
```
|
|
44
|
-
use
|
|
45
|
-
use
|
|
46
|
-
|
|
44
|
+
use macroforge_ts::macros::{ts_macro_derive, body};
|
|
45
|
+
use macroforge_ts::ts_syn::{
|
|
46
|
+
Data, DeriveInput, MacroforgeError, TsStream, parse_ts_macro_input,
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
#[ts_macro_derive(
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
JSON,
|
|
51
|
+
description = "Generates toJSON() returning a plain object"
|
|
52
52
|
)]
|
|
53
|
-
pub
|
|
54
|
-
|
|
53
|
+
pub fn derive_json(mut input: TsStream) -> Result<TsStream, MacroforgeError> {
|
|
54
|
+
let input = parse_ts_macro_input!(input as DeriveInput);
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
56
|
+
match &input.data {
|
|
57
|
+
Data::Class(class) => {
|
|
58
|
+
Ok(body! {
|
|
59
|
+
toJSON(): Record<string, unknown> {
|
|
60
|
+
return {
|
|
61
|
+
{#for field in class.field_names()}
|
|
62
|
+
@{field}: this.@{field},
|
|
63
|
+
{/for}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
_ => Err(MacroforgeError::new(
|
|
69
|
+
input.decorator_span(),
|
|
70
|
+
"@derive(JSON) only works on classes",
|
|
71
|
+
)),
|
|
72
|
+
}
|
|
73
73
|
}
|
|
74
74
|
``` ## Create package.json
|
|
75
75
|
```
|
|
76
76
|
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
77
|
+
"name": "@my-org/macros",
|
|
78
|
+
"version": "0.1.0",
|
|
79
|
+
"main": "index.js",
|
|
80
|
+
"types": "index.d.ts",
|
|
81
|
+
"napi": {
|
|
82
|
+
"name": "my-macros",
|
|
83
|
+
"triples": {
|
|
84
|
+
"defaults": true
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"files": [
|
|
88
|
+
"index.js",
|
|
89
|
+
"index.d.ts",
|
|
90
|
+
"*.node"
|
|
91
|
+
],
|
|
92
|
+
"scripts": {
|
|
93
|
+
"build": "napi build --release",
|
|
94
|
+
"prepublishOnly": "napi build --release"
|
|
95
|
+
},
|
|
96
|
+
"devDependencies": {
|
|
97
|
+
"@napi-rs/cli": "^3.0.0-alpha.0"
|
|
98
|
+
}
|
|
99
99
|
}
|
|
100
100
|
``` ## Build the Package
|
|
101
101
|
```
|
|
102
|
-
|
|
103
|
-
npm
|
|
102
|
+
# Build the native addon
|
|
103
|
+
npm run build
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
# This creates:
|
|
106
|
+
# - index.js (JavaScript bindings)
|
|
107
|
+
# - index.d.ts (TypeScript types)
|
|
108
|
+
# - *.node (native binary)
|
|
109
109
|
``` **Tip For cross-platform builds, use GitHub Actions with the NAPI-RS CI template. ## Next Steps
|
|
110
110
|
- [Learn the #[ts_macro_derive] attribute](../../docs/custom-macros/ts-macro-derive)
|
|
111
111
|
- [Master the template syntax](../../docs/custom-macros/ts-quote)
|