diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index d8cdb7c5..00000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.js.map -diff -*.min.js -diff diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml deleted file mode 100644 index 59742a4a..00000000 --- a/.github/workflows/check_dependencies.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: check dependencies -on: - push: - branches: ["master"] - pull_request: - paths: - - '**/package.json' - - '.github/workflows/check_dependencies.yml' -jobs: - check-dependencies: - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - - name: Install dependencies - run: npm i - - name: Check if the dependencies are free of any conflict and match "overrides" in the root package.json - run: npm ls diff --git a/.github/workflows/_common_jobs.yml b/.github/workflows/ci.yml similarity index 54% rename from .github/workflows/_common_jobs.yml rename to .github/workflows/ci.yml index 3d65fbbd..1d1034c7 100644 --- a/.github/workflows/_common_jobs.yml +++ b/.github/workflows/ci.yml @@ -1,36 +1,34 @@ -name: Launch CI jobs for a package or app +name: CI on: - workflow_call: - inputs: - workspace: - required: true - type: string + push: + branches: ["master"] + pull_request: jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm i - - run: npm run lint -w ${{ inputs.workspace }} + - run: npm run lint typecheck: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm i - - run: npm run typecheck -w ${{ inputs.workspace }} + - run: npm run typecheck test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm i - - run: npm run coverage -w ${{ inputs.workspace }} + - run: npm run coverage buildcheck: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm i - - run: npm run build -w ${{ inputs.workspace }} + - run: npm run build \ No newline at end of file diff --git a/.github/workflows/ci_packages_cli.yml b/.github/workflows/ci_packages_cli.yml deleted file mode 100644 index 5d8eeb1f..00000000 --- a/.github/workflows/ci_packages_cli.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: packages/cli -on: - push: - branches: ["master"] - pull_request: - paths: - - 'packages/components/**' - - 'packages/cli/**' - - '.github/workflows/_common_jobs.yml' - - '.github/workflows/ci_packages_cli.yml' - - 'eslint.config.js' - - 'package.json' -jobs: - build-components: - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - - name: Install dependencies - run: npm i - - name: Build components package - run: npm run build -w @hyparam/components - ci: - needs: build-components - uses: ./.github/workflows/_common_jobs.yml - with: - workspace: hyperparam diff --git a/.github/workflows/ci_packages_components.yml b/.github/workflows/ci_packages_components.yml deleted file mode 100644 index 936673a4..00000000 --- a/.github/workflows/ci_packages_components.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: packages/components -on: - push: - branches: ["master"] - pull_request: - paths: - - 'packages/components/**' - - '.github/workflows/_common_jobs.yml' - - '.github/workflows/ci_packages_components.yml' - - 'eslint.config.js' - - 'package.json' -jobs: - ci: - uses: ./.github/workflows/_common_jobs.yml - with: - workspace: '@hyparam/components' diff --git a/.github/workflows/ci_root.yml b/.github/workflows/ci_root.yml deleted file mode 100644 index 5ab17e0a..00000000 --- a/.github/workflows/ci_root.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: root -on: - push: - branches: ["master"] - pull_request: - paths: - - '*' - - 'test/**' - - '.github/workflows/ci_root.yml' - - 'eslint.config.js' -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: npm i - - run: npm run lint - - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: npm i - - run: npm run test diff --git a/.gitignore b/.gitignore index cb5d3b0a..bf9ddadb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,34 @@ -package-lock.json +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + node_modules +dist +dist-ssr +*.local +coverage + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +package-lock.json *.tgz .vscode *.parquet -coverage -.DS_Store +/coverage/ + +/lib/ +tsconfig.tsbuildinfo \ No newline at end of file diff --git a/README.md b/README.md index f7201928..7bd32ba7 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,75 @@ -# Hyperparam monorepo +# hyperparam -This is a monorepo for the Hyperparam project. +[](https://www.npmjs.com/package/hyperparam) +[](https://github.com/hyparam/hyperparam-cli/actions) +[](https://opensource.org/licenses/MIT) + -It contains the following packages, published to npm: +This is the hyperparam cli tool. -- [`@hyparam/components`](./packages/components): a library of React components and utilities for building Hyperparam UIs. -- [`hyperparam`](./packages/cli): a cli tool for viewing arbitrarily large datasets in the browser. +The hyperparam cli tool is for viewing arbitrarily large datasets in the browser. -## Use +## Viewer -Install all the workspaces with: +To open a file browser in your current local directory run: -```bash -npm install +```sh +npx hyperparam ``` -Lint all the workspaces: +You can also pass a specific file, folder, or url: -```bash -npm run lint -ws +```sh +npx hyperparam example.parquet +npx hyperparam directory/ +npx hyperparam https://hyperparam-public.s3.amazonaws.com/bunnies.parquet ``` -Test all the workspaces: +## Chat -```bash -npm test -ws +To start a chat with hyperparam: + +```sh +npx hyperparam chat ``` -Compute the coverage for all the workspaces: +## Installation + +Install for all users: -```bash -npm run coverage -ws +```sh +sudo npm i -g hyperparam ``` -Build all the workspaces (they are built in order, so the dependencies are built first - it's defined manually by the order of the workspaces in the `package.json`): +Now you can just run: -```bash -npm run build -ws +```sh +hyperparam ``` -- `hyperparam`: +or: -```bash -npm run dev -w hyperparam +```sh +hyp ``` -- `components`: +## Developers -```bash -npm run dev -w @hyparam/components -``` +To develop the CLI locally: -## Development +```sh +npm i +npm run dev +``` -The monorepo is managed with [npm workspaces](https://docs.npmjs.com/cli/v10/using-npm/workspaces). Some workspaces are dependencies of others. Currently: +The application will be rebuild automatically when you make changes, and the browser will refresh. -- `@hyparam/components` is a dependency of `hyperparam`. +### Library and application -It means that if you make a change to `@hyparam/components`, you need to rebuild it before developing `hyperparam`. +Hyperparam is an application that relies on node.js scripts in the `bin/` directory and serves the static web application built in the `dist/` directory. -Also, if you increment the version of `@hyparam/components`, you need to update the version of `@hyparam/components` in the `package.json` of `hyperparam`, as we use exact versions in the `package.json` of the workspaces. Note that we don't have to increment the version after every change, only when we want to publish a new version with a significant batch of changes. +The `hyperparam` package also includes a library that can be used in other applications. The library is in the `lib/` directory. For example: -The root package.json contains a special field, `overrides`, which sets the shared dependencies versions we want to have in all the workspaces. The "check_dependencies" GitHub action checks that the dependencies are the same in all the workspaces (`npm ls` would fail if dependency version mismatch). +```js +import { asyncBufferFrom, AsyncBufferFrom, parquetDataFrame } from "hyperparam"; +``` diff --git a/packages/cli/src/chat.js b/bin/chat.js similarity index 100% rename from packages/cli/src/chat.js rename to bin/chat.js diff --git a/packages/cli/src/cli.js b/bin/cli.js similarity index 95% rename from packages/cli/src/cli.js rename to bin/cli.js index 0ce19ebd..c8f27937 100755 --- a/packages/cli/src/cli.js +++ b/bin/cli.js @@ -49,7 +49,7 @@ if (arg === 'chat') { */ function checkForUpdates() { const currentVersion = packageJson.version - return fetch('https://registry.npmjs.org/hyperparam/latest') + return void fetch('https://registry.npmjs.org/hyperparam/latest') .then(response => response.json()) .then(data => { const latestVersion = data.version @@ -58,5 +58,4 @@ function checkForUpdates() { console.log('\x1b[33mRun \'npm install -g hyperparam\' to update\x1b[0m') } }) - .catch(() => {}) // ignore errors } diff --git a/packages/cli/src/serve.js b/bin/serve.js similarity index 96% rename from packages/cli/src/serve.js rename to bin/serve.js index afa2a625..b9688b19 100644 --- a/packages/cli/src/serve.js +++ b/bin/serve.js @@ -80,17 +80,20 @@ function handleRequest(req, serveDirectory) { // get location of hyperparam assets const hyperparamPath = decodeURIComponent(import.meta.url) .replace('file://', '') - .replace('/src/serve.js', '') + .replace('/bin/serve.js', '') if (pathname === '/' || pathname === '/files/') { // redirect to /files return { status: 301, content: '/files' } } else if (pathname.startsWith('/files')) { // serve index.html - return handleStatic(`${hyperparamPath}/public/index.html`) - } else if (pathname.startsWith('/public/')) { + return handleStatic(`${hyperparamPath}/dist/index.html`) + } else if (pathname.startsWith('/assets/') || pathname.startsWith('/favicon') ) { // serve static files - return handleStatic(`${hyperparamPath}${pathname}`) + return handleStatic(`${hyperparamPath}/dist${pathname}`) + // else if (pathname.startsWith('/public/')) { + // // serve static files + // return handleStatic(`${hyperparamPath}${pathname.replace(/^(\/public).*/, '/dist')}`) } else if (serveDirectory && pathname === '/api/store/list') { // serve file list const prefix = parsedUrl.query.prefix || '' diff --git a/packages/cli/src/streamConverters.js b/bin/streamConverters.js similarity index 100% rename from packages/cli/src/streamConverters.js rename to bin/streamConverters.js diff --git a/eslint.config.js b/eslint.config.js index 8034c8bd..bb1ba40b 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,8 +1,12 @@ import javascript from '@eslint/js' +import react from 'eslint-plugin-react' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' import globals from 'globals' +import tseslint from 'typescript-eslint' /** @type {import('eslint').Linter.Config.RulesRecord} */ -export const sharedJsRules = { +const sharedJsRules = { 'arrow-spacing': 'error', camelcase: 'off', 'comma-spacing': 'error', @@ -42,28 +46,66 @@ export const sharedJsRules = { } /** @type {import('eslint').Linter.Config.RulesRecord} */ -export const sharedTsRules = { +const sharedTsRules = { '@typescript-eslint/restrict-template-expressions': 'off', '@typescript-eslint/no-unused-vars': 'warn', '@typescript-eslint/require-await': 'warn', } -/** @type {import('eslint').Linter.Config[]} */ -export default [ +export default tseslint.config( + { ignores: ['coverage/', 'dist/', 'lib/', 'packages/'] }, { - ignores: ['**/coverage/**'], + settings: { react: { version: '18.3' } }, + extends: [javascript.configs.recommended, ...tseslint.configs.strictTypeChecked, ...tseslint.configs.stylisticTypeChecked], + files: ['**/*.{ts,tsx,js}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + project: ['./tsconfig.json', './tsconfig.eslint.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, + plugins: { + 'react': react, + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules, + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + ...javascript.configs.recommended.rules, + ...tseslint.configs.recommended.rules, + ...sharedJsRules, + ...sharedTsRules, + 'no-extra-parens': 'warn', + }, }, { + files: ['test/**/*.{ts,tsx}', '*.{js,ts}'], languageOptions: { + ecmaVersion: 2020, globals: { - ...globals.browser, ...globals.node, + ...globals.browser, }, }, - rules: { - ...javascript.configs.recommended.rules, - ...sharedJsRules, + }, + { + files: ['**/*.js'], + ...tseslint.configs.disableTypeChecked, + }, + { + files: ['bin/**/*.js', 'test/bin/**/*.js'], + languageOptions: { + globals: { + ...globals.node, + }, }, - files: ['eslint.config.js', 'test/**/*.js'], }, -] +) diff --git a/packages/cli/public/index.html b/index.html similarity index 73% rename from packages/cli/public/index.html rename to index.html index 0201371a..e29dff84 100644 --- a/packages/cli/public/index.html +++ b/index.html @@ -3,15 +3,14 @@