-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.cursorrules
More file actions
138 lines (109 loc) · 15.2 KB
/
Copy path.cursorrules
File metadata and controls
138 lines (109 loc) · 15.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# bQuery.js — Cursor Rules
You are working on bQuery.js, a batteries-included TypeScript full-stack web framework with a jQuery-inspired API.
> 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.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.
bQuery.js is not a utility library; treat its broad module surface as the product, and keep guidance aligned with that scope.
## 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.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`.
- No runtime dependencies. Zero `dependencies` in package.json.
- Keep `src/full.ts` aligned with `src/*/index.ts` whenever public runtime exports change.
- `$()` throws if element not found → use `$$()` for optional queries.
- Signal `.value` tracks dependencies → use `.peek()` to avoid tracking.
- `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.
- `@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.
## 1.15.1 API Notes
- Security-and-correctness patch; no breaking changes. XSS hardening across every HTML sink, evaluator code-execution paths closed, Trusted Types wired in via the new `trustedHtmlForSink()` (`@bquery/bquery/security`), secure-by-default session/CSRF cookies. Additive APIs: `effectScope(detached?)` and `dispose()` on `deferred()`'s handle.
## 1.14.1 API Notes
- `@bquery/bquery/motion` now refreshes its cached reduced-motion `MediaQueryList` whenever `window.matchMedia` changes, so `prefersReducedMotion()` and `reducedMotionSignal()` stay aligned with the active implementation instead of returning stale values.
## 1.14.0 API Notes
- `@bquery/bquery/media` becomes batteries-included with 25+ new reactive composables: preferences (`usePreferredColorScheme`, `usePreferredContrast`, `usePreferredReducedTransparency`, `usePreferredLanguage`, `usePreferredLanguages`); page state (`useOnlineStatus`, `usePageVisibility`, `useDocumentFocus`, `useWindowFocus`, `useIdle`); element observers (`useElementSize`, `useElementBounding`, `useElementVisibility`, `useHover`, `useFocus`, `useFocusWithin`, `useActiveElement`); pointer/scroll (`usePointer`, `useScroll`); platform (`usePermission`, `useWakeLock`, `useShare`, `useShareSupported`, `useBroadcastChannel`, `useEventListener`, `useMediaDevices`, `useStorage`); clipboard upgrades (`isSupported`, `isImageSupported`, `readImage`, `writeImage`, `clipboardText`). All accept optional `{ signal: AbortSignal }`.
- `@bquery/bquery/plugin` adds a WP-style hook bus + DI: `addFilter`/`applyFilters`/`removeFilter`/`listFilters`, `addAction`/`doAction`/`removeAction`/`listActions`, `createInjectionKey`/`provide`/`inject`/`hasProvided`/`resetDi`, `ctx.onCleanup`. New `unuse(name)`/`uninstall(name)` lifecycle; `install` may return `void | Promise<void>`; plugin metadata (`version`, `description`, `dependencies`, `dependencyMode`), `getPluginInfo`, `getInstalledPlugins({ withMetadata: true })`, directive lifecycle objects, namespaced directive names.
- `@bquery/bquery/devtools` ships ring-buffered timelines (`maxTimelineEntries`), expanded `TimelineEntry` (`payload`/`source`/`duration`), new event types (`signal:create`/`signal:dispose`/`effect:dispose`/`component:mount`/`component:unmount`/`component:render`/`route:guard`/`error:caught`/`measure`/`mark`), `filterTimeline`, `subscribeTimeline`, privacy-aware `inspectSignals({ includeValues: false })`, `diffSignals`/`diffStores`, `traceSignal`/`untraceSignal`, `inspectEffects`, `exportDevtoolsSnapshot`/`importDevtoolsSnapshot`, `installBrowserBridge`, plus `time`/`measureRender`/`getPerformanceSummary`.
- `@bquery/bquery/testing` becomes batteries-included: auto-cleanup, `fireEvent.click`/`.input`/`.change`/`.submit`/`.focus`/`.blur`/`.dblClick`/`.keyDown`/`.keyUp` shortcuts; `userEvent` namespace; shadow-DOM-aware screen queries via `screen` + `within`; reactive harnesses (`mockComputed`, `mockEffect`); async helpers (`tick`, `flushPromises`, `runScheduled`); module mocks (`mockStore`, `mockI18n`, `mockForm`, `mockFetch`, `mockWebSocket`); snapshot/a11y (`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`); `@bquery/bquery/server` (`ServerHttpError`, `ctx.body`/`ctx.cookies`/`ctx.setCookie`/`ctx.accepts`/`ctx.stream`/`ctx.sse`/`ctx.renderStream`/`ctx.renderResponse`, `app.listen()`).
## 1.13.0 API Notes
- `@bquery/bquery/forms` graduates to batteries-included: many new validators (`integer`, `numeric`, `between`, `length`, `oneOf`, `notOneOf`, `arrayOf`, `requiredIf`, `requiredUnless`, `dateAfter`, `dateBefore`, `validDate`, `fileSize`, `fileType`) and combinators (`compose`, `all`, `not`, `withMessage`); enriched field/form state (`isValidating`, `isFocused`, `dirtySince`, `disabled`, `submitCount`, `submitError`, `isPristine`, …); dynamic field arrays via `createFieldArray`; fluent `schema()` declaration; two-way DOM bindings (`bindField`, `bindForm`); scope-aware composables (`useForm`, `useField`, `useFieldArray`); SSR helpers (`serializeFormState`, `readSerializedFormState`, `hydrateForm`).
- `@bquery/bquery/component` adds `useSlot` / `hasSlot` / `slotText`, `useRef`, `useAsync`, `whenIdle`, `provide` / `inject` / `formContextKey`, additive `beforeUnmount` and `errorBoundary` hooks, instance-level `setProp` / `getProp`, delegated event helpers (`on`, `onClick`, `onInput`, `onChange`, `onSubmit`, `bindDelegatedEvents`), a `css` tagged template with adoptable stylesheets, and `keyedList` / `reconcileKeyed` for keyed list rendering.
- `@bquery/bquery/motion` ships a major expansion: full Penner easing family with `cubicBezier()` / `steps()` / `mix()` / `chain()`; `tween()` interpolation with full transport controls + `AbortSignal`, plus Promise-based `animateValue()`; `animate()` gains `signal` + `playbackRate`, `animateTo()` builds keyframes from CSS records; `spring()` gains `.velocity()` / `.set()`, `springVector()`, and `wobbly`/`slow`/`molasses` presets; timelines support labels, `reverse()`, `playbackRate()`, `repeat()`, `yoyo()`, `onUpdate()`, `progress()`; new `scrollProgress()`, `inView()`, `magnetic()`, `tilt()`, `shake()`, `pulse()`, `countUp()`; richer `stagger()` (grid, axis, deterministic random); reactive `onReducedMotionChange()` / `reducedMotionSignal()`.
- `@bquery/bquery/core` adds a deep `utils/` expansion: array (`groupBy`, `keyBy`, `partition`, `zip`, `range`, `sample`, `shuffle`, `uniqueBy`, `sortBy`, `intersection`, `difference`, `flattenDeep`, `move`, `chunkBy`, …); function (`memoize`, `compose`, `pipe`, `curry`, `partial`, `retry`, plus richer `debounce`/`throttle` + `.flush()`); object (deep `get`/`set`/`has`, `mapValues`, `mapKeys`, `invert`, `deepEqual`, deep `freeze`, `defaults`, typed iteration); string (`toSnakeCase`, `toPascalCase`, `toTitleCase`, `pad`, `wordCount`, safe `template`, `stripHtml`, `randomString`, `lines`); number (`round`, `roundTo`, `lerp`, `mapRange`, `formatBytes`, `randomFloat`, `sum`, `average`, `median`, …); misc (`uuid`, `tryCatch`, `times`, `pollUntil`, `nextFrame`, `nextTick`); and many extra type guards.
## 1.12.0 API Notes
- `@bquery/bquery/store` includes `unregisterPlugin()` and `clearPlugins()` for plugin teardown, test isolation, and runtime plugin reloads.
- `@bquery/bquery/reactive` exports the public `WebSocketSendData` type for raw WebSocket frames, serializers, and heartbeat messages.
- `src/full.ts` and `bun run check:full-bundle` now cover public type-only export drift for platform, a11y, and media surfaces.
- `@bquery/bquery/server` is a public backend helper entry point; keep `createServer()`, SSR-aware responses, and runtime-agnostic WebSocket session helpers visible in guidance.
- `@bquery/bquery/ssr` includes `renderToStringAsync()`, `renderToStream()`, `renderToResponse()`, `createSSRContext()`, runtime adapters such as `createSSRHandler()`, hydration strategies, store snapshots, and resumability hooks.
- `@bquery/bquery/concurrency` includes explicit RPC workers, task/RPC pools, opt-in reactive worker wrappers, and high-level helpers such as `parallel()`, `batchTasks()`, `map()`, `filter()`, `reduce()`, and `pipeline()`.
- `watchDebounce()` / `watchThrottle()`, `bq-error` / `bq-aria`, and the media observer composables remain first-class public APIs.
## Module Imports
```ts
import { $, $$ } from '@bquery/bquery/core';
import {
signal,
computed,
effect,
batch,
watchDebounce,
watchThrottle,
createHttp,
useWebSocket,
useEventSource,
useResource,
useSubmit,
} from '@bquery/bquery/reactive';
import type { WebSocketSendData } from '@bquery/bquery/reactive';
import { batchTasks, createReactiveRpcPool, createReactiveRpcWorker, createReactiveTaskPool, createReactiveTaskWorker, createRpcPool, createRpcWorker, createTaskPool, createTaskWorker, every, filter, find, map, parallel, pipeline, reduce, runTask, some } from '@bquery/bquery/concurrency';
import { component, html } from '@bquery/bquery/component';
import { storyHtml, when } from '@bquery/bquery/storybook';
import { animate, transition, spring } from '@bquery/bquery/motion';
import { sanitizeHtml, escapeHtml } from '@bquery/bquery/security';
import { storage, cache } from '@bquery/bquery/platform';
import { createRouter, navigate } from '@bquery/bquery/router';
import { clearPlugins, createStore, defineStore, unregisterPlugin } from '@bquery/bquery/store';
import { mount } from '@bquery/bquery/view';
import { createForm, required } from '@bquery/bquery/forms';
import { createI18n } from '@bquery/bquery/i18n';
import { trapFocus } from '@bquery/bquery/a11y';
import { draggable } from '@bquery/bquery/dnd';
import {
mediaQuery,
useIntersectionObserver,
useMutationObserver,
useResizeObserver,
} from '@bquery/bquery/media';
import { use } from '@bquery/bquery/plugin';
import { enableDevtools } from '@bquery/bquery/devtools';
import { renderComponent } from '@bquery/bquery/testing';
import { createSSRContext, renderToResponse, renderToString, renderToStringAsync } from '@bquery/bquery/ssr';
import { createServer, isServerWebSocketSession, isWebSocketRequest } from '@bquery/bquery/server';
```
## Test Pattern
```ts
import { describe, expect, it } from 'bun:test';
it('description', () => {
const el = document.createElement('div');
document.body.appendChild(el);
// test...
el.remove();
});
```
## File Structure
- Source: `src/<module>/index.ts` re-exports public API
- Tests: `tests/<module>.test.ts`
- Types: `src/<module>/types.ts`
- Internal helpers: marked with `@internal` JSDoc
- Public module docs: `docs/guide/<module>.md` plus `docs/.vitepress/config.ts`
## See Also
- `AGENT.md` for full architecture and API reference
- `llms.txt` for compact project overview
- `.github/copilot-instructions.md` for Copilot-specific context
- `bun run check:ai-guidance` before finishing version / engine / repo-guidance refreshes