create-crossbind 2.0.0-beta.64 → 2.0.0-beta.66

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 (29) hide show
  1. package/package.json +1 -1
  2. package/src/manifest.json +8 -0
  3. package/templates/backend-nodejs-native/package.json +3 -3
  4. package/templates/backend-nodejs-standalone/package.json +1 -1
  5. package/templates/backend-nodejs-wasm/package.json +2 -2
  6. package/templates/cloud-cloudflare-worker/package.json +1 -1
  7. package/templates/desktop-app/README.md +106 -0
  8. package/templates/desktop-app/_gitignore +3 -0
  9. package/templates/desktop-app/crossbind.config.js +17 -0
  10. package/templates/desktop-app/e2e/run.mjs +60 -0
  11. package/templates/desktop-app/index.html +11 -0
  12. package/templates/desktop-app/package.json +38 -0
  13. package/templates/desktop-app/src/main.js +15 -0
  14. package/templates/desktop-app/src/native/native.cpp +9 -0
  15. package/templates/desktop-app/src/native/native.h +12 -0
  16. package/templates/desktop-app/vite.config.js +6 -0
  17. package/templates/desktop-electron/package.json +3 -3
  18. package/templates/lib-cmake/package.json +1 -1
  19. package/templates/lib-prebuilt/package.json +2 -2
  20. package/templates/lib-source/package.json +1 -1
  21. package/templates/mobile-reactnative-cli/package.json +15 -15
  22. package/templates/mobile-reactnative-expo/package-lock.json +213 -352
  23. package/templates/mobile-reactnative-expo/package.json +6 -6
  24. package/templates/native-executable/package.json +2 -2
  25. package/templates/web-react-rspack/package.json +3 -3
  26. package/templates/web-react-vite/package.json +2 -2
  27. package/templates/web-svelte-vite/package.json +2 -2
  28. package/templates/web-vanilla/package.json +2 -2
  29. package/templates/web-vue-vite/package.json +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-crossbind",
3
- "version": "2.0.0-beta.64",
3
+ "version": "2.0.0-beta.66",
4
4
  "description": "Create crossbind Applications",
5
5
  "homepage": "https://github.com/crossbind/crossbind/tree/main/tooling/create-app#readme",
6
6
  "repository": {
package/src/manifest.json CHANGED
@@ -59,6 +59,14 @@
59
59
  "nativeFolders": false,
60
60
  "keepLockfile": true
61
61
  },
62
+ {
63
+ "key": "desktop-app",
64
+ "group": "Desktop",
65
+ "framework": null,
66
+ "label": "App",
67
+ "kind": "app",
68
+ "source": "examples/desktop-app"
69
+ },
62
70
  {
63
71
  "key": "desktop-electron",
64
72
  "group": "Desktop",
@@ -12,11 +12,11 @@
12
12
  "e2e:prod": "node e2e/run.mjs"
13
13
  },
14
14
  "dependencies": {
15
- "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.64"
15
+ "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.66"
16
16
  },
17
17
  "devDependencies": {
18
- "@crossbind/core-embind-napi": "^2.0.0-beta.64",
19
- "crossbind": "^2.0.0-beta.64"
18
+ "@crossbind/core-embind-napi": "^2.0.0-beta.66",
19
+ "crossbind": "^2.0.0-beta.66"
20
20
  },
21
21
  "keywords": [
22
22
  "crossbind-sample",
@@ -11,7 +11,7 @@
11
11
  "e2e:prod": "node e2e/run.mjs"
12
12
  },
13
13
  "dependencies": {
14
- "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.64"
14
+ "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.66"
15
15
  },
16
16
  "keywords": [
17
17
  "crossbind-sample",
@@ -10,10 +10,10 @@
10
10
  "build": "crossbind build -p wasm -a wasm32 -r st -e node -b release"
11
11
  },
12
12
  "dependencies": {
13
- "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.64"
13
+ "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.66"
14
14
  },
15
15
  "devDependencies": {
16
- "crossbind": "^2.0.0-beta.64"
16
+ "crossbind": "^2.0.0-beta.66"
17
17
  },
18
18
  "keywords": [
19
19
  "crossbind-sample",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "dependencies": {},
25
25
  "devDependencies": {
26
- "crossbind": "^2.0.0-beta.64",
26
+ "crossbind": "^2.0.0-beta.66",
27
27
  "wrangler": "^4.136.3",
28
28
  "@playwright/test": "^1.63.0"
29
29
  },
@@ -0,0 +1,106 @@
1
+ # @crossbind/example-desktop-app
2
+ **crossbind desktop app sample**
3
+
4
+ A macOS, Linux, Windows, iOS and Android app whose page runs in the system webview and whose C++ runs natively in the
5
+ app: crossbind builds `src/native` and the matrix library into the app's own host, and the page calls it with the same
6
+ `initNative()` and awaited calls as a web build that runs its module in a worker. There is no Node.js and no browser
7
+ engine in the app; the page uses the system's own, WKWebView on macOS and iOS, WebKitGTK on Linux, WebView2 on
8
+ Windows and Android System WebView on Android.
9
+
10
+ # Getting Started
11
+
12
+ >**Note**: Make sure you have completed the [crossbind - Prerequisites](https://crossbind.dev/docs/guide/getting-started/prerequisites) instructions.
13
+ Apps build on macOS with Xcode's command line tools, iOS apps with Xcode and its iOS platform, and Linux, Windows and
14
+ Android apps in crossbind's linux, windows and android-app images, which carry everything they build with; the
15
+ bindings are generated in Docker. A macOS or iOS build fetches React Native's Hermes once into `~/.crossbind/hermes`.
16
+
17
+ ## Setup
18
+
19
+ Install the dependencies:
20
+
21
+ ```bash
22
+ pnpm install
23
+ ```
24
+
25
+ Inside the crossbind repository, build the library's archives first:
26
+ `pnpm --filter @crossbind/example-lib-prebuilt-matrix run build:desktop`, `run build:ios` for the iOS app and
27
+ `run build:android` for the Android app.
28
+
29
+ ## Get Started
30
+
31
+ ```bash
32
+ pnpm dev
33
+ ```
34
+
35
+ opens the app on Vite's dev server: edits to the page reload it, edits to the C++ rebuild the app and open it again,
36
+ and the page's console shows in the terminal. Closing the window ends the session.
37
+
38
+ ## Build
39
+
40
+ ```bash
41
+ pnpm build
42
+ ```
43
+
44
+ writes the app to `dist/crossbind-example-desktop-app.app`, signed ad hoc, so it opens on the Mac that built it, and
45
+ its disk image beside it; a Developer ID and an App Store Connect API key in the environment sign it for every Mac
46
+ (see `docs/api/app.md`). On Linux it writes `dist/crossbind-example-desktop-app-linux-<arch>/`, the same as a
47
+ `.tar.gz`, which runs where WebKitGTK 4.1 is installed (`libwebkit2gtk-4.1-0` on Debian and Ubuntu), and a `.deb`
48
+ that installs it with WebKitGTK.
49
+
50
+ ```bash
51
+ pnpm build:linux
52
+ ```
53
+
54
+ writes the Linux app for x64 and arm64, on a Mac as well.
55
+
56
+ ```bash
57
+ pnpm build:windows
58
+ ```
59
+
60
+ writes the Windows app for x64 and arm64, on a Mac or Linux as well: `dist/crossbind-example-desktop-app-win32-<arch>/`,
61
+ the same as a `.zip`, which runs where the WebView2 Runtime is installed, as on Windows 11, and a `-setup.exe` that
62
+ installs it, with the runtime where Windows has none; a signing key in the environment signs both (see
63
+ `docs/api/app.md`).
64
+
65
+ ## iOS
66
+
67
+ ```bash
68
+ pnpm dev:ios
69
+ ```
70
+
71
+ opens the app in the iOS Simulator on Vite's dev server, as `pnpm dev` does on the desktop; ending the app in the
72
+ Simulator ends the session.
73
+
74
+ ```bash
75
+ pnpm build:ios
76
+ ```
77
+
78
+ writes the app's Xcode project to `dist/crossbind-example-desktop-app-ios/`. Open it in Xcode to run the app on an
79
+ iPhone, once `crossbind.config.js` names the app's bundle id and Apple team (`app: { id, team }`).
80
+
81
+ ## Android
82
+
83
+ ```bash
84
+ pnpm dev:android
85
+ ```
86
+
87
+ opens the app on the attached Android device or the running emulator on Vite's dev server, as `pnpm dev` does on the
88
+ desktop; ending the app ends the session. Start an emulator first, in Android Studio's Device Manager, or connect a
89
+ phone with USB debugging on. crossbind reaches it with the machine's `adb` (`brew install --cask
90
+ android-platform-tools` on macOS, `sudo apt install adb` on Debian and Ubuntu, or Android Studio's).
91
+
92
+ ```bash
93
+ pnpm build:android
94
+ ```
95
+
96
+ writes `dist/crossbind-example-desktop-app-android.apk`, signed with this machine's debug key, which `adb install`
97
+ puts on a device. With `CROSSBIND_ANDROID_KEYSTORE`, `CROSSBIND_ANDROID_KEY_ALIAS` and
98
+ `CROSSBIND_ANDROID_KEYSTORE_PASSWORD` set to Google Play's upload key, the APK is signed with it and
99
+ `dist/crossbind-example-desktop-app-android.aab` is the bundle Google Play takes. Gradle runs in Docker, so no JDK or
100
+ Android SDK is needed; the Gradle project it builds stays in `dist/crossbind-example-desktop-app-android/`.
101
+
102
+ ## Test
103
+
104
+ `pnpm run e2e:prod` opens the built app and waits for the page to log the result; with `CROSSBIND_APP_PLATFORM=ios` it
105
+ builds the Xcode project for the Simulator and opens the app there, and with `android` it builds the Gradle project as
106
+ a debug APK and opens the app on the attached device.
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ .crossbind
3
+ dist
@@ -0,0 +1,17 @@
1
+ import Matrix from '@crossbind/example-lib-prebuilt-matrix/crossbind.config.js';
2
+
3
+ export default {
4
+ general: {
5
+ name: 'crossbind-example-desktop-app',
6
+ },
7
+ dependencies: [
8
+ Matrix,
9
+ ],
10
+ // The page runs in the system webview and the C++ in the app's own process.
11
+ target: {
12
+ runtimeEnv: 'app',
13
+ },
14
+ paths: {
15
+ config: import.meta.url,
16
+ },
17
+ };
@@ -0,0 +1,60 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { resolve } from 'node:path';
4
+ import config from '../crossbind.config.js';
5
+
6
+ // Opens the app `pnpm build` made and waits for its page to log what the C++ returned. With CROSSBIND_APP_PLATFORM=ios
7
+ // the app is the Xcode project `pnpm build:ios` made, built and opened in the Simulator, and with android the Gradle
8
+ // project `pnpm build:android` made, built and opened on the attached device.
9
+ // A cold Simulator on a CI runner can take over a minute to show the page.
10
+ const RUN_TIMEOUT_MS = 300000;
11
+ const EXPECTED = 'Matrix multiplier with c++ => J₃ * (2*J₃) = 6*J₃';
12
+
13
+ const root = resolve(import.meta.dirname, '..');
14
+ const { name } = config.general;
15
+ const env = { CROSSBIND_APP_CONSOLE: '1' };
16
+
17
+ function missing(file) {
18
+ console.error(`FAIL: ${file} is missing - run \`pnpm build\` first.`);
19
+ process.exit(1);
20
+ }
21
+
22
+ async function open() {
23
+ const platform = process.env.CROSSBIND_APP_PLATFORM;
24
+ if (platform) {
25
+ const project = `${root}/dist/${name}-${platform}`;
26
+ if (!existsSync(project)) missing(project);
27
+ const { buildForSimulator, openInSimulator, buildApk, openOnDevice } = await import('crossbind');
28
+ return platform === 'ios' ? openInSimulator(buildForSimulator(project), { env }) : openOnDevice(buildApk(project), { env });
29
+ }
30
+ // A macOS app is a bundle; a Linux or Windows app a directory named after its platform and arch.
31
+ const executable = process.platform === 'darwin'
32
+ ? `${root}/dist/${name}.app/Contents/MacOS/${name}`
33
+ : `${root}/dist/${name}-${process.platform}-${process.arch}/${name}${process.platform === 'win32' ? '.exe' : ''}`;
34
+ if (!existsSync(executable)) missing(executable);
35
+ return { child: spawn(executable, [], { env: { ...process.env, ...env } }), close: () => {} };
36
+ }
37
+
38
+ let out = '';
39
+ const { child: app, close } = await open();
40
+
41
+ function finish(problem) {
42
+ clearTimeout(timer);
43
+ close();
44
+ app.kill();
45
+ if (problem) {
46
+ console.error(`FAIL: ${problem}:\n${out}`);
47
+ process.exit(1);
48
+ }
49
+ console.log(`ok: ${EXPECTED}`);
50
+ process.exit(0);
51
+ }
52
+
53
+ const timer = setTimeout(() => finish('the page did not log the result in time'), RUN_TIMEOUT_MS);
54
+ const read = (chunk) => {
55
+ out += chunk;
56
+ if (out.includes(EXPECTED)) finish();
57
+ };
58
+ app.stdout.on('data', read);
59
+ app.stderr.on('data', read);
60
+ app.on('exit', (code) => finish(`the app exited with ${code} before the page logged the result`));
@@ -0,0 +1,11 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>crossbind desktop app sample</title>
6
+ </head>
7
+ <body>
8
+ <p>Matrix multiplier with c++ =&gt; <span id="cppMessage">loading ...</span></p>
9
+ <script type="module" src="/src/main.js"></script>
10
+ </body>
11
+ </html>
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@crossbind/example-desktop-app",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "description": "crossbind - desktop app sample",
6
+ "homepage": "https://github.com/crossbind/crossbind/tree/main/examples/desktop-app#readme",
7
+ "repository": "https://github.com/crossbind/crossbind.git",
8
+ "license": "MIT",
9
+ "type": "module",
10
+ "scripts": {
11
+ "dev": "crossbind app dev",
12
+ "dev:ios": "crossbind app dev -p ios",
13
+ "dev:android": "crossbind app dev -p android",
14
+ "build": "crossbind app build",
15
+ "build:linux": "crossbind app build -p linux",
16
+ "build:windows": "crossbind app build -p windows",
17
+ "build:ios": "crossbind app build -p ios",
18
+ "build:android": "crossbind app build -p android",
19
+ "e2e:prod": "node e2e/run.mjs"
20
+ },
21
+ "dependencies": {
22
+ "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.66"
23
+ },
24
+ "devDependencies": {
25
+ "@crossbind/core-app-host": "^2.0.0-beta.66",
26
+ "@crossbind/plugin-vite": "^2.0.0-beta.66",
27
+ "crossbind": "^2.0.0-beta.66",
28
+ "vite": "^8.2.1"
29
+ },
30
+ "keywords": [
31
+ "crossbind-sample",
32
+ "desktop",
33
+ "app",
34
+ "webview",
35
+ "c++",
36
+ "vite"
37
+ ]
38
+ }
@@ -0,0 +1,15 @@
1
+ import { initNative, Native } from './native/native.h';
2
+
3
+ const message = document.querySelector('#cppMessage');
4
+
5
+ initNative()
6
+ .then(() => Native.sample())
7
+ .then((result) => {
8
+ message.textContent = result;
9
+ // During development the page's console shows in the terminal that runs `pnpm dev`.
10
+ console.log(`Matrix multiplier with c++ => ${result}`);
11
+ })
12
+ .catch((error) => {
13
+ message.textContent = error.message;
14
+ console.error(error);
15
+ });
@@ -0,0 +1,9 @@
1
+ #include "native.h"
2
+ #include <Matrix.h>
3
+
4
+ std::string Native::sample() {
5
+ auto firstMatrix = std::make_shared<Matrix>(9, 1);
6
+ auto secondMatrix = std::make_shared<Matrix>(9, 2);
7
+ auto resultStr = std::to_string(firstMatrix->multiple(secondMatrix)->get(0));
8
+ return "J₃ * (2*J₃) = " + resultStr + "*J₃";
9
+ }
@@ -0,0 +1,12 @@
1
+ #ifndef _NATIVE_H
2
+ #define _NATIVE_H
3
+
4
+ #include <string>
5
+ #include <memory>
6
+
7
+ class Native {
8
+ public:
9
+ static std::string sample();
10
+ };
11
+
12
+ #endif
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from 'vite';
2
+ import viteCrossbindPlugin from '@crossbind/plugin-vite';
3
+
4
+ export default defineConfig({
5
+ plugins: [viteCrossbindPlugin()],
6
+ });
@@ -16,10 +16,10 @@
16
16
  "e2e:prod": "electron-builder --dir && playwright test --project=packaged"
17
17
  },
18
18
  "devDependencies": {
19
- "@crossbind/core-embind-napi": "^2.0.0-beta.64",
20
- "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.64",
19
+ "@crossbind/core-embind-napi": "^2.0.0-beta.66",
20
+ "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.66",
21
21
  "@playwright/test": "^1.63.0",
22
- "crossbind": "^2.0.0-beta.64",
22
+ "crossbind": "^2.0.0-beta.66",
23
23
  "electron": "^44.5.1",
24
24
  "electron-builder": "^26.15.3"
25
25
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossbind/example-lib-cmake",
3
- "version": "2.0.0-beta.64",
3
+ "version": "2.0.0-beta.66",
4
4
  "description": "crossbind sample library: simple cmake library",
5
5
  "homepage": "https://github.com/crossbind/crossbind/tree/main/examples/lib-cmake#readme",
6
6
  "repository": "https://github.com/crossbind/crossbind.git",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossbind/example-lib-prebuilt-matrix",
3
- "version": "2.0.0-beta.64",
3
+ "version": "2.0.0-beta.66",
4
4
  "description": "crossbind sample prebuilt library: matrix multiplier",
5
5
  "homepage": "https://github.com/crossbind/crossbind/tree/main/examples/lib-prebuilt-matrix#readme",
6
6
  "repository": "https://github.com/crossbind/crossbind.git",
@@ -18,7 +18,7 @@
18
18
  "prepublishOnly": "crossbind build"
19
19
  },
20
20
  "devDependencies": {
21
- "crossbind": "^2.0.0-beta.64"
21
+ "crossbind": "^2.0.0-beta.66"
22
22
  },
23
23
  "keywords": [
24
24
  "crossbind-sample",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossbind/example-lib-source",
3
- "version": "2.0.0-beta.64",
3
+ "version": "2.0.0-beta.66",
4
4
  "description": "crossbind sample library: simple source library",
5
5
  "homepage": "https://github.com/crossbind/crossbind/tree/main/examples/lib-source#readme",
6
6
  "repository": "https://github.com/crossbind/crossbind.git",
@@ -20,12 +20,12 @@
20
20
  "e2e:android": "pnpm run run:android && pnpm run maestro:android"
21
21
  },
22
22
  "dependencies": {
23
- "@crossbind/core-embind-jsi": "^2.0.0-beta.64",
24
- "@crossbind/plugin-react-native": "^2.0.0-beta.64",
25
- "@crossbind/plugin-react-native-ios-helper": "^2.0.0-beta.64",
26
- "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.64",
27
- "react": "19.3.0",
28
- "react-native": "0.87.1",
23
+ "@crossbind/core-embind-jsi": "^2.0.0-beta.66",
24
+ "@crossbind/plugin-react-native": "^2.0.0-beta.66",
25
+ "@crossbind/plugin-react-native-ios-helper": "^2.0.0-beta.66",
26
+ "@crossbind/example-lib-prebuilt-matrix": "^2.0.0-beta.66",
27
+ "react": "19.3.1",
28
+ "react-native": "0.88.0",
29
29
  "react-native-safe-area-context": "^5.8.0",
30
30
  "hermes-compiler": "250829098.0.17"
31
31
  },
@@ -36,22 +36,22 @@
36
36
  "@react-native-community/cli": "20.2.0",
37
37
  "@react-native-community/cli-platform-android": "20.2.0",
38
38
  "@react-native-community/cli-platform-ios": "20.2.0",
39
- "@react-native/babel-preset": "0.87.1",
40
- "@react-native/codegen": "0.87.1",
41
- "@react-native/eslint-config": "0.87.1",
42
- "@react-native/jest-preset": "0.87.1",
43
- "@react-native/gradle-plugin": "0.87.1",
44
- "@react-native/metro-config": "0.87.1",
45
- "@react-native/typescript-config": "0.87.1",
39
+ "@react-native/babel-preset": "0.88.0",
40
+ "@react-native/codegen": "0.88.0",
41
+ "@react-native/eslint-config": "0.88.0",
42
+ "@react-native/jest-preset": "0.88.0",
43
+ "@react-native/gradle-plugin": "0.88.0",
44
+ "@react-native/metro-config": "0.88.0",
45
+ "@react-native/typescript-config": "0.88.0",
46
46
  "@types/jest": "^29.5.13",
47
47
  "@types/react": "^19.3.0",
48
48
  "@types/react-test-renderer": "^19.3.0",
49
49
  "eslint": "^8.19.0",
50
50
  "jest": "^29.6.3",
51
51
  "prettier": "3.9.10",
52
- "react-test-renderer": "19.3.0",
52
+ "react-test-renderer": "19.3.1",
53
53
  "typescript": "^6.0.3",
54
- "@crossbind/plugin-metro": "^2.0.0-beta.64"
54
+ "@crossbind/plugin-metro": "^2.0.0-beta.66"
55
55
  },
56
56
  "engines": {
57
57
  "node": ">=24"