wstp-node 0.4.0 → 0.4.1

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.
@@ -0,0 +1,171 @@
1
+ # Building wstp-node on Windows
2
+
3
+ This guide walks through compiling the native WSTP addon (`wstp.node`) on a
4
+ Windows 10 / 11 x64 machine so that the
5
+ [Wolfbook VS Code extension](https://github.com/vanbaalon/wolfbook) can use it
6
+ without any build step on the end-user's machine.
7
+
8
+ ---
9
+
10
+ ## Prerequisites
11
+
12
+ ### 1. Wolfram Engine (or Mathematica)
13
+
14
+ Download the free **Wolfram Engine** from:
15
+ https://wolfram.com/engine/
16
+
17
+ Default installation path after setup:
18
+ ```
19
+ C:\Program Files\Wolfram Research\Wolfram Engine\14.x\
20
+ ```
21
+
22
+ Verify the WSTP DeveloperKit is present:
23
+ ```
24
+ C:\Program Files\Wolfram Research\Wolfram Engine\14.x\SystemFiles\Links\WSTP\DeveloperKit\Windows-x86-64\CompilerAdditions\
25
+ ```
26
+ The key files needed are `wstp64i4s.lib` and `wstp.h` inside that folder.
27
+
28
+ > If your Wolfram version or install path differs, set the `WSTP_DIR` environment
29
+ > variable to the `CompilerAdditions` folder before building:
30
+ > ```powershell
31
+ > $env:WSTP_DIR = "C:\Program Files\Wolfram Research\Wolfram Engine\14.x\SystemFiles\Links\WSTP\DeveloperKit\Windows-x86-64\CompilerAdditions"
32
+ > ```
33
+
34
+ ---
35
+
36
+ ### 2. Visual Studio Build Tools (C++ compiler)
37
+
38
+ Run the following in **PowerShell as Administrator**:
39
+
40
+ ```powershell
41
+ winget install Microsoft.VisualStudio.2022.BuildTools
42
+ ```
43
+
44
+ Then open **Visual Studio Installer** → **Modify** → select the
45
+ **"Desktop development with C++"** workload. Make sure these components
46
+ are checked:
47
+
48
+ - ✅ MSVC v143 – VS 2022 C++ x64/x86 build tools
49
+ - ✅ Windows 11 SDK (or Windows 10 SDK)
50
+ - ✅ C++ CMake tools (optional but useful)
51
+
52
+ ---
53
+
54
+ ### 3. Node.js ≥ 18 (LTS)
55
+
56
+ ```powershell
57
+ winget install OpenJS.NodeJS.LTS
58
+ ```
59
+
60
+ Restart your shell after installation, then verify:
61
+
62
+ ```powershell
63
+ node --version # 20.x or 22.x
64
+ npm --version
65
+ ```
66
+
67
+ ---
68
+
69
+ ### 4. Git
70
+
71
+ ```powershell
72
+ winget install Git.Git
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Build
78
+
79
+ Open a **Developer PowerShell for VS 2022** (or a regular PowerShell — `node-gyp`
80
+ finds MSVC automatically if the Build Tools are installed correctly).
81
+
82
+ ```powershell
83
+ git clone https://github.com/vanbaalon/mathematica-wstp-node.git
84
+ cd mathematica-wstp-node
85
+
86
+ npm install
87
+ npm run build
88
+ ```
89
+
90
+ A successful build prints:
91
+ ```
92
+ Build succeeded: build\Release\wstp.node
93
+ ```
94
+
95
+ ### Verify the build
96
+
97
+ ```powershell
98
+ node -e "const {WstpSession}=require('./build/Release/wstp.node'); const s=new WstpSession(); s.evaluate('1+1').then(r=>{console.log(r.result.value); s.close()})"
99
+ ```
100
+ Expected output: `2`
101
+
102
+ ---
103
+
104
+ ## Contributing the binary to the Wolfbook extension
105
+
106
+ After building, copy the binary to the extension's `wstp/prebuilt/` folder and
107
+ commit it so CI can package the Windows VSIX:
108
+
109
+ ```powershell
110
+ # from inside the mathematica-wstp-node directory:
111
+ copy build\Release\wstp.node ..\wolfbook\wstp\prebuilt\wstp-win32-x64.node
112
+ ```
113
+
114
+ Then on macOS / Linux, run the deploy script to build both platform VSIXs:
115
+
116
+ ```bash
117
+ bash deploy-extension.sh package
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Setting up a self-hosted GitHub Actions runner (optional)
123
+
124
+ If you want CI to build the Windows binary automatically on every release tag:
125
+
126
+ **In your browser:** go to
127
+ `https://github.com/vanbaalon/mathematica-wstp-node` →
128
+ Settings → Actions → Runners → **New self-hosted runner** → Windows x64
129
+
130
+ GitHub shows you a unique token and the exact download URL. Run those commands
131
+ in **PowerShell as Administrator**:
132
+
133
+ ```powershell
134
+ mkdir C:\actions-runner; cd C:\actions-runner
135
+
136
+ # Replace the URL and token with what GitHub shows you:
137
+ Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v2.x.x/actions-runner-win-x64-2.x.x.zip -OutFile runner.zip
138
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
139
+ [System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\runner.zip", "$PWD")
140
+
141
+ .\config.cmd --url https://github.com/vanbaalon/mathematica-wstp-node --token YOUR_TOKEN_HERE
142
+
143
+ # Install as a Windows service so it runs even when you are logged out:
144
+ .\svc.cmd install
145
+ .\svc.cmd start
146
+ ```
147
+
148
+ Verify the runner is online: GitHub → Settings → Actions → Runners → green dot.
149
+
150
+ Once both the macOS and Windows runners are registered, push a version tag from
151
+ your Mac to trigger a full build:
152
+
153
+ ```bash
154
+ git tag v0.5.0 && git push origin v0.5.0
155
+ ```
156
+
157
+ The workflow builds both binaries and publishes them as assets on the
158
+ `mathematica-wstp-node` GitHub Release. The `wolfbook` workflow then downloads
159
+ those assets and packages the platform-specific VSIXs automatically.
160
+
161
+ ---
162
+
163
+ ## Troubleshooting
164
+
165
+ | Problem | Solution |
166
+ |---------|----------|
167
+ | `gyp ERR! find VS` | Open Developer PowerShell for VS 2022, or run `npm config set msvs_version 2022` |
168
+ | `LINK : fatal error LNK1181: cannot open input file 'wstp64i4s.lib'` | WSTP DeveloperKit not found — set `WSTP_DIR` (see Prerequisites) |
169
+ | `node.exe` crashes on `require('./build/Release/wstp.node')` | Node.js architecture mismatch — ensure you installed 64-bit Node |
170
+ | Runner shows offline | `cd C:\actions-runner && .\svc.cmd status`, then `.\svc.cmd start` |
171
+ | `error MSB8036: The Windows SDK version X was not found` | Install the matching Windows SDK via Visual Studio Installer |
package/README.md CHANGED
@@ -54,11 +54,16 @@ const { WstpSession, WstpReader, setDiagHandler } = require('./build/Release/wst
54
54
 
55
55
  | Requirement | Notes |
56
56
  |-------------|-------|
57
- | macOS | Tested on macOS 13+; Linux should work with minor path changes |
57
+ | macOS | Tested on macOS 13+ (ARM64 and x86-64) |
58
+ | Windows 10/11 x64 | See [InstallationWindows.md](InstallationWindows.md) for the full Windows guide |
59
+ | Linux x86-64 / ARM64 | Should work with standard `node-gyp` toolchain |
58
60
  | Node.js ≥ 18 | Earlier versions may work but are untested |
59
- | Clang / Xcode Command Line Tools | `xcode-select --install` |
61
+ | Clang / Xcode Command Line Tools (macOS) | `xcode-select --install` |
62
+ | MSVC Build Tools with C++ workload (Windows) | Visual Studio 2019+ or Build Tools |
60
63
  | Wolfram Mathematica or Wolfram Engine | Provides `WolframKernel` and the WSTP SDK headers/libraries |
61
64
 
65
+ > **Windows users:** follow [InstallationWindows.md](InstallationWindows.md) instead of the steps below.
66
+
62
67
  ### 1. Clone
63
68
 
64
69
  ```bash
@@ -92,7 +97,7 @@ The script automatically locates the WSTP SDK inside the default Wolfram install
92
97
  node test.js
93
98
  ```
94
99
 
95
- Expected last line: `All 28 tests passed.`
100
+ Expected last line: `All 36 tests passed.`
96
101
 
97
102
  A more comprehensive suite (both modes + In/Out + comparison) lives in `tmp/tests_all.js`:
98
103
 
package/binding.gyp CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "variables": {
3
- # Detect arch: arm64 → MacOSX-ARM64, x86_64 MacOSX-x86-64
4
- # Override the whole path by setting WSTP_DIR in the environment.
5
- "wstp_dir%": "<!(echo \"${WSTP_DIR:-/Applications/Wolfram 3.app/Contents/SystemFiles/Links/WSTP/DeveloperKit/$(uname -m | sed 's/x86_64/MacOSX-x86-64/;s/arm64/MacOSX-ARM64/')/CompilerAdditions}\")"
3
+ # Cross-platform WSTP DeveloperKit path.
4
+ # Override by setting WSTP_DIR in the environment.
5
+ # See scripts/wstp_dir.js for auto-detection logic.
6
+ "wstp_dir%": "<!@(node scripts/wstp_dir.js)"
6
7
  },
7
8
  "targets": [
8
9
  {
@@ -16,13 +17,9 @@
16
17
 
17
18
  "defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"],
18
19
 
19
- "libraries": [
20
- # The static library ships as libWSTPi4.a in the macOS DeveloperKit.
21
- "<(wstp_dir)/libWSTPi4.a"
22
- ],
23
-
24
20
  "conditions": [
25
21
  ["OS=='mac'", {
22
+ "libraries": ["<(wstp_dir)/libWSTPi4.a"],
26
23
  "xcode_settings": {
27
24
  "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
28
25
  "MACOSX_DEPLOYMENT_TARGET": "11.0",
@@ -37,8 +34,9 @@
37
34
  }
38
35
  }],
39
36
  ["OS=='linux'", {
37
+ "libraries": ["<(wstp_dir)/libWSTPi4.a"],
40
38
  "cflags_cc": ["-std=c++17", "-Wall", "-Wextra"],
41
- "libraries": ["-lrt", "-lpthread", "-ldl", "-lm"]
39
+ "link_settings": { "libraries": ["-lrt", "-lpthread", "-ldl", "-lm"] }
42
40
  }],
43
41
  ["OS=='win'", {
44
42
  "msvs_settings": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wstp-node",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Native Node.js addon for Wolfram/Mathematica WSTP — kernel sessions with evaluation queue, streaming Print/messages, Dialog subsessions, and side-channel WstpReader",
5
5
  "main": "build/Release/wstp.node",
6
6
  "types": "index.d.ts",
@@ -20,16 +20,19 @@
20
20
  "license": "MIT",
21
21
  "os": [
22
22
  "darwin",
23
- "linux"
23
+ "linux",
24
+ "win32"
24
25
  ],
25
26
  "engines": {
26
27
  "node": ">=18"
27
28
  },
28
29
  "files": [
29
30
  "src/addon.cc",
31
+ "scripts/wstp_dir.js",
30
32
  "build.sh",
31
33
  "binding.gyp",
32
34
  "index.d.ts",
35
+ "InstallationWindows.md",
33
36
  "examples/",
34
37
  "test.js",
35
38
  "test_interrupt_dialog.js"
@@ -0,0 +1,78 @@
1
+ /**
2
+ * wstp_dir.js
3
+ * Cross-platform helper used by binding.gyp to locate the WSTP DeveloperKit.
4
+ *
5
+ * Usage in binding.gyp: "wstp_dir%": "<!@(node scripts/wstp_dir.js)"
6
+ *
7
+ * Precedence:
8
+ * 1. WSTP_DIR environment variable (always wins)
9
+ * 2. Platform-specific auto-detect below
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ const path = require('path');
15
+ const fs = require('fs');
16
+
17
+ function resolve () {
18
+ // ── 1. Explicit override ────────────────────────────────────────────────
19
+ if (process.env.WSTP_DIR) {
20
+ return process.env.WSTP_DIR;
21
+ }
22
+
23
+ // ── 2. Windows ──────────────────────────────────────────────────────────
24
+ if (process.platform === 'win32') {
25
+ const base = 'C:\\Program Files\\Wolfram Research\\Wolfram Engine';
26
+ let versions;
27
+ try {
28
+ versions = fs.readdirSync(base)
29
+ .filter(d => /^\d/.test(d))
30
+ .sort()
31
+ .reverse();
32
+ } catch (e) {
33
+ throw new Error(
34
+ `WSTP DeveloperKit not found at "${base}".\n` +
35
+ `Install Wolfram Engine or set WSTP_DIR to the CompilerAdditions folder.`
36
+ );
37
+ }
38
+ if (!versions.length) throw new Error(`No Wolfram Engine version found under "${base}"`);
39
+ return path.join(
40
+ base, versions[0],
41
+ 'SystemFiles', 'Links', 'WSTP', 'DeveloperKit',
42
+ 'Windows-x86-64', 'CompilerAdditions'
43
+ );
44
+ }
45
+
46
+ // ── 3. macOS ────────────────────────────────────────────────────────────
47
+ if (process.platform === 'darwin') {
48
+ const { execSync } = require('child_process');
49
+ const machine = execSync('uname -m').toString().trim();
50
+ const archDir = machine === 'arm64' ? 'MacOSX-ARM64' : 'MacOSX-x86-64';
51
+ return path.join(
52
+ '/Applications/Wolfram 3.app/Contents/SystemFiles/Links/WSTP/DeveloperKit',
53
+ archDir, 'CompilerAdditions'
54
+ );
55
+ }
56
+
57
+ // ── 4. Linux ────────────────────────────────────────────────────────────
58
+ {
59
+ const { execSync } = require('child_process');
60
+ const machine = execSync('uname -m').toString().trim();
61
+ const archDir = machine === 'aarch64' ? 'Linux-ARM64' : 'Linux-x86-64';
62
+ const candidates = [
63
+ path.join(process.env.HOME || '/root', 'Wolfram', 'WolframEngine',
64
+ 'SystemFiles', 'Links', 'WSTP', 'DeveloperKit', archDir, 'CompilerAdditions'),
65
+ path.join('/usr/local/Wolfram/WolframEngine',
66
+ 'SystemFiles', 'Links', 'WSTP', 'DeveloperKit', archDir, 'CompilerAdditions'),
67
+ ];
68
+ for (const c of candidates) {
69
+ if (fs.existsSync(c)) return c;
70
+ }
71
+ throw new Error(
72
+ 'WSTP DeveloperKit not found for Linux.\n' +
73
+ 'Set WSTP_DIR to the CompilerAdditions directory.'
74
+ );
75
+ }
76
+ }
77
+
78
+ process.stdout.write(resolve());