i wrote puuid in typescript
This commit is contained in:
parent
8a2c3d05c9
commit
91284c242a
4 changed files with 100 additions and 45 deletions
|
|
@ -1,22 +1,40 @@
|
||||||
|
import { definePrefix, type Puuid } from "./puuid"
|
||||||
|
|
||||||
|
export const UserID = definePrefix("user");
|
||||||
|
export const GroupID = definePrefix("group");
|
||||||
|
export const ServerID = definePrefix("srv");
|
||||||
|
|
||||||
|
export type UserId = Puuid<"user">;
|
||||||
|
export type GroupId = Puuid<"group">;
|
||||||
|
export type ServerId = Puuid<"srv">;
|
||||||
|
|
||||||
|
|
||||||
export const Status: Record<string, 1|2|3> = {
|
export const Status: Record<string, 1|2|3> = {
|
||||||
OFFLINE: 1,
|
OFFLINE: 1,
|
||||||
DND: 2,
|
DND: 2,
|
||||||
ONLINE: 3
|
ONLINE: 3
|
||||||
}
|
}
|
||||||
|
|
||||||
interface InnerData {
|
export interface User {
|
||||||
id: string
|
id: UserId
|
||||||
}
|
|
||||||
export interface Friend extends InnerData {
|
|
||||||
name: string,
|
name: string,
|
||||||
status: 1|2|3,
|
status: 1|2|3,
|
||||||
image: string
|
image: string
|
||||||
}
|
}
|
||||||
export interface Group extends InnerData {
|
export interface Group {
|
||||||
|
id: GroupId
|
||||||
name: string
|
name: string
|
||||||
members: number
|
members: number
|
||||||
}
|
}
|
||||||
export interface Server extends InnerData {
|
export interface Server {
|
||||||
|
id: ServerId
|
||||||
name: string
|
name: string
|
||||||
image: string
|
image: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface Data {
|
||||||
|
friends: User[],
|
||||||
|
groups: Group[],
|
||||||
|
servers: Server[],
|
||||||
|
};
|
||||||
|
|
|
||||||
42
src/lib/puuid.ts
Normal file
42
src/lib/puuid.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { v7 as uuidv7 } from "uuid";
|
||||||
|
|
||||||
|
type Brand<K, T> = K & { __brand: T };
|
||||||
|
|
||||||
|
export type Puuid<Prefix extends string> = Brand<
|
||||||
|
string,
|
||||||
|
{ prefix: Prefix }
|
||||||
|
>;
|
||||||
|
|
||||||
|
export function definePrefix<const P extends string>(prefix: P) {
|
||||||
|
const withPrefix = (uuid: string) =>
|
||||||
|
`${prefix}_${uuid}` as Puuid<P>;
|
||||||
|
|
||||||
|
return {
|
||||||
|
prefix,
|
||||||
|
is(value: string): value is Puuid<P> {
|
||||||
|
return value.startsWith(prefix + "_");
|
||||||
|
},
|
||||||
|
|
||||||
|
newV7(): Puuid<P> {
|
||||||
|
return withPrefix(uuidv7());
|
||||||
|
},
|
||||||
|
|
||||||
|
newV4(): Puuid<P> {
|
||||||
|
return withPrefix(uuidv4());
|
||||||
|
},
|
||||||
|
|
||||||
|
parse(value: string): Puuid<P> {
|
||||||
|
if (!value.startsWith(prefix + "_")) {
|
||||||
|
throw new Error(
|
||||||
|
`Invalid prefix, expected "${prefix}_"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return value as Puuid<P>;
|
||||||
|
},
|
||||||
|
|
||||||
|
inner(id: Puuid<P>): string {
|
||||||
|
return id.slice(prefix.length + 1);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,47 +1,40 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Status, type Server, type Group, type Friend } from "$lib";
|
import { Status, type Server, type Group, type User, GroupID, UserID, ServerID, type GroupId, type ServerId, type UserId, type Data } from "$lib";
|
||||||
import AppSidebar from "$lib/components/app-sidebar.svelte";
|
import AppSidebar from "$lib/components/app-sidebar.svelte";
|
||||||
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
|
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
|
||||||
|
|
||||||
let currentPageID: string|null = $state(null);
|
let currentPageID: (UserId|GroupId|ServerId)|null = $state(null);
|
||||||
let currentPageType: string|null = $state(null);
|
let currentPage: User | Group | Server | undefined = $state();
|
||||||
let currentPage: Friend | Group | Server | null = $state(null);
|
|
||||||
|
|
||||||
const overview_data = {
|
const overview_data: Data = {
|
||||||
friends: [
|
friends: [
|
||||||
{ id: crypto.randomUUID(), name: "Alice", status: Status.OFFLINE, image: "https://placehold.co/40x40" },
|
{ id: UserID.newV7(), name: "Alice", status: Status.OFFLINE, image: "https://placehold.co/40x40" },
|
||||||
{ id: crypto.randomUUID(), name: "Bob", status: Status.DND, image: "https://placehold.co/40x40" },
|
{ id: UserID.newV7(), name: "Bob", status: Status.DND, image: "https://placehold.co/40x40" },
|
||||||
{ id: crypto.randomUUID(), name: "Charlie", status: Status.ONLINE, image: "https://placehold.co/40x40" },
|
{ id: UserID.newV7(), name: "Charlie", status: Status.ONLINE, image: "https://placehold.co/40x40" },
|
||||||
],
|
],
|
||||||
groups: [
|
groups: [
|
||||||
{ id: crypto.randomUUID(), name: "Work Team", members: 5 },
|
{ id: GroupID.newV7(), name: "Work Team", members: 5 },
|
||||||
{ id: crypto.randomUUID(), name: "Gaming Group", members: 8 },
|
{ id: GroupID.newV7(), name: "Gaming Group", members: 8 },
|
||||||
],
|
],
|
||||||
servers: [
|
servers: [
|
||||||
{ id: crypto.randomUUID(), name: "Main Server", image: "https://placehold.co/40x40" },
|
{ id: ServerID.newV7(), name: "Main Server", image: "https://placehold.co/40x40" },
|
||||||
{ id: crypto.randomUUID(), name: "Backup Server", image: "https://placehold.co/40x40" },
|
{ id: ServerID.newV7(), name: "Backup Server", image: "https://placehold.co/40x40" },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(overview_data)
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (currentPageID) {
|
if (currentPageID) {
|
||||||
let f = overview_data.friends.find(friend => friend.id === currentPageID);
|
if(UserID.is(currentPageID)) {
|
||||||
let g = overview_data.groups.find(group => group.id === currentPageID);
|
currentPage = overview_data.friends.find(friend => friend.id === currentPageID);
|
||||||
let s = overview_data.servers.find(server => server.id === currentPageID);
|
} else if(GroupID.is(currentPageID)) {
|
||||||
|
currentPage = overview_data.groups.find(group => group.id === currentPageID);
|
||||||
if(f) {
|
} else if(ServerID.is(currentPageID)) {
|
||||||
currentPageType = "friend";
|
currentPage = overview_data.servers.find(server => server.id === currentPageID);
|
||||||
currentPage = f;
|
|
||||||
} else if(g) {
|
|
||||||
currentPageType = "group";
|
|
||||||
currentPage = g;
|
|
||||||
} else if(s) {
|
|
||||||
currentPageType = "server";
|
|
||||||
currentPage = s;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
currentPage = null;
|
currentPage = undefined;
|
||||||
currentPageType = null;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -52,22 +45,24 @@
|
||||||
<Sidebar.Inset>
|
<Sidebar.Inset>
|
||||||
<header class="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
<header class="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
<Sidebar.Trigger class="-ms-1" />
|
<Sidebar.Trigger class="-ms-1" />
|
||||||
{#if currentPageType == "server"}
|
{#if currentPageID && currentPage}
|
||||||
{@const server = (currentPage as Server)}
|
{#if ServerID.is(currentPageID)}
|
||||||
|
{@const server = (currentPage as Server)}
|
||||||
|
|
||||||
<img src={server!.image} alt={server!.name} class="size-6 rounded-full" />
|
<img src={server!.image} alt={server!.name} class="size-6 rounded-full" />
|
||||||
|
|
||||||
<h1>{server!.name}</h1>
|
<h1>{server!.name}</h1>
|
||||||
{:else if currentPageType == "friend"}
|
{:else if UserID.is(currentPageID)}
|
||||||
{@const friend = (currentPage as Friend)}
|
{@const friend = (currentPage as User)}
|
||||||
|
|
||||||
<img src={friend.image} alt={friend!.name} class="size-6 rounded-full" />
|
<img src={friend.image} alt={friend!.name} class="size-6 rounded-full" />
|
||||||
|
|
||||||
<h1>{friend!.name} [{friend.status == Status.ONLINE ? "Online!" : friend.status == Status.DND ? "DND" : friend.status == Status.OFFLINE ? "Offline" : "Unknown"}]</h1>
|
<h1>{friend!.name} [{friend.status == Status.ONLINE ? "Online!" : friend.status == Status.DND ? "DND" : friend.status == Status.OFFLINE ? "Offline" : "Unknown"}]</h1>
|
||||||
{:else if currentPageType == "group"}
|
{:else if GroupID.is(currentPageID)}
|
||||||
{@const group = (currentPage as Group)}
|
{@const group = (currentPage as Group)}
|
||||||
|
|
||||||
<h1>{group!.name} ({group.members} member{group.members > 1 ? "s" : ""})</h1>
|
<h1>{group!.name} ({group.members} member{group.members > 1 ? "s" : ""})</h1>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</header>
|
</header>
|
||||||
<h1> this is like lowkirkounely the content, i should put messages and shi here</h1>
|
<h1> this is like lowkirkounely the content, i should put messages and shi here</h1>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
<div class="flex min-h-screen flex-col items-center justify-center gap-2">
|
<div class="flex min-h-screen flex-col items-center justify-center gap-2">
|
||||||
<div class='w-1/2 p-2 bg-secondary rounded-md '>
|
<div class='w-1/2 p-2 bg-secondary rounded-md '>
|
||||||
<div class="text-center pb-2">
|
<div class="text-center pb-2">
|
||||||
<Title size="2xl"></Title>
|
<Title class="text-2xl"></Title>
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="?/register">
|
<form method="post" action="?/register">
|
||||||
<Input name="username" class="mb-2" type="text" placeholder="Username"></Input>
|
<Input name="username" class="mb-2" type="text" placeholder="Username"></Input>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue