Moved TTP to this repo and updated other stuff
This commit is contained in:
parent
2f5e10140c
commit
38241e57eb
14 changed files with 1823 additions and 71 deletions
|
|
@ -4,3 +4,4 @@ coverage
|
||||||
.tmp
|
.tmp
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
bun.lock
|
bun.lock
|
||||||
|
packages/desktop/build
|
||||||
42
bun.lock
42
bun.lock
|
|
@ -28,7 +28,7 @@
|
||||||
"@tensamin/core-user": "workspace:*",
|
"@tensamin/core-user": "workspace:*",
|
||||||
"@tensamin/markdown": "workspace:*",
|
"@tensamin/markdown": "workspace:*",
|
||||||
"@tensamin/shared": "workspace:*",
|
"@tensamin/shared": "workspace:*",
|
||||||
"@tensamin/ttp": "git+https://github.com/Tensamin/TTP.git",
|
"@tensamin/ttp": "workspace:*",
|
||||||
"@tensamin/ui": "workspace:*",
|
"@tensamin/ui": "workspace:*",
|
||||||
"lucide-solid": "^0.564.0",
|
"lucide-solid": "^0.564.0",
|
||||||
"solid-js": "^1.9.11",
|
"solid-js": "^1.9.11",
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
"@codemirror/commands": "^6.10.2",
|
"@codemirror/commands": "^6.10.2",
|
||||||
"@codemirror/lang-markdown": "^6.5.0",
|
"@codemirror/lang-markdown": "^6.5.0",
|
||||||
"@codemirror/state": "^6.5.4",
|
"@codemirror/state": "^6.5.4",
|
||||||
"@codemirror/view": "^6.39.16",
|
"@codemirror/view": "^6.39.15",
|
||||||
"@tensamin/ui": "workspace:*",
|
"@tensamin/ui": "workspace:*",
|
||||||
"solid-js": "^1.9.11",
|
"solid-js": "^1.9.11",
|
||||||
},
|
},
|
||||||
|
|
@ -67,12 +67,28 @@
|
||||||
"solid-js": "^1.9.11",
|
"solid-js": "^1.9.11",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"packages/core/ttp": {
|
||||||
|
"name": "@tensamin/ttp",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@solidjs/router": "^0.15.4",
|
||||||
|
"@tensamin/core-crypto": "workspace:*",
|
||||||
|
"@tensamin/core-storage": "workspace:*",
|
||||||
|
"@tensamin/shared": "workspace:*",
|
||||||
|
"@tensamin/ui": "workspace:*",
|
||||||
|
"solid-js": "^1.9.10",
|
||||||
|
"zod": "^4.3.6",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^10.0.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
"packages/core/user": {
|
"packages/core/user": {
|
||||||
"name": "@tensamin/core-user",
|
"name": "@tensamin/core-user",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tensamin/shared": "workspace:*",
|
"@tensamin/shared": "workspace:*",
|
||||||
"@tensamin/ttp": "git+https://github.com/Tensamin/TTP.git",
|
"@tensamin/ttp": "workspace:*",
|
||||||
"solid-js": "^1.9.11",
|
"solid-js": "^1.9.11",
|
||||||
"zod": "^4.3.6",
|
"zod": "^4.3.6",
|
||||||
},
|
},
|
||||||
|
|
@ -148,7 +164,7 @@
|
||||||
"@tensamin/core-storage": "workspace:*",
|
"@tensamin/core-storage": "workspace:*",
|
||||||
"@tensamin/core-user": "workspace:*",
|
"@tensamin/core-user": "workspace:*",
|
||||||
"@tensamin/shared": "workspace:*",
|
"@tensamin/shared": "workspace:*",
|
||||||
"@tensamin/ttp": "git+https://github.com/Tensamin/TTP.git",
|
"@tensamin/ttp": "workspace:*",
|
||||||
"@tensamin/ui": "workspace:*",
|
"@tensamin/ui": "workspace:*",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
|
@ -507,7 +523,7 @@
|
||||||
|
|
||||||
"@tensamin/shared": ["@tensamin/shared@workspace:packages/shared"],
|
"@tensamin/shared": ["@tensamin/shared@workspace:packages/shared"],
|
||||||
|
|
||||||
"@tensamin/ttp": ["@tensamin/ttp@github:Tensamin/TTP#58a5e2b", { "dependencies": { "@solidjs/router": "^0.15.4", "@tensamin/core-crypto": "workspace:*", "@tensamin/core-storage": "workspace:*", "@tensamin/shared": "workspace:*", "@tensamin/ui": "workspace:*", "solid-js": "^1.9.10", "zod": "^4.3.6" } }, "Tensamin-TTP-58a5e2b"],
|
"@tensamin/ttp": ["@tensamin/ttp@workspace:packages/core/ttp"],
|
||||||
|
|
||||||
"@tensamin/ui": ["@tensamin/ui@workspace:packages/ui"],
|
"@tensamin/ui": ["@tensamin/ui@workspace:packages/ui"],
|
||||||
|
|
||||||
|
|
@ -1035,20 +1051,6 @@
|
||||||
|
|
||||||
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
"@codemirror/autocomplete/@codemirror/view": ["@codemirror/view@6.39.15", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-aCWjgweIIXLBHh7bY6cACvXuyrZ0xGafjQ2VInjp4RM4gMfscK5uESiNdrH0pE+e1lZr2B4ONGsjchl2KsKZzg=="],
|
|
||||||
|
|
||||||
"@codemirror/commands/@codemirror/view": ["@codemirror/view@6.39.15", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-aCWjgweIIXLBHh7bY6cACvXuyrZ0xGafjQ2VInjp4RM4gMfscK5uESiNdrH0pE+e1lZr2B4ONGsjchl2KsKZzg=="],
|
|
||||||
|
|
||||||
"@codemirror/lang-html/@codemirror/view": ["@codemirror/view@6.39.15", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-aCWjgweIIXLBHh7bY6cACvXuyrZ0xGafjQ2VInjp4RM4gMfscK5uESiNdrH0pE+e1lZr2B4ONGsjchl2KsKZzg=="],
|
|
||||||
|
|
||||||
"@codemirror/lang-javascript/@codemirror/view": ["@codemirror/view@6.39.15", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-aCWjgweIIXLBHh7bY6cACvXuyrZ0xGafjQ2VInjp4RM4gMfscK5uESiNdrH0pE+e1lZr2B4ONGsjchl2KsKZzg=="],
|
|
||||||
|
|
||||||
"@codemirror/lang-markdown/@codemirror/view": ["@codemirror/view@6.39.15", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-aCWjgweIIXLBHh7bY6cACvXuyrZ0xGafjQ2VInjp4RM4gMfscK5uESiNdrH0pE+e1lZr2B4ONGsjchl2KsKZzg=="],
|
|
||||||
|
|
||||||
"@codemirror/language/@codemirror/view": ["@codemirror/view@6.39.15", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-aCWjgweIIXLBHh7bY6cACvXuyrZ0xGafjQ2VInjp4RM4gMfscK5uESiNdrH0pE+e1lZr2B4ONGsjchl2KsKZzg=="],
|
|
||||||
|
|
||||||
"@codemirror/lint/@codemirror/view": ["@codemirror/view@6.39.15", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-aCWjgweIIXLBHh7bY6cACvXuyrZ0xGafjQ2VInjp4RM4gMfscK5uESiNdrH0pE+e1lZr2B4ONGsjchl2KsKZzg=="],
|
|
||||||
|
|
||||||
"@corvu/dialog/solid-presence": ["solid-presence@0.2.0", "", { "dependencies": { "@corvu/utils": "~0.4.2" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-YM92o+jvpzX3XGaD4rLYmq/Kc2ZVh47GSCLEufHBFQQIurvZTs8SoGJxO8BJGNDxBKdcS8F3dYhW1SDXp4BNjA=="],
|
"@corvu/dialog/solid-presence": ["solid-presence@0.2.0", "", { "dependencies": { "@corvu/utils": "~0.4.2" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-YM92o+jvpzX3XGaD4rLYmq/Kc2ZVh47GSCLEufHBFQQIurvZTs8SoGJxO8BJGNDxBKdcS8F3dYhW1SDXp4BNjA=="],
|
||||||
|
|
||||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
@ -1067,6 +1069,8 @@
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"@tensamin/notifications/@tensamin/ttp": ["TTP@github:Tensamin/TTP#42bee9c", {}, "Tensamin-TTP-42bee9c"],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.0", "@typescript-eslint/types": "8.57.0", "@typescript-eslint/typescript-estree": "8.57.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ=="],
|
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.0", "@typescript-eslint/types": "8.57.0", "@typescript-eslint/typescript-estree": "8.57.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
"lint": "bun scripts/lint-packages.ts",
|
"lint": "bun scripts/lint-packages.ts",
|
||||||
"build:packages": "bun scripts/build-packages.ts",
|
"build:packages": "bun scripts/build-packages.ts",
|
||||||
"install:packages": "bun scripts/install-packages.ts",
|
"install:packages": "bun scripts/install-packages.ts",
|
||||||
"update:packages": "bun scripts/update-packages.ts",
|
|
||||||
"dev": "cd packages/web && bun dev"
|
"dev": "cd packages/web && bun dev"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
"@tanstack/solid-query": "^5.90.23",
|
"@tanstack/solid-query": "^5.90.23",
|
||||||
"@tanstack/solid-virtual": "^3.13.21",
|
"@tanstack/solid-virtual": "^3.13.21",
|
||||||
"@tensamin/core-crypto": "workspace:*",
|
"@tensamin/core-crypto": "workspace:*",
|
||||||
"@tensamin/ttp": "git+https://github.com/Tensamin/TTP.git",
|
"@tensamin/ttp": "workspace:*",
|
||||||
"@tensamin/core-storage": "workspace:*",
|
"@tensamin/core-storage": "workspace:*",
|
||||||
"@tensamin/core-user": "workspace:*",
|
"@tensamin/core-user": "workspace:*",
|
||||||
"@tensamin/markdown": "workspace:*",
|
"@tensamin/markdown": "workspace:*",
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
"@codemirror/commands": "^6.10.2",
|
"@codemirror/commands": "^6.10.2",
|
||||||
"@codemirror/lang-markdown": "^6.5.0",
|
"@codemirror/lang-markdown": "^6.5.0",
|
||||||
"@codemirror/state": "^6.5.4",
|
"@codemirror/state": "^6.5.4",
|
||||||
"@codemirror/view": "^6.39.16",
|
"@codemirror/view": "^6.39.15",
|
||||||
"@tensamin/ui": "workspace:*",
|
"@tensamin/ui": "workspace:*",
|
||||||
"solid-js": "^1.9.11"
|
"solid-js": "^1.9.11"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
29
packages/core/ttp/package.json
Normal file
29
packages/core/ttp/package.json
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "@tensamin/ttp",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
"./core": "./src/core.ts",
|
||||||
|
"./context": "./src/context.tsx",
|
||||||
|
"./send": "./src/send.ts",
|
||||||
|
"./values": "./src/values.ts"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"format": "bunx prettier --write .",
|
||||||
|
"lint": "eslint src --ext .ts,.tsx",
|
||||||
|
"build": "tsc -p tsconfig.json --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@solidjs/router": "^0.15.4",
|
||||||
|
"@tensamin/core-crypto": "workspace:*",
|
||||||
|
"@tensamin/core-storage": "workspace:*",
|
||||||
|
"@tensamin/shared": "workspace:*",
|
||||||
|
"@tensamin/ui": "workspace:*",
|
||||||
|
"solid-js": "^1.9.10",
|
||||||
|
"zod": "^4.3.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^10.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
312
packages/core/ttp/src/context.tsx
Normal file
312
packages/core/ttp/src/context.tsx
Normal file
|
|
@ -0,0 +1,312 @@
|
||||||
|
import { log } from "@tensamin/shared/log";
|
||||||
|
import {
|
||||||
|
createContext,
|
||||||
|
createEffect,
|
||||||
|
createSignal,
|
||||||
|
onCleanup,
|
||||||
|
Show,
|
||||||
|
untrack,
|
||||||
|
useContext,
|
||||||
|
type ParentProps,
|
||||||
|
} from "solid-js";
|
||||||
|
|
||||||
|
import { createTransportClient, READY_STATE, type BoundSendFn } from "./core";
|
||||||
|
import {
|
||||||
|
PING_INTERVAL,
|
||||||
|
RETRY_COUNT,
|
||||||
|
RETRY_INTERVAL,
|
||||||
|
TRANSPORT_URL,
|
||||||
|
} from "./values";
|
||||||
|
import {
|
||||||
|
socket as schemas,
|
||||||
|
type Socket as Schemas,
|
||||||
|
} from "@tensamin/shared/data";
|
||||||
|
import { useStorage } from "@tensamin/core-storage/context";
|
||||||
|
import { useCrypto } from "@tensamin/core-crypto/context";
|
||||||
|
import Loading from "@tensamin/ui/screens/loading";
|
||||||
|
import ErrorScreen from "@tensamin/ui/screens/error";
|
||||||
|
import { useNavigate } from "@solidjs/router";
|
||||||
|
|
||||||
|
type OmikronData = {
|
||||||
|
id: number;
|
||||||
|
public_key: string;
|
||||||
|
ip_address: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ContextType = {
|
||||||
|
send: BoundSendFn<Schemas>;
|
||||||
|
readyState: () => number;
|
||||||
|
ownPing: () => number;
|
||||||
|
iotaPing: () => number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const socketContext = createContext<ContextType>();
|
||||||
|
|
||||||
|
export default function Provider(props: ParentProps) {
|
||||||
|
const [omikron, setOmikron] = createSignal<OmikronData | null>(null);
|
||||||
|
const [readyState, setReadyState] = createSignal<number>(READY_STATE.CLOSED);
|
||||||
|
const [identified, setIdentified] = createSignal<boolean>(false);
|
||||||
|
|
||||||
|
const [ownPing, setOwnPing] = createSignal<number>(0);
|
||||||
|
const [iotaPing, setIotaPing] = createSignal<number>(0);
|
||||||
|
|
||||||
|
const [error, setError] = createSignal<string>("");
|
||||||
|
const [errorDescription, setErrorDescription] = createSignal<string>("");
|
||||||
|
|
||||||
|
const { load } = useStorage();
|
||||||
|
const { get_shared_secret, decrypt } = useCrypto();
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
let client: ReturnType<typeof createTransportClient<Schemas>> | null = null;
|
||||||
|
|
||||||
|
// Load Omikron
|
||||||
|
createEffect(() => {
|
||||||
|
if (omikron()) return;
|
||||||
|
|
||||||
|
const controller = new AbortController();
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const userId = await load("user_id");
|
||||||
|
|
||||||
|
// Redirect to login
|
||||||
|
if (userId === 0) {
|
||||||
|
navigate("/login");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
"https://omega.tensamin.net/api/get/omikron/" + String(userId),
|
||||||
|
{ signal: controller.signal },
|
||||||
|
);
|
||||||
|
const data = await res.json();
|
||||||
|
setOmikron(data);
|
||||||
|
} catch (e) {
|
||||||
|
if (controller.signal.aborted) return;
|
||||||
|
|
||||||
|
setError("Failed to load Omikron data");
|
||||||
|
setErrorDescription(
|
||||||
|
"An error occurred while fetching the Omikron server data. Please try again later.",
|
||||||
|
);
|
||||||
|
log(0, "Socket", "red", "Failed to fetch Omikron data", e);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
onCleanup(() => controller.abort());
|
||||||
|
});
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (identified()) {
|
||||||
|
const interval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const originalNow = Date.now();
|
||||||
|
|
||||||
|
const data = await send("ping", {
|
||||||
|
last_ping: originalNow,
|
||||||
|
});
|
||||||
|
|
||||||
|
const travelTime = Date.now() - originalNow;
|
||||||
|
|
||||||
|
setOwnPing(travelTime);
|
||||||
|
setIotaPing(data.data.ping_iota);
|
||||||
|
} catch (error) {
|
||||||
|
log(1, "Socket", "yellow", "Ping failed", error);
|
||||||
|
}
|
||||||
|
}, PING_INTERVAL);
|
||||||
|
|
||||||
|
onCleanup(() => clearInterval(interval));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create connection
|
||||||
|
createEffect(() => {
|
||||||
|
if (!omikron()) return;
|
||||||
|
|
||||||
|
let attempts = 0;
|
||||||
|
let reconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
let disposed = false;
|
||||||
|
|
||||||
|
const transportClient = createTransportClient(schemas, {
|
||||||
|
url: TRANSPORT_URL,
|
||||||
|
onReadyStateChange: setReadyState,
|
||||||
|
onClose: ({ error: closeError, intentional }) => {
|
||||||
|
setIdentified(false);
|
||||||
|
|
||||||
|
if (disposed || intentional) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(0, "Socket", "red", "Disconnected", closeError);
|
||||||
|
|
||||||
|
if (attempts < RETRY_COUNT) {
|
||||||
|
attempts += 1;
|
||||||
|
reconnectTimer = setTimeout(() => {
|
||||||
|
void connect();
|
||||||
|
}, RETRY_INTERVAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setError("Connection Failed");
|
||||||
|
setErrorDescription(
|
||||||
|
"Unable to connect to the server after multiple attempts. Please check your internet connection or try again later.",
|
||||||
|
);
|
||||||
|
log(0, "Socket", "red", "Reconnection attempts exhausted", closeError);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
client = transportClient;
|
||||||
|
|
||||||
|
async function identify(activeClient: typeof transportClient) {
|
||||||
|
const userId = await load("user_id");
|
||||||
|
const privateKey = await load("private_key");
|
||||||
|
const currentOmikron = untrack(() => omikron());
|
||||||
|
|
||||||
|
activeClient
|
||||||
|
.send("identification", { user_id: userId })
|
||||||
|
.then(async (data) => {
|
||||||
|
const ownUserData = await activeClient.send("get_user_data", {
|
||||||
|
user_id: userId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!currentOmikron?.public_key) {
|
||||||
|
setError("Omikron data missing");
|
||||||
|
setErrorDescription(
|
||||||
|
"Omikron server data is missing. Please try again later.",
|
||||||
|
);
|
||||||
|
log(0, "Socket", "red", "Omikron public key missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const sharedSecret = await get_shared_secret(
|
||||||
|
privateKey,
|
||||||
|
ownUserData.data.public_key,
|
||||||
|
currentOmikron.public_key,
|
||||||
|
);
|
||||||
|
|
||||||
|
const solvedChallenge = await decrypt(
|
||||||
|
sharedSecret,
|
||||||
|
data.data.challenge,
|
||||||
|
);
|
||||||
|
|
||||||
|
activeClient
|
||||||
|
.send("challenge_response", {
|
||||||
|
challenge: btoa(solvedChallenge),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
if (client !== activeClient || disposed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(1, "Socket", "green", "Identification successful");
|
||||||
|
setIdentified(true);
|
||||||
|
setError("");
|
||||||
|
setErrorDescription("");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
log(0, "Socket", "red", "Challenge failed", error);
|
||||||
|
setError("Challenge Failed");
|
||||||
|
setErrorDescription(
|
||||||
|
"Failed to respond to the server's challenge. Please try again later.",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
setError("Validation Failed");
|
||||||
|
setErrorDescription(
|
||||||
|
"Failed to validate the server's identity. Please try again later.",
|
||||||
|
);
|
||||||
|
log(0, "Socket", "red", "Server identity validation failed", err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
log(0, "Socket", "red", "Identification failed", e);
|
||||||
|
setError("Identification Failed");
|
||||||
|
setErrorDescription(
|
||||||
|
"Failed to identify with the server. Please try again later.",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function connect() {
|
||||||
|
if (disposed) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await transportClient.connect(TRANSPORT_URL);
|
||||||
|
attempts = 0;
|
||||||
|
await identify(transportClient);
|
||||||
|
} catch (error) {
|
||||||
|
if (!disposed) {
|
||||||
|
log(0, "Socket", "red", "Connection attempt failed", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect();
|
||||||
|
|
||||||
|
onCleanup(() => {
|
||||||
|
disposed = true;
|
||||||
|
if (reconnectTimer) clearTimeout(reconnectTimer);
|
||||||
|
if (client === transportClient) {
|
||||||
|
client = null;
|
||||||
|
}
|
||||||
|
void transportClient.close("context-dispose");
|
||||||
|
setReadyState(READY_STATE.CLOSED);
|
||||||
|
setIdentified(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create Send Function
|
||||||
|
const send: BoundSendFn<Schemas> = ((
|
||||||
|
type: string,
|
||||||
|
data?: Record<string, unknown>,
|
||||||
|
options?: { id?: number; noResponse?: boolean },
|
||||||
|
) => {
|
||||||
|
if (!client) {
|
||||||
|
return Promise.reject(new Error("Socket is not connected"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.noResponse) {
|
||||||
|
return client.send(type as keyof Schemas & string, data as never, {
|
||||||
|
...options,
|
||||||
|
noResponse: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return client.send(type as keyof Schemas & string, data as never, {
|
||||||
|
...options,
|
||||||
|
noResponse: false,
|
||||||
|
});
|
||||||
|
}) as BoundSendFn<Schemas>;
|
||||||
|
|
||||||
|
const progress = () => {
|
||||||
|
if (!omikron()) return 40;
|
||||||
|
if (readyState() !== READY_STATE.OPEN) return 70;
|
||||||
|
if (!identified()) return 90;
|
||||||
|
return 100;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Show
|
||||||
|
when={error() === "" && errorDescription() === ""}
|
||||||
|
fallback={
|
||||||
|
<ErrorScreen error={error()} description={errorDescription()} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Show
|
||||||
|
when={omikron() && identified()}
|
||||||
|
fallback={<Loading progress={progress()} />}
|
||||||
|
>
|
||||||
|
<socketContext.Provider value={{ send, readyState, ownPing, iotaPing }}>
|
||||||
|
{props.children}
|
||||||
|
</socketContext.Provider>
|
||||||
|
</Show>
|
||||||
|
</Show>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSocket(): ContextType {
|
||||||
|
const context = useContext(socketContext);
|
||||||
|
if (!context)
|
||||||
|
throw new Error("useSocket must be used within a SocketProvider");
|
||||||
|
return context;
|
||||||
|
}
|
||||||
1434
packages/core/ttp/src/core.ts
Normal file
1434
packages/core/ttp/src/core.ts
Normal file
File diff suppressed because it is too large
Load diff
5
packages/core/ttp/src/values.ts
Normal file
5
packages/core/ttp/src/values.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const RESPONSE_TIMEOUT = 15_000;
|
||||||
|
export const RETRY_COUNT = 10;
|
||||||
|
export const RETRY_INTERVAL = 3_000;
|
||||||
|
export const PING_INTERVAL = 5_000;
|
||||||
|
export const TRANSPORT_URL = "https://methanium.net:959";
|
||||||
13
packages/core/ttp/tsconfig.json
Normal file
13
packages/core/ttp/tsconfig.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"jsx": "preserve",
|
||||||
|
"jsxImportSource": "solid-js",
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noEmit": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"build": "tsc -p tsconfig.json --noEmit"
|
"build": "tsc -p tsconfig.json --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tensamin/ttp": "git+https://github.com/Tensamin/TTP.git",
|
"@tensamin/ttp": "workspace:*",
|
||||||
"@tensamin/shared": "workspace:*",
|
"@tensamin/shared": "workspace:*",
|
||||||
"solid-js": "^1.9.11",
|
"solid-js": "^1.9.11",
|
||||||
"zod": "^4.3.6"
|
"zod": "^4.3.6"
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tensamin/chat": "workspace:*",
|
"@tensamin/chat": "workspace:*",
|
||||||
"@tensamin/core-crypto": "workspace:*",
|
"@tensamin/core-crypto": "workspace:*",
|
||||||
"@tensamin/ttp": "git+https://github.com/Tensamin/TTP.git",
|
"@tensamin/ttp": "workspace:*",
|
||||||
"@tensamin/core-storage": "workspace:*",
|
"@tensamin/core-storage": "workspace:*",
|
||||||
"@tensamin/core-user": "workspace:*",
|
"@tensamin/core-user": "workspace:*",
|
||||||
"@tensamin/shared": "workspace:*",
|
"@tensamin/shared": "workspace:*",
|
||||||
|
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
import { existsSync, readdirSync, statSync } from "fs";
|
|
||||||
import { join } from "path";
|
|
||||||
import { execSync } from "child_process";
|
|
||||||
|
|
||||||
import { fileURLToPath } from "node:url";
|
|
||||||
import { dirname } from "node:path";
|
|
||||||
|
|
||||||
const _dirname = dirname(fileURLToPath(import.meta.url));
|
|
||||||
|
|
||||||
const packagesDir = join(_dirname, "..", "packages");
|
|
||||||
|
|
||||||
function getPackageDirs(dir: string): string[] {
|
|
||||||
const entries = readdirSync(dir);
|
|
||||||
const dirs: string[] = [];
|
|
||||||
|
|
||||||
for (const entry of entries) {
|
|
||||||
const fullPath = join(dir, entry);
|
|
||||||
if (!statSync(fullPath).isDirectory()) continue;
|
|
||||||
|
|
||||||
if (existsSync(join(fullPath, "package.json"))) {
|
|
||||||
dirs.push(fullPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs.push(...getPackageDirs(fullPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
return dirs;
|
|
||||||
}
|
|
||||||
|
|
||||||
const packageDirs = getPackageDirs(packagesDir);
|
|
||||||
|
|
||||||
for (const fullPath of packageDirs) {
|
|
||||||
const entry = fullPath.replace(packagesDir + "/", "");
|
|
||||||
console.log(`Updating ${entry}...`);
|
|
||||||
try {
|
|
||||||
execSync("bun update", { cwd: fullPath, stdio: "inherit" });
|
|
||||||
console.log(`${entry} updated successfully.`);
|
|
||||||
} catch {
|
|
||||||
console.error(`Failed to update ${entry}.`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Done!");
|
|
||||||
Loading…
Reference in a new issue