mirror of
https://github.com/EthanShoeDev/fressh.git
synced 2026-01-11 14:22:51 +00:00
Compare commits
18 Commits
0.0.1
...
@fressh/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f48e96a4f | ||
|
|
e8808bddfb | ||
|
|
242f26b383 | ||
|
|
de963a9d64 | ||
|
|
ec3876ac3a | ||
|
|
64d385038c | ||
|
|
57765da5e8 | ||
|
|
26c5bb8332 | ||
|
|
3a1893e08c | ||
|
|
49d4a667b9 | ||
|
|
fffc3b103c | ||
|
|
a3c2b67513 | ||
|
|
3acde79485 | ||
|
|
711335367e | ||
|
|
e4139c6f7b | ||
|
|
8e7ec01e28 | ||
|
|
0fc4481e82 | ||
|
|
fa2ad2708e |
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@@ -9,6 +9,7 @@
|
||||
"yoavbls.pretty-ts-errors",
|
||||
"ctf0.duplicated-code-new",
|
||||
"github.vscode-github-actions",
|
||||
"mkhl.direnv"
|
||||
"mkhl.direnv",
|
||||
"jnoortheen.nix-ide"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
"expo-font": "~14.0.8",
|
||||
"expo-glass-effect": "^0.1.4",
|
||||
"expo-haptics": "~15.0.7",
|
||||
"expo-image": "~3.0.8",
|
||||
"expo-image": "~3.0.9",
|
||||
"expo-linking": "~8.0.8",
|
||||
"expo-router": "6.0.10",
|
||||
"expo-secure-store": "~15.0.7",
|
||||
|
||||
@@ -467,6 +467,9 @@ type KeyboardToolbarButtonProps =
|
||||
| KeyboardToolbarModifierButtonProps
|
||||
| KeyboardToolbarInstantButtonProps;
|
||||
|
||||
const propsToKey = (props: KeyboardToolbarButtonProps) =>
|
||||
'label' in props ? props.label : props.iconName;
|
||||
|
||||
function KeyboardToolbarButton({
|
||||
style,
|
||||
...props
|
||||
@@ -487,7 +490,8 @@ function KeyboardToolbarButton({
|
||||
);
|
||||
|
||||
const modifierActive =
|
||||
props.type === 'modifier' && modifierKeysActive.includes(props);
|
||||
props.type === 'modifier' &&
|
||||
!!modifierKeysActive.find((m) => propsToKey(m) === propsToKey(props));
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
@@ -505,8 +509,10 @@ function KeyboardToolbarButton({
|
||||
onPress={() => {
|
||||
if (props.type === 'modifier') {
|
||||
setModifierKeysActive((modifierKeysActive) =>
|
||||
modifierKeysActive.includes(props)
|
||||
? modifierKeysActive.filter((m) => m !== props)
|
||||
modifierKeysActive.find((m) => propsToKey(m) === propsToKey(props))
|
||||
? modifierKeysActive.filter(
|
||||
(m) => propsToKey(m) !== propsToKey(props),
|
||||
)
|
||||
: [...modifierKeysActive, props],
|
||||
);
|
||||
return;
|
||||
|
||||
11
flake.nix
11
flake.nix
@@ -63,6 +63,8 @@
|
||||
fen.targets.armv7-linux-androideabi.stable.rust-std
|
||||
fen.targets.x86_64-linux-android.stable.rust-std
|
||||
fen.targets.i686-linux-android.stable.rust-std
|
||||
fen.targets.aarch64-apple-ios.stable.rust-std
|
||||
fen.targets.aarch64-apple-ios-sim.stable.rust-std
|
||||
];
|
||||
|
||||
defaultPkgs = with pkgs; [
|
||||
@@ -93,6 +95,11 @@
|
||||
clang-tools
|
||||
];
|
||||
|
||||
mkShellFn =
|
||||
if pkgs.stdenv.isDarwin
|
||||
then pkgs.mkShellNoCC
|
||||
else pkgs.mkShell;
|
||||
|
||||
ndkId = "27-1-12297006"; # nix flake show github:tadfisher/android-nixpkgs | grep ndk
|
||||
ndkAttr = "ndk-${ndkId}";
|
||||
ndkVer = builtins.replaceStrings ["-"] ["."] ndkId;
|
||||
@@ -218,13 +225,13 @@
|
||||
export PROMPT_COMMAND=". \"$FRESSH_STARSHIP_PREINIT\""
|
||||
'';
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
default = mkShellFn {
|
||||
packages = defaultPkgs ++ [remoteAndroidSdk.androidSdk];
|
||||
shellHook =
|
||||
commonAndroidInit remoteAndroidSdk.sdkRoot;
|
||||
};
|
||||
|
||||
android-emulator = pkgs.mkShell {
|
||||
android-emulator = mkShellFn {
|
||||
packages = defaultPkgs ++ [fullAndroidSdk.androidSdk];
|
||||
shellHook =
|
||||
commonAndroidInit fullAndroidSdk.sdkRoot;
|
||||
|
||||
33
packages/react-native-uniffi-russh/.npmignore
Normal file
33
packages/react-native-uniffi-russh/.npmignore
Normal file
@@ -0,0 +1,33 @@
|
||||
# Workspace caches
|
||||
.turbo/
|
||||
|
||||
# Node modules (npm excludes by default)
|
||||
node_modules/
|
||||
|
||||
# OS junk
|
||||
**/.DS_Store
|
||||
|
||||
# Platform build outputs and local config
|
||||
ios/build/
|
||||
android/build/
|
||||
android/gradle/
|
||||
android/gradlew
|
||||
android/gradlew.bat
|
||||
android/local.properties
|
||||
|
||||
# Tests and mocks
|
||||
**/__tests__/
|
||||
**/__fixtures__/
|
||||
**/__mocks__/
|
||||
|
||||
# Dotfiles and editors
|
||||
**/.*
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Coverage and logs
|
||||
coverage/
|
||||
*.log
|
||||
*.local
|
||||
|
||||
rust/target/
|
||||
@@ -29,7 +29,7 @@ export default {
|
||||
|
||||
hooks: {
|
||||
'before:init': ['turbo run lint:check'],
|
||||
'after:bump': ['turbo run build:android', 'turbo run build:ios'],
|
||||
'after:bump': ['turbo run build:android build:ios'],
|
||||
'after:release': 'echo "Published ${npm.name} v${version} to npm"',
|
||||
},
|
||||
} satisfies Config;
|
||||
|
||||
9
packages/react-native-uniffi-russh/CHANGELOG.md
Normal file
9
packages/react-native-uniffi-russh/CHANGELOG.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## [0.0.4](https://github.com/EthanShoeDev/fressh/compare/@fressh/react-native-uniffi-russh-v0.0.3...${npm.name}-v0.0.4) (2025-10-08)
|
||||
|
||||
## [0.0.3](https://github.com/EthanShoeDev/fressh/compare/@fressh/react-native-uniffi-russh-v0.0.2...${npm.name}-v0.0.3) (2025-10-08)
|
||||
|
||||
## 0.0.2 (2025-10-07)
|
||||
|
||||
## [0.0.1](https://github.com/EthanShoeDev/fressh/compare/@fressh/react-native-xtermjs-webview-v0.0.1...@fressh/react-native-xtermjs-webview-v0.0.4) (2025-10-07)
|
||||
@@ -16,11 +16,42 @@ Peer dependencies (you manage): `react`, `react-native`.
|
||||
### Usage
|
||||
|
||||
This package exposes a native Rust module for SSH transport. For a complete,
|
||||
working integration, see the example app in this monorepo at `apps/mobile`.
|
||||
working integration, see the example app:
|
||||
|
||||
- https://github.com/EthanShoeDev/fressh/tree/main/apps/mobile
|
||||
|
||||
### API overview
|
||||
|
||||
High-level API surface (see code for full types):
|
||||
|
||||
```ts
|
||||
import { RnRussh } from '@fressh/react-native-uniffi-russh';
|
||||
|
||||
await RnRussh.uniffiInitAsync();
|
||||
|
||||
const conn = await RnRussh.connect({
|
||||
host: 'example.com',
|
||||
port: 22,
|
||||
username: 'me',
|
||||
security: { type: 'password', password: '...' },
|
||||
onServerKey: async () => true,
|
||||
});
|
||||
|
||||
const shell = await conn.startShell({ term: 'Xterm' });
|
||||
shell.addListener(
|
||||
(ev) => {
|
||||
// handle TerminalChunk or DropNotice
|
||||
},
|
||||
{ cursor: { mode: 'live' } },
|
||||
);
|
||||
```
|
||||
|
||||
### Links
|
||||
|
||||
- Changelog: [`CHANGELOG.md`](./CHANGELOG.md)
|
||||
- Contributing: see the monorepo guide at
|
||||
[`../../CONTRIBUTING.md`](../../CONTRIBUTING.md)
|
||||
- Changelog:
|
||||
[`CHANGELOG.md`](https://github.com/EthanShoeDev/fressh/blob/main/packages/react-native-uniffi-russh/CHANGELOG.md)
|
||||
- Contributing:
|
||||
[`CONTRIBUTING.md`](https://github.com/EthanShoeDev/fressh/blob/main/CONTRIBUTING.md)
|
||||
- API source:
|
||||
[`src/api.ts`](https://github.com/EthanShoeDev/fressh/blob/main/packages/react-native-uniffi-russh/src/api.ts)
|
||||
- License: MIT
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "@fressh/react-native-uniffi-russh",
|
||||
"homepage": "https://github.com/EthanShoeDev/fressh",
|
||||
"homepage": "https://github.com/EthanShoeDev/fressh#readme",
|
||||
"license": "MIT",
|
||||
"description": "Uniffi bindings for russh",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.4",
|
||||
"type": "module",
|
||||
"main": "./lib/module/api.js",
|
||||
"types": "./lib/typescript/src/api.d.ts",
|
||||
@@ -18,20 +18,16 @@
|
||||
"lib",
|
||||
"android",
|
||||
"ios",
|
||||
"src",
|
||||
"cpp",
|
||||
"rust",
|
||||
"*.podspec",
|
||||
"*.xcframework",
|
||||
"react-native.config.js",
|
||||
"LICENSE",
|
||||
"!ios/build",
|
||||
"!android/build",
|
||||
"!android/gradle",
|
||||
"!android/gradlew",
|
||||
"!android/gradlew.bat",
|
||||
"!android/local.properties",
|
||||
"!**/__tests__",
|
||||
"!**/__fixtures__",
|
||||
"!**/__mocks__",
|
||||
"!**/.*"
|
||||
"*.md",
|
||||
"*.config.*",
|
||||
"tsconfig*.json",
|
||||
"LICENSE"
|
||||
],
|
||||
"scripts": {
|
||||
"fmt": "cross-env SORT_IMPORTS=true prettier --write .",
|
||||
@@ -52,15 +48,23 @@
|
||||
"release": "GITHUB_TOKEN=$(gh auth token) release-it",
|
||||
"release:dry": "release-it --dry-run"
|
||||
},
|
||||
"keywords": [
|
||||
"react-native",
|
||||
"ios",
|
||||
"android"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/EthanShoeDev/fressh.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/EthanShoeDev/fressh/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"react-native",
|
||||
"ssh",
|
||||
"russh",
|
||||
"uniffi",
|
||||
"rust",
|
||||
"expo",
|
||||
"android",
|
||||
"ios"
|
||||
],
|
||||
"author": "EthanShoeDev <13422990+EthanShoeDev@users.noreply.github.com> (https://github.com/EthanShoeDev)",
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/"
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"dependsOn": ["build:bob"],
|
||||
},
|
||||
"typecheck": {
|
||||
"dependsOn": ["build:native"],
|
||||
"dependsOn": ["build:native", "build:bob"],
|
||||
},
|
||||
|
||||
// Special tasks
|
||||
|
||||
20
packages/react-native-xtermjs-webview/.npmignore
Normal file
20
packages/react-native-xtermjs-webview/.npmignore
Normal file
@@ -0,0 +1,20 @@
|
||||
# Exclude build and workspace caches not meant for publication
|
||||
.turbo/
|
||||
|
||||
# Node modules should never be packed (npm ignores it by default, but explicit is fine)
|
||||
node_modules/
|
||||
|
||||
# OS cruft
|
||||
**/.DS_Store
|
||||
|
||||
# Keep dist outputs and sources; do not exclude them here
|
||||
# dist/
|
||||
# dist-internal/
|
||||
# src/
|
||||
|
||||
# Common ignores that shouldn't ship
|
||||
coverage/
|
||||
.vscode/
|
||||
.idea/
|
||||
*.log
|
||||
*.local
|
||||
@@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## [0.0.8](https://github.com/EthanShoeDev/fressh/compare/@fressh/react-native-xtermjs-webview-v0.0.7...${npm.name}-v0.0.8) (2025-10-08)
|
||||
|
||||
## [0.0.7](https://github.com/EthanShoeDev/fressh/compare/@fressh/react-native-xtermjs-webview-v0.0.6...${npm.name}-v0.0.7) (2025-10-08)
|
||||
|
||||
## [0.0.6](https://github.com/EthanShoeDev/fressh/compare/@fressh/react-native-xtermjs-webview-v0.0.5...${npm.name}-v0.0.6) (2025-10-07)
|
||||
|
||||
## [0.0.5](https://github.com/EthanShoeDev/fressh/compare/@fressh/react-native-xtermjs-webview-v0.0.4...${npm.name}-v0.0.5) (2025-10-07)
|
||||
|
||||
## [0.0.4](https://github.com/EthanShoeDev/fressh/compare/@fressh/react-native-xtermjs-webview-v0.0.1...${npm.name}-v0.0.4) (2025-10-07)
|
||||
|
||||
## 0.0.1 (2025-10-07)
|
||||
|
||||
@@ -11,28 +11,33 @@ defaults and a bridge for input and output.
|
||||
pnpm add @fressh/react-native-xtermjs-webview react-native-webview
|
||||
```
|
||||
|
||||
Peer dependencies: `react`, `react-dom` (for web), `react-native-webview`.
|
||||
Peer dependencies: `react`, `react-native-webview`.
|
||||
|
||||
### Usage
|
||||
|
||||
See `apps/mobile` in this monorepo for a complete example. Basic usage:
|
||||
For a complete production example, see the mobile app:
|
||||
https://github.com/EthanShoeDev/fressh/tree/main/apps/mobile
|
||||
|
||||
Basic usage:
|
||||
|
||||
```tsx
|
||||
import React, { useRef } from 'react';
|
||||
import {
|
||||
XtermJsWebView,
|
||||
type XtermWebViewHandle,
|
||||
} from '@fressh/react-native-xtermjs-webview';
|
||||
import type { XtermWebViewHandle } from '@fressh/react-native-xtermjs-webview';
|
||||
import { XtermJsWebView } from '@fressh/react-native-xtermjs-webview';
|
||||
|
||||
export function Terminal() {
|
||||
const termRef = useRef<XtermWebViewHandle | null>(null);
|
||||
|
||||
return (
|
||||
<XtermJsWebView
|
||||
ref={termRef}
|
||||
onInitialized={() =>
|
||||
termRef.current?.write(new TextEncoder().encode('hello'))
|
||||
}
|
||||
onData={(input) => console.log('user input:', input)}
|
||||
onInitialized={() => {
|
||||
const hello = new TextEncoder().encode('hello');
|
||||
termRef.current?.write(hello);
|
||||
}}
|
||||
onData={(input) => {
|
||||
console.log('user input:', input);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -60,8 +65,14 @@ transparency and debugging.
|
||||
|
||||
### Links
|
||||
|
||||
- Changelog: [`CHANGELOG.md`](./CHANGELOG.md)
|
||||
- Contributing: see the monorepo guide at
|
||||
[`../../CONTRIBUTING.md`](../../CONTRIBUTING.md)
|
||||
- Example: `apps/mobile`
|
||||
- Changelog:
|
||||
[`CHANGELOG.md`](https://github.com/EthanShoeDev/fressh/blob/main/packages/react-native-xtermjs-webview/CHANGELOG.md)
|
||||
- Contributing:
|
||||
[`CONTRIBUTING.md`](https://github.com/EthanShoeDev/fressh/blob/main/CONTRIBUTING.md)
|
||||
- Example app:
|
||||
[`apps/mobile`](https://github.com/EthanShoeDev/fressh/tree/main/apps/mobile)
|
||||
and source usage:
|
||||
[`apps/mobile/src/app/(tabs)/shell/detail.tsx`](<https://github.com/EthanShoeDev/fressh/blob/main/apps/mobile/src/app/(tabs)/shell/detail.tsx>)
|
||||
- API source:
|
||||
[`src/index.tsx`](https://github.com/EthanShoeDev/fressh/blob/main/packages/react-native-xtermjs-webview/src/index.tsx)
|
||||
- License: MIT
|
||||
|
||||
@@ -1,20 +1,39 @@
|
||||
{
|
||||
"name": "@fressh/react-native-xtermjs-webview",
|
||||
"private": false,
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.8",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"src",
|
||||
"dist",
|
||||
"dist-internal",
|
||||
"!node_modules",
|
||||
"!.turbo",
|
||||
"*"
|
||||
"*.config.*",
|
||||
"tsconfig*.json",
|
||||
"*.md",
|
||||
"*.html"
|
||||
],
|
||||
"exports": {
|
||||
".": "./dist/index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/EthanShoeDev/fressh.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/EthanShoeDev/fressh/issues"
|
||||
},
|
||||
"homepage": "https://github.com/EthanShoeDev/fressh#readme",
|
||||
"keywords": [
|
||||
"react-native",
|
||||
"xterm",
|
||||
"webview",
|
||||
"terminal",
|
||||
"ssh",
|
||||
"expo",
|
||||
"android",
|
||||
"ios"
|
||||
],
|
||||
"scripts": {
|
||||
"fmt": "cross-env SORT_IMPORTS=true prettier --write .",
|
||||
"fmt:check": "cross-env SORT_IMPORTS=true prettier --check .",
|
||||
@@ -33,7 +52,6 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-native-webview": "13.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -113,8 +113,8 @@ importers:
|
||||
specifier: ~15.0.7
|
||||
version: 15.0.7(expo@54.0.12)
|
||||
expo-image:
|
||||
specifier: ~3.0.8
|
||||
version: 3.0.8(expo@54.0.12)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
specifier: ~3.0.9
|
||||
version: 3.0.9(expo@54.0.12)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
expo-linking:
|
||||
specifier: ~8.0.8
|
||||
version: 8.0.8(expo@54.0.12)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
@@ -5336,8 +5336,8 @@ packages:
|
||||
peerDependencies:
|
||||
expo: '*'
|
||||
|
||||
expo-image@3.0.8:
|
||||
resolution: {integrity: sha512-L83fTHVjvE5hACxUXPk3dpABteI/IypeqxKMeOAAcT2eB/jbqT53ddsYKEvKAP86eoByQ7+TCtw9AOUizEtaTQ==}
|
||||
expo-image@3.0.9:
|
||||
resolution: {integrity: sha512-GkPIjeqrODMBdpbRWOzbwiq8ztxjgq1rdZrnqwt/pzQavgXPlr4rW/7aigue9Jm5t5vebhMNAuc1A/XIXXqpcA==}
|
||||
peerDependencies:
|
||||
expo: '*'
|
||||
react: '*'
|
||||
@@ -15754,7 +15754,7 @@ snapshots:
|
||||
dependencies:
|
||||
expo: 54.0.12(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.10)(react-native-webview@13.15.0(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
|
||||
expo-image@3.0.8(expo@54.0.12)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
expo-image@3.0.9(expo@54.0.12)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
expo: 54.0.12(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.10)(react-native-webview@13.15.0(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
|
||||
react: 19.1.0
|
||||
|
||||
Reference in New Issue
Block a user