Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ Thanks for your support.

Your donation encourages `typia` development.

Also, `typia` is re-distributing half of donations to core contributors of `typia`.

- [`nonara/ts-patch`](https://github.com/nonara/ts-patch)
- [`ryoppippi/unplugin-typia`](https://github.com/ryoppippi/unplugin-typia)
Also, `typia` is re-distributing quarter of donations to [`nonara/ts-patch`](https://github.com/nonara/ts-patch).

[![Sponsors](https://opencollective.com/typia/badge.svg?avatarHeight=75&width=600)](https://opencollective.com/typia)

Expand Down
182 changes: 182 additions & 0 deletions website/src/components/home/HomeCodeHighlight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
"use client";

import React, { ReactNode } from "react";

// VS Code Dark+ inspired colors
const COLORS = {
keyword: "#c586c0", // import, from, const, interface, type, export, return, if, await, async, new
declare: "#569cd6", // const, let, var, function, class
string: "#ce9178", // "...", '...', `...`
comment: "#6a9955", // // ...
type: "#4ec9b0", // type names after : or generic
number: "#b5cea8", // numeric literals
func: "#dcdcaa", // function calls
param: "#9cdcfe", // parameters, variables
operator: "#d4d4d4", // = , ; . etc
bracket: "#ffd700", // < > for generics
default: "#d4d4d4",
};

const KEYWORDS = new Set([
"import", "from", "export", "return", "if", "else", "throw",
"await", "async", "new", "typeof", "instanceof", "in", "of",
"for", "while", "do", "switch", "case", "break", "continue",
"try", "catch", "finally", "default", "as", "extends", "implements",
]);

const DECLARES = new Set([
"const", "let", "var", "function", "class", "interface", "type",
"enum", "namespace", "module", "abstract", "readonly",
]);

const BUILTIN_TYPES = new Set([
"string", "number", "boolean", "void", "null", "undefined",
"never", "any", "unknown", "object", "true", "false",
"Record", "Partial", "Required", "Array", "Promise",
"Uint8Array", "FormData", "URLSearchParams",
]);

interface Token {
type: "keyword" | "declare" | "string" | "comment" | "type" | "number" | "func" | "operator" | "default";
value: string;
}

function tokenize(code: string): Token[] {
const tokens: Token[] = [];
let i = 0;

while (i < code.length) {
// Line comments
if (code[i] === "/" && code[i + 1] === "/") {
let end = code.indexOf("\n", i);
if (end === -1) end = code.length;
tokens.push({ type: "comment", value: code.slice(i, end) });
i = end;
continue;
}

// Block comments
if (code[i] === "/" && code[i + 1] === "*") {
let end = code.indexOf("*/", i + 2);
if (end === -1) end = code.length;
else end += 2;
tokens.push({ type: "comment", value: code.slice(i, end) });
i = end;
continue;
}

// Strings (double quote)
if (code[i] === '"') {
let end = i + 1;
while (end < code.length && code[end] !== '"') {
if (code[end] === "\\") end++;
end++;
}
end++;
tokens.push({ type: "string", value: code.slice(i, end) });
i = end;
continue;
}

// Strings (single quote)
if (code[i] === "'") {
let end = i + 1;
while (end < code.length && code[end] !== "'") {
if (code[end] === "\\") end++;
end++;
}
end++;
tokens.push({ type: "string", value: code.slice(i, end) });
i = end;
continue;
}

// Template literals
if (code[i] === "`") {
let end = i + 1;
while (end < code.length && code[end] !== "`") {
if (code[end] === "\\") end++;
end++;
}
end++;
tokens.push({ type: "string", value: code.slice(i, end) });
i = end;
continue;
}

// Numbers
if (/[0-9]/.test(code[i]) && (i === 0 || /[\s,;:(=<>!+\-*/&|^~\[\]\{]/.test(code[i - 1]))) {
let end = i;
while (end < code.length && /[0-9._eExXa-fA-F]/.test(code[end])) end++;
tokens.push({ type: "number", value: code.slice(i, end) });
i = end;
continue;
}

// Identifiers and keywords
if (/[a-zA-Z_$]/.test(code[i])) {
let end = i;
while (end < code.length && /[a-zA-Z0-9_$]/.test(code[end])) end++;
const word = code.slice(i, end);

if (KEYWORDS.has(word)) {
tokens.push({ type: "keyword", value: word });
} else if (DECLARES.has(word)) {
tokens.push({ type: "declare", value: word });
} else if (BUILTIN_TYPES.has(word)) {
tokens.push({ type: "type", value: word });
} else if (end < code.length && code[end] === "(") {
// Function call
tokens.push({ type: "func", value: word });
} else if (word[0] === word[0].toUpperCase() && /[a-z]/.test(word.slice(1))) {
// PascalCase — likely a type
tokens.push({ type: "type", value: word });
} else {
tokens.push({ type: "default", value: word });
}
i = end;
continue;
}

// Whitespace
if (/\s/.test(code[i])) {
let end = i;
while (end < code.length && /\s/.test(code[end])) end++;
tokens.push({ type: "operator", value: code.slice(i, end) });
i = end;
continue;
}

// Operators and punctuation
tokens.push({ type: "operator", value: code[i] });
i++;
}

return tokens;
}

const COLOR_MAP: Record<Token["type"], string> = {
keyword: COLORS.keyword,
declare: COLORS.declare,
string: COLORS.string,
comment: COLORS.comment,
type: COLORS.type,
number: COLORS.number,
func: COLORS.func,
operator: COLORS.operator,
default: COLORS.default,
};

const HomeCodeHighlight = (props: { children: string }) => {
const tokens = tokenize(props.children);
return (
<>
{tokens.map((token, i) => (
<span key={i} style={{ color: COLOR_MAP[token.type] }}>
{token.value}
</span>
))}
</>
);
};
export default HomeCodeHighlight;
3 changes: 3 additions & 0 deletions website/src/components/home/HomeLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ const HomeLayout = styled("div")(({ theme }) => ({
marginLeft: "-15rem",
marginRight: "-15rem",
},
"& > *": {
maxWidth: "100%",
},
}));
export default HomeLayout;
23 changes: 7 additions & 16 deletions website/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import Stack from '@mui/material/Stack';
],
[
"Build Status",
"https://github.com/samchon/typia/workflows/build/badge.svg",
"https://github.com/samchon/typia/actions?query=workflow%3Abuild",
"https://github.com/samchon/typia/workflows/test/badge.svg",
"https://github.com/samchon/typia/actions?query=workflow%3Atest",
],
[
"Guide Documents",
Expand Down Expand Up @@ -68,17 +68,11 @@ export namespace json {

// AI FUNCTION CALLING SCHEMA
export namespace llm {
// collection of function calling schemas
// collection of function calling schemas + validators/parsers
export function application<Class>(): ILlmApplication<Class>;
export function controller<Class>(
name: string,
execute: Class,
): ILlmController; // +executor
// structured output
export function parameters<P>(): ILlmSchema.IParameters;
export function schema<T>(
$defs: Record<string, ILlmSchema>,
): ILlmSchema; // type schema
export function structuredOutput<P>(): ILlmStructuredOutput;
// lenient json parser + type corecion
export function parse<T>(str: string): T;
Comment on lines +74 to +75
}

// PROTOCOL BUFFER
Expand Down Expand Up @@ -151,10 +145,7 @@ Thanks for your support.

Your donation encourages `typia` development.

Also, `typia` is re-distributing half of donations to core contributors of `typia`.

- [`nonara/ts-patch`](https://github.com/nonara/ts-patch)
- [`ryoppippi/unplugin-typia`](https://github.com/ryoppippi/unplugin-typia)
Also, `typia` is re-distributing quarter of donations to [`nonara/ts-patch`](https://github.com/nonara/ts-patch).

[![Sponsors](https://opencollective.com/typia/badge.svg?avatarHeight=75&width=600)](https://opencollective.com/typia)

Expand Down
54 changes: 13 additions & 41 deletions website/src/content/index.mdx
Original file line number Diff line number Diff line change
@@ -1,54 +1,26 @@
---
title: Home
---
import HomeLayout from "../components/home/HomeLayout";
import HomeHeroMovie from "../movies/HomeHeroMovie";
import HomeCompilationMovie from "../movies/HomeCompilationMovie";
import HomeStrengthMovie from "../movies/HomeStrengthMovie";
import HomeInnovationMovie from "../movies/HomeInnovationMovie";
import HomeLlmMovie from "../movies/HomeLlmMovie";
import HomeSponsorMovie from "../movies/HomeSponsorMovie";
import HomeLayout from "../components/home/HomeLayout";

## Transformer

![Typia Logo](/logo.png)

<center>
[Guide Documents](/docs) · [Playground (Online IDE)](/playground) · [Github Repository](https://github.com/samchon/typia)
</center>
<HomeLayout>

`typia` is a transformer library converting TypeScript types to runtime function.
<HomeHeroMovie />

If you call one of the `typia` function, it would be compiled like below. This is the key concept of `typia`, transforming TypeScript type to a runtime function. The `typia.is<T>()` function is transformed to a dedicated type checker by analyzing the target type `T` in the compilation level.
<HomeCompilationMovie />

This feature enables developers to ensure type safety in their applications, leveraging TypeScript's static typing while also providing runtime validation. Instead of defining additional schemas, you can simply utilize the pure TypeScript type itself.
<HomeStrengthMovie />

```typescript
//----
// examples/checkString.ts
//----
import typia, { tags } from "typia";
export const checkString = typia.createIs<string>();
<HomeInnovationMovie />

//----
// examples/checkString.js
//----
import typia from "typia";
export const checkString = (() => {
return (input) => "string" === typeof input;
})();
```
<HomeLlmMovie />

## Key Features
<HomeSponsorMovie />

<HomeLayout>
<HomeStrengthMovie />
</HomeLayout>

## Sponsors

Thanks for your support.

Your donation encourages `typia` development.

Also, `typia` is re-distributing half of donations to core contributors of `typia`.

- [`nonara/ts-patch`](https://github.com/nonara/ts-patch)
- [`ryoppippi/unplugin-typia`](https://github.com/ryoppippi/unplugin-typia)

[![Sponsors](https://opencollective.com/typia/badge.svg?avatarHeight=75&width=600)](https://opencollective.com/typia)
Loading
Loading