diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..3b8bd73 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +public/* \ No newline at end of file diff --git a/components/onesearch/onesearch.tsx b/components/onesearch/onesearch.tsx index c6f5b46..daccf96 100644 --- a/components/onesearch/onesearch.tsx +++ b/components/onesearch/onesearch.tsx @@ -110,13 +110,12 @@ export default function OneSearch() { })(); }, []); - useEffect(() => { if (tokenizer !== null) return; (async function () { await loadTokenizer(); })(); - },[]); + }, []); async function loadModel(modelPath: string) { ort.env.wasm.wasmPaths = "/onnx/"; diff --git a/lib/nlp/tokenize/BPEtokenizer.ts b/lib/nlp/tokenize/BPEtokenizer.ts index 4ef9d70..8a9abc7 100644 --- a/lib/nlp/tokenize/BPEtokenizer.ts +++ b/lib/nlp/tokenize/BPEtokenizer.ts @@ -1,81 +1,81 @@ class TrieNode { - children: Map; - tokenId: number | null; + children: Map; + tokenId: number | null; - constructor() { - this.children = new Map(); - this.tokenId = null; - } + constructor() { + this.children = new Map(); + this.tokenId = null; + } } class Trie { - root: TrieNode; + root: TrieNode; - constructor() { - this.root = new TrieNode(); - } + constructor() { + this.root = new TrieNode(); + } - insert(token: string, tokenId: number) { - let node = this.root; - for (const char of token) { - if (!node.children.has(char)) { - node.children.set(char, new TrieNode()); - } - node = node.children.get(char)!; - } - node.tokenId = tokenId; - } + insert(token: string, tokenId: number) { + let node = this.root; + for (const char of token) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + node = node.children.get(char)!; + } + node.tokenId = tokenId; + } - searchLongestToken(text: string): [number | null, number] { - let node = this.root; - let longestTokenId: number | null = null; - let currentTokenLength = 0; + searchLongestToken(text: string): [number | null, number] { + let node = this.root; + let longestTokenId: number | null = null; + let currentTokenLength = 0; - for (const char of text) { - if (!node.children.has(char)) { - break; - } - node = node.children.get(char)!; - currentTokenLength += 1; - if (node.tokenId !== null) { - longestTokenId = node.tokenId; - } - } + for (const char of text) { + if (!node.children.has(char)) { + break; + } + node = node.children.get(char)!; + currentTokenLength += 1; + if (node.tokenId !== null) { + longestTokenId = node.tokenId; + } + } - return [longestTokenId, currentTokenLength]; - } + return [longestTokenId, currentTokenLength]; + } } export default class BPETokenizer { - private trie: Trie; + private trie: Trie; - constructor(vocabulary: { [key: string]: number }) { - this.trie = new Trie(); - for (const token in vocabulary) { - if (vocabulary.hasOwnProperty(token)) { - this.trie.insert(token, vocabulary[token]); - } - } - } + constructor(vocabulary: { [key: string]: number }) { + this.trie = new Trie(); + for (const token in vocabulary) { + if (vocabulary.hasOwnProperty(token)) { + this.trie.insert(token, vocabulary[token]); + } + } + } - tokenize(text: string): number[] { - const tokenIds: number[] = []; - let i = 0; + tokenize(text: string): number[] { + const tokenIds: number[] = []; + let i = 0; - while (i < text.length) { - const [longestTokenId, length] = this.trie.searchLongestToken(text.slice(i)); - if (longestTokenId !== null) { - tokenIds.push(longestTokenId); - i += length; - } else { - // If no token is found, treat the character as a single token - tokenIds.push(text.charCodeAt(i)); - i += 1; - } - } + while (i < text.length) { + const [longestTokenId, length] = this.trie.searchLongestToken(text.slice(i)); + if (longestTokenId !== null) { + tokenIds.push(longestTokenId); + i += length; + } else { + // If no token is found, treat the character as a single token + tokenIds.push(text.charCodeAt(i)); + i += 1; + } + } - return tokenIds; - } + return tokenIds; + } } // Example usage: @@ -91,4 +91,4 @@ export default class BPETokenizer { // const text = 'ababbaa'; // const tokenIds = tokenizer.tokenize(text); -// console.log(tokenIds); // Output: [ 3, 3, 6, 1 ] \ No newline at end of file +// console.log(tokenIds); // Output: [ 3, 3, 6, 1 ] diff --git a/lib/server/startScript.ts b/lib/server/startScript.ts new file mode 100644 index 0000000..264ad92 --- /dev/null +++ b/lib/server/startScript.ts @@ -0,0 +1,22 @@ +import { promises as dns } from "node:dns"; + +// Copied from vite/src/node/utils.ts + +/** + * Returns resolved localhost address when `dns.lookup` result differs from DNS + * + * `dns.lookup` result is same when defaultResultOrder is `verbatim`. + * Even if defaultResultOrder is `ipv4first`, `dns.lookup` result maybe same. + * For example, when IPv6 is not supported on that machine/network. + */ +export async function getLocalhostAddressIfDiffersFromDNS(): Promise { + const [nodeResult, dnsResult] = await Promise.all([ + dns.lookup("localhost"), + dns.lookup("localhost", { verbatim: true }) + ]); + const isSame = + nodeResult.family === dnsResult.family && nodeResult.address === dnsResult.address; + return isSame ? undefined : nodeResult.address; +} + +export const wildcardHosts = new Set(["0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"]); diff --git a/package.json b/package.json index 0bc707e..138790d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "sparkhome", + "name": "sparkast", "private": false, "version": "5.8.1", "type": "module", diff --git a/pages/about/index.tsx b/pages/about/index.tsx index 37eb647..1ba9687 100644 --- a/pages/about/index.tsx +++ b/pages/about/index.tsx @@ -48,8 +48,12 @@ export default function AboutPage() {

Presented By

- {!darkMode && } - {darkMode && } + {!darkMode && ( + + )} + {darkMode && ( + + )} ); } diff --git a/server.ts b/server.ts index 43785b6..9e6df04 100644 --- a/server.ts +++ b/server.ts @@ -5,60 +5,32 @@ import pjson from "./package.json"; import { networkInterfaces } from "os"; import cac from "cac"; import { configureBackendRoutes } from "./backend/route"; +import { Server, IncomingMessage, ServerResponse } from "http"; +import { getLocalhostAddressIfDiffersFromDNS, wildcardHosts } from "lib/server/startScript"; async function helloMessage() { const { base } = await ViteExpress.getViteConfig(); - const timeCost = new Date().getTime() - start.getTime(); - console.log(""); + const timeCost = Date.now() - start.getTime(); console.log( - " ", - chalk.redBright("SparkHome"), - chalk.redBright("v" + pjson.version), - chalk.whiteBright(" ready in"), - `${Math.round(timeCost)} ms` + `\n ${chalk.redBright("sparkast v" + pjson.version)} ${chalk.whiteBright("ready in")} ${Math.round(timeCost)} ms\n` ); - console.log(""); - console.log( - " ", - chalk.redBright("➜ "), - "Local:\t", - chalk.cyan(`http://${host}:${port}${base}`) - ); - if (host !== "localhost") { - for (const ip of ips) { + console.log(` ${chalk.redBright("➜ Local:")} ${chalk.cyan(`http://${name}:${port}${base}`)}`); + if (host === undefined) { + ips.forEach((ip) => console.log( - " ", - chalk.redBright("➜ "), - "Network:\t", - chalk.cyan(`http://${ip}:${port}${base}`) - ); - } + ` ${chalk.redBright("➜ Network:")} ${chalk.cyan(`http://${ip}:${port}${base}`)}` + ) + ); } - console.log( - " ", - chalk.red("➜ "), - chalk.whiteBright("press"), - "h + enter", - chalk.whiteBright("to show help") - ); + console.log(` ${chalk.red("➜ ")}${chalk.whiteBright("press h + enter to show help")}`); } -async function handleInput() { +async function handleInput(server: Server) { for await (const line of console) { - switch (line) { + switch (line.trim()) { case "h": - console.log(" Shortcuts"); console.log( - " ", - chalk.whiteBright("press"), - "c + enter ", - chalk.whiteBright("to clear console") - ); - console.log( - " ", - chalk.whiteBright("press"), - "q + enter ", - chalk.whiteBright("to quit") + ` Shortcuts\n ${chalk.whiteBright("press c + enter to clear console")}\n ${chalk.whiteBright("press q + enter to quit")}` ); break; case "c": @@ -68,8 +40,6 @@ async function handleInput() { server.on("vite:close", () => {}); server.close(); return; - default: - break; } } } @@ -77,41 +47,48 @@ async function handleInput() { const start = new Date(); const cli = cac(); const nets = networkInterfaces(); -const ips: string[] = []; -for (const name of Object.keys(nets)) { - if (nets[name] === undefined) { - continue; - } - for (const net of nets[name]) { - // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses - // 'IPv4' is in Node <= 17, from 18 it's a number 4 or 6 - const familyV4Value = typeof net.family === "string" ? "IPv4" : 4; - if (net.family === familyV4Value && !net.internal) { - ips.push(net.address); - } - } -} +const ips: string[] = Object.values(nets) + .flat() + .filter( + (net) => + !!net && net.family === (typeof net.family === "string" ? "IPv4" : 4) && !net.internal + ) + .map((net) => (!!net ? net.address : undefined)) + .filter((v) => v !== undefined); const app = express(); const port = 3000; -let host = "localhost"; -cli.option("--host [host]", "Sepcify host name"); -cli.help(); -cli.version(pjson.version); +let host: string | undefined = "localhost"; + +cli.option("--host [host]", "Specify host name").help().version(pjson.version); const parsed = cli.parse(); -if ( - parsed.options.host !== undefined && - typeof parsed.options.host == "boolean" && - parsed.options.host -) { - host = "0.0.0.0"; +const optionsHost: string | boolean | undefined = parsed.options.host; + +if (optionsHost === undefined || optionsHost === false) { + // Use a secure default + host = "localhost"; +} else if (optionsHost === true) { + // If passed --host in the CLI without arguments + host = undefined; // undefined typically means 0.0.0.0 or :: (listen on all IPs) +} else { + host = optionsHost; +} + +// Set host name to localhost when possible +let name = host === undefined || wildcardHosts.has(host) ? "localhost" : host; + +if (host === "localhost") { + const localhostAddr = await getLocalhostAddressIfDiffersFromDNS(); + if (localhostAddr) { + name = localhostAddr; + } } configureBackendRoutes(app); - -const server = app.listen(port, host); +// if the var `host` is undefined, then just not pass it. +const server = host ? app.listen(port, host) : app.listen(port); ViteExpress.bind(app, server, helloMessage); -handleInput(); +handleInput(server);