Install
openclaw skills install @josunlp/bqueryUse this skill when working with @bquery/bquery, bQuery apps, or the bQuery ecosystem. It helps the agent choose the right bQuery module, write idiomatic code, and use the library across core DOM APIs, reactivity, concurrency workers, Web Components, motion, security, platform helpers, router, store, declarative views, forms, i18n, accessibility, drag-and-drop, media observers, plugins, devtools, testing, Storybook, and SSR.
openclaw skills install @josunlp/bqueryUse this skill whenever a task involves @bquery/bquery.
bQuery is a modular, TypeScript-first, zero-build-capable browser library that combines jQuery-style DOM ergonomics with signals, async workflows, Web Components, motion, routing, stores, declarative views, forms, accessibility helpers, media observers, plugins, devtools, testing, and SSR.
Current documented baseline to keep in mind:
watchDebounce() and watchThrottle() are public reactive APIsbq-error and bq-aria are part of the view surfaceuseIntersectionObserver(), useResizeObserver(), and
useMutationObserver() are public media composablesparallel(),
batchTasks(), map(), filter(), reduce(), and pipeline()Activate this skill when any of the following are true:
package.json includes @bquery/bquery@bquery/bquery or subpaths like:
@bquery/bquery/core@bquery/bquery/reactive@bquery/bquery/component@bquery/bquery/viewbq-* directivesview module, mention CSP implications:
the view evaluator uses new Function() and requires unsafe-eval.Prefer targeted imports:
import { $, $$ } from '@bquery/bquery/core';
import {
signal,
computed,
effect,
watch,
watchDebounce,
watchThrottle,
} from '@bquery/bquery/reactive';
import { component, html } from '@bquery/bquery/component';
Use the root entry only for broad demos:
import {
$,
signal,
component,
registerDefaultComponents,
} from '@bquery/bquery';
| Need | Use |
|---|---|
| DOM selection, traversal, classes, attrs, events | @bquery/bquery/core |
| Signals, computed values, effects, async data, HTTP, sockets | @bquery/bquery/reactive |
| Worker tasks, RPC workers, pools, pipelines | @bquery/bquery/concurrency |
| Web Components | @bquery/bquery/component |
| Storybook helpers | @bquery/bquery/storybook |
| Animation and transitions | @bquery/bquery/motion |
| Sanitization, Trusted Types, CSP helpers | @bquery/bquery/security |
| Storage, cookies, page meta, announcers | @bquery/bquery/platform |
| SPA routing | @bquery/bquery/router |
| App-level state | @bquery/bquery/store |
Declarative DOM with bq-* directives | @bquery/bquery/view |
| Form state and validation | @bquery/bquery/forms |
| Internationalization | @bquery/bquery/i18n |
| Focus and keyboard UX | @bquery/bquery/a11y |
| Drag and drop | @bquery/bquery/dnd |
| Viewport, clipboard, observers, device/browser signals | @bquery/bquery/media |
| Plugins/custom directives | @bquery/bquery/plugin |
| Debugging helpers | @bquery/bquery/devtools |
| Test helpers | @bquery/bquery/testing |
| Server rendering and hydration | @bquery/bquery/ssr |
Use core for direct DOM work:
$(), $$()css() getter/setteris(selector)find(selector)debounce(), throttle(), uid, merge, oncePrefer this for:
Use reactive for state and async workflows:
signal(), computed(), effect(), batch()watch(), watchDebounce(), watchThrottle()linkedSignal(), persistedSignal(), readonly()useAsyncData(), useFetch(), createUseFetch()createHttp(), httpusePolling()usePaginatedFetch(), useInfiniteFetch()useWebSocket(), useWebSocketChannel()useEventSource()useResource(), useResourceList()useSubmit()createRestClient()createRequestQueue()deduplicateRequest()Important reminder:
watchDebounce() and watchThrottle() should be treated like watch()
with the same cleanup-safe callback style.
Use concurrency for CPU-heavy work or isolated execution:
runTask()createTaskWorker(), createTaskPool()createRpcWorker(), createRpcPool()createReactiveTaskWorker(), createReactiveTaskPool()createReactiveRpcWorker(), createReactiveRpcPool()callWorkerMethod()batchTasks()parallel(), pipeline()map(), filter(), reduce(), find(), every(), some()getConcurrencySupport()Prefer this for:
Do not use worker orchestration for tiny UI-only tasks.
Use component for reusable Web Components:
component(tag, def)defineComponent(tag, def)htmlsafeHtmlbool()registerDefaultComponents()Prefer this for:
Use motion for browser-native animation:
animate()transition()flip(), flipElements(), flipList()spring()timeline(), sequence()stagger()scrollAnimate()prefersReducedMotion()Always account for reduced motion.
Use security whenever HTML is dynamic:
sanitize(), sanitizeHtml()trusted()escapeHtml()stripTags()Hard rule: never inject untrusted HTML without sanitizing it first.
Use router for SPA navigation:
createRouter()navigate()back(), forward()currentRoutelink()interceptLinks()resolve()Use store for app-level state:
createStore()defineStore()createPersistedStore()mapState, mapGetters, mapActionswatchStore()Store patterns commonly include:
$state$reset$patch$patchDeep$subscribe$onActionUse view for declarative HTML binding:
mount()createTemplate()clearExpressionCache()Current directive surface to remember includes:
bq-textbq-htmlbq-ifbq-forbq-modelbq-classbq-stylebq-showbq-bindbq-on:eventbq-errorbq-ariaImportant:
the view module uses new Function() internally. Mention that strict CSP
setups need unsafe-eval.
Use:
createForm() and validators from formscreateI18n() from i18ntrapFocus(), releaseFocus(), rovingTabIndex() from a11ydraggable(), droppable(), sortable() from dndmediaQuery(), useViewport(), clipboarduseIntersectionObserver(), useResizeObserver(),
useMutationObserver() from mediaimport { $, $$ } from '@bquery/bquery/core';
$('#save').on('click', () => {
console.log('Saved');
});
$('#list').delegate('click', '.item', (_event, target) => {
$(target).toggleClass('active');
});
$('#box').addClass('ready').css({ opacity: '0.85' });
if ($('#box').is('.ready')) {
console.log($('#box').css('opacity'));
}
$$('.container').find('.item').addClass('found');
import {
computed,
effect,
signal,
useFetch,
watchDebounce,
} from '@bquery/bquery/reactive';
const query = signal('');
const page = signal(1);
const normalizedQuery = computed(() => query.value.trim());
const results = useFetch<{ items: string[]; total: number }>(
() =>
`/search?q=${encodeURIComponent(normalizedQuery.value)}&page=${
page.value
}`,
{
baseUrl: 'https://api.example.com',
watch: [query, page],
}
);
watchDebounce(
query,
() => {
page.value = 1;
},
250
);
effect(() => {
console.log(results.pending.value);
console.log(results.data.value);
console.log(results.error.value);
});
import {
createReactiveTaskPool,
parallel,
} from '@bquery/bquery/concurrency';
const pool = createReactiveTaskPool(
({ value }: { value: number }) => value * 2,
{ size: 4 }
);
const output = await parallel(
[1, 2, 3, 4].map((value) => () => pool.run({ value }))
);
console.log(output);
console.log(pool.pending$.value);
import {
bool,
component,
safeHtml,
} from '@bquery/bquery/component';
import { sanitizeHtml, trusted } from '@bquery/bquery/security';
const badge = trusted(sanitizeHtml('<span class="badge">Active</span>'));
component('user-card', {
props: {
username: { type: String, required: true },
},
state: {
disabled: false,
},
render({ props, state }) {
return safeHtml`
<button class="user-card" ${bool('disabled', state.disabled)}>
${badge}
<span>Hello ${props.username}</span>
</button>
`;
},
});
bq-error and bq-aria<section id="profile-form">
<input
id="email"
bq-model="email"
bq-aria="{ invalid: fieldState.value.invalid, 'aria-describedby': fieldState.value.describedBy }"
type="email"
/>
<p id="email-error" bq-error="formError"></p>
<button bq-on:click="submit">Save</button>
</section>
import { mount } from '@bquery/bquery/view';
import { signal } from '@bquery/bquery/reactive';
const email = signal('');
const formError = signal('');
const fieldState = signal({
invalid: false,
describedBy: '',
});
mount('#profile-form', {
email,
formError,
fieldState,
submit: () => {
const value = email.value.trim();
const invalid = !value.includes('@');
formError.value = invalid ? 'Please enter a valid email address.' : '';
fieldState.value = {
invalid,
describedBy: invalid ? 'email-error' : '',
};
},
});
Note:
if this is used in a strict CSP environment, mention that @bquery/bquery/view
needs unsafe-eval.
When answering bQuery questions:
view moduleDo not:
bq-html with unsafe user content@bquery/bquery/viewIf the task is vague, prefer:
core for small DOM tasksreactive for stateful UIcomponent for reusable widgetsview for declarative plain-HTML bindingforms for structured validationrouter + store for SPA structuresecurity for any dynamic HTMLmedia for observer-driven behaviorconcurrency only when heavy work justifies itUse bQuery as a modular, browser-native toolkit: choose the smallest module, prefer subpath imports, use signals and Web Components idiomatically, sanitize dynamic HTML, document CSP constraints for the view layer, and include accessibility, cleanup, and reduced-motion behavior by default.