Initial commit

This commit is contained in:
Alois 2026-03-10 20:44:25 +01:00
commit 2f5e10140c
133 changed files with 10429 additions and 0 deletions

View file

@ -0,0 +1,23 @@
{
"name": "@tensamin/shared",
"private": true,
"version": "0.0.0",
"type": "module",
"exports": {
"./data": "./src/data.ts",
"./log": "./src/log.tsx",
"./features/legal/schema": "./src/features/legal/schema.ts",
"./features/conversation/schema": "./src/features/conversation/schema.ts"
},
"scripts": {
"format": "bunx prettier --write .",
"lint": "eslint src",
"build": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"lucide-solid": "^0.564.0",
"solid-js": "^1.9.11",
"solid-sonner": "^0.2.8",
"zod": "^4.3.6"
}
}

164
packages/shared/src/data.ts Normal file
View file

@ -0,0 +1,164 @@
import { z } from "zod";
import { legalDocsSchema } from "./features/legal/schema";
import { community, conversation } from "./features/conversation/schema";
const fileFromMessage = z.object({
name: z.string(),
id: z.uuidv4(),
type: z.enum(["image", "image_top_right", "file"]),
});
const message = z.object({
height: z.number(),
not_encrypted: z.boolean().optional(),
sent_by_self: z.boolean(),
timestamp: z.number(),
content: z.base64(),
files: z.array(fileFromMessage).optional(),
tint: z.string().length(7).startsWith("#").optional(),
avatar: z.boolean().optional(),
display: z.boolean().optional(),
});
// Socket
export const socket = {
identification: {
request: z.object({
user_id: z.number(),
}),
response: z.object({
challenge: z.string(),
public_key: z.base64(),
}),
},
get_user_data: {
request: z.object({
user_id: z.number(),
}),
response: z.object({
about: z.string().max(255).optional(),
avatar: z.string().optional(),
display: z.string().max(15),
iota_id: z.number(),
omikron_connections: z.array(z.number()),
omikron_id: z.number().optional(),
online_status: z.enum([
"user_offline",
"user_online",
"user_dnd",
"user_idle",
"user_wc",
"user_borked",
"iota_offline",
"iota_online",
"iota_borked",
]),
public_key: z.base64(),
status: z.string().max(15).optional(),
sub_end: z.number(),
sub_level: z.number(),
user_id: z.number(),
username: z.string().max(15),
}),
},
challenge_response: {
request: z.object({
challenge: z.base64(),
}),
response: z.object({}),
},
ping: {
request: z.object({
last_ping: z.number(),
}),
response: z.object({
ping_iota: z.number(),
}),
},
get_chats: {
request: z.object({}),
response: z.object({
user_ids: z.array(conversation),
}),
},
get_communities: {
request: z.object({}),
response: z.object({
communities: z.array(community),
}),
},
live_message: {
request: z.object({}),
response: z.object({
sender_id: z.number(),
send_time: z.number(),
message,
}),
},
messages_get: {
request: z.object({
user_id: z.number(),
amount: z.number(),
offset: z.number(),
}),
response: z.object({
messages: z.array(message),
}),
},
message_send: {
request: z.object({
height: z.number(),
content: z.base64(),
receiver_id: z.number(),
send_time: z.number(),
files: z.array(fileFromMessage).optional(),
}),
response: z.object({}),
},
} satisfies Record<string, { request: z.ZodType; response: z.ZodType }>;
export type Socket = typeof socket;
// Storage
export interface Storage {
user_id: number;
private_key: string;
ppandtos_done: boolean;
accepted_terms_of_service: boolean;
accepted_privacy_policy: boolean;
analytics_crash_reports: boolean;
analytics_usage_data: boolean;
analytics_done: boolean;
legal_docs: z.infer<typeof legalDocsSchema>;
chat_invert_enter_behaviour: boolean;
}
export const storageDefaults: Storage = {
user_id: 0,
private_key: "",
ppandtos_done: false,
accepted_terms_of_service: false,
accepted_privacy_policy: false,
analytics_crash_reports: true,
analytics_usage_data: true,
analytics_done: false,
legal_docs: {
eula: {
version: "0.0",
hash: "000000000000",
unix: 0,
},
tos: {
version: "0.0",
hash: "000000000000",
unix: 0,
},
pp: {
version: "0.0",
hash: "000000000000",
unix: 0,
},
},
chat_invert_enter_behaviour: false,
};

View file

@ -0,0 +1,16 @@
import { z } from "zod";
export const conversation = z.object({
user_id: z.number(),
calls: z.array(z.uuidv4()).optional(),
last_message_at: z.number(),
});
export const community = z.object({
community_address: z.string(),
community_title: z.string(),
position: z.string(),
});
export type Conversation = z.infer<typeof conversation>;
export type Community = z.infer<typeof community>;

View file

@ -0,0 +1,13 @@
import { z } from "zod";
const legalDocSchema = z.object({
version: z.string().regex(/^\d+\.\d+$/),
hash: z.string().regex(/^[a-f0-9]{12}$/),
unix: z.number().int().positive(),
});
export const legalDocsSchema = z.object({
eula: legalDocSchema,
tos: legalDocSchema,
pp: legalDocSchema,
});

View file

@ -0,0 +1,52 @@
import { toast as sonnerToast } from "solid-sonner";
import { Ban, Check, Info, TriangleAlert } from "lucide-solid";
export function log(
logLevel: number,
logger: string,
color: "red" | "green" | "yellow" | "purple" | "blue",
...args: unknown[]
) {
const currentLogLevel = Number(localStorage.getItem("log_level") || 0);
if (logLevel > currentLogLevel) return;
const colorCodes: Record<typeof color, string> = {
red: "\x1b[31m",
green: "\x1b[32m",
yellow: "\x1b[33m",
purple: "\x1b[35m",
blue: "\x1b[34m",
};
const resetCode = "\x1b[0m";
console.log(`${colorCodes[color]}[${logger}]${resetCode}`, ...args);
}
const size = 20;
export function toast(
type: "error" | "info" | "warn" | "success",
message: string,
) {
switch (type) {
case "error":
sonnerToast(message, {
icon: <Ban size={size} />,
});
break;
case "info":
sonnerToast(message, {
icon: <Info size={size} />,
});
break;
case "warn":
sonnerToast(message, {
icon: <TriangleAlert size={size} />,
});
break;
case "success":
sonnerToast(message, {
icon: <Check size={size} />,
});
break;
}
}

View 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"]
}