@bobfrankston/msger 0.1.355 → 0.1.358
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/msger-native/bin/msgernative.exe +0 -0
- package/msger-native/builder/README.md +3 -1
- package/msger-native/builder/build-config.json +13 -8
- package/msger-native/builder/build-under-wsl.ts +7 -7
- package/msger-native/builder/builder.ts +7 -7
- package/msger-native/builder/postinstall.js +5 -1
- package/package.json +3 -2
- package/prep-mac-source.d.ts +2 -0
- package/prep-mac-source.js +60 -0
- package/shower.d.ts +2 -0
- package/shower.js +21 -3
- package/sync-mac-binary.d.ts +2 -0
- package/sync-mac-binary.js +73 -0
|
Binary file
|
|
@@ -19,7 +19,8 @@ Edit `builder/build-config.json` to control which platforms are built:
|
|
|
19
19
|
"windows": true, // Build Windows x64 binary
|
|
20
20
|
"wsl": false, // Build Linux x64 binary (via WSL)
|
|
21
21
|
"pi": false, // Build Raspberry Pi ARM64 binary (remote build on Pi)
|
|
22
|
-
"arm64": false
|
|
22
|
+
"arm64": false, // Build Linux ARM64 binary (cross-compile via WSL)
|
|
23
|
+
"mac": false // Sync Mac binaries from OneDrive `mac/` staging into bin/ at publish time
|
|
23
24
|
},
|
|
24
25
|
"options": {
|
|
25
26
|
"release": true, // Use release mode (optimized)
|
|
@@ -38,6 +39,7 @@ Edit `builder/build-config.json` to control which platforms are built:
|
|
|
38
39
|
| `wsl` | `bin/msgernative` | Native build in WSL | WSL with Rust toolchain |
|
|
39
40
|
| `pi` | `bin/msgernative-linux-aarch64` | **Remote build on Pi** (slower, guaranteed compatible) | SSH access to Raspberry Pi |
|
|
40
41
|
| `arm64` | `bin/msgernative-linux-aarch64` | **Cross-compile on WSL** (faster, requires setup) | WSL with ARM64 cross-compilation toolchain |
|
|
42
|
+
| `mac` | `bin/msgernative-darwin-{arm64,x64}` | Sync from `mac/` (OneDrive staging) at publish time — Mac builds happen on the Mac via `mac/build-mac.sh` | A Mac (or stale OneDrive copy) |
|
|
41
43
|
|
|
42
44
|
**Pi vs ARM64:**
|
|
43
45
|
- **`pi`**: Builds on the actual Raspberry Pi via SSH - slower but guaranteed to work
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
// msger-native build configuration (JSONC — comments stripped before parse).
|
|
2
|
+
// Each platform flag toggles whether that target is built/synced; defaults are
|
|
3
|
+
// conservative so a fresh checkout only builds the local Windows binary.
|
|
1
4
|
{
|
|
2
5
|
"platforms": {
|
|
3
|
-
"windows": true,
|
|
4
|
-
"wsl": false,
|
|
5
|
-
"pi": false,
|
|
6
|
-
"arm64": false
|
|
6
|
+
"windows": true, // Native build on Windows via cargo (msgernative.exe)
|
|
7
|
+
"wsl": false, // Cross-build Linux x64 via WSL (msgernative-linux)
|
|
8
|
+
"pi": false, // Remote SSH build on a Raspberry Pi (msgernative-linux-aarch64)
|
|
9
|
+
"arm64": false, // Cross-compile Linux ARM64 via WSL (msgernative-linux-aarch64)
|
|
10
|
+
"mac": false // Sync mac/msgernative-darwin-{arm64,x64} into bin/ at publish time
|
|
11
|
+
// (Mac binaries are produced on a Mac via mac/build-mac.sh)
|
|
7
12
|
},
|
|
8
13
|
"options": {
|
|
9
|
-
"release": true,
|
|
10
|
-
"verbose": true,
|
|
11
|
-
"piHost": "pi4c",
|
|
12
|
-
"piProjectPath": "/home/pi/msger/msger-native"
|
|
14
|
+
"release": true, // cargo --release (optimized) vs debug
|
|
15
|
+
"verbose": true, // Stream cargo output instead of capturing
|
|
16
|
+
"piHost": "pi4c", // SSH host alias for the `pi` platform
|
|
17
|
+
"piProjectPath": "/home/pi/msger/msger-native" // Where source is staged on the Pi
|
|
13
18
|
}
|
|
14
19
|
}
|
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
* msger-native WSL builder — delegates to @bobfrankston/rust-builder
|
|
4
4
|
* Run this directly inside WSL: node builder/build-under-wsl.ts
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { build, type BuildConfig } from "@bobfrankston/rust-builder";
|
|
7
7
|
import path from "path";
|
|
8
|
+
import fs from "fs";
|
|
8
9
|
import { fileURLToPath } from "url";
|
|
10
|
+
import JSON5 from "json5";
|
|
9
11
|
|
|
10
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
13
|
const nativeDir = path.join(__dirname, "..");
|
|
12
14
|
const binDir = path.join(nativeDir, "bin");
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
binDir
|
|
19
|
-
);
|
|
16
|
+
// build-config.json may contain comments — parse with json5 instead of using
|
|
17
|
+
// rust-builder's loadConfig (which is strict JSON-only).
|
|
18
|
+
const json = JSON5.parse(fs.readFileSync(path.join(__dirname, "build-config.json"), "utf-8"));
|
|
19
|
+
const config: BuildConfig = { binaryName: "msgernative", cargoDir: nativeDir, binDir, ...json };
|
|
20
20
|
|
|
21
21
|
// Only build WSL targets when running inside WSL
|
|
22
22
|
config.platforms.windows = false;
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* msger-native builder — delegates to @bobfrankston/rust-builder
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { build, type BuildConfig } from "@bobfrankston/rust-builder";
|
|
6
6
|
import path from "path";
|
|
7
|
+
import fs from "fs";
|
|
7
8
|
import { fileURLToPath } from "url";
|
|
9
|
+
import JSON5 from "json5";
|
|
8
10
|
|
|
9
11
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
12
|
const nativeDir = path.join(__dirname, "..");
|
|
11
13
|
const binDir = path.join(nativeDir, "bin");
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
binDir
|
|
18
|
-
);
|
|
15
|
+
// build-config.json may contain comments — parse with json5 instead of using
|
|
16
|
+
// rust-builder's loadConfig (which is strict JSON-only).
|
|
17
|
+
const json = JSON5.parse(fs.readFileSync(path.join(__dirname, "build-config.json"), "utf-8"));
|
|
18
|
+
const config: BuildConfig = { binaryName: "msgernative", cargoDir: nativeDir, binDir, ...json };
|
|
19
19
|
|
|
20
20
|
// msger-specific: copy icons
|
|
21
21
|
config.options = config.options || {};
|
|
@@ -27,7 +27,11 @@ if (isWindows) {
|
|
|
27
27
|
baseName = "msgernative";
|
|
28
28
|
ext = ".exe";
|
|
29
29
|
} else if (process.platform === "darwin") {
|
|
30
|
-
|
|
30
|
+
// Mac binaries use explicit darwin names so they don't collide with the
|
|
31
|
+
// Pi (`msgernative-arm64`) or generic Linux ARM (`msgernative-linux-aarch64`)
|
|
32
|
+
// binaries. Built on a Mac via build-mac.sh, synced via OneDrive's `mac/`,
|
|
33
|
+
// copied into bin/ at prepublishOnly time.
|
|
34
|
+
baseName = arch === "arm64" ? "msgernative-darwin-arm64" : "msgernative-darwin-x64";
|
|
31
35
|
ext = "";
|
|
32
36
|
} else {
|
|
33
37
|
baseName = arch === "arm64" ? "msgernative-linux-aarch64" : "msgernative";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/msger",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.358",
|
|
4
4
|
"description": "Fast, lightweight, cross-platform message box - Rust-powered alternative to msgview",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"clean": "node msger-native/builder/clean.ts",
|
|
22
22
|
"test": "node test.js",
|
|
23
23
|
"postinstall": "node msger-native/builder/postinstall.js",
|
|
24
|
-
"
|
|
24
|
+
"prep:mac": "node prep-mac-source.js",
|
|
25
|
+
"prepublishOnly": "node sync-mac-binary.js && npm run build:ts && npm run build:native",
|
|
25
26
|
"prerelease:local": "git add -A && (git diff-index --quiet HEAD || git commit -m \"Pre-release commit\")",
|
|
26
27
|
"preversion": "npm run build:ts && npm run build:native && git add -A",
|
|
27
28
|
"release": "npm run prerelease:local && npm version patch && npm publish --quiet",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* prep-mac-source.js — copy `msger-native/` Rust source into `mac/msger-native/`
|
|
4
|
+
* so the Mac (which sees `mac/` via OneDrive) has source to build from.
|
|
5
|
+
*
|
|
6
|
+
* Run from Windows whenever the Rust source changes and you want the Mac to
|
|
7
|
+
* pick it up on its next `./build-mac.sh`. Idempotent — only copies files that
|
|
8
|
+
* are missing or newer.
|
|
9
|
+
*
|
|
10
|
+
* Excludes `target/` (build output, gigabytes), `pibuild/` (Pi-specific),
|
|
11
|
+
* and the existing `bin/` (Linux/Windows binaries — Mac doesn't need them).
|
|
12
|
+
*/
|
|
13
|
+
import fs from "fs";
|
|
14
|
+
import path from "path";
|
|
15
|
+
import { fileURLToPath } from "url";
|
|
16
|
+
|
|
17
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
const srcDir = path.join(__dirname, "msger-native");
|
|
19
|
+
const dstDir = path.join(__dirname, "mac", "msger-native");
|
|
20
|
+
|
|
21
|
+
const SKIP_DIRS = new Set(["target", "pibuild", "bin", "node_modules", ".git"]);
|
|
22
|
+
|
|
23
|
+
if (!fs.existsSync(srcDir)) {
|
|
24
|
+
console.error(`✗ msger-native/ not found at ${srcDir}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
if (!fs.existsSync(path.dirname(dstDir))) {
|
|
28
|
+
console.error(`✗ mac/ not found — make sure the OneDrive junction is in place`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let copied = 0;
|
|
33
|
+
let skipped = 0;
|
|
34
|
+
|
|
35
|
+
function copyDir(src, dst) {
|
|
36
|
+
fs.mkdirSync(dst, { recursive: true });
|
|
37
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
38
|
+
const srcPath = path.join(src, entry.name);
|
|
39
|
+
const dstPath = path.join(dst, entry.name);
|
|
40
|
+
if (entry.isDirectory()) {
|
|
41
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
42
|
+
copyDir(srcPath, dstPath);
|
|
43
|
+
} else if (entry.isFile()) {
|
|
44
|
+
const srcMtime = fs.statSync(srcPath).mtimeMs;
|
|
45
|
+
const dstMtime = fs.existsSync(dstPath) ? fs.statSync(dstPath).mtimeMs : 0;
|
|
46
|
+
if (dstMtime >= srcMtime) {
|
|
47
|
+
skipped++;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
fs.copyFileSync(srcPath, dstPath);
|
|
51
|
+
copied++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
copyDir(srcDir, dstDir);
|
|
57
|
+
|
|
58
|
+
console.log(` msger: prep:mac — ${copied} file(s) copied, ${skipped} unchanged`);
|
|
59
|
+
console.log(` msger: source staged at mac/msger-native/. OneDrive will sync to the Mac;`);
|
|
60
|
+
console.log(` msger: then run \`./build-mac.sh\` from the OneDrive folder on the Mac.`);
|
package/shower.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export interface MessageBoxOptions {
|
|
|
39
39
|
reset?: boolean; /** Clear localStorage on startup (default: false) */
|
|
40
40
|
icon?: string; /** Path to window icon. Decoded for the runtime title-bar / taskbar icon. PNG decodes most reliably; the `image` crate's ICO+PNG path is fragile. */
|
|
41
41
|
relaunchIcon?: string; /** Optional path forwarded to `PKEY_AppUserModel_RelaunchIconResource` so pinned taskbar shortcuts get the app's own icon. Must be a `.ico`. Path is consumed verbatim (no decode). */
|
|
42
|
+
relaunchCommand?: string; /** Command Windows runs when the user clicks the pinned shortcut (`PKEY_AppUserModel_RelaunchCommand`). Critical for msger-hosted apps: without it, the pin captures the bare `mailx.exe` (a webview host that expects JSON stdin) and clicking it does nothing. */
|
|
43
|
+
relaunchDisplayName?: string; /** Display name for the pinned shortcut (`PKEY_AppUserModel_RelaunchDisplayNameResource`). */
|
|
42
44
|
dev?: boolean; /** Open DevTools automatically on startup (default: false) */
|
|
43
45
|
debug?: boolean; /** Return debug information (HTML, size) in result (default: false) */
|
|
44
46
|
showVersion?: boolean; /** Show version in window title (default: false) */
|
package/shower.js
CHANGED
|
@@ -89,11 +89,24 @@ function getUserBinDir() { return getUserBinDirFor(_appName); }
|
|
|
89
89
|
* bundled binary. Returns null only if msger truly isn't installed. */
|
|
90
90
|
function findMsgerSource() {
|
|
91
91
|
const isWindows = platform() === 'win32';
|
|
92
|
+
const isDarwin = platform() === 'darwin';
|
|
92
93
|
const arch = process.arch;
|
|
93
94
|
const ext = isWindows ? '.exe' : '';
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
let baseName;
|
|
96
|
+
if (isWindows) {
|
|
97
|
+
baseName = 'msgernative';
|
|
98
|
+
}
|
|
99
|
+
else if (isDarwin) {
|
|
100
|
+
// Mac binaries are built infrequently on a Mac and synced via OneDrive.
|
|
101
|
+
// Names are explicit so they don't collide with the Pi/Linux ARM binaries.
|
|
102
|
+
baseName = arch === 'arm64' ? 'msgernative-darwin-arm64' : 'msgernative-darwin-x64';
|
|
103
|
+
}
|
|
104
|
+
else if (arch === 'arm64') {
|
|
105
|
+
baseName = 'msgernative-linux-aarch64';
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
baseName = 'msgernative';
|
|
109
|
+
}
|
|
97
110
|
const msgerBin = getUserBinDirFor('msger');
|
|
98
111
|
const pkgBin = path.join(import.meta.dirname, 'msger-native', 'bin');
|
|
99
112
|
const stable = path.join(msgerBin, `${baseName}${ext}`);
|
|
@@ -276,6 +289,7 @@ function provisionAppIcon(perAppDir) {
|
|
|
276
289
|
* own taskbar identity. */
|
|
277
290
|
function resolveBinaryPath() {
|
|
278
291
|
const isWindows = platform() === 'win32';
|
|
292
|
+
const isDarwin = platform() === 'darwin';
|
|
279
293
|
const arch = process.arch;
|
|
280
294
|
const pkgBinDir = path.join(import.meta.dirname, 'msger-native', 'bin');
|
|
281
295
|
const userBinDir = getUserBinDir();
|
|
@@ -285,6 +299,10 @@ function resolveBinaryPath() {
|
|
|
285
299
|
baseName = 'msgernative';
|
|
286
300
|
ext = '.exe';
|
|
287
301
|
}
|
|
302
|
+
else if (isDarwin) {
|
|
303
|
+
baseName = arch === 'arm64' ? 'msgernative-darwin-arm64' : 'msgernative-darwin-x64';
|
|
304
|
+
ext = '';
|
|
305
|
+
}
|
|
288
306
|
else if (arch === 'arm64') {
|
|
289
307
|
baseName = 'msgernative-linux-aarch64';
|
|
290
308
|
ext = '';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* sync-mac-binary.js — copy Mac binaries from the OneDrive-synced `mac/`
|
|
4
|
+
* staging area into `msger-native/bin/` so they ship in the next npm publish.
|
|
5
|
+
*
|
|
6
|
+
* Workflow:
|
|
7
|
+
* - On a Mac: run `build-mac.sh`. It compiles, ad-hoc codesigns, and drops
|
|
8
|
+
* the binary into `mac/msgernative-darwin-{arm64,x64}`.
|
|
9
|
+
* - OneDrive syncs that file back to Windows.
|
|
10
|
+
* - This script (run by `prepublishOnly`) copies it into `msger-native/bin/`.
|
|
11
|
+
*
|
|
12
|
+
* Gated by `platforms.mac` in builder/build-config.json (parallel to `pi`).
|
|
13
|
+
* Skipped entirely when false so a publish doesn't refresh Mac binaries — useful
|
|
14
|
+
* when no Mac is available, or to avoid pulling in a stale OneDrive copy.
|
|
15
|
+
*
|
|
16
|
+
* Tolerant of a missing `mac/` or missing binaries — Mac is built rarely, and
|
|
17
|
+
* a publish without a current Mac binary is fine. Mac users on that version
|
|
18
|
+
* will get a clear "Binary not found" error and can flag it for a rebuild.
|
|
19
|
+
*/
|
|
20
|
+
import fs from "fs";
|
|
21
|
+
import path from "path";
|
|
22
|
+
import { fileURLToPath } from "url";
|
|
23
|
+
import JSON5 from "json5";
|
|
24
|
+
|
|
25
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
const macDir = path.join(__dirname, "mac");
|
|
27
|
+
const binDir = path.join(__dirname, "msger-native", "bin");
|
|
28
|
+
const configPath = path.join(__dirname, "msger-native", "builder", "build-config.json");
|
|
29
|
+
|
|
30
|
+
// build-config.json may contain comments — use json5 (already a msger dep).
|
|
31
|
+
const config = JSON5.parse(fs.readFileSync(configPath, "utf-8"));
|
|
32
|
+
if (!config.platforms?.mac) {
|
|
33
|
+
console.log(" msger: platforms.mac=false in build-config.json — skipping Mac binary sync");
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const targets = ["msgernative-darwin-arm64", "msgernative-darwin-x64"];
|
|
38
|
+
|
|
39
|
+
if (!fs.existsSync(macDir)) {
|
|
40
|
+
console.log(" msger: no mac/ staging dir — skipping Mac binary sync");
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let copied = 0;
|
|
45
|
+
let skipped = 0;
|
|
46
|
+
for (const name of targets) {
|
|
47
|
+
const src = path.join(macDir, name);
|
|
48
|
+
const dst = path.join(binDir, name);
|
|
49
|
+
if (!fs.existsSync(src)) continue;
|
|
50
|
+
|
|
51
|
+
const srcMtime = fs.statSync(src).mtimeMs;
|
|
52
|
+
const dstMtime = fs.existsSync(dst) ? fs.statSync(dst).mtimeMs : 0;
|
|
53
|
+
if (dstMtime >= srcMtime) {
|
|
54
|
+
console.log(` msger: ${name} already current in bin/`);
|
|
55
|
+
skipped++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
fs.copyFileSync(src, dst);
|
|
61
|
+
fs.chmodSync(dst, 0o755);
|
|
62
|
+
const sizeMB = (fs.statSync(dst).size / 1024 / 1024).toFixed(1);
|
|
63
|
+
console.log(` msger: synced ${name} (${sizeMB} MB) → bin/`);
|
|
64
|
+
copied++;
|
|
65
|
+
} catch (e) {
|
|
66
|
+
console.error(` msger: failed to sync ${name}: ${e.message}`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (copied === 0 && skipped === 0) {
|
|
72
|
+
console.log(" msger: no Mac binaries in mac/ — Mac users will get \"Binary not found\" until you build one");
|
|
73
|
+
}
|