From f3f1e7e72c465c90d2554c7150c1017977bf818f Mon Sep 17 00:00:00 2001 From: Mark Stuart Date: Sun, 9 Aug 2026 17:46:40 -0700 Subject: [PATCH 1/2] chore: migrate to ultracite --- biome.jsonc | 4 +++ package.json | 90 ++++++++++++++++++++++++++-------------------------- 2 files changed, 49 insertions(+), 45 deletions(-) create mode 100644 biome.jsonc diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 0000000..a39804b --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,4 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["ultracite/biome/core"] +} diff --git a/package.json b/package.json index f3f8c9e..5b6ec29 100644 --- a/package.json +++ b/package.json @@ -1,47 +1,47 @@ { - "name": "graphql-hash", - "version": "1.0.0", - "description": "Generate a deterministic hash of a GraphQL query for caching and persisted queries", - "license": "MIT", - "repository": "mstuart/graphql-hash", - "funding": "https://github.com/sponsors/mstuart", - "author": { - "name": "Mark Stuart", - "email": "mstuart@users.noreply.github.com", - "url": "https://github.com/mstuart" - }, - "type": "module", - "exports": { - "types": "./index.d.ts", - "default": "./index.js" - }, - "sideEffects": false, - "engines": { - "node": ">=20" - }, - "scripts": { - "test": "xo && ava && tsd" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "graphql", - "hash", - "query", - "persisted", - "cache", - "fingerprint", - "sha256", - "normalize" - ], - "devDependencies": { - "ava": "^7.0.0", - "tsd": "^0.33.0", - "xo": "^1.2.3" - }, - "overrides": { - "@eslint/plugin-kit": ">=0.3.4" - } + "name": "graphql-hash", + "version": "1.0.0", + "description": "Generate a deterministic hash of a GraphQL query for caching and persisted queries", + "keywords": [ + "graphql", + "hash", + "query", + "persisted", + "cache", + "fingerprint", + "sha256", + "normalize" + ], + "repository": "mstuart/graphql-hash", + "funding": "https://github.com/sponsors/mstuart", + "license": "MIT", + "author": { + "name": "Mark Stuart", + "email": "mstuart@users.noreply.github.com", + "url": "https://github.com/mstuart" + }, + "sideEffects": false, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "scripts": { + "check": "ultracite check", + "fix": "ultracite fix", + "test": "ava && tsd" + }, + "devDependencies": { + "@biomejs/biome": "2.5.6", + "ava": "^7.0.0", + "tsd": "^0.33.0", + "ultracite": "7.10.2" + }, + "engines": { + "node": ">=20" + } } From 88a9667a8df0fa7ee21d9d10a6aa25dbe1bf73c0 Mon Sep 17 00:00:00 2001 From: Mark Stuart Date: Sun, 9 Aug 2026 21:08:35 -0700 Subject: [PATCH 2/2] chore: enforce ultracite --- .github/workflows/main.yml | 2 + AGENTS.md | 123 ++++++++++++++++++++++++++++++++ docs/assets/logo.svg | 60 +++++++++++++--- index.d.ts | 8 +-- index.js | 18 ++--- index.test-d.ts | 10 +-- renovate.json | 28 ++++---- test.js | 142 +++++++++++++++++++------------------ 8 files changed, 281 insertions(+), 110 deletions(-) create mode 100644 AGENTS.md diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c97378f..ec99b59 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,4 +19,6 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: npm install + - name: Ultracite check + run: npm run check - run: npm test diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..28d2de8 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,123 @@ +# Ultracite Code Standards + +This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting. + +## Quick Reference + +- **Format code**: `npm exec -- ultracite fix` +- **Check for issues**: `npm exec -- ultracite check` +- **Diagnose setup**: `npm exec -- ultracite doctor` + +Biome (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable. + +--- + +## Core Principles + +Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity. + +### Type Safety & Explicitness + +- Use explicit types for function parameters and return values when they enhance clarity +- Prefer `unknown` over `any` when the type is genuinely unknown +- Use const assertions (`as const`) for immutable values and literal types +- Leverage TypeScript's type narrowing instead of type assertions +- Use meaningful variable names instead of magic numbers - extract constants with descriptive names + +### Modern JavaScript/TypeScript + +- Use arrow functions for callbacks and short functions +- Prefer `for...of` loops over `.forEach()` and indexed `for` loops +- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access +- Prefer template literals over string concatenation +- Use destructuring for object and array assignments +- Use `const` by default, `let` only when reassignment is needed, never `var` + +### Async & Promises + +- Always `await` promises in async functions - don't forget to use the return value +- Use `async/await` syntax instead of promise chains for better readability +- Handle errors appropriately in async code with try-catch blocks +- Don't use async functions as Promise executors + +### React & JSX + +- Use function components over class components +- Call hooks at the top level only, never conditionally +- Specify all dependencies in hook dependency arrays correctly +- Use the `key` prop for elements in iterables (prefer unique IDs over array indices) +- Nest children between opening and closing tags instead of passing as props +- Don't define components inside other components +- Use semantic HTML and ARIA attributes for accessibility: + - Provide meaningful alt text for images + - Use proper heading hierarchy + - Add labels for form inputs + - Include keyboard event handlers alongside mouse events + - Use semantic elements (`