├── .cargo-ok ├── .github └── FUNDING.yml ├── examples ├── create-wasm-app │ ├── .gitignore │ ├── .travis.yml │ ├── performance.js │ ├── bootstrap.js │ ├── log.js │ ├── webpack.config.js │ ├── .bin │ │ └── create-wasm-app.js │ ├── LICENSE-MIT │ ├── package.json │ ├── index.html │ ├── README.md │ ├── index.js │ ├── LICENSE-APACHE │ └── phrases.js ├── voy-with-nextjs │ ├── .prettierrc │ ├── public │ │ ├── voy.gif │ │ ├── favicon.ico │ │ ├── vercel.svg │ │ ├── thirteen.svg │ │ └── next.svg │ ├── src │ │ ├── styles │ │ │ ├── Home.module.css │ │ │ └── globals.css │ │ ├── pages │ │ │ ├── _document.tsx │ │ │ ├── _app.tsx │ │ │ ├── api │ │ │ │ ├── process.ts │ │ │ │ └── embeddings.ts │ │ │ ├── index.tsx │ │ │ ├── server-side.tsx │ │ │ └── client-side.tsx │ │ ├── components │ │ │ ├── NavigationBar.module.css │ │ │ └── NavigationBar.tsx │ │ └── context │ │ │ └── VoyContext.tsx │ ├── README.md │ ├── next.config.js │ ├── .gitignore │ ├── tsconfig.json │ ├── package.json │ ├── LICENSE_MIT │ └── LICENSE_APACHE └── nextjs-transformersjs │ ├── .eslintrc.json │ ├── public │ ├── favicon.ico │ ├── vercel.svg │ └── next.svg │ ├── postcss.config.js │ ├── pages │ ├── _app.tsx │ ├── _document.tsx │ ├── api │ │ └── hello.ts │ └── index.tsx │ ├── next.config.js │ ├── .gitignore │ ├── tailwind.config.js │ ├── tsconfig.json │ ├── styles │ └── globals.css │ ├── package.json │ └── README.md ├── voy.gif ├── .gitignore ├── src ├── wasm │ ├── mod.rs │ ├── types.rs │ ├── voy.rs │ └── fns.rs ├── engine │ ├── mod.rs │ ├── hash.rs │ ├── tests │ │ └── mod.rs │ └── engine.rs ├── lib.rs └── utils.rs ├── tests └── web.rs ├── .appveyor.yml ├── books.json ├── LICENSE_MIT ├── Cargo.toml ├── .travis.yml ├── README.md └── LICENSE_APACHE /.cargo-ok: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: DawChihLiou 2 | -------------------------------------------------------------------------------- /examples/create-wasm-app/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /voy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tantaraio/voy/HEAD/voy.gif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | bin/ 5 | pkg/ 6 | wasm-pack.log 7 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false 4 | } 5 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /src/wasm/mod.rs: -------------------------------------------------------------------------------- 1 | mod fns; 2 | mod types; 3 | mod voy; 4 | 5 | pub use fns::*; 6 | pub use types::*; 7 | pub use voy::*; 8 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/public/voy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tantaraio/voy/HEAD/examples/voy-with-nextjs/public/voy.gif -------------------------------------------------------------------------------- /examples/create-wasm-app/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: "10" 3 | 4 | script: 5 | - ./node_modules/.bin/webpack 6 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tantaraio/voy/HEAD/examples/voy-with-nextjs/public/favicon.ico -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tantaraio/voy/HEAD/examples/nextjs-transformersjs/public/favicon.ico -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/engine/mod.rs: -------------------------------------------------------------------------------- 1 | mod engine; 2 | mod hash; 3 | 4 | #[cfg(test)] 5 | mod tests; 6 | 7 | pub use engine::{add, clear, index, remove, search, size, Index, Query}; 8 | pub use hash::hash; 9 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/styles/Home.module.css: -------------------------------------------------------------------------------- 1 | #example { 2 | display: block; 3 | width: 100%; 4 | } 5 | 6 | .primary { 7 | font-weight: bold; 8 | } 9 | 10 | .secondary { 11 | font-weight: 100; 12 | color: gray; 13 | } -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '@/styles/globals.css' 2 | import type { AppProps } from 'next/app' 3 | 4 | export default function App({ Component, pageProps }: AppProps) { 5 | return 6 | } 7 | -------------------------------------------------------------------------------- /src/engine/hash.rs: -------------------------------------------------------------------------------- 1 | use std::collections::hash_map::DefaultHasher; 2 | use std::hash::{Hash, Hasher}; 3 | 4 | pub fn hash(target: &T) -> u64 { 5 | let mut hasher = DefaultHasher::new(); 6 | target.hash(&mut hasher); 7 | 8 | hasher.finish() 9 | } 10 | -------------------------------------------------------------------------------- /examples/create-wasm-app/performance.js: -------------------------------------------------------------------------------- 1 | export const perf = () => { 2 | const t0 = performance.now(); 3 | return { 4 | stop() { 5 | const t1 = performance.now(); 6 | const seconds = ((t1 - t0) / 1000).toFixed(2); 7 | return seconds; 8 | }, 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod engine; 2 | mod utils; 3 | mod wasm; 4 | 5 | pub use wasm::*; 6 | 7 | // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global 8 | // allocator. 9 | #[cfg(feature = "wee_alloc")] 10 | #[global_allocator] 11 | static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; 12 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | webpack: function (config, options) { 5 | config.experiments = { asyncWebAssembly: true }; 6 | return config; 7 | }, 8 | }; 9 | 10 | module.exports = nextConfig; 11 | -------------------------------------------------------------------------------- /tests/web.rs: -------------------------------------------------------------------------------- 1 | //! Test suite for the Web and headless browsers. 2 | 3 | #![cfg(target_arch = "wasm32")] 4 | 5 | extern crate wasm_bindgen_test; 6 | use wasm_bindgen_test::*; 7 | 8 | wasm_bindgen_test_configure!(run_in_browser); 9 | 10 | #[wasm_bindgen_test] 11 | fn pass() { 12 | assert_eq!(1 + 1, 2); 13 | } 14 | -------------------------------------------------------------------------------- /examples/create-wasm-app/bootstrap.js: -------------------------------------------------------------------------------- 1 | // A dependency graph that contains any wasm must all be imported 2 | // asynchronously. This `bootstrap.js` file does the single async import, so 3 | // that no one else needs to worry about it again. 4 | import("./index.js") 5 | .catch(e => console.error("Error importing `index.js`:", e)); 6 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from 'next/document' 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from "next/document"; 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { VoyProvider } from "@/context/VoyContext"; 2 | import "@/styles/globals.css"; 3 | import type { AppProps } from "next/app"; 4 | 5 | export default function App({ Component, pageProps }: AppProps) { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /.appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe 3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly 4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin 5 | - rustc -V 6 | - cargo -V 7 | 8 | build: false 9 | 10 | test_script: 11 | - cargo test --locked 12 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from 'next' 3 | 4 | type Data = { 5 | name: string 6 | } 7 | 8 | export default function handler( 9 | req: NextApiRequest, 10 | res: NextApiResponse 11 | ) { 12 | res.status(200).json({ name: 'John Doe' }) 13 | } 14 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | yarn dev 9 | ``` 10 | 11 | Open [http://localhost:3000](http://localhost:3000) with your browser to see Voy and Next.js. 12 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | pub fn set_panic_hook() { 2 | // When the `console_error_panic_hook` feature is enabled, we can call the 3 | // `set_panic_hook` function at least once during initialization, and then 4 | // we will get better error messages if our code ever panics. 5 | // 6 | // For more details see 7 | // https://github.com/rustwasm/console_error_panic_hook#readme 8 | #[cfg(feature = "console_error_panic_hook")] 9 | console_error_panic_hook::set_once(); 10 | } 11 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/components/NavigationBar.module.css: -------------------------------------------------------------------------------- 1 | .ul { 2 | display: block; 3 | 4 | margin-left: 0; 5 | padding-left: 0; 6 | } 7 | 8 | .ul li { 9 | display: inline; 10 | } 11 | 12 | .ul li a { 13 | text-decoration: none; 14 | color: #fff; 15 | background-color: rgb(55, 55, 60); 16 | padding: 1rem 1rem; 17 | border-radius: 0.5rem; 18 | box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px; 19 | font-weight: bold; 20 | font-family: Arial; 21 | margin: 0.1rem; 22 | 23 | } -------------------------------------------------------------------------------- /examples/voy-with-nextjs/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | webpack: (config, context) => { 5 | config.experiments = { 6 | ...config.experiments, 7 | topLevelAwait: true, 8 | asyncWebAssembly: true, 9 | }; 10 | 11 | config.module.rules.push({ 12 | test: /\.md$/i, 13 | use: "raw-loader", 14 | }); 15 | 16 | return config; 17 | }, 18 | transpilePackages: ["@visheratin/web-ai"], 19 | }; 20 | 21 | module.exports = nextConfig; 22 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/styles/globals.css: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | align-items: center; 6 | min-height: 100vh; 7 | background-color: #121212; 8 | color: #ffffff; 9 | font-size: 16px; 10 | font-family: Arial, Helvetica, sans-serif; 11 | } 12 | 13 | section { 14 | background-color: rgb(36, 36, 36); 15 | padding: 1rem 2rem; 16 | border-radius: 1rem; 17 | width: 48rem; 18 | box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px; 19 | } 20 | 21 | 22 | img { 23 | max-width: 100%; 24 | } -------------------------------------------------------------------------------- /examples/voy-with-nextjs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 5 | './components/**/*.{js,ts,jsx,tsx,mdx}', 6 | './app/**/*.{js,ts,jsx,tsx,mdx}', 7 | ], 8 | theme: { 9 | extend: { 10 | backgroundImage: { 11 | 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 12 | 'gradient-conic': 13 | 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | } 19 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/context/VoyContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext, PropsWithChildren } from "react"; 2 | 3 | import * as voy from "voy-search"; 4 | 5 | const VoyContext = createContext(null); 6 | 7 | export const useVoy = () => { 8 | const context = useContext(VoyContext); 9 | if (context === null) { 10 | throw new Error("useVoy must be used within a VoyProvider"); 11 | } 12 | return context; 13 | }; 14 | 15 | export const VoyProvider = ({ children }: PropsWithChildren) => { 16 | return {children}; 17 | }; 18 | -------------------------------------------------------------------------------- /examples/create-wasm-app/log.js: -------------------------------------------------------------------------------- 1 | const append = (box) => (str) => { 2 | const input = Array.isArray(str) ? str : [str]; 3 | 4 | input.forEach((s) => { 5 | const para = document.createElement("p"); 6 | const text = document.createTextNode(s); 7 | 8 | para.appendChild(text); 9 | box.appendChild(para); 10 | }); 11 | }; 12 | const intro = document.querySelector("#intro"); 13 | const index = document.querySelector("#index"); 14 | const resource = document.querySelector("#resource"); 15 | 16 | export const logIntro = append(intro); 17 | export const logIndex = append(index); 18 | export const logResource = append(resource); 19 | -------------------------------------------------------------------------------- /examples/create-wasm-app/webpack.config.js: -------------------------------------------------------------------------------- 1 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | mode: "development", 6 | entry: "./bootstrap.js", 7 | output: { 8 | path: path.resolve(__dirname, "dist"), 9 | filename: "bootstrap.js", 10 | }, 11 | plugins: [new CopyWebpackPlugin(["index.html"])], 12 | experiments: { 13 | asyncWebAssembly: true, 14 | syncWebAssembly: true, 15 | }, 16 | devServer: { 17 | static: { 18 | directory: path.join(__dirname, "dist"), 19 | }, 20 | compress: true, 21 | port: 3000, 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/create-wasm-app/.bin/create-wasm-app.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require("child_process"); 4 | const fs = require("fs"); 5 | 6 | let folderName = '.'; 7 | 8 | if (process.argv.length >= 3) { 9 | folderName = process.argv[2]; 10 | if (!fs.existsSync(folderName)) { 11 | fs.mkdirSync(folderName); 12 | } 13 | } 14 | 15 | const clone = spawn("git", ["clone", "https://github.com/rustwasm/create-wasm-app.git", folderName]); 16 | 17 | clone.on("close", code => { 18 | if (code !== 0) { 19 | console.error("cloning the template failed!") 20 | process.exit(code); 21 | } else { 22 | console.log("🦀 Rust + 🕸 Wasm = ❤"); 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "paths": { 18 | "@/*": ["./*"] 19 | } 20 | }, 21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | } 20 | }, 21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/components/NavigationBar.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | 3 | import classes from "./NavigationBar.module.css"; 4 | 5 | export const NavigationBar = () => { 6 | return ( 7 | <> 8 |

Voy

9 |

🕸️🦀 A WASM vector similarity search written in Rust

10 |
    11 |
  • 12 | ⭐ Start 13 |
  • 14 | 15 |
  • 16 | 🌐 Server Side Example 17 |
  • 18 | 19 |
  • 20 | 🧑🏽‍💻 Client Side Example 21 |
  • 22 |
23 | 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/pages/api/process.ts: -------------------------------------------------------------------------------- 1 | import { NextApiRequest, NextApiResponse } from "next"; 2 | 3 | import { load } from "@tensorflow-models/universal-sentence-encoder"; 4 | 5 | require("@tensorflow/tfjs-node"); 6 | 7 | import { index, search } from "voy-search"; 8 | 9 | const model = await load(); 10 | 11 | export default async function handler( 12 | req: NextApiRequest, 13 | res: NextApiResponse 14 | ) { 15 | const { embeddings = [], searchQuery = "" } = JSON.parse(req.body); 16 | 17 | const indexed = index({ embeddings }); 18 | 19 | const q = await model.embed([searchQuery.toString()]); 20 | const result = search(indexed, q.arraySync()[0] as any, 4); 21 | 22 | res.status(200).json(result); 23 | } 24 | -------------------------------------------------------------------------------- /examples/nextjs-transformersjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "voy-nextjs-transformersjs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@types/node": "20.4.1", 13 | "@types/react": "18.2.14", 14 | "@types/react-dom": "18.2.6", 15 | "@xenova/transformers": "^2.4.0", 16 | "autoprefixer": "10.4.14", 17 | "eslint": "8.44.0", 18 | "eslint-config-next": "13.4.9", 19 | "next": "13.4.9", 20 | "postcss": "8.4.25", 21 | "react": "18.2.0", 22 | "react-dom": "18.2.0", 23 | "tailwindcss": "3.3.2", 24 | "typescript": "5.1.6", 25 | "voy-search": "file:../../pkg" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /books.json: -------------------------------------------------------------------------------- 1 | { 2 | "books": [ 3 | { 4 | "title": "The Great Gatsby", 5 | "author": "F. Scott Fitzgerald", 6 | "summary": "The story primarily concerns the young and mysterious millionaire Jay Gatsby and his quixotic passion and obsession with the beautiful former debutante Daisy Buchanan." 7 | }, 8 | { 9 | "title": "The Catcher in the Rye", 10 | "author": "J. D. Salinger", 11 | "summary": "The story is told in the first person by Holden Caulfield, a cynical teenager who recently has been expelled from prep school." 12 | }, 13 | { 14 | "title": "The Grapes of Wrath", 15 | "author": "John Steinbeck", 16 | "summary": "The novel tells the story of the Joad family, who are driven from their Oklahoma homestead and forced to travel west to the promised land of California." 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/pages/api/embeddings.ts: -------------------------------------------------------------------------------- 1 | import { NextApiRequest, NextApiResponse } from "next"; 2 | 3 | import { load } from "@tensorflow-models/universal-sentence-encoder"; 4 | 5 | require("@tensorflow/tfjs-node"); 6 | 7 | const model = await load(); 8 | 9 | export default async function handler( 10 | _req: NextApiRequest, 11 | res: NextApiResponse 12 | ) { 13 | const phrases = [ 14 | "That is a very happy Person", 15 | "That is a Happy Dog", 16 | "Today is a sunny day", 17 | "Yesterday is a sunny day", 18 | ]; 19 | 20 | // Create text embeddings 21 | const processed = await model.embed(phrases); 22 | const data = processed.arraySync().map((result: number[], i: number) => ({ 23 | id: String(i), 24 | title: phrases[i], 25 | url: `/path/${i}`, 26 | embeddings: result, 27 | })); 28 | 29 | res.status(200).json({ embeddings: data }); 30 | } 31 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "voy-with-nextjs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@tensorflow-models/universal-sentence-encoder": "1.3.1", 13 | "@tensorflow/tfjs": "^4.2.0", 14 | "@tensorflow/tfjs-converter": "^2.0.1", 15 | "@tensorflow/tfjs-core": "^4.2.0", 16 | "@tensorflow/tfjs-node": "^4.2.0", 17 | "@types/node": "18.15.11", 18 | "@types/react": "18.0.31", 19 | "@types/react-dom": "18.0.11", 20 | "@visheratin/web-ai": "^0.7.4", 21 | "jimp": "^0.22.7", 22 | "next": "13.2.4", 23 | "node-localstorage": "^2.2.1", 24 | "raw-loader": "^4.0.2", 25 | "react": "18.2.0", 26 | "react-dom": "18.2.0", 27 | "react-markdown": "^8.0.6", 28 | "rehype-raw": "^6.1.1", 29 | "typescript": "5.0.3", 30 | "voy-search": "file:../../pkg" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | 3 | import ReactMarkdown from "react-markdown"; 4 | import rehypeRaw from "rehype-raw"; 5 | 6 | import { NavigationBar } from "@/components/NavigationBar"; 7 | 8 | const readme = require("./../../../../README.md").default; 9 | 10 | export default function Home() { 11 | return ( 12 | <> 13 | 14 | Voy & Next.js Example 15 | 16 | 17 | 18 |
19 | 20 |
21 |

22 | This example project includes a client side project using 23 | @visheratin/web-ai for the embeddings, and a server side project 24 | using @tensorflow-models/universal-sentence-encoder for the 25 | embeddings. 26 |

27 |
28 | {readme} 29 |
30 |
31 | 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /examples/voy-with-nextjs/public/thirteen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/wasm/types.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | use tsify::Tsify; 3 | 4 | pub type NumberOfResult = usize; 5 | pub type Query = Vec; 6 | pub type SerializedIndex = String; 7 | 8 | #[derive(Serialize, Deserialize, Debug, Clone, Tsify)] 9 | #[tsify(into_wasm_abi, from_wasm_abi)] 10 | pub struct EmbeddedResource { 11 | pub id: String, 12 | pub title: String, 13 | pub url: String, 14 | pub embeddings: Vec, 15 | } 16 | 17 | #[derive(Serialize, Deserialize, Debug, Tsify)] 18 | #[tsify(into_wasm_abi, from_wasm_abi)] 19 | pub struct Resource { 20 | // TODO: Support different type of resources 21 | // pub documents: Vec, 22 | // pub audio: Vec