commit 49fd7832ae2fe5af13236007a67deafa29c1a5aa Author: Gilad S Date: Sun Aug 13 00:03:50 2023 +0300 feat: first commit diff --git a/.commitlintrc.json b/.commitlintrc.json new file mode 100644 index 0000000..f4fbb7d --- /dev/null +++ b/.commitlintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["@commitlint/config-conventional"] +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2caf72c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +root = true + +[*] +indent_style = space +indent_size = 4 + +[{*.ts,*.tsx,*.js,*.jsx,*.css,*.scss}] +insert_final_newline = true + +[{package.json,package-lock.json,manifest.json}] +indent_size = 2 + +[.babelrc] +indent_size = 2 + +[*.yml] +indent_size = 2 diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..6f39a4b --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,126 @@ +{ + "root": true, + "env": { + "node": true, + "browser": false, + "es6": true + }, + "ignorePatterns": ["/dist", "/llama"], + "extends": [ + "eslint:recommended" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 2021, + "sourceType": "module" + }, + "overrides": [{ + "files": ["**.ts"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint", + "import", + "node" + ], + "rules": { + "@typescript-eslint/explicit-module-boundary-types": ["off"], + "@typescript-eslint/ban-ts-comment": ["off"], + "@typescript-eslint/no-explicit-any": ["off"], + "semi": ["off"], + "@typescript-eslint/semi": ["warn", "always"], + "@typescript-eslint/no-inferrable-types": ["off"] + } + }], + "plugins": [ + "@typescript-eslint", + "import", + "node" + ], + "settings": { + "import/parsers": { + "@typescript-eslint/parser": [".ts"] + } + }, + "rules": { + "indent": ["warn", 4, { + "SwitchCase": 1, + "FunctionDeclaration": { + "parameters": "first" + } + }], + "eqeqeq": ["off"], + "no-undef": "off", + "quotes": ["warn", "double", { "avoidEscape": true }], + "no-unused-vars": ["warn", { + "args": "none", + "ignoreRestSiblings": true, + "varsIgnorePattern": "^set" + }], + "no-prototype-builtins": ["off"], + "object-curly-spacing": ["warn", "never"], + "semi": ["warn", "always"], + "no-undefined": ["off"], + "array-bracket-newline": ["error", "consistent"], + "brace-style": ["error", "1tbs", { + "allowSingleLine": false + }], + "comma-spacing": ["error", { + "before": false, + "after": true + }], + "comma-style": ["error", "last"], + "comma-dangle": ["error", "never"], + "no-var": ["error"], + "import/order": ["error", { + "groups": ["builtin", "external","internal", "parent", "sibling", "index", "type", "object", "unknown"], + "warnOnUnassignedImports": true + }], + "node/file-extension-in-import": ["error", "always", { + "tryExtensions": [".js", ".json"] + }], + "newline-per-chained-call": ["error", { + "ignoreChainWithDepth": 2 + }], + "no-confusing-arrow": ["error"], + "no-const-assign": ["error"], + "no-duplicate-imports": ["error", { + "includeExports": true + }], + "camelcase": ["warn"], + "jsx-quotes": ["warn"], + "yoda": ["error", "never", { + "exceptRange": true + }], + "no-eval": ["error"], + "array-callback-return": ["error"], + "valid-jsdoc": ["error", { + "requireParamType": true, + "requireReturnType": true, + "requireReturn": false, + "requireParamDescription": false, + "requireReturnDescription": false + }], + "no-empty": ["error", { + "allowEmptyCatch": true + }], + "keyword-spacing": ["warn"], + "space-infix-ops": ["warn"], + "spaced-comment": ["warn", "always"], + "eol-last": ["warn", "always"], + "max-len": ["warn", { + "code": 140, + "tabWidth": 4, + "ignoreStrings": true + }] + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f4c82a1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +*.ico filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.webp filter=lfs diff=lfs merge=lfs -text +*.woff2 filter=lfs diff=lfs merge=lfs -text diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..0368857 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,32 @@ +### Description of change + + + + +### Pull-Request Checklist + + + +- [ ] Code is up-to-date with the `master` branch +- [ ] `npm run format` to apply prettier formatting +- [ ] `npm run test` passes with this change +- [ ] This pull request links relevant issues as `Fixes #0000` +- [ ] There are new or updated unit tests validating the change +- [ ] Documentation has been updated to reflect this change +- [ ] The new commits follow conventions explained in [CONTRIBUTING.md](https://github.com/withcatai/node-llama-cpp/blob/master/CONTRIBUTING.md) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..16c6bf6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,208 @@ +name: Build +on: + push: + + workflow_dispatch: + + + +concurrency: release-${{ github.ref }} +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "20" + - name: Install modules + run: npm ci --ignore-scripts + - name: Build + run: npm run build + - name: Publish artifact + uses: actions/upload-artifact@v3 + with: + name: "build" + path: "dist" + + build-binaries: + name: Build binaries - ${{ matrix.config.name }} + needs: + - build + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - name: "Windows MSVC" + os: windows-2022 + cc: "cl" + cxx: "cl" + environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" + generators: "Visual Studio 17 2022" + artifact: "win" + - name: "Ubuntu GCC" + os: ubuntu-22.04 + cc: "gcc" + cxx: "g++" + generators: "Ninja" + artifact: "linux" + - name: "macOS Clang" + os: macos-12 + cc: "clang" + cxx: "clang++" + generators: "Xcode" + artifact: "mac" + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "20" + + - uses: actions/download-artifact@v3 + with: + name: build + path: dist + + - uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install dependencies on windows + if: startsWith(matrix.config.os, 'windows') + run: | + choco install ninja cmake + + - name: Install dependencies on ubuntu + if: startsWith(matrix.config.name, 'Ubuntu Latest GCC') + run: | + sudo apt-get update + sudo apt-get install ninja-build cmake libtbb-dev + + - name: Install dependencies on macos + if: startsWith(matrix.config.os, 'macos') + run: | + brew install cmake ninja + alias make=cmake + + - name: Setup & Build + id: build + shell: bash + timeout-minutes: 40 + env: + ARTIFACT_NAME: ${{ matrix.config.artifact }} + run: | + npm ci --ignore-scripts + + npx zx -y <<'EOF' + + async function getLatestNodeVersions(maxDate) { + const res = await fetch("https://nodejs.org/dist/index.json"); + const data = await res.json(); + const versions = new Map(); + let latestVersion = null; + + for (const version of data) { + const majorVersion = Number(version.version.split(".")[0].slice("v".length)); + const versionDate = new Date(version.date); + + if (maxDate != null && versionDate.getTime() > maxDate) + continue; + + if (!versions.has(majorVersion)) { + versions.set(majorVersion, version.version); + } + + if (latestVersion === null || majorVersion > latestVersion) { + latestVersion = majorVersion; + } + } + + return {versions, latestVersion}; + } + + function getArches() { + switch (process.env.ARTIFACT_NAME) { + case "win": + return ["x64"]; + case "linux": + return ["x64", "arm64", "armv7l", "ppc64le"]; + case "mac": + return ["x64", "arm64"]; + } + + return ["x64"]; + } + + const {versions: latestNodeVersions, latestVersion: latestNodeVersion} = await getLatestNodeVersions(Date.now() - 1000 * 60 * 60 * 24 * 14); + + const minNodeVersion = latestNodeVersion - 4; + + const nodeVersions = [...latestNodeVersions].reduce((acc, [majorVersion, version]) => { + if (majorVersion >= minNodeVersion) + acc.push(version); + + return acc; + }, []); + const arches = getArches(); + + console.log("Building for node versions", nodeVersions, "and archs", arches); + + await $`mkdir -p llamaBins`; + + for (const nodeVersion of nodeVersions) { + for (const arch of arches) { + console.log(`Building ${arch} for node ${nodeVersion}`); + + const majorNodeVersion = parseInt(nodeVersion.slice("v".length)) + + const binName = `${process.env.ARTIFACT_NAME}-${arch}-${majorNodeVersion}.node`; + await $`node ./dist/cli/cli.js download --arch ${arch} --nodeTarget ${nodeVersion}`; + await $`mv ./llama/build/Release/llama.node ${"./llamaBins/" + binName}`; + } + } + + await $`echo "Built binaries:"`; + await $`ls llamaBins`; + + EOF + + - name: Publish artifact + uses: actions/upload-artifact@v3 + with: + name: "bins-${{ matrix.config.artifact }}" + path: "llamaBins/*" + + release: + name: Release + if: github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + needs: + - build + - build-binaries + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "20" + - name: Install modules + run: npm ci --ignore-scripts + - uses: actions/download-artifact@v3 + with: + path: artifacts + - name: Move artifacts + run: | + mkdir -p llamaBins + mv artifacts/bins-*/* llamaBins/ + mv artifacts/build dist/ + + echo "Built binaries:" + ls llamaBins + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npx semantic-release + diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..c0f2da3 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,16 @@ +name: Test +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "18" + - name: Install modules + run: npm ci --ignore-scripts + - name: ESLint + run: npx eslint --ext .js --ext .ts . + - name: TypeScript validity + run: npm run test:typescript diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7728c11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +/.idea +/.vscode +node_modules +.DS_Store + +/dist + +/.env +/.eslintcache + +/llama/compile_commands.json +/llama/llama.cpp +/llama/.temp +/llama/build +/llama/Release +/llama/Debug +/llamaBins diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..e810522 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npx --no -- commitlint --edit $1 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +* diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..fe88970 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,12 @@ +{ + "branches": [ + "master" + ], + "ci": true, + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/npm", + "@semantic-release/github" + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..710de8e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,81 @@ +## Commit Message Guidelines + +This repository has very precise rules over how git commit messages can be formatted. +This leads to **more readable messages** that are easy to follow when looking through **project history**. +But also, git commit messages as used to **generate changelog**. + +### Commit Message Format +Each commit message consists of a **header**, a **body** and a **footer**. +The header has a special format that includes a **type** and a **subject**: + +``` +: + + + +