Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .clinerules
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ You are working on bQuery.js (`@bquery/bquery`), a batteries-included TypeScript

bQuery.js is not a utility library; its broad module surface is the product. The reactive module now also covers HTTP clients, polling, pagination, WebSocket / SSE, REST helpers, request queues, and request deduplication.

Current release baseline: **1.16.0**.
Current release baseline: **1.16.1**.

Version `1.16.1` is a toolchain-and-build maintenance patch with no source, API, or module status changes: the Bun floor moves from `1.3.13` to `1.4.0` (Node.js stays `>=24.0.0`), dev dependencies are refreshed (Storybook `10.5.10`, `@typescript-eslint/*` `8.68.0`, `eslint` `10.9.1`, `happy-dom` `20.11.6`, `vite` `8.2.2`), and both Vite configs build warning-free — `import.meta.dirname` instead of `__dirname` for `configLoader: 'native'`, plus a throwing `node:*` stub in the UMD/IIFE build so the unreachable `node:http` import in `createServer().listen()` stops triggering Vite's browser-externalized warning.

Version `1.16.0` is a quality-and-performance release with no breaking changes and no module status transitions. `@bquery/bquery/reactive`: `batch()` coalesces transitive updates (diamond dependencies trigger their effect once per batch), computeds re-validate and notify subscribers only when their value actually changes (`Object.is`), hot-path allocation cuts on signal writes and dependency tracking; the only new API is the additive `trailing` option on `watchThrottle` (`WatchThrottleOptions`). `@bquery/bquery/core`: `undelegate()` works across wrapper instances (module-level delegation registry; `delegate()` idempotent per handler tuple), `wrap()` clone correctness, cheaper `replaceWith(string)`/`empty()`/`children()`/`siblings()`/`index()`/`unwrap()`. `@bquery/bquery/view`: unchanged DOM writes skipped (fixes the `bq-model` caret reset), `bq-for` dispatched before other directives on the same element, `bq-once`/`bq-memo`/`bq-init` evaluate untracked. `@bquery/bquery/motion`: `onReducedMotionChange` re-binds to the current `window.matchMedia` on subscribe. `@bquery/bquery/store`: `deepClone` special-cases only the dangerous `__proto__` key.

Expand All @@ -29,7 +31,7 @@ Version `1.12.0` adds Store plugin teardown APIs (`unregisterPlugin()`, `clearPl
- Read `AGENT.md` for the full architecture, module API tables, and common tasks.
- All commands use Bun: `bun test`, `bun run build`, `bun run lint`.
- Tests use `bun:test` imports and `happy-dom` for DOM simulation.
- Supported engines: Node.js `>=24.0.0`, Bun `>=1.3.13`.
- Supported engines: Node.js `>=24.0.0`, Bun `>=1.4.0`.
- If you touch release metadata or repo guidance files, run `bun run check:ai-guidance` before finishing.

## Core Invariants
Expand Down
8 changes: 6 additions & 2 deletions .cursorrules
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ You are working on bQuery.js, a batteries-included TypeScript full-stack web fra

> Derived snapshot for Cursor. If this file conflicts with `package.json`, `src/*/index.ts`, or `AGENT.md`, trust those files in that order and then realign this one.

Current release baseline: **1.16.0**.
Current release baseline: **1.16.1**.

Version `1.15.0` graduates the final thirteen modules to **Stable** — `view`, `forms`, `i18n`, `a11y`, `dnd`, `media`, `plugin`, `devtools`, `testing`, `storybook`, `concurrency`, `ssr`, `server` — so every module is now Stable, with no Beta or Experimental tiers (canonical record: `STABILITY.md`, enforced by `bun run check:stability`). Additive APIs this cycle: `@bquery/bquery/view` enter/leave/move transitions + the optional `@bquery/bquery/view/compiler` (no `'unsafe-eval'`); `@bquery/bquery/forms` `formAction`/`useFormStatus`/`optimistic`; `@bquery/bquery/i18n` ICU MessageFormat + `@bquery/bquery/i18n/extract` (`bquery-i18n` CLI); an opt-in file-route convention (`createFileRoutes`, `mountFileRoutes`) with typed `load`/`action`; `@bquery/bquery/server` `session`/`csrf`/`guard`/`basicAuth`/`bearerAuth`; `@bquery/bquery/ssr` production `hydrate`/`detectHydrationMismatches` + resumable boundaries; a versioned `@bquery/bquery/devtools` bridge protocol + reference extension; and `definePlugin()`. No breaking changes.

Expand All @@ -13,7 +13,7 @@ bQuery.js is not a utility library; treat its broad module surface as the produc
## Critical Rules

- Tooling/tests: Use Bun for repository workflows (`bun test`, `bun:test` imports). Runtime support for SSR/server workflows includes Node.js, and runtime-agnostic server APIs may also target environments such as Deno where applicable.
- Supported toolchain: Node.js `>=24.0.0`, Bun `>=1.3.13`.
- Supported toolchain: Node.js `>=24.0.0`, Bun `>=1.4.0`.
- TypeScript: strict mode, ES2020 target, Bundler module resolution.
- Security: ALL DOM HTML writes MUST use `sanitizeHtml()` from `src/security/sanitize.ts` (re-exported via `src/security/index.ts`).
- Chaining: Mutating methods on `BQueryElement` / `BQueryCollection` return `this`.
Expand All @@ -24,6 +24,10 @@ bQuery.js is not a utility library; treat its broad module surface as the produc
- `useSignal()`, `useComputed()`, and `useEffect()` from `@bquery/bquery/component` must be called from component lifecycle hooks, not from `render()`.
- When version, engine, or repo guidance files change, run `bun run check:ai-guidance` before finishing.

## 1.16.1 API Notes

- Toolchain-and-build maintenance patch with no source, API, or module status changes: the Bun floor moves from `1.3.13` to `1.4.0` (Node.js stays `>=24.0.0`), dev dependencies are refreshed (Storybook `10.5.10`, `@typescript-eslint/*` `8.68.0`, `eslint` `10.9.1`, `happy-dom` `20.11.6`, `vite` `8.2.2`), and both Vite configs build warning-free — `import.meta.dirname` instead of `__dirname` for `configLoader: 'native'`, plus a throwing `node:*` stub in the UMD/IIFE build so the unreachable `node:http` import in `createServer().listen()` stops triggering Vite's browser-externalized warning.

## 1.16.0 API Notes

- Quality-and-performance release; no breaking changes, no module status transitions. `@bquery/bquery/reactive`: `batch()` coalesces transitive updates, computeds notify subscribers only when their value actually changes (`Object.is`), hot-path allocation cuts; additive `trailing` option on `watchThrottle` (`WatchThrottleOptions`) is the only new API.
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ body:
id: runtime
attributes:
label: Runtime details
description: Include your runtime and version, for example Node 24, Bun 1.3.13, Chrome 136, or Safari 18.
placeholder: Bun 1.3.13 on macOS 15
description: Include your runtime and version, for example Node 24, Bun 1.4.0, Chrome 136, or Safari 18.
placeholder: Bun 1.4.0 on macOS 15
validations:
required: true
- type: textarea
Expand Down
17 changes: 12 additions & 5 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Work autonomously inside the scope of the current request, but do not invent a h

bQuery.js is a batteries-included framework, not a utility library. It is modular, tree-shakeable, has zero runtime dependencies, and currently ships **23 public entry points**.

Current release baseline: **1.16.0**.
Current release baseline: **1.16.1**.

Version `1.15.0` graduates the final thirteen modules to **Stable** — `view`, `forms`, `i18n`, `a11y`, `dnd`, `media`, `plugin`, `devtools`, `testing`, `storybook`, `concurrency`, `ssr`, `server` — so every module is now Stable, with no Beta or Experimental tiers (canonical record: `STABILITY.md`, enforced by `bun run check:stability`). Additive APIs this cycle: `@bquery/bquery/view` enter/leave/move transitions + the optional `@bquery/bquery/view/compiler` (no `'unsafe-eval'`); `@bquery/bquery/forms` `formAction`/`useFormStatus`/`optimistic`; `@bquery/bquery/i18n` ICU MessageFormat + `@bquery/bquery/i18n/extract` (`bquery-i18n` CLI); an opt-in file-route convention (`createFileRoutes`, `mountFileRoutes`) with typed `load`/`action`; `@bquery/bquery/server` `session`/`csrf`/`guard`/`basicAuth`/`bearerAuth`; `@bquery/bquery/ssr` production `hydrate`/`detectHydrationMismatches` + resumable boundaries; a versioned `@bquery/bquery/devtools` bridge protocol + reference extension; and `definePlugin()`. No breaking changes.

Expand All @@ -32,6 +32,13 @@ Prefer pointing back to those files instead of duplicating large architecture se

For repo guidance refreshes, keep the role split clear: `AGENT.md` is the deep reference, `llms.txt` is the compact mirror, this file stays behavioral/meta-oriented, and `.cursorrules` / `.clinerules` are derivative tool snapshots.

## Version 1.16.1 highlights

- Toolchain-and-build maintenance patch. Nothing under `src/` changed: no API changes, no breaking changes, no module status transitions — every 1.16.0 API behaves identically.
- Supported Bun floor moves from `1.3.13` to `1.4.0` (`engines.bun`), mirrored in `mise.toml`, the runtime support matrix, the AI guidance files, and the bug-report template. Node.js stays at `>=24.0.0`. CI installs `bun-version: 'latest'`; the SSR cross-runtime matrix leg `bun-1.3` is now `bun-1.4`.
- Build: `vite.config.ts` and `vite.umd.config.ts` use `import.meta.dirname` instead of `__dirname` (compatible with Vite's `configLoader: 'native'`), and the UMD/IIFE build stubs `node:*` with a throwing module so the unreachable `node:http` import in `createServer().listen()` no longer triggers Vite's browser-externalized warning. Bundle contents unchanged.
- Dev dependencies refreshed: Storybook `10.5.10`, `@typescript-eslint/*` `8.68.0`, `bun-types` `1.4.0`, `eslint` `10.9.1`, `globals` `17.11.0`, `happy-dom` `20.11.6`, `vite` `8.2.2`. Still zero runtime dependencies.

## Version 1.16.0 highlights

- Quality-and-performance release; no breaking changes, no module status transitions. `@bquery/bquery/reactive`: `batch()` coalesces transitive updates (diamond dependencies trigger their effect once per batch), computeds re-validate and notify subscribers only when their value actually changes (`Object.is`), hot-path allocation cuts on signal writes and dependency tracking; the only new API is the additive `trailing` option on `watchThrottle` (`WatchThrottleOptions`).
Expand All @@ -53,7 +60,7 @@ For repo guidance refreshes, keep the role split clear: `AGENT.md` is the deep r
- `@bquery/bquery/testing` graduates into a batteries-included tier: auto cleanup (`cleanup`, `autoCleanup`); `fireEvent.click`/`.input`/`.change`/`.submit`/`.focus`/`.blur`/`.dblClick`/`.keyDown`/`.keyUp` shortcut methods on the existing `fireEvent`; `userEvent` namespace with `click`, `dblClick`, `hover`, `unhover`, `type`, `clear`, `selectOptions`, `tab`, `paste`; shadow-DOM-aware screen queries via `screen` and `within(el)` with `getByRole`/`getByText`/`getByLabelText`/`getByPlaceholderText`/`getByTestId` plus their `query*` and `find*` variants; reactive harnesses (`mockComputed`, `mockEffect`); async helpers (`tick`, `nextTick`, `flushPromises`, `runScheduled`); module mocks (`mockStore`, `mockI18n`, `mockForm`, `mockFetch`, `mockWebSocket`); snapshot/a11y helpers (`prettyDOM`, `getReactiveSummary`, `expectAccessible`).
- Additive 1.14.0 module expansions: `@bquery/bquery/router` (`NavigationResult`, `pushResult`/`replaceResult`, `beforeResolve`, `resolveRoute`, dynamic `addRoute`/`removeRoute`/`hasRoute`, `isReady`, `lastNavigation`, `useNavigation`), `@bquery/bquery/view` (`parseDirective`, `ParsedDirective`, new `bq-once`/`bq-init`/`bq-pre`/`bq-cloak`/`bq-html-safe`/`bq-memo`, full `bq-on` modifier system), `@bquery/bquery/a11y` (`createLiveRegion`, `keyboardUserSignal`, `focusVisible`, `prefersReducedTransparency`/`prefersReducedData`/`forcedColors`, `inert`/`scrollLock`/`autoFocus`), `@bquery/bquery/i18n` (`negotiateLocale`, `detectLocale`, `isRTL`, `formatRelativeTime`/`formatList`/`formatDisplayName`/`segment`), `@bquery/bquery/dnd` (programmatic handle APIs, `grid`/`delay`/`touchStartThreshold`/`keyboard`/`keyboardStep`, `'viewport'` bounds, reactive `useDraggable`/`useDroppable`/`useSortable`), `@bquery/bquery/storybook` (`classMap`/`styleMap`/`ifDefined`/`repeat`/`storyText`/`unsafeHtml`/`storySvg`), `@bquery/bquery/concurrency` (`withTransferables`, `createSharedBuffer`, RPC `maxInFlight`, pool priorities, `pause`/`resume`/`onIdle`, rolling reactive metrics), `@bquery/bquery/ssr` (`flushBoundary`, `createSSRCache`, `createSSRMetrics`, `createEdgeHandler`, cache-aware `renderToResponse`, multi-chunk `renderToStream`), and `@bquery/bquery/server` (`ServerHttpError`, `ctx.body`/`ctx.cookies`/`ctx.setCookie`/`ctx.accepts`/`ctx.stream`/`ctx.sse`/`ctx.renderStream`/`ctx.renderResponse`, `app.listen()`).
- The `1.13.0` forms/component/motion/core-utils baselines remain first-class public surface, as do the `1.12.0` store/reactive surface (`unregisterPlugin`, `clearPlugins`, `WebSocketSendData`), the `1.11.0` SSR/server runtime (`createServer`, `renderToStringAsync`, `renderToStream`, `renderToResponse`, runtime-agnostic WebSocket sessions), `1.10.0` concurrency, and `1.9.0` watcher/view/media APIs.
- Publish and local validation target Node.js `>=24.0.0` and Bun `>=1.3.13`; when release metadata or repo guidance changes, `bun run check:ai-guidance` is part of the expected validation.
- Publish and local validation target Node.js `>=24.0.0` and Bun `>=1.4.0`; when release metadata or repo guidance changes, `bun run check:ai-guidance` is part of the expected validation.

## Version 1.13.0 highlights

Expand All @@ -63,7 +70,7 @@ For repo guidance refreshes, keep the role split clear: `AGENT.md` is the deep r
- `@bquery/bquery/core` adds a deep `utils/` expansion: array helpers (`groupBy`, `keyBy`, `partition`, `zip`, `range`, `take`, `drop`, `sample`, `shuffle`, `uniqueBy`, `sortBy`, `intersection`, `difference`, `flattenDeep`, `move`, `chunkBy`); function helpers (`memoize`, `compose`, `pipe`, `curry`, `partial`, `retry`, plus richer `debounce`/`throttle` options + `.flush()`); object helpers (deep `get`/`set`/`has`, `mapValues`, `mapKeys`, `invert`, `deepEqual`/`isEqual`, deep `freeze`, `defaults`, typed `entriesTyped`/`keysTyped`); string helpers (`toSnakeCase`, `toPascalCase`, `toTitleCase`, `pad`, `wordCount`, safe `template`, `stripHtml`, `randomString`, `lines`); number helpers (`round`, `roundTo`, `lerp`, `inverseLerp`, `mapRange`, `formatBytes`, `randomFloat`, `sum`, `average`, `median`, `degToRad`, `radToDeg`); misc helpers (`uuid`, `tryCatch`, `times`, `pollUntil`, `nextFrame`, `nextTick`); and additional type guards (`isError`, `isMap`, `isSet`, `isRegExp`, `isSymbol`, `isBigInt`, `isAsyncFunction`, `isIterable`, `isAsyncIterable`, `isNullish`, `isDefined`).
- The `1.12.0` store/reactive surface (`unregisterPlugin`, `clearPlugins`, `WebSocketSendData`) and the `1.11.0` SSR/server runtime (`createServer`, `renderToStringAsync`, `renderToStream`, `renderToResponse`, runtime-agnostic WebSocket sessions) remain first-class public surface.
- The `1.10.0` concurrency additions plus the `1.9.0` watcher/view/media APIs remain first-class public surface and should still appear in documentation refreshes.
- Publish and local validation target Node.js `>=24.0.0` and Bun `>=1.3.13`; when release metadata or repo guidance changes, `bun run check:ai-guidance` is part of the expected validation.
- Publish and local validation target Node.js `>=24.0.0` and Bun `>=1.4.0`; when release metadata or repo guidance changes, `bun run check:ai-guidance` is part of the expected validation.

## Version 1.12.0 highlights

Expand All @@ -72,7 +79,7 @@ For repo guidance refreshes, keep the role split clear: `AGENT.md` is the deep r
- The `/full` bundle and `bun run check:full-bundle` now cover public type-only export drift for platform, a11y, and media surfaces.
- The `1.11.0` server/SSR runtime surface remains first-class; repo guidance should still treat `createServer()`, runtime-agnostic WebSocket sessions, `renderToStringAsync()`, `renderToStream()`, and `renderToResponse()` as documented surface.
- The `1.10.0` concurrency additions plus the `1.9.0` watcher/view/media APIs remain first-class public surface and should still appear in documentation refreshes.
- Publish and local validation target Node.js `>=24.0.0` and Bun `>=1.3.13`; when release metadata or repo guidance changes, `bun run check:ai-guidance` is part of the expected validation.
- Publish and local validation target Node.js `>=24.0.0` and Bun `>=1.4.0`; when release metadata or repo guidance changes, `bun run check:ai-guidance` is part of the expected validation.

## Source of truth

Expand Down Expand Up @@ -118,7 +125,7 @@ For any implementation task, follow this order:

Use Bun for repository workflows.

Supported engines: Node.js `>=24.0.0`, Bun `>=1.3.13`.
Supported engines: Node.js `>=24.0.0`, Bun `>=1.4.0`.

- `bun test` — primary test suite with `happy-dom`
- `bun test --watch` — watch mode
Expand Down
2 changes: 1 addition & 1 deletion .github/skills/bquery-ssr-server-workflow/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Typical triggers:
- `src/index.ts`
- `src/full.ts`
2. Inspect the nearby implementation before editing behavior.
3. Preserve runtime-agnostic behavior across Node.js >= 24, Bun >= 1.3.13, and Deno unless the task explicitly changes support.
3. Preserve runtime-agnostic behavior across Node.js >= 24, Bun >= 1.4.0, and Deno unless the task explicitly changes support.
4. Update tests together with the implementation:
- `tests/ssr.test.ts`
- `tests/ssr-runtime.test.ts`
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: '1.3.13'
bun-version: 'latest'

- name: Install dependencies
run: bun install --frozen-lockfile
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/eslint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.13'
bun-version: 'latest'

- name: Install dependencies
run: bun install --frozen-lockfile
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.13'
bun-version: 'latest'
- run: bun install --frozen-lockfile
- run: bun test
- run: bun run build
Expand All @@ -33,7 +33,7 @@ jobs:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.13'
bun-version: 'latest'
- run: bun install --frozen-lockfile
- run: bun run build:docs
- uses: actions/upload-pages-artifact@v5
Expand All @@ -55,7 +55,7 @@ jobs:
registry-url: 'https://registry.npmjs.org'
- uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.14'
bun-version: 'latest'

- run: bun install --frozen-lockfile
- run: bun run build
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/ssr-cross-runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: '1.3.13'
bun-version: 'latest'

- name: Install dependencies
run: bun install --frozen-lockfile
Expand All @@ -51,7 +51,7 @@ jobs:
fail-fast: false
matrix:
include:
- runtime: bun-1.3
- runtime: bun-1.4
- runtime: node-24
- runtime: deno-2

Expand All @@ -66,13 +66,13 @@ jobs:
path: dist

- name: Setup Bun
if: matrix.runtime == 'bun-1.3'
if: matrix.runtime == 'bun-1.4'
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: '1.3.13'
bun-version: 'latest'

- name: Run smoke test (Bun)
if: matrix.runtime == 'bun-1.3'
if: matrix.runtime == 'bun-1.4'
run: bun tests/cross-runtime/run.mjs

- name: Setup Node 24
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: '1.3.13'
bun-version: 'latest'

- name: Install dependencies
run: bun install --frozen-lockfile
Expand Down
Loading
Loading